1
1
import { Link , Loader , Image } from "./" ;
2
- import React from 'react'
3
- import { utils } from 'ethers'
2
+ import { formatEther } from '@ethersproject/units'
3
+ import React , { useEffect } from 'react'
4
+ import { utils , BigNumber } from 'ethers'
4
5
import { Contract } from '@ethersproject/contracts'
5
- import { useContractFunction , useEthers , useCall } from '@usedapp/core'
6
+ import { useContractFunction , useEthers , useCall , useEtherBalance } from '@usedapp/core'
6
7
import { Erc721 } from '../../gen/types'
7
8
import { addresses , abis } from "@my-app/contracts" ;
8
9
import { Web3Storage } from 'web3.storage/dist/bundle.esm.min.js' ;
9
10
import loader from "../assets/reggae-loader.svg" ;
10
11
import myImage from "../assets/lode-runner.png" ;
11
- import { Button } from '@chakra-ui/react'
12
12
import { FaEthereum } from 'react-icons/fa' ;
13
-
13
+ import { Button , useToast } from '@chakra-ui/react'
14
14
15
15
const nftInterface = new utils . Interface ( abis . erc721 )
16
16
const nftContract = new Contract ( addresses . erc721 , nftInterface ) as Erc721
17
17
18
18
export const Mint = ( ) => {
19
19
20
+ // const ens = useLookupAddress();
20
21
const { account, chainId } = useEthers ( ) ;
22
+ const toast = useToast ( )
23
+ const userBalance = useEtherBalance ( account , { chainId } )
21
24
22
25
const { state, send } = useContractFunction ( nftContract , 'safeMint' )
23
26
const onTx = async ( ) => {
24
27
25
- console . log ( "nft contract address ✅ : " , nftContract . address )
28
+ if ( account === null || account === undefined ) {
29
+
30
+ toast ( {
31
+ position : "bottom-left" ,
32
+ title : "Disconnected 😿" ,
33
+ description : "It seems like you're not connected. Please click on the Connect Wallet' button." ,
34
+ status : "warning" ,
35
+ duration : 5000 ,
36
+ isClosable : true ,
37
+ } )
38
+
39
+ return (
40
+ < > </ >
41
+ )
42
+ }
26
43
27
44
if ( chainId !== 4 ) {
28
45
46
+ toast ( {
47
+ position : "bottom-left" ,
48
+ title : "Wrong network 🌈" ,
49
+ description : "Please switch your network to Rinkeby " ,
50
+ status : "warning" ,
51
+ duration : 2000 ,
52
+ isClosable : true ,
53
+ } )
54
+
29
55
return (
30
- < > </ > // prevents user to click
56
+ < > </ >
31
57
)
58
+ }
32
59
33
- }
60
+ const formatter = new Intl . NumberFormat ( 'en-us' , {
61
+ minimumFractionDigits : 4 ,
62
+ maximumFractionDigits : 4 ,
63
+ } )
64
+
65
+ const formatBalance = ( balance : BigNumber | undefined ) =>
66
+ formatter . format ( parseFloat ( formatEther ( balance ?? BigNumber . from ( '0' ) ) ) )
67
+
68
+ if ( formatBalance ( userBalance ) as any < 0.001 ) {
69
+
70
+ toast ( {
71
+ position : "bottom-left" ,
72
+ title : "Insufficient funds 💰" ,
73
+ description : "You need a handful of Rinkeby ETH to mint your NFT." ,
74
+ status : "error" ,
75
+ duration : 3000 ,
76
+ isClosable : true ,
77
+ } )
78
+
79
+ return (
80
+ < > </ >
81
+ )
82
+ }
34
83
35
84
function getAccessToken ( ) {
36
- console . log ( "getAccessToken ✅ " )
85
+ console . log ( "✅ getAccessToken " )
37
86
return process . env . REACT_APP_WEB3STORAGE_TOKEN ;
38
87
}
39
88
40
89
function makeStorageClient ( ) {
41
- console . log ( "makeStorageClient ✅ " ) ;
90
+ console . log ( "✅ makeStorageClient " ) ;
42
91
return new Web3Storage ( { token : getAccessToken ( ) } ) ;
43
92
}
44
93
45
94
function makeFileObjects ( ) {
46
- console . log ( "makeFileObjects ✅ " ) ;
95
+ console . log ( "✅ makeFileObjects " ) ;
47
96
const obj = {
48
97
"name" : "Lode Runner #1" ,
49
98
"author" : "Julien" ,
@@ -81,18 +130,19 @@ export const Mint = () => {
81
130
}
82
131
83
132
async function storeFiles ( files ) {
84
- console . log ( "storeFiles ✅ " ) ;
133
+ console . log ( "✅ storeFiles " ) ;
85
134
const client = makeStorageClient ( ) ;
86
135
const cid = await client . put ( files ) ;
87
- console . log ( 'stored files with CID ✅ : ' , cid , "🎉" ) ;
136
+ console . log ( '✅ stored files with CID: ' , cid , "🎉" ) ;
88
137
return cid ;
89
138
}
90
139
91
- console . log ( "Hello! 👋 " ) ;
140
+ console . log ( "👋 Hello! " ) ;
92
141
makeStorageClient ( ) ;
93
142
const uri = await storeFiles ( makeFileObjects ( ) ) + "/lode-runner.json" ;
94
- console . log ( "uri: " , uri ) ;
143
+ console . log ( "✅ uri: " , uri ) ;
95
144
145
+ console . log ( "✅ nft contract address: " , nftContract . address )
96
146
97
147
await send (
98
148
// TODO: check the type of an address
@@ -101,17 +151,32 @@ export const Mint = () => {
101
151
)
102
152
}
103
153
154
+ useEffect ( ( ) => {
155
+ if ( state . transaction ?. hash ) {
156
+ if ( state . status === "Success" ) {
157
+ console . log ( "✅ tx hash: " , state . transaction ?. hash )
158
+ toast ( {
159
+ position : "top-left" ,
160
+ title : "Success 🎉" ,
161
+ description : "You just minted an NFT! Here's your tx hash my friend: " + state . transaction ?. hash + ". Thank you for using Mojito app." ,
162
+ status : "success" ,
163
+ duration : 8000 ,
164
+ isClosable : true ,
165
+ } )
166
+ }
167
+ }
168
+ } , [ state . transaction ?. hash , toast , state . status ] ) ;
169
+
104
170
const txHash = state . transaction ?. hash
105
171
const etherscanUrl = "https://rinkeby.etherscan.io/tx/" + txHash
106
172
107
- // TODO: read-only https://usedapp-docs.netlify.app/docs/Guides/Connecting/Read-only
108
173
const { value : bal } =
109
174
useCall ( {
110
175
contract : new Contract ( addresses . erc721 , abis . erc721 ) ,
111
176
method : "balanceOf" ,
112
- args : ( account === null || account === undefined ) ? [ "0xbFBaa5a59e3b6c06afF9c975092B8705f804Fa1c " ] : [ account ] ,
177
+ args : ( account === null || account === undefined ) ? [ "0x157555B75fE690351b9199384e3C473cCFb6EFab " ] : [ account ] ,
113
178
} ) ?? { } ;
114
-
179
+
115
180
const { value : supply } =
116
181
useCall ( {
117
182
contract : new Contract ( addresses . erc721 , abis . erc721 ) ,
@@ -121,10 +186,6 @@ export const Mint = () => {
121
186
122
187
const id = Number ( supply ) - 1
123
188
const openseaUrl = "https://testnets.opensea.io/assets/0x61681514ea040d19dc4279301adc10bf654d886a/" + id
124
-
125
- // TODO: handle sig denied by user
126
- // TODO: handle insufficient funds error
127
- // TODO: invite to switch network if not on Rinkeby
128
189
129
190
return (
130
191
@@ -133,7 +194,9 @@ export const Mint = () => {
133
194
134
195
< Image src = { myImage } />
135
196
136
- { bal && < p > You own < strong > { bal . toString ( ) } </ strong > of these.</ p > }
197
+ { /* {!!!account || ens ? <p>Please connect your wallet.</p> : <p></p>} */ }
198
+ { bal === null || bal === undefined ? < p > </ p > : < p > You own < strong > { bal . toString ( ) } </ strong > of these.</ p > }
199
+
137
200
{ state . status === "Mining" || state . status === "PendingSignature" ?
138
201
< Loader src = { loader } /> :
139
202
@@ -150,9 +213,6 @@ export const Mint = () => {
150
213
{ state . status === "Success" && < > < Link href = { openseaUrl } > { openseaUrl } </ Link >
151
214
< Link href = { etherscanUrl } > { etherscanUrl } </ Link > </ > }
152
215
153
-
154
- { /* <Link href={openseaUrl}>{openseaUrl}</Link>
155
- <Link href={etherscanUrl}>{etherscanUrl} </Link></> */ }
156
216
</ >
157
217
)
158
218
}
0 commit comments