@@ -38,6 +38,20 @@ import { useWallet } from "@solana/wallet-adapter-react";
3838import { Metaplex , walletAdapterIdentity , toBigNumber } from "@metaplex-foundation/js" ;
3939import { WalletMultiButton } from "@solana/wallet-adapter-react-ui" ;
4040
41+ const MAX_RETRIES = 5 ;
42+ const RETRY_DELAY = 2000 ;
43+
44+ const waitForAccountCreation = async ( connection : Connection , address : PublicKey , maxAttempts = 10 ) => {
45+ for ( let attempt = 0 ; attempt < maxAttempts ; attempt ++ ) {
46+ const account = await connection . getAccountInfo ( address ) ;
47+ if ( account ) {
48+ return account ;
49+ }
50+ await new Promise ( resolve => setTimeout ( resolve , 1000 ) ) ;
51+ }
52+ return null ;
53+ } ;
54+
4155interface BrandFormProps {
4256 mode : "create" | "edit" ;
4357 initialData ?: BrandData | null ;
@@ -259,8 +273,14 @@ export default function CreateBrand({
259273 }
260274
261275 try {
276+ // Create a new connection with confirmed commitment
277+ const confirmedConnection = new Connection (
278+ clusterApiUrl ( "devnet" ) ,
279+ 'confirmed'
280+ ) ;
281+
262282 // Check SOL balance
263- const balance = await connection . getBalance ( publicKey ) ;
283+ const balance = await confirmedConnection . getBalance ( publicKey ) ;
264284 const MINIMUM_BALANCE = LAMPORTS_PER_SOL * 0.05 ; // 0.05 SOL
265285 if ( balance < MINIMUM_BALANCE ) {
266286 toast . error ( "Insufficient SOL balance. Need at least 0.05 SOL" ) ;
@@ -294,20 +314,23 @@ export default function CreateBrand({
294314 const metadataUri = `${ process . env . NEXT_PUBLIC_GATEWAY_URL } /ipfs/${ IpfsHash } ` ;
295315
296316 // Create Brand Collection with retries
297- let retries = 3 ;
317+ let retries = MAX_RETRIES ;
298318 let lastError ;
299319
300320 while ( retries > 0 ) {
301321 try {
322+ // Create a new Metaplex instance with the confirmed connection
323+ const confirmedMetaplex = new Metaplex ( confirmedConnection ) . use ( walletAdapterIdentity ( wallet ) ) ;
324+
302325 // Create the NFT collection
303- const { nft : collectionNft , response : createResponse } = await metaplex . nfts ( ) . create ( {
326+ const { nft : collectionNft , response : createResponse } = await confirmedMetaplex . nfts ( ) . create ( {
304327 uri : metadataUri ,
305328 name : form . getValues ( "name" ) ,
306329 sellerFeeBasisPoints : 500 , // 5% royalty
307330 symbol : "BRAND" ,
308331 isCollection : true ,
309332 maxSupply : null ,
310- updateAuthority : metaplex . identity ( ) ,
333+ updateAuthority : confirmedMetaplex . identity ( ) ,
311334 creators : [
312335 {
313336 address : publicKey ,
@@ -316,25 +339,39 @@ export default function CreateBrand({
316339 ] ,
317340 } ) ;
318341
319- // Wait for transaction confirmation with increased commitment
320- const confirmResponse = await connection . confirmTransaction (
321- createResponse . signature ,
322- 'finalized'
323- ) ;
324-
325- if ( confirmResponse . value . err ) {
326- throw new Error ( `Transaction failed: ${ confirmResponse . value . err . toString ( ) } ` ) ;
342+ console . log ( "NFT creation transaction submitted:" , createResponse . signature ) ;
343+
344+ // Wait for transaction confirmation with retry mechanism
345+ let confirmationAttempts = 3 ;
346+ while ( confirmationAttempts > 0 ) {
347+ try {
348+ const confirmResponse = await confirmedConnection . confirmTransaction (
349+ createResponse . signature ,
350+ 'confirmed'
351+ ) ;
352+
353+ if ( confirmResponse . value . err ) {
354+ throw new Error ( `Transaction failed: ${ confirmResponse . value . err . toString ( ) } ` ) ;
355+ }
356+ break ;
357+ } catch ( error ) {
358+ console . warn ( `Confirmation attempt ${ 3 - confirmationAttempts + 1 } failed:` , error ) ;
359+ confirmationAttempts -- ;
360+ if ( confirmationAttempts === 0 ) throw error ;
361+ await new Promise ( resolve => setTimeout ( resolve , 2000 ) ) ;
362+ }
327363 }
328364
329- // Add longer delay for network propagation
330- await new Promise ( resolve => setTimeout ( resolve , 5000 ) ) ;
331-
332- // Verify the NFT exists
333- const nftAccount = await connection . getAccountInfo ( collectionNft . address ) ;
365+ // Wait for account to be queryable
366+ console . log ( "Waiting for NFT account to be queryable..." ) ;
367+ const nftAccount = await waitForAccountCreation ( confirmedConnection , collectionNft . address ) ;
368+
334369 if ( ! nftAccount ) {
335- throw new Error ( "NFT account not found after creation " ) ;
370+ throw new Error ( "NFT account not found after multiple attempts " ) ;
336371 }
337372
373+ console . log ( "NFT account found:" , collectionNft . address . toString ( ) ) ;
374+
338375 // Store collection address for future reference
339376 setIsDeployed ( true ) ;
340377 return collectionNft . address . toString ( ) ;
@@ -343,8 +380,9 @@ export default function CreateBrand({
343380 lastError = error ;
344381 retries -- ;
345382 if ( retries > 0 ) {
346- console . warn ( `NFT creation failed, retrying... (${ retries } attempts left)` ) ;
347- await new Promise ( resolve => setTimeout ( resolve , 5000 ) ) ; // Increased wait time between retries
383+ const delay = RETRY_DELAY * ( MAX_RETRIES - retries ) ; // Exponential backoff
384+ console . warn ( `NFT creation failed, retrying in ${ delay } ms... (${ retries } attempts left)` ) ;
385+ await new Promise ( resolve => setTimeout ( resolve , delay ) ) ;
348386 }
349387 }
350388 }
@@ -367,6 +405,15 @@ export default function CreateBrand({
367405 }
368406
369407 try {
408+ // Create a new connection with confirmed commitment
409+ const confirmedConnection = new Connection (
410+ clusterApiUrl ( "devnet" ) ,
411+ 'confirmed'
412+ ) ;
413+
414+ // Create a new Metaplex instance with the confirmed connection
415+ const confirmedMetaplex = new Metaplex ( confirmedConnection ) . use ( walletAdapterIdentity ( wallet ) ) ;
416+
370417 const metadata = {
371418 name : memory_name ,
372419 symbol : "TRADE" ,
@@ -397,23 +444,73 @@ export default function CreateBrand({
397444 const data = await response . json ( ) ;
398445 const metadataUri = `${ process . env . NEXT_PUBLIC_GATEWAY_URL } /ipfs/${ data . IpfsHash } ` ;
399446
400- const { nft : tradingCollection } = await metaplex . nfts ( ) . create ( {
401- uri : metadataUri ,
402- name : memory_name ,
403- sellerFeeBasisPoints : platformFee * 100 ,
404- symbol : "TRADE" ,
405- isCollection : true ,
406- updateAuthority : metaplex . identity ( ) ,
407- } ) ;
447+ let retries = MAX_RETRIES ;
448+ let lastError ;
408449
409- setIsDeployed ( true ) ;
410- return {
411- mintAddress : tradingCollection . address . toString ( ) ,
412- metadataAddress : tradingCollection . metadataAddress . toString ( ) ,
413- // tokenAddress: tradingCollection.tokenAddress?.toString() || null,
414- } ;
450+ while ( retries > 0 ) {
451+ try {
452+ const { nft : tradingCollection , response : createResponse } = await confirmedMetaplex . nfts ( ) . create ( {
453+ uri : metadataUri ,
454+ name : memory_name ,
455+ sellerFeeBasisPoints : platformFee * 100 ,
456+ symbol : "TRADE" ,
457+ isCollection : true ,
458+ maxSupply : null ,
459+ updateAuthority : confirmedMetaplex . identity ( ) ,
460+ } ) ;
461+
462+ console . log ( "Trading collection creation submitted:" , createResponse . signature ) ;
463+
464+ // Wait for transaction confirmation with retry mechanism
465+ let confirmationAttempts = 3 ;
466+ while ( confirmationAttempts > 0 ) {
467+ try {
468+ const confirmResponse = await confirmedConnection . confirmTransaction (
469+ createResponse . signature ,
470+ 'confirmed'
471+ ) ;
472+
473+ if ( confirmResponse . value . err ) {
474+ throw new Error ( `Transaction failed: ${ confirmResponse . value . err . toString ( ) } ` ) ;
475+ }
476+ break ;
477+ } catch ( error ) {
478+ console . warn ( `Confirmation attempt ${ 3 - confirmationAttempts + 1 } failed:` , error ) ;
479+ confirmationAttempts -- ;
480+ if ( confirmationAttempts === 0 ) throw error ;
481+ await new Promise ( resolve => setTimeout ( resolve , 2000 ) ) ;
482+ }
483+ }
484+
485+ // Wait for account to be queryable
486+ console . log ( "Waiting for trading collection account to be queryable..." ) ;
487+ const nftAccount = await waitForAccountCreation ( confirmedConnection , tradingCollection . address ) ;
488+
489+ if ( ! nftAccount ) {
490+ throw new Error ( "Trading collection account not found after multiple attempts" ) ;
491+ }
492+
493+ console . log ( "Trading collection account found:" , tradingCollection . address . toString ( ) ) ;
494+
495+ return {
496+ mintAddress : tradingCollection . address . toString ( ) ,
497+ metadataAddress : tradingCollection . metadataAddress . toString ( ) ,
498+ } ;
499+ } catch ( error ) {
500+ console . error ( "Trading collection creation error:" , error ) ;
501+ lastError = error ;
502+ retries -- ;
503+ if ( retries > 0 ) {
504+ const delay = RETRY_DELAY * ( MAX_RETRIES - retries ) ; // Exponential backoff
505+ console . warn ( `Trading collection creation failed, retrying in ${ delay } ms... (${ retries } attempts left)` ) ;
506+ await new Promise ( resolve => setTimeout ( resolve , delay ) ) ;
507+ }
508+ }
509+ }
510+
511+ throw lastError ;
415512 } catch ( error ) {
416- console . error ( "Deployment error:" , error ) ;
513+ console . error ( "Trading collection deployment error:" , error ) ;
417514 toast . error ( "Error deploying trading collection: " + error ) ;
418515 throw error ;
419516 }
@@ -601,12 +698,6 @@ export default function CreateBrand({
601698 "TradehubMetadataAddress" ,
602699 tradingCollectionAddresses . metadataAddress
603700 ) ;
604- // if (tradingCollectionAddresses.tokenAddress) {
605- // localStorage.setItem(
606- // "TradehubTokenAddress",
607- // tradingCollectionAddresses.tokenAddress
608- // );
609- // }
610701 console . log (
611702 "Trading collection deployed at:" ,
612703 tradingCollectionAddresses . mintAddress
0 commit comments