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
- New authentication system with
@thirdweb-dev/auth
- Improved React hooks with
@thirdweb-dev/react
- Updated SDK with
@thirdweb-dev/sdk
- Migration from ethers v5 to ethers v6
- 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:
- Test wallet connection with different wallets
- Test authentication flow
- Test NFT browsing and viewing
- Test marketplace functionality (listing, buying, etc.)
- 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.59ethers
: ^5.7.2
This suggests a hybrid architecture where:
- Reservoir likely handles marketplace aggregation, collection browsing, and token discovery
- 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.
Recommended Upgrade Approach
Based on the typical integration patterns, here's a phased approach:
Phase 1: Minimal Viable Upgrade
- 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>
);
}
- 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 ...
- 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
- Provider Conflicts: Reservoir and thirdweb both might try to manage providers. Ensure they don't conflict.
- Wallet Connection: If Reservoir uses its own wallet connection, you might need to synchronize wallet state.
- Chain Switching: Both libraries might handle chain switching differently in V5.
- Transaction Handling: Watch for differences in how transactions are handled.
Testing Strategy
- Create a feature branch for the upgrade
- Implement Phase 1 changes
- Test basic wallet connection
- Test Reservoir browsing functionality
- Implement Phase 2 changes
- Test contract interactions
- Implement Phase 3 changes
- 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:
- How you've integrated the ThirdwebProvider
- How you're handling wallet connections
- Any direct contract interactions using thirdweb
- How Reservoir and thirdweb components interact in your UI
Would you like to share any specific code files for a more detailed analysis?