Skip to content
Merged

v3 #157

Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d19304d
Add social OAuth endpoint and update payments API
0xFirekeeper Sep 8, 2025
f096e7b
Remove User model and related code from EmbeddedWallet
0xFirekeeper Sep 8, 2025
bf6809e
Refactor RPC types and update namespace usage
0xFirekeeper Sep 8, 2025
88d44e4
Remove unused Nethereum import in ThirdwebBundler
0xFirekeeper Sep 8, 2025
7e89bb1
Remove Nethereum.RLP dependency and refactor RLP usage
0xFirekeeper Sep 8, 2025
4047d93
Refactor tests to use guest wallet instead of private key wallet
0xFirekeeper Sep 8, 2025
0bffbe3
Remove deprecated EngineWallet implementation
0xFirekeeper Sep 8, 2025
d81764e
Remove deprecated ThirdwebPay payment module
0xFirekeeper Sep 8, 2025
438e324
Remove Thirdweb AI and Indexer modules
0xFirekeeper Sep 8, 2025
13c7997
Remove commented Indexer and AI demo code
0xFirekeeper Sep 8, 2025
c15edc6
Remove Nebula AI tests and rename API client file
0xFirekeeper Sep 8, 2025
53eeaec
Remove unused exception and enum, refactor DataStorage
0xFirekeeper Sep 8, 2025
03a824c
Move EIP712 and RLP utilities to Utils folder
0xFirekeeper Sep 8, 2025
75c1f55
Refactor namespaces and consolidate type files
0xFirekeeper Sep 8, 2025
28a0b1c
Add Makefile and generator, update API client
0xFirekeeper Sep 24, 2025
6367923
Remove Thirdweb.Bridge and related constants
0xFirekeeper Sep 24, 2025
899a4f8
Update Makefile help text and remove generate-api alias
0xFirekeeper Sep 24, 2025
7ae8427
Remove marketplace extensions and update wallet flows
0xFirekeeper Sep 24, 2025
1c9894c
Comment out social auth example and remove marketplace tests
0xFirekeeper Sep 24, 2025
8c45dc2
Merge branch 'main' into v3
0xFirekeeper Sep 24, 2025
602e6eb
Update guest account logic and codecov ignore paths
0xFirekeeper Sep 24, 2025
cd1d59d
Make ThirdwebTransactionInput properties public and auto-implemented
0xFirekeeper Sep 24, 2025
098c1a6
Fix property backing fields in ThirdwebTransactionInput
0xFirekeeper Sep 24, 2025
9ef0d3d
Add extension methods for sending transactions
0xFirekeeper Sep 24, 2025
7123619
Fix missing await in LoginWithGuest call in tests
0xFirekeeper Sep 24, 2025
1c59cf3
Update Nethereum packages and remove AA silent revert tests
0xFirekeeper Sep 24, 2025
a816486
Refactor transaction input handling and remove ThirdwebApi
0xFirekeeper Sep 24, 2025
018ec19
Remove MinimalForwarder signature support
0xFirekeeper Sep 24, 2025
2edf6ef
Use cts.Token for delay in transaction polling
0xFirekeeper Sep 24, 2025
d2fc677
Update Program.cs
0xFirekeeper Sep 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 7 additions & 147 deletions Thirdweb.Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,17 @@

#region Basic Wallet Interaction

// Create a private key wallet
var privateKeyWallet = await PrivateKeyWallet.Generate(client);

// var walletAddress = await privateKeyWallet.GetAddress();
// Console.WriteLine($"PK Wallet address: {walletAddress}");
// Create a guest wallet
var guestWallet = await InAppWallet.Create(client, authProvider: AuthProvider.Guest);
var walletAddress = await guestWallet.LoginWithGuest();
Console.WriteLine($"Guest Wallet address: {walletAddress}");

#endregion

#region Basic Contract Interaction

// var contract = await ThirdwebContract.Create(client: client, address: "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d", chain: 1);
// var nfts = await contract.ERC721_GetAllNFTs();
// var nfts = await contract.ERC721_GetNFT(0);
// Console.WriteLine($"NFTs: {JsonConvert.SerializeObject(nfts, Formatting.Indented)}");

#endregion
Expand Down Expand Up @@ -174,143 +173,6 @@

#endregion

#region Indexer

// // Create a ThirdwebInsight instance
// var insight = await ThirdwebInsight.Create(client);

// var ethPriceToday = await insight.GetTokenPrice(addressOrSymbol: "ETH", chainId: 1);
// Console.WriteLine($"ETH price today: {ethPriceToday.PriceUsd}");

// var ethPriceYesterday = await insight.GetTokenPrice(addressOrSymbol: "ETH", chainId: 1, timestamp: Utils.GetUnixTimeStampNow() - 86400);
// Console.WriteLine($"ETH price yesterday: {ethPriceYesterday.PriceUsd}");

// var multiTokenPrices = await insight.GetTokenPrices(addressOrSymbols: new[] { "POL", "APE" }, chainIds: new BigInteger[] { 137, 33139 });
// Console.WriteLine($"Multi token prices: {JsonConvert.SerializeObject(multiTokenPrices, Formatting.Indented)}");

// // Setup some filters
// var address = await Utils.GetAddressFromENS(client, "vitalik.eth");
// var chains = new BigInteger[] { 1, 137, 42161 };

// // Fetch all token types
// var tokens = await insight.GetTokens(address, chains);
// Console.WriteLine($"ERC20 Count: {tokens.erc20Tokens.Length} | ERC721 Count: {tokens.erc721Tokens.Length} | ERC1155 Count: {tokens.erc1155Tokens.Length}");

// // Fetch specific token types
// var erc20Tokens = await insight.GetTokens_ERC20(address, chains);
// Console.WriteLine($"ERC20 Tokens: {JsonConvert.SerializeObject(erc20Tokens, Formatting.Indented)}");

// // Fetch specific token types
// var erc721Tokens = await insight.GetTokens_ERC721(address, chains);
// Console.WriteLine($"ERC721 Tokens: {JsonConvert.SerializeObject(erc721Tokens, Formatting.Indented)}");

// // Fetch specific token types
// var erc1155Tokens = await insight.GetTokens_ERC1155(address, chains);
// Console.WriteLine($"ERC1155 Tokens: {JsonConvert.SerializeObject(erc1155Tokens, Formatting.Indented)}");

// // Fetch events (great amount of optional filters available)
// var events = await insight.GetEvents(
// chainIds: new BigInteger[] { 1 }, // ethereum
// contractAddress: "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d", // bored apes
// eventSignature: "Transfer(address,address,uint256)", // transfer event
// fromTimestamp: Utils.GetUnixTimeStampNow() - 3600, // last hour
// sortBy: SortBy.TransactionIndex, // block number, block timestamp or transaction index
// sortOrder: SortOrder.Desc, // latest first
// limit: 5 // last 5 transfers
// );
// Console.WriteLine($"Events: {JsonConvert.SerializeObject(events, Formatting.Indented)}");

// // Fetch transactions (great amount of optional filters available)
// var transactions = await insight.GetTransactions(
// chainIds: new BigInteger[] { 1 }, // ethereum
// contractAddress: "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d", // bored apes
// fromTimestamp: Utils.GetUnixTimeStampNow() - 3600, // last hour
// sortBy: SortBy.TransactionIndex, // block number, block timestamp or transaction index
// sortOrder: SortOrder.Desc, // latest first
// limit: 5 // last 5 transactions
// );
// Console.WriteLine($"Transactions: {JsonConvert.SerializeObject(transactions, Formatting.Indented)}");

// // Use ToNFT to ToNFTList extensions
// var convertedNft = erc721Tokens[0].ToNFT();

// var convertedNfts = erc721Tokens.ToNFTList();

// // Use NFT Extensions (GetNFTImageBytes, or GetNFTSprite in Unity)
// var imageBytes = await convertedNft.GetNFTImageBytes(client);
// var pathToSave = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "nft.png");
// await File.WriteAllBytesAsync(pathToSave, imageBytes);
// Console.WriteLine($"NFT image saved to: {pathToSave}");

#endregion

#region AI

// // Prepare some context
// var myChain = 11155111;
// var myWallet = await SmartWallet.Create(personalWallet: await PrivateKeyWallet.Generate(client), chainId: myChain, gasless: true);
// var myContractAddress = "0xe2cb0eb5147b42095c2FfA6F7ec953bb0bE347D8"; // DropERC1155
// var usdcAddress = "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238";

// // Create a Nebula session
// var nebula = await ThirdwebNebula.Create(client);

// // Chat, passing wallet context
// var response1 = await nebula.Chat(message: "What is my wallet address?", wallet: myWallet);
// Console.WriteLine($"Response 1: {response1.Message}");

// // Chat, passing contract context
// var response2 = await nebula.Chat(
// message: "What's the total supply of token id 0 for this contract?",
// context: new NebulaContext(contractAddresses: new List<string> { myContractAddress }, chainIds: new List<BigInteger> { myChain })
// );
// Console.WriteLine($"Response 2: {response2.Message}");

// // Chat, passing multiple messages and context
// var response3 = await nebula.Chat(
// messages: new List<NebulaChatMessage>
// {
// new($"Tell me the name of this contract: {myContractAddress}", NebulaChatRole.User),
// new("The name of the contract is CatDrop", NebulaChatRole.Assistant),
// new("What's the symbol of this contract?", NebulaChatRole.User),
// },
// context: new NebulaContext(contractAddresses: new List<string> { myContractAddress }, chainIds: new List<BigInteger> { myChain })
// );
// Console.WriteLine($"Response 3: {response3.Message}");

// // Execute, this directly sends transactions
// var executionResult = await nebula.Execute("Approve 1 USDC to vitalik.eth", wallet: myWallet, context: new NebulaContext(contractAddresses: new List<string>() { usdcAddress }));
// if (executionResult.TransactionReceipts != null && executionResult.TransactionReceipts.Count > 0)
// {
// Console.WriteLine($"Receipt: {executionResult.TransactionReceipts[0]}");
// }
// else
// {
// Console.WriteLine($"Message: {executionResult.Message}");
// }

// // Batch execute
// var batchExecutionResult = await nebula.Execute(
// new List<NebulaChatMessage>
// {
// new("What's the address of vitalik.eth", NebulaChatRole.User),
// new("The address of vitalik.eth is 0xd8dA6BF26964aF8E437eEa5e3616511D7G3a3298", NebulaChatRole.Assistant),
// new("Approve 1 USDC to them", NebulaChatRole.User),
// },
// wallet: myWallet,
// context: new NebulaContext(contractAddresses: new List<string>() { usdcAddress })
// );
// if (batchExecutionResult.TransactionReceipts != null && batchExecutionResult.TransactionReceipts.Count > 0)
// {
// Console.WriteLine($"Receipts: {JsonConvert.SerializeObject(batchExecutionResult.TransactionReceipts, Formatting.Indented)}");
// }
// else
// {
// Console.WriteLine($"Message: {batchExecutionResult.Message}");
// }

#endregion

#region Get Social Profiles

// var socialProfiles = await Utils.GetSocialProfiles(client, "joenrv.eth");
Expand All @@ -320,15 +182,15 @@

#region AA 0.6

// var smartWallet06 = await SmartWallet.Create(personalWallet: privateKeyWallet, chainId: 421614, gasless: true);
// var smartWallet06 = await SmartWallet.Create(personalWallet: guestWallet, chainId: 421614, gasless: true);
// var receipt06 = await smartWallet06.Transfer(chainId: 421614, toAddress: await smartWallet06.GetAddress(), weiAmount: 0);
// Console.WriteLine($"Receipt: {receipt06}");

#endregion

#region AA 0.7

// var smartWallet07 = await SmartWallet.Create(personalWallet: privateKeyWallet, chainId: 421614, gasless: true, entryPoint: Constants.ENTRYPOINT_ADDRESS_V07);
// var smartWallet07 = await SmartWallet.Create(personalWallet: guestWallet, chainId: 421614, gasless: true, entryPoint: Constants.ENTRYPOINT_ADDRESS_V07);
// var receipt07 = await smartWallet07.Transfer(chainId: 421614, toAddress: await smartWallet07.GetAddress(), weiAmount: 0);
// Console.WriteLine($"Receipt: {receipt07}");

Expand Down Expand Up @@ -498,8 +360,6 @@

// var ecosystemPersonalSignature = await ecosystemWallet.PersonalSign("Hello, Thirdweb!");
// Console.WriteLine($"Ecosystem Wallet personal sign: {ecosystemPersonalSignature}");
// var isValidPersonal = (await ecosystemWallet.RecoverAddressFromPersonalSign("Hello, Thirdweb!", ecosystemPersonalSignature)) == ecosystemWalletAddress;
// Console.WriteLine($"Ecosystem Wallet personal sign valid: {isValidPersonal}");

// var ecosystemTypedSignature = await ecosystemWallet.SignTypedDataV4(
// /*lang=json,strict*/
Expand Down
12 changes: 12 additions & 0 deletions Thirdweb.Tests/BaseTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,16 @@ public void DotEnvTest()
{
Assert.NotNull(this.SecretKey);
}

public async Task<IThirdwebWallet> GetGuestAccount()
{
return await InAppWallet.Create(this.Client, authProvider: AuthProvider.Guest);
}

public async Task<SmartWallet> GetSmartAccount(int chainId = 421614)
{
var privateKeyAccount = await this.GetGuestAccount();
var smartAccount = await SmartWallet.Create(personalWallet: privateKeyAccount, chainId: chainId);
return smartAccount;
}
}
83 changes: 0 additions & 83 deletions Thirdweb.Tests/Thirdweb.AI/Thirdweb.AI.Tests.cs

This file was deleted.

8 changes: 3 additions & 5 deletions Thirdweb.Tests/Thirdweb.Contracts/Thirdweb.Contracts.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ public async Task WriteTest_SmartAccount_FullSig()
public async Task WriteTest_PrivateKeyAccount()
{
var contract = await this.GetContract();
var privateKeyAccount = await PrivateKeyWallet.Generate(contract.Client);
var privateKeyAccount = await this.GetGuestAccount();
var receiver = await privateKeyAccount.GetAddress();
var quantity = BigInteger.One;
var currency = Constants.NATIVE_TOKEN_ADDRESS;
Expand All @@ -212,8 +212,7 @@ public async Task WriteTest_PrivateKeyAccount()
[Fact(Timeout = 120000)]
public async Task SignatureMint_Generate()
{
var client = this.Client;
var signer = await PrivateKeyWallet.Generate(client);
var signer = await this.GetGuestAccount();

var randomDomain = "Test";
var randomVersion = "1.0.0";
Expand Down Expand Up @@ -290,8 +289,7 @@ public async Task SignatureMint_Generate()

private async Task<SmartWallet> GetAccount()
{
var client = this.Client;
var privateKeyAccount = await PrivateKeyWallet.Generate(client);
var privateKeyAccount = await this.GetGuestAccount();
var smartAccount = await SmartWallet.Create(personalWallet: privateKeyAccount, factoryAddress: "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", gasless: true, chainId: 421614);
return smartAccount;
}
Expand Down
22 changes: 11 additions & 11 deletions Thirdweb.Tests/Thirdweb.Extensions/Thirdweb.Extensions.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public ExtensionsTests(ITestOutputHelper output)

private async Task<IThirdwebWallet> GetSmartWallet()
{
var privateKeyWallet = await PrivateKeyWallet.Generate(this.Client);
var privateKeyWallet = await this.GetGuestAccount();
return await SmartWallet.Create(personalWallet: privateKeyWallet, chainId: 421614);
}

Expand Down Expand Up @@ -1420,8 +1420,8 @@ public async Task TokenERC20_NullChecks()
public async Task TokenERC20_GenerateMintSignature_WithVerify()
{
var contract = await this.GetTokenERC20Contract();
var fakeAuthorizedSigner = await PrivateKeyWallet.Generate(this.Client);
var randomReceiver = await PrivateKeyWallet.Generate(this.Client);
var fakeAuthorizedSigner = await this.GetGuestAccount();
var randomReceiver = await this.GetGuestAccount();
var mintRequest = new TokenERC20_MintRequest { To = await randomReceiver.GetAddress(), Quantity = BigInteger.Parse("1.5".ToWei()) };
Comment on lines +1423 to 1425
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Ensure GetGuestAccount returns a connected wallet.

These tests call GetAddress() or sign immediately. If GetGuestAccount doesn’t perform LoginWithGuest, these will flake.

Check BaseTests.GetGuestAccount implementation:

Expected: it creates InAppWallet with AuthProvider.Guest and either is already connected or calls LoginWithGuest before returning. If not, update helper to connect.

I can patch BaseTests to guarantee connection on return if needed.

Also applies to: 1531-1533, 1566-1568, 1699-1701, 1736-1738


🏁 Script executed:

#!/bin/bash
rg -n -C4 'async\s+Task<\s*IThirdwebWallet\s*>\s*GetGuestAccount' && rg -n -C2 'LoginWithGuest|IsConnected\(\)' Thirdweb.Tests

Length of output: 1963


Ensure GetGuestAccount connects before returning
Modify BaseTests.GetGuestAccount to call LoginWithGuest on the newly created wallet so any subsequent GetAddress() or signing calls won’t flake:

 public async Task<IThirdwebWallet> GetGuestAccount()
 {
-    return await InAppWallet.Create(this.Client, authProvider: AuthProvider.Guest);
+    var wallet = await InAppWallet.Create(this.Client, authProvider: AuthProvider.Guest);
+    await wallet.LoginWithGuest();
+    return wallet;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var fakeAuthorizedSigner = await this.GetGuestAccount();
var randomReceiver = await this.GetGuestAccount();
var mintRequest = new TokenERC20_MintRequest { To = await randomReceiver.GetAddress(), Quantity = BigInteger.Parse("1.5".ToWei()) };
public async Task<IThirdwebWallet> GetGuestAccount()
{
var wallet = await InAppWallet.Create(this.Client, authProvider: AuthProvider.Guest);
await wallet.LoginWithGuest();
return wallet;
}
🤖 Prompt for AI Agents
In Thirdweb.Tests/Thirdweb.Extensions/Thirdweb.Extensions.Tests.cs around lines
1423-1425, the tests call GetGuestAccount() but that helper must ensure the
created wallet is connected; update BaseTests.GetGuestAccount to call and await
LoginWithGuest (or the equivalent connect/login method) on the new wallet
instance before returning it so subsequent GetAddress() or signing calls are
reliable; ensure the call is awaited and surface or throw any errors if login
fails.


(var payload, var signature) = await contract.TokenERC20_GenerateMintSignature(fakeAuthorizedSigner, mintRequest);
Expand Down Expand Up @@ -1528,8 +1528,8 @@ public async Task TokenERC721_NullChecks()
public async Task TokenERC721_GenerateMintSignature_WithUri_WithVerify()
{
var contract = await this.GetTokenERC721Contract();
var fakeAuthorizedSigner = await PrivateKeyWallet.Generate(this.Client);
var randomReceiver = await PrivateKeyWallet.Generate(this.Client);
var fakeAuthorizedSigner = await this.GetGuestAccount();
var randomReceiver = await this.GetGuestAccount();
var mintRequest = new TokenERC721_MintRequest { To = await randomReceiver.GetAddress(), Uri = "" };

(var payload, var signature) = await contract.TokenERC721_GenerateMintSignature(fakeAuthorizedSigner, mintRequest);
Expand Down Expand Up @@ -1563,8 +1563,8 @@ public async Task TokenERC721_GenerateMintSignature_WithUri_WithVerify()
public async Task TokenERC721_GenerateMintSignature_WithNFTMetadata_WithVerify()
{
var contract = await this.GetTokenERC721Contract();
var fakeAuthorizedSigner = await PrivateKeyWallet.Generate(this.Client);
var randomReceiver = await PrivateKeyWallet.Generate(this.Client);
var fakeAuthorizedSigner = await this.GetGuestAccount();
var randomReceiver = await this.GetGuestAccount();
var mintRequest = new TokenERC721_MintRequest { To = await randomReceiver.GetAddress() };

(var payload, var signature) = await contract.TokenERC721_GenerateMintSignature(
Expand Down Expand Up @@ -1696,8 +1696,8 @@ public async Task TokenERC1155_NullChecks()
public async Task TokenERC1155_GenerateMintSignature_WithUri_WithVerify()
{
var contract = await this.GetTokenERC1155Contract();
var fakeAuthorizedSigner = await PrivateKeyWallet.Generate(this.Client);
var randomReceiver = await PrivateKeyWallet.Generate(this.Client);
var fakeAuthorizedSigner = await this.GetGuestAccount();
var randomReceiver = await this.GetGuestAccount();
var mintRequest = new TokenERC1155_MintRequest { To = await randomReceiver.GetAddress(), Uri = "" };

(var payload, var signature) = await contract.TokenERC1155_GenerateMintSignature(fakeAuthorizedSigner, mintRequest);
Expand Down Expand Up @@ -1733,8 +1733,8 @@ public async Task TokenERC1155_GenerateMintSignature_WithUri_WithVerify()
public async Task TokenERC1155_GenerateMintSignature_WithNFTMetadata_WithVerify()
{
var contract = await this.GetTokenERC1155Contract();
var fakeAuthorizedSigner = await PrivateKeyWallet.Generate(this.Client);
var randomReceiver = await PrivateKeyWallet.Generate(this.Client);
var fakeAuthorizedSigner = await this.GetGuestAccount();
var randomReceiver = await this.GetGuestAccount();
var mintRequest = new TokenERC1155_MintRequest { To = await randomReceiver.GetAddress() };

(var payload, var signature) = await contract.TokenERC1155_GenerateMintSignature(
Expand Down
Loading
Loading