1+ import { Spinner } from "@/components/ui/Spinner/Spinner" ;
2+ import { Button } from "@/components/ui/button" ;
13import {
24 Form ,
35 FormControl ,
@@ -11,14 +13,25 @@ import { zodResolver } from "@hookform/resolvers/zod";
1113import { useMutation } from "@tanstack/react-query" ;
1214import { useForm } from "react-hook-form" ;
1315import { toast } from "sonner" ;
14- import { type ContractOptions , waitForReceipt } from "thirdweb" ;
16+ import {
17+ type ContractOptions ,
18+ prepareContractCall ,
19+ waitForReceipt ,
20+ } from "thirdweb" ;
1521import { MintableERC721 } from "thirdweb/modules" ;
16- import { useReadContract , useSendTransaction } from "thirdweb/react" ;
22+ import {
23+ useActiveAccount ,
24+ useReadContract ,
25+ useSendTransaction ,
26+ } from "thirdweb/react" ;
1727import { z } from "zod" ;
1828import { ModuleCardUI , type ModuleCardUIProps } from "./module-card" ;
1929
2030const formSchema = z . object ( {
2131 primarySaleRecipient : z . string ( ) ,
32+ tokenId : z . string ( ) ,
33+ amount : z . string ( ) ,
34+ recipient : z . string ( ) ,
2235} ) ;
2336
2437export type MintableModuleFormValues = z . infer < typeof formSchema > ;
@@ -30,6 +43,7 @@ export function MintableModule(
3043 } ,
3144) {
3245 const { contract } = props ;
46+ const account = useActiveAccount ( ) ;
3347 const { mutateAsync : sendTransaction } = useSendTransaction ( ) ;
3448 const { data : primarySaleRecipient , isLoading } = useReadContract (
3549 MintableERC721 . getSaleConfig ,
@@ -56,11 +70,57 @@ export function MintableModule(
5670 }
5771 }
5872
73+ async function mint ( values : {
74+ tokenId : string ;
75+ amount : string ;
76+ recipient : string ;
77+ //_uri: string,
78+ //_data: string,
79+ } ) {
80+ const { tokenId, amount, recipient } = values ;
81+ const grantTransaction = prepareContractCall ( {
82+ contract,
83+ method : "function grantRoles(address user, uint256 roles)" ,
84+ params : [ account ?. address || "0x0" , BigInt ( 1 ) ] ,
85+ } ) ;
86+
87+ const grantTxResult = await sendTransaction ( grantTransaction ) ;
88+ console . log ( "grantTxResult: " , grantTxResult ) ;
89+
90+ try {
91+ await waitForReceipt ( grantTxResult ) ;
92+ toast . success ( "Successfully granted Roles to account" ) ;
93+ } catch ( _ ) {
94+ toast . error ( "Failed to grant Roles to account" ) ;
95+ }
96+ try {
97+ const transaction = prepareContractCall ( {
98+ contract,
99+ method :
100+ "function mint(address to, uint256 tokenId, uint256 amount, string calldata baseURI, bytes memory data)" ,
101+ params : [ recipient , BigInt ( tokenId ) , BigInt ( amount ) , "" , "0x" ] ,
102+ } ) ;
103+
104+ const txResult = await sendTransaction ( transaction ) ;
105+ console . log ( "mint txResult: " , txResult ) ;
106+
107+ try {
108+ await waitForReceipt ( txResult ) ;
109+ toast . success ( "Successfully minted" ) ;
110+ } catch ( _ ) {
111+ toast . error ( "Failed to mint" ) ;
112+ }
113+ } catch ( e ) {
114+ console . log ( "mint error: " , e ) ;
115+ }
116+ }
117+
59118 return (
60119 < MintableModuleUI
61120 isPending = { isLoading }
62121 primarySaleRecipient = { primarySaleRecipient || "" }
63122 update = { update }
123+ mint = { mint }
64124 { ...props }
65125 />
66126 ) ;
@@ -72,12 +132,20 @@ export function MintableModuleUI(
72132 isPending : boolean ;
73133 isOwnerAccount : boolean ;
74134 update : ( values : MintableModuleFormValues ) => Promise < void > ;
135+ mint : ( values : {
136+ tokenId : string ;
137+ amount : string ;
138+ recipient : string ;
139+ } ) => Promise < void > ;
75140 } ,
76141) {
77142 const form = useForm < MintableModuleFormValues > ( {
78143 resolver : zodResolver ( formSchema ) ,
79144 values : {
80145 primarySaleRecipient : props . primarySaleRecipient ,
146+ tokenId : "" ,
147+ amount : "" ,
148+ recipient : "" ,
81149 } ,
82150 reValidateMode : "onChange" ,
83151 } ) ;
@@ -86,13 +154,24 @@ export function MintableModuleUI(
86154 mutationFn : props . update ,
87155 } ) ;
88156
157+ const mintMutation = useMutation ( {
158+ mutationFn : props . mint ,
159+ } ) ;
160+
89161 const onSubmit = async ( ) => {
90162 const _values = form . getValues ( ) ;
91163 const values = { ..._values } ;
92164
93165 updateMutation . mutate ( values ) ;
94166 } ;
95167
168+ const mint = ( ) => {
169+ const _values = form . getValues ( ) ;
170+ const values = { ..._values } ;
171+
172+ mintMutation . mutate ( values ) ;
173+ } ;
174+
96175 if ( props . isPending ) {
97176 return < Skeleton className = "h-36" /> ;
98177 }
@@ -108,8 +187,7 @@ export function MintableModuleUI(
108187 >
109188 < Form { ...form } >
110189 < form onSubmit = { form . handleSubmit ( onSubmit ) } >
111- < div className = "flex gap-4" >
112- { /* Switch */ }
190+ < div className = "flex flex-col gap-4" >
113191 < FormField
114192 control = { form . control }
115193 name = "primarySaleRecipient"
@@ -126,6 +204,76 @@ export function MintableModuleUI(
126204 </ FormItem >
127205 ) }
128206 />
207+
208+ < div className = "h-5" />
209+
210+ < div className = "flex gap-4" >
211+ < FormField
212+ control = { form . control }
213+ name = "tokenId"
214+ render = { ( { field } ) => (
215+ < FormItem className = "flex flex-1 flex-col gap-3" >
216+ < FormLabel > Token ID</ FormLabel >
217+ < FormControl >
218+ < Input
219+ placeholder = "0"
220+ { ...field }
221+ disabled = { ! props . isOwnerAccount }
222+ />
223+ </ FormControl >
224+ </ FormItem >
225+ ) }
226+ />
227+
228+ < FormField
229+ control = { form . control }
230+ name = "amount"
231+ render = { ( { field } ) => (
232+ < FormItem className = "flex flex-1 flex-col gap-3" >
233+ < FormLabel > Amount</ FormLabel >
234+ < FormControl >
235+ < Input
236+ placeholder = "0"
237+ { ...field }
238+ disabled = { ! props . isOwnerAccount }
239+ />
240+ </ FormControl >
241+ </ FormItem >
242+ ) }
243+ />
244+
245+ < FormField
246+ control = { form . control }
247+ name = "recipient"
248+ render = { ( { field } ) => (
249+ < FormItem className = "flex flex-1 flex-col gap-3" >
250+ < FormLabel > Recipient</ FormLabel >
251+ < FormControl >
252+ < Input
253+ placeholder = "0x..."
254+ { ...field }
255+ disabled = { ! props . isOwnerAccount }
256+ />
257+ </ FormControl >
258+ </ FormItem >
259+ ) }
260+ />
261+ </ div >
262+ </ div >
263+
264+ < div className = "h-5" />
265+
266+ < div className = "flex justify-end" >
267+ < Button
268+ size = "sm"
269+ className = "min-w-24 gap-2"
270+ type = "button"
271+ onClick = { ( ) => mint ( ) }
272+ disabled = { mintMutation . isPending || ! props . isOwnerAccount }
273+ >
274+ { mintMutation . isPending && < Spinner className = "size-4" /> }
275+ Mint
276+ </ Button >
129277 </ div >
130278 </ form >
131279 </ Form >
0 commit comments