V5

Upgrading to thirdweb V5

Thirdweb V5 introduces significant improvements and breaking changes compared to V3 that your project is currently using. Here's a comprehensive guide to upgrade your Ikigai Labs XYZ platform to thirdweb V5.

Overview of Major Changes

  1. New authentication system with @thirdweb-dev/auth
  2. Improved React hooks with @thirdweb-dev/react
  3. Updated SDK with @thirdweb-dev/sdk
  4. Migration from ethers v5 to ethers v6
  5. New wallet connection system

Step-by-Step Upgrade Instructions

1. Update Dependencies

First, update your package.json with the new thirdweb V5 dependencies:

npm uninstall @thirdweb-dev/react @thirdweb-dev/sdk ethers
npm install @thirdweb-dev/react@latest @thirdweb-dev/sdk@latest @thirdweb-dev/auth@latest ethers@6

2. Update ThirdwebProvider

The ThirdwebProvider has changed significantly in V5. Update your provider implementation:

// ... existing code ...
import { 
  ThirdwebProvider, 
  metamaskWallet,
  coinbaseWallet,
  walletConnect,
  localWallet,
  embeddedWallet
} from "@thirdweb-dev/react";
import { Ethereum, Polygon, Base, Zora } from "@thirdweb-dev/chains";

export function ThirdwebProviderWrapper({ children }: { children: React.ReactNode }) {
  // Define supported chains
  const supportedChains = [Ethereum, Polygon, Base, Zora];
  
  // Define supported wallets
  const supportedWallets = [
    metamaskWallet(),
    coinbaseWallet(),
    walletConnect(),
    localWallet(),
    embeddedWallet()
  ];

  return (
    <ThirdwebProvider
      clientId={process.env.NEXT_PUBLIC_THIRDWEB_CLIENT_ID}
      activeChain="ethereum"
      supportedChains={supportedChains}
      supportedWallets={supportedWallets}
    >
      {children}
    </ThirdwebProvider>
  );
}
// ... existing code ...

3. Update Authentication

If you're using thirdweb for authentication, update your auth implementation:

// ... existing code ...
import { useConnect, useDisconnect, useWallet, useAddress } from "@thirdweb-dev/react";

export function LoginButton() {
  const { connect, connectors } = useConnect();
  const { disconnect } = useDisconnect();
  const address = useAddress();
  const wallet = useWallet();
  
  if (address) {
    return (
      <Button onClick={() => disconnect()}>
        Disconnect {address.slice(0, 6)}...{address.slice(-4)}
      </Button>
    );
  }
  
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button>Connect Wallet</Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        {connectors.map((connector) => (
          <DropdownMenuItem 
            key={connector.id} 
            onClick={() => connect(connector)}
          >
            {connector.name}
          </DropdownMenuItem>
        ))}
      </DropdownMenuContent>
    </DropdownMenu>
  );
}
// ... existing code ...

4. Update Contract Interactions

Update how you interact with contracts:

// ... existing code ...
import { useContract, useNFTs, useContractMetadata } from "@thirdweb-dev/react";

export function CollectionDetails({ contractAddress }) {
  const { contract } = useContract(contractAddress);
  const { data: nfts, isLoading: nftsLoading } = useNFTs(contract);
  const { data: metadata, isLoading: metadataLoading } = useContractMetadata(contract);
  
  if (nftsLoading || metadataLoading) {
    return <div>Loading...</div>;
  }
  
  return (
    <div>
      <h1>{metadata?.name}</h1>
      <p>{metadata?.description}</p>
      <div className="grid grid-cols-3 gap-4">
        {nfts?.map((nft) => (
          <div key={nft.metadata.id}>
            <img src={nft.metadata.image} alt={nft.metadata.name} />
            <h3>{nft.metadata.name}</h3>
          </div>
        ))}
      </div>
    </div>
  );
}
// ... existing code ...

5. Update Marketplace Interactions

If you're using marketplace functionality:

// ... existing code ...
import { useContract, useCreateDirectListing, Web3Button } from "@thirdweb-dev/react";

export function CreateListing({ contractAddress, tokenId }) {
  const { contract: marketplace } = useContract(
    process.env.NEXT_PUBLIC_MARKETPLACE_ADDRESS,
    "marketplace-v3"
  );
  
  const { contract: nftCollection } = useContract(contractAddress);
  const { mutateAsync: createDirectListing } = useCreateDirectListing(marketplace);
  
  async function handleCreateListing(e) {
    e.preventDefault();
    const form = e.target;
    const price = form.price.value;
    
    try {
      await createDirectListing({
        assetContractAddress: contractAddress,
        tokenId: tokenId,
        pricePerToken: price,
        currencyContractAddress: "0x0000000000000000000000000000000000000000", // ETH
        startTimestamp: new Date(),
        endTimestamp: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days
      });
    } catch (error) {
      console.error("Error creating listing:", error);
    }
  }
  
  return (
    <form onSubmit={handleCreateListing}>
      <input name="price" type="number" step="0.01" placeholder="Price" />
      <Web3Button
        contractAddress={process.env.NEXT_PUBLIC_MARKETPLACE_ADDRESS}
        action={() => {}}
        type="submit"
      >
        Create Listing
      </Web3Button>
    </form>
  );
}
// ... existing code ...

6. Update API Routes

Update your API routes that use thirdweb:

// ... existing code ...
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
import { NextRequest, NextResponse } from "next/server";

export async function GET(
  request: NextRequest,
  { params }: { params: { address: string } }
) {
  try {
    const { address } = params;
    const sdk = ThirdwebSDK.fromPrivateKey(
      process.env.THIRDWEB_ADMIN_PRIVATE_KEY!,
      "ethereum"
    );
    
    const contract = await sdk.getContract(address);
    const metadata = await contract.metadata.get();
    
    return NextResponse.json({ metadata });
  } catch (error) {
    console.error("Error fetching contract metadata:", error);
    return NextResponse.json(
      { error: "Failed to fetch contract metadata" },
      { status: 500 }
    );
  }
}
// ... existing code ...

7. Update ethers v6 Usage

Ethers v6 has significant changes from v5. Update any direct ethers usage:

// ... existing code ...
import { ethers } from "ethers";

export async function getContractEvents(contractAddress: string, abi: any[]) {
  // ethers v6 changes
  const provider = new ethers.JsonRpcProvider(process.env.NEXT_PUBLIC_RPC_URL);
  const contract = new ethers.Contract(contractAddress, abi, provider);
  
  // Filter has changed in v6
  const filter = contract.filters.Transfer();
  const events = await contract.queryFilter(filter, -1000, "latest");
  
  return events;
}
// ... existing code ...

8. Update Environment Variables

Make sure to update your environment variables:

NEXT_PUBLIC_THIRDWEB_CLIENT_ID=your-client-id
NEXT_PUBLIC_THIRDWEB_SECRET_KEY=your-secret-key
THIRDWEB_ADMIN_PRIVATE_KEY=your-admin-private-key

9. Testing

After implementing these changes, thoroughly test your application:

  1. Test wallet connection with different wallets
  2. Test authentication flow
  3. Test NFT browsing and viewing
  4. Test marketplace functionality (listing, buying, etc.)
  5. Test across different chains

Additional Resources

This upgrade will significantly improve your application's performance and capabilities while ensuring compatibility with the latest blockchain standards and features.


I'll need to analyze your code to understand how you're currently using Reservoir Tools alongside thirdweb V3, which will help determine the scope of refactoring needed for the thirdweb V5 upgrade. Since you haven't shared specific code files, I'll provide guidance based on common integration patterns and potential impact areas.

Thirdweb V5 Upgrade Analysis with Reservoir Tools Integration

Current Architecture Assessment

In Ikigai Labs XYZ, you're using both Reservoir Tools and thirdweb SDK V3, with dependencies:

  • @reservoir0x/reservoir-kit-ui: ^1.0.1
  • @thirdweb-dev/react: ^3.14.40
  • @thirdweb-dev/sdk: ^3.10.59
  • ethers: ^5.7.2

This suggests a hybrid architecture where:

  1. Reservoir likely handles marketplace aggregation, collection browsing, and token discovery
  2. Thirdweb likely handles wallet connection, authentication, and possibly smart contract interactions

Impact Analysis

1. Wallet Connection & Authentication

If you're using thirdweb for wallet connection:

// Current implementation might look like:
import { useMetamask, useWalletConnect, useCoinbaseWallet } from "@thirdweb-dev/react";

// This needs to change to:
import { 
  useConnect,
  metamaskWallet,
  walletConnect,
  coinbaseWallet
} from "@thirdweb-dev/react";

Impact Level: High - This is a fundamental change in how wallet connections work.

2. Reservoir Integration Points

Reservoir Kit UI typically uses its own providers and hooks:

// Example of Reservoir provider
import { ReservoirKitProvider } from '@reservoir0x/reservoir-kit-ui';

// This likely won't change with thirdweb V5

Impact Level: Low - Reservoir components should continue to work with minimal changes.

3. Contract Interactions

If you're using thirdweb for direct contract interactions:

// Current implementation
import { useContract, useNFTCollection } from "@thirdweb-dev/react";

// Needs to change to:
import { useContract, useNFTs } from "@thirdweb-dev/react";

Impact Level: Medium - Contract interaction hooks have changed, but the concept remains similar.

4. Ethers Integration

Both Reservoir and thirdweb use ethers, but thirdweb V5 uses ethers v6:

// If you have direct ethers usage:
import { ethers } from "ethers";
const provider = new ethers.providers.Web3Provider(window.ethereum);

// Needs to change to:
import { ethers } from "ethers";
const provider = new ethers.BrowserProvider(window.ethereum);

Impact Level: Medium to High - Depends on how much direct ethers code you have.

Based on the typical integration patterns, here's a phased approach:

Phase 1: Minimal Viable Upgrade

  1. Update ThirdwebProvider only:
import { 
  ThirdwebProvider, 
  metamaskWallet,
  coinbaseWallet,
  walletConnect
} from "@thirdweb-dev/react";

export function ThirdwebProviderWrapper({ children }) {
  return (
    <ThirdwebProvider
      clientId={process.env.NEXT_PUBLIC_THIRDWEB_CLIENT_ID}
      activeChain="ethereum"
      supportedWallets={[
        metamaskWallet(),
        coinbaseWallet(),
        walletConnect()
      ]}
    >
      {children}
    </ThirdwebProvider>
  );
}
  1. Update wallet connection hooks:
// ... existing code ...
import { useConnect, useDisconnect, useAddress } from "@thirdweb-dev/react";

export function WalletConnectButton() {
  const { connect, connectors } = useConnect();
  const { disconnect } = useDisconnect();
  const address = useAddress();
  
  // Rest of your component logic
}
// ... existing code ...
  1. Keep Reservoir integration unchanged initially.

Phase 2: Contract Interaction Updates

Update any direct thirdweb contract interactions:

// ... existing code ...
import { useContract, useMintNFT } from "@thirdweb-dev/react";

export function MintButton({ contractAddress }) {
  const { contract } = useContract(contractAddress);
  const { mutateAsync: mintNft, isLoading } = useMintNFT(contract);
  
  // Rest of your component logic
}
// ... existing code ...

Phase 3: Ethers Updates

If you have direct ethers usage, update to ethers v6 syntax:

// ... existing code ...
import { ethers } from "ethers";

export async function signMessage(message) {
  // Old v5 code
  // const provider = new ethers.providers.Web3Provider(window.ethereum);
  // const signer = provider.getSigner();
  
  // New v6 code
  const provider = new ethers.BrowserProvider(window.ethereum);
  const signer = await provider.getSigner();
  
  return await signer.signMessage(message);
}
// ... existing code ...

Potential Conflicts to Watch For

  1. Provider Conflicts: Reservoir and thirdweb both might try to manage providers. Ensure they don't conflict.
  2. Wallet Connection: If Reservoir uses its own wallet connection, you might need to synchronize wallet state.
  3. Chain Switching: Both libraries might handle chain switching differently in V5.
  4. Transaction Handling: Watch for differences in how transactions are handled.

Testing Strategy

  1. Create a feature branch for the upgrade
  2. Implement Phase 1 changes
  3. Test basic wallet connection
  4. Test Reservoir browsing functionality
  5. Implement Phase 2 changes
  6. Test contract interactions
  7. Implement Phase 3 changes
  8. Comprehensive testing across all features

Conclusion

The upgrade to thirdweb V5 while maintaining Reservoir Tools integration should be manageable with a phased approach. The most significant changes will be in wallet connection and authentication flows, while Reservoir components should continue to work with minimal adjustments.

To provide more specific guidance, I would need to see your actual implementation code, particularly:

  1. How you've integrated the ThirdwebProvider
  2. How you're handling wallet connections
  3. Any direct contract interactions using thirdweb
  4. How Reservoir and thirdweb components interact in your UI

Would you like to share any specific code files for a more detailed analysis?