Skip to content

Commit 8b5bd30

Browse files
chore: fix deployment issue
1 parent 60b87e8 commit 8b5bd30

1 file changed

Lines changed: 132 additions & 41 deletions

File tree

src/components/BrandForm.tsx

Lines changed: 132 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,20 @@ import { useWallet } from "@solana/wallet-adapter-react";
3838
import { Metaplex, walletAdapterIdentity, toBigNumber } from "@metaplex-foundation/js";
3939
import { 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+
4155
interface 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

Comments
 (0)