diff --git a/contracts/Rocketeer.sol b/contracts/Rocketeer.sol index f5aaa50..45242fd 100644 --- a/contracts/Rocketeer.sol +++ b/contracts/Rocketeer.sol @@ -13,7 +13,7 @@ contract Rocketeer is ERC721Tradable { // /////////////////////////////// // Globals // /////////////////////////////// - uint256 private ROCKETEER_MAX_SUPPLY = 5; + uint256 private ROCKETEER_MAX_SUPPLY = 9001; // Construct as Opensea tradable item constructor(address _proxyRegistryAddress) diff --git a/minter/src/App.js b/minter/src/App.js index 826457b..53a906d 100644 --- a/minter/src/App.js +++ b/minter/src/App.js @@ -1,12 +1,25 @@ import Fox from './assets/metamask-fox.svg' // import LaunchBackground from './assets/undraw_To_the_stars_qhyy.svg' -import LaunchBackground from './assets/undraw_relaunch_day_902d-fixed.svg' +// import LaunchBackground from './assets/undraw_relaunch_day_902d-fixed.svg' +import LaunchBackground from './assets/undraw_launch_day_4e04.svg' import './App.css' import { useState, useEffect } from 'react' -import { getAddress, useAddress, useTotalSupply, useContract } from './modules/web3' -import { log } from './modules/helpers' +import { getAddress, useAddress, useTotalSupply, useContract, useChainId, rocketeerUriOnOpensea } from './modules/web3' +import { log, setListenerAndReturnUnlistener } from './modules/helpers' + +const Container = ( { children } ) =>
+ +
+ + { children } + +
+ + Launching rocket + +
function App() { @@ -15,8 +28,10 @@ function App() { // /////////////////////////////// const [ loading, setLoading ] = useState( 'Detecting metamask...' ) const [ error, setError ] = useState( undefined ) + const [ mintedTokenId, setMintedTokenId ] = useState( undefined ) const totalSupply = useTotalSupply( ) const address = useAddress() + const chainId = useChainId() // Handle contract interactions const contract = useContract() @@ -55,9 +70,11 @@ function App() { const response = await contract.spawnRocketeer( address ) log( 'Successful mint with: ', response ) + setLoading( 'Waiting for confirmations...' ) + } catch( e ) { log( 'Minting error: ', e ) - } finally { + alert( `Minting error: ${ e.message }` ) setLoading( false ) } @@ -66,7 +83,20 @@ function App() { // /////////////////////////////// // Lifecycle // /////////////////////////////// + useEffect( f => setListenerAndReturnUnlistener( contract, 'Transfer', async ( from, to, amount, event ) => { + + try { + log( `useEffect: Transfer ${ from } sent to ${ to } `, amount, event ) + const [ transFrom, transTo, tokenId ] = event.args + setMintedTokenId( tokenId.toString() ) + setLoading( false ) + + } catch( e ) { + log( 'Error getting Transfer event from contract: ', e ) + } + + } ), [ contract, loading ] ) // Check for metamask on load useEffect( f => window.ethereum ? setLoading( false ) : setError( 'No web3 provider detected, please install metamask' ), [] ) @@ -76,10 +106,15 @@ function App() { // /////////////////////////////// // Initialisation interface - if( error || loading || !address ) return
+ if( error || loading || !address ) return { error &&

{ error }

} - { loading &&

{ loading }

} - { !address && ( !error && !loading ) &&
+ { loading &&
+ +
+

{ loading }

+ +
} + { !address && ( !error && !loading ) && <>

Rocketeer Minter

This interface is used to mint new Rocketeer NFTs. Minting is free, except for the gas fees. After minting you can view your new Rocketeer and its attributes on Opensea.

@@ -89,35 +124,35 @@ function App() { Connect wallet -
} -
+ } + + + if( mintedTokenId ) return + +

Minting Successful!

+ View on Opensea + +
// Render main interface return ( -
- -
- +

Rocketeer Minter

We are ready to mint! There are currently { totalSupply } minted Rocketeers.

- + { contract && metamask fox Mint new Rocketeer } - - - -
Launching rocket -
- ); + + ) } export default App; diff --git a/minter/src/assets/undraw_launch_day_4e04.svg b/minter/src/assets/undraw_launch_day_4e04.svg new file mode 100644 index 0000000..d88a1dd --- /dev/null +++ b/minter/src/assets/undraw_launch_day_4e04.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/minter/src/index.css b/minter/src/index.css index 50f130d..1d6dd99 100644 --- a/minter/src/index.css +++ b/minter/src/index.css @@ -53,14 +53,54 @@ input#address { .stretchBackground { position: absolute; - opacity: 1; + width: 120%; + min-width: 1920px; + opacity: .5; z-index: -1; } -h1, p, label, .button { - background: rgba( 255, 255, 255, .8 ); +.container { + padding: 2rem; + background: rgba( 255, 255, 255, 1 ); + box-shadow: 0px 0 5px 5px rgb(0 0 0 / 10%); + text-align: center; } h1, p, label { padding: .2rem .5rem; -} \ No newline at end of file +} + +/*Loading spinner*/ +.loading { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} +.loading * { + margin: 2rem 0; +} +.lds-dual-ring { + display: inline-block; + width: 80px; + height: 80px; +} +.lds-dual-ring:after { + content: " "; + display: block; + width: 64px; + height: 64px; + margin: 8px; + border-radius: 50%; + border: 6px solid black; + border-color: black transparent black transparent; + animation: lds-dual-ring 1.2s linear infinite; +} +@keyframes lds-dual-ring { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/minter/src/modules/web3.js b/minter/src/modules/web3.js index d6f2b20..5575120 100644 --- a/minter/src/modules/web3.js +++ b/minter/src/modules/web3.js @@ -134,7 +134,8 @@ export function useChainId() { // /////////////////////////////// const contractAddressByChainId = { '0x1': '', - '0x4': '0x2829ba9d76e675b8867E1707A9aB49B280D916c6' + // '0x4': '0x2829ba9d76e675b8867E1707A9aB49B280D916c6', // Old + '0x4': '0x89D9f02D2877A35E8323DC1b578FD1f6014B04d0' } const ABI = [ @@ -223,4 +224,17 @@ export function useContract() { return contract -} \ No newline at end of file +} + +export function rocketeerCollectionUriOnOpensea( chainId ) { + + return `${ chainId === '0x01' ? '' : 'testnets.' }opensea.io/collection/rocketeer` + +} + +export function rocketeerUriOnOpensea( chainId, tokenId ) { + + return `https://${ chainId === '0x01' ? '' : 'testnets.' }opensea.io/assets/${ contractAddressByChainId[ chainId ] }/${ tokenId }` + +} +