Skip to content

Conversation

0xFirekeeper
Copy link
Member

@0xFirekeeper 0xFirekeeper commented Sep 8, 2025

WIP


PR-Codex overview

This PR primarily focuses on the removal of several files and refactoring of existing code within the Thirdweb library, including changes to wallet management, transaction handling, and API response structures.

Detailed summary

  • Deleted multiple files related to Thirdweb.RPC, Thirdweb.AI, Thirdweb.Pay, and Thirdweb.Wallets.
  • Refactored ThirdwebBridge and ThirdwebBridgeExtensions namespaces.
  • Changed RpcRequest and RpcResponse structures.
  • Updated wallet handling methods to use guest accounts instead of private key wallets.
  • Simplified SignInWithOauthAsync method to return a VerifyResult directly.
  • Removed unused signing methods from IThirdwebWallet.
  • Introduced a new ThirdwebTransactionReceipt class for transaction details.
  • Updated TimeoutOptions class to remove interface implementation.
  • Refined error handling in transaction receipt processing.

The following files were skipped due to too many changes: Thirdweb.Tests/Thirdweb.Wallets/Thirdweb.Wallets.Tests.cs, Thirdweb.Console/Program.cs, Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs, Thirdweb.Tests/Thirdweb.Wallets/Thirdweb.SmartWallet.Tests.cs, Thirdweb/Thirdweb.Api/GeneratedClient.cs

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • New Features

    • Console/sample flows now default to an in-app Guest Wallet; Smart Wallet examples updated accordingly.
  • Refactor

    • Bridge types moved to the Thirdweb namespace.
    • TimeoutOptions no longer uses an interface; client factory now accepts TimeoutOptions.
    • RPC models consolidated; transaction revert errors simplified.
  • Removals

    • Removed AI/Nebula, Pay (buy with crypto/fiat), and Insight indexer APIs.
    • Removed PrivateKeyWallet and EthSign/address-recovery methods from wallets.
  • Tests

    • Updated to use Guest Wallets; removed PrivateKeyWallet and Nebula-related tests.

Introduces a new /auth/social endpoint for OAuth flows, deprecates the old OAuth method, and updates documentation accordingly. Refactors payments API: renames and restructures payment creation, completion, and history endpoints, and moves token swap functionality to a new bridge/swap endpoint. Expands wallet token retrieval with new filtering and sorting options.
Deleted the User class and the VerifyResult class that referenced it from EmbeddedWallet.Misc.cs. Also removed the Nethereum.HdWallet package reference from the project file, likely as part of cleaning up unused code and dependencies.
Moved and consolidated RPC-related types into Thirdweb.RPC namespace, replacing previous implementations. Updated all references and usages to the new types and namespace throughout the codebase. Renamed BundlerClient to ThirdwebBundler and updated all relevant calls. This improves code organization and clarity for RPC handling.
Eliminated the unnecessary Nethereum.JsonRpc.Client.RpcMessages import and added Thirdweb.RPC import to clean up dependencies in ThirdwebBundler.cs.
Replaced usage of Nethereum.RLP with a custom RLP implementation in Thirdweb.Wallets. Removed PrivateKeyWallet and related RLP-based transaction decoding from Utils. Updated ThirdwebRPC to use JTokenType for error handling. This refactor reduces external dependencies and centralizes RLP logic.
Replaced usage of PrivateKeyWallet with InAppWallet using AuthProvider.Guest across all tests and sample code. Removed PrivateKeyWallet-specific tests and helper methods, consolidating wallet creation to use guest accounts for consistency and future compatibility.
Deleted EngineWallet.cs as the EngineWallet class is obsolete and scheduled for removal. Developers should use ServerWallet instead.
Deleted all ThirdwebPay payment-related files, including crypto and fiat payment processing, quote/status retrieval, and associated types. This module was marked as deprecated in favor of ThirdwebBridge.
Deleted all files related to Thirdweb.AI and Thirdweb.Indexer, including clients, types, and extension methods. This removes Nebula chat, execution, session management, and insight functionality from the codebase.
Deleted large blocks of commented-out code related to Indexer and AI features in Program.cs to clean up the file and improve readability.
Deleted Thirdweb.AI.Tests.cs to remove Nebula-related tests. Renamed GeneratedClient.cs to ThirdwebApi.cs and updated nswag.json output path to reflect the new filename for consistency.
Deleted VerificationException and UserStatus as they are no longer used. Refactored DataStorage to use auto-properties with DataMember attributes instead of backing fields, simplifying the class structure.
Renamed EIP712.cs, EIP712Encoder.cs, and RLP.cs from the Wallets folder to the Utils folder to better reflect their utility nature and improve project organization.
Moved several classes from Thirdweb.RPC and Thirdweb.Bridge namespaces to Thirdweb, and removed unused Thirdweb.RPC references across the codebase. Consolidated TimeoutOptions and TimeoutType into ThirdwebClient.Types.cs, and moved ThirdwebTransactionReceipt into ThirdwebTransaction.Types.cs. Performed file renames for consistency and reorganized EmbeddedWallet files under Thirdweb.EWS. Cleaned up obsolete interface and type files.
Copy link

coderabbitai bot commented Sep 8, 2025

Walkthrough

The PR removes Nebula AI, Insight Indexer, and Pay modules; deletes PrivateKeyWallet and ETH-sign/recovery APIs; refactors SmartWallet to use ThirdwebBundler and CreateCallData; consolidates RPC types; simplifies transaction revert handling; adds an RLP encoder; updates Embedded/In-App wallet EWS storage and OAuth flows; adjusts Bridge namespaces; changes client timeout types; updates samples/tests to use guest InAppWallet.

Changes

Cohort / File(s) Summary
Console sample updates
Thirdweb.Console/Program.cs
Switch to InAppWallet guest auth; adjust NFT fetch; remove Indexer samples; SmartWallet samples use guest wallet; add commented deploy sample; remove personal-sign validation output.
Tests: guest wallet migration
Thirdweb.Tests/BaseTests.cs, Thirdweb.Tests/Thirdweb.Contracts/Thirdweb.Contracts.Tests.cs, Thirdweb.Tests/Thirdweb.Extensions/*, Thirdweb.Tests/Thirdweb.Transactions/*, Thirdweb.Tests/Thirdweb.Wallets/Thirdweb.SmartWallet.Tests.cs, Thirdweb.Tests/Thirdweb.Utils/Thirdweb.Utils.Tests.cs, Thirdweb.Tests/Thirdweb.Extensions/Thirdweb.MarketplaceExtensions.Tests.cs
Replace PrivateKeyWallet.Generate(...) with GetGuestAccount(); add helpers GetGuestAccount() and GetSmartAccount(); adjust assertions/types; remove several sign/recover tests.
Tests: deletions
Thirdweb.Tests/Thirdweb.AI/Thirdweb.AI.Tests.cs, Thirdweb.Tests/Thirdweb.Wallets/Thirdweb.PrivateKeyWallet.Tests.cs
Remove Nebula test suite and PrivateKeyWallet test suite.
Nebula AI removal
Thirdweb/Thirdweb.AI/*
Delete Nebula clients, session manager, types, and ThirdwebNebula public API.
Insight Indexer removal
Thirdweb/Thirdweb.Indexer/*
Delete Insight client, types, and NFT conversion extensions.
Pay module removal
Thirdweb/Thirdweb.Pay/*
Delete deprecated ThirdwebPay class, all Pay APIs, and related DTOs.
Wallets: API trimming and removals
Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs, .../PrivateKeyWallet/PrivateKeyWallet.cs, .../ServerWallet/ServerWallet.cs
Remove EthSign and address-recovery APIs from interfaces/implementations; delete PrivateKeyWallet entirely.
InApp/Ecosystem/Embedded wallet changes
.../InAppWallet/EcosystemWallet/EcosystemWallet.cs, .../Thirdweb.EWS/*
Switch bundler calls to ThirdwebBundler; remove EthSign/recovery methods; change OAuth to sync return; remove enclave migration; add EWS LocalStorage types and session helpers; remove AWS/crypto/share/IV/internal components; adjust VerifyResult and server flows.
SmartWallet refactor to ThirdwebBundler
.../SmartWallet/SmartWallet.cs, .../Thirdweb.AccountAbstraction/ThirdwebBundler.cs, .../Thirdweb.AccountAbstraction/ThirdwebBundler.Types.cs
Migrate bundler calls to ThirdwebBundler; use CreateCallData for calldata; remove ExecuteFunction message class; remove EthSign/recovery APIs.
RPC types consolidation
Thirdweb/Thirdweb.RPC/ThirdwebRPC.Types.cs, Thirdweb/Thirdweb.RPC/ThirdwebRPC.cs, Thirdweb/Thirdweb.RPC/{RpcError.cs,RpcRequest.cs,RpcResponse.cs}
Add unified RPC request/response types and parameter converter; adjust error data handling; remove older RPC DTO files.
Transactions: receipt/type and error handling
Thirdweb/Thirdweb.Transactions/ThirdwebTransaction.Types.cs, Thirdweb/Thirdweb.Transactions/ThirdwebTransaction.cs, Thirdweb/Thirdweb.Transactions/ThirdwebTransactionReceipt.cs
Add receipt DTO in Types; remove old receipt file; simplify revert handling to a generic message.
Utils: RLP and decode changes
Thirdweb/Thirdweb.Utils/RLP.cs, Thirdweb/Thirdweb.Utils/Utils.cs, Thirdweb/Thirdweb.Utils/EIP712.cs
Add RLP encoder utility; remove event/transaction decode helpers and RLP-based decoding; minor using cleanup.
Bridge namespace move
Thirdweb/Thirdweb.Bridge/*
Move ThirdwebBridge, extensions, and types from Thirdweb.Bridge to Thirdweb.
Client timeout API change
Thirdweb/Thirdweb.Client/{ThirdwebClient.cs,ThirdwebClient.Types.cs,ITimeoutOptions.cs,TimeoutType.cs}
Remove ITimeoutOptions and standalone TimeoutType; add TimeoutType inside Types; change ThirdwebClient.Create param to TimeoutOptions.
Project/config
Thirdweb/Thirdweb.csproj, nswag.json
Remove Nethereum EIP712 and HdWallet package refs; change NSwag C# output path.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant App
  participant SmartWallet
  participant ThirdwebBundler
  participant EntryPoint

  App->>SmartWallet: create/prepare userOp (createCallData)
  SmartWallet->>ThirdwebBundler: ThirdwebGetUserOperationGasPrice
  ThirdwebBundler-->>SmartWallet: gas price data
  SmartWallet->>ThirdwebBundler: PMSponsorUserOperation / ZkPaymasterData (if gasless/erc20)
  ThirdwebBundler-->>SmartWallet: sponsor data
  SmartWallet->>ThirdwebBundler: EthSendUserOperation(userOp)
  ThirdwebBundler-->>SmartWallet: userOpHash
  SmartWallet->>ThirdwebBundler: EthGetUserOperationReceipt(userOpHash)
  ThirdwebBundler-->>SmartWallet: receipt (success/fail)
  SmartWallet-->>App: tx hash / throw "execution reverted" on Status==0
  Note over SmartWallet: Revert reason decoding removed
Loading
sequenceDiagram
  autonumber
  participant App
  participant EmbeddedWallet
  participant EWS_Server

  App->>EmbeddedWallet: SignInWithOauthAsync(authResult)
  activate EmbeddedWallet
  EmbeddedWallet->>EWS_Server: VerifyOAuth(authResult)
  EWS_Server-->>EmbeddedWallet: VerifyResult(token, user ids, ...)
  EmbeddedWallet-->>App: VerifyResult (sync return)
  deactivate EmbeddedWallet
  Note over EmbeddedWallet: Removed async token exchange / lambda path
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Pre-merge checks (2 warnings, 1 inconclusive)

❌ Failed Checks (2 warnings, 1 inconclusive)
Check Name Status Explanation Resolution
Description Check ⚠️ Warning The current description only includes “WIP” and an auto-generated summary without providing the context, motivation, or rationale behind the extensive file removals and refactoring. Introduce a structured pull request template for your repository and update this description to include the problem statement, design decisions, and any breaking changes or migration guidance.
Docstring Coverage ⚠️ Warning Docstring coverage is 16.81% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive The title “v3” is overly generic and does not convey the primary changes or context of this pull request, making it difficult for reviewers to understand at a glance. Rename the pull request to a descriptive summary of the key changes, for example “Refactor wallet handling to use guest accounts and remove deprecated AI, RPC, and Pay modules.”
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch v3

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License

View full report

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 18

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (11)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.Types.cs (1)

9-26: Rename AuthToken to CookieString in VerifyResult and update all .AuthToken usages

  • Apply the diff below in Server.Types.cs to make intent explicit and add an obsolete shim.
  • Update every call site that reads VerifyResult.AuthToken or passes an authToken—including in Server.cs, EcosystemWallet.cs (headers, session data, link/unlink calls) and LocalStorage.Types.cs—to use CookieString (or fall back to AuthToken via the shim).
-        internal VerifyResult(string authProvider, bool isNewUser, string authToken, string walletUserId, string email, string phoneNumber, string authIdentifier)
+        internal VerifyResult(string authProvider, bool isNewUser, string cookieString, string walletUserId, string email, string phoneNumber, string authIdentifier)
         {
             this.AuthProvider = authProvider;
             this.IsNewUser = isNewUser;
-            this.AuthToken = authToken;
+            this.CookieString = cookieString;
             this.WalletUserId = walletUserId;
             this.Email = email;
             this.PhoneNumber = phoneNumber;
             this.AuthIdentifier = authIdentifier;
         }

         internal string AuthProvider { get; }
         internal bool IsNewUser { get; }
-        internal string AuthToken { get; }
+        internal string CookieString { get; }
+
+        [System.Obsolete("Use CookieString; this was previously misnamed.")]
+        internal string AuthToken => CookieString;
         internal string WalletUserId { get; }
         internal string Email { get; }
         internal string PhoneNumber { get; }
         internal string AuthIdentifier { get; }
Thirdweb/Thirdweb.Bridge/ThirdwebBridge.Types.cs (1)

376-386: Bug: Status mapping ignores PROCESSING and CREATED

StatusData.StatusType maps only FAILED/PENDING/COMPLETED/NOT_FOUND, causing PROCESSING/CREATED to resolve to UNKNOWN (while OnrampStatusData handles them). This leads to inconsistent behavior and premature loop exits downstream.

Apply:

-    public StatusType StatusType =>
-        this.Status switch
-        {
-            "FAILED" => StatusType.FAILED,
-            "PENDING" => StatusType.PENDING,
-            "COMPLETED" => StatusType.COMPLETED,
-            "NOT_FOUND" => StatusType.NOT_FOUND,
-            _ => StatusType.UNKNOWN,
-        };
+    public StatusType StatusType =>
+        this.Status switch
+        {
+            "FAILED" => StatusType.FAILED,
+            "PENDING" => StatusType.PENDING,
+            "COMPLETED" => StatusType.COMPLETED,
+            "NOT_FOUND" => StatusType.NOT_FOUND,
+            "PROCESSING" => StatusType.PROCESSING,
+            "CREATED" => StatusType.CREATED,
+            _ => StatusType.UNKNOWN,
+        };

Also applies to: 395-405

Thirdweb/Thirdweb.Bridge/ThirdwebBridge.Extensions.cs (1)

85-99: Guard against null/empty steps and transactions to avoid NREs

preparedTransfer.Transactions can be null; enumerating step.Transactions will throw.

-    private static async Task<List<ThirdwebTransactionReceipt>> ExecuteInternal(this ThirdwebBridge bridge, IThirdwebWallet executor, List<Step> steps, CancellationToken cancellationToken = default)
+    private static async Task<List<ThirdwebTransactionReceipt>> ExecuteInternal(this ThirdwebBridge bridge, IThirdwebWallet executor, List<Step> steps, CancellationToken cancellationToken = default)
     {
         var receipts = new List<ThirdwebTransactionReceipt>();
-        foreach (var step in steps)
+        if (steps == null || steps.Count == 0)
+        {
+            return receipts;
+        }
+        foreach (var step in steps)
         {
-            foreach (var tx in step.Transactions)
+            var txs = step?.Transactions;
+            if (txs == null || txs.Count == 0) continue;
+            foreach (var tx in txs)
             {
                 var thirdwebTx = await tx.ToThirdwebTransaction(executor);
                 var hash = await ThirdwebTransaction.Send(thirdwebTx);
                 receipts.Add(await ThirdwebTransaction.WaitForTransactionReceipt(executor.Client, tx.ChainId, hash, cancellationToken));
-                _ = await bridge.WaitForStatusCompletion(hash, tx.ChainId, cancellationToken);
+                await bridge.WaitForStatusCompletion(hash, tx.ChainId, cancellationToken);
             }
         }
         return receipts;
     }
Thirdweb/Thirdweb.Bridge/ThirdwebBridge.cs (4)

58-66: Validate destinationTokenAddress in Buy_Quote

Origin is validated; destination isn’t. Add symmetric validation to fail fast on bad input.

         if (!Utils.IsValidAddress(originTokenAddress))
         {
             throw new ArgumentException("originTokenAddress is not a valid address", nameof(originTokenAddress));
         }
 
+        if (!Utils.IsValidAddress(destinationTokenAddress))
+        {
+            throw new ArgumentException("destinationTokenAddress is not a valid address", nameof(destinationTokenAddress));
+        }
+
         if (buyAmountWei <= 0)
         {
             throw new ArgumentException("buyAmountWei cannot be less than or equal to 0", nameof(buyAmountWei));
         }

123-141: Validate destinationTokenAddress in Buy_Prepare

Mirror origin validation for destination to avoid server-side 4xx.

         if (!Utils.IsValidAddress(originTokenAddress))
         {
             throw new ArgumentException("originTokenAddress is not a valid address", nameof(originTokenAddress));
         }
 
+        if (!Utils.IsValidAddress(destinationTokenAddress))
+        {
+            throw new ArgumentException("destinationTokenAddress is not a valid address", nameof(destinationTokenAddress));
+        }
+
         if (buyAmountWei <= 0)
         {
             throw new ArgumentException("buyAmountWei cannot be less than or equal to 0", nameof(buyAmountWei));
         }

204-212: Validate destinationTokenAddress in Sell_Quote

Same issue as Buy_Quote.

         if (!Utils.IsValidAddress(originTokenAddress))
         {
             throw new ArgumentException("originTokenAddress is not a valid address", nameof(originTokenAddress));
         }
 
+        if (!Utils.IsValidAddress(destinationTokenAddress))
+        {
+            throw new ArgumentException("destinationTokenAddress is not a valid address", nameof(destinationTokenAddress));
+        }
+
         if (sellAmountWei <= 0)
         {
             throw new ArgumentException("sellAmountWei cannot be less than or equal to 0", nameof(sellAmountWei));
         }

269-287: Validate destinationTokenAddress in Sell_Prepare

Mirror origin validation for destination.

         if (!Utils.IsValidAddress(originTokenAddress))
         {
             throw new ArgumentException("originTokenAddress is not a valid address", nameof(originTokenAddress));
         }
 
+        if (!Utils.IsValidAddress(destinationTokenAddress))
+        {
+            throw new ArgumentException("destinationTokenAddress is not a valid address", nameof(destinationTokenAddress));
+        }
+
         if (sellAmountWei <= 0)
         {
             throw new ArgumentException("sellAmountWei cannot be less than or equal to 0", nameof(sellAmountWei));
         }
Thirdweb.Tests/Thirdweb.Utils/Thirdweb.Utils.Tests.cs (1)

503-514: Avoid async void in xUnit tests; use Task. Also rename misleading variable.

Async void hides test failures. Use Task and rename pkWallet to guestWallet to match GetGuestAccount().

-[Fact(Timeout = 120000)]
-public async void ToJsonExternalWalletFriendly_ReturnsCorrectValue4()
+[Fact(Timeout = 120000)]
+public async Task ToJsonExternalWalletFriendly_ReturnsCorrectValue4()
 {
-    var pkWallet = await this.GetGuestAccount(); // Assume external wallet
+    var guestWallet = await this.GetGuestAccount(); // Guest InApp wallet
     var msg = new AccountAbstraction.AccountMessage { Message = new byte[] { 0x01, 0x02, 0x03, 0x04 } };
-    var verifyingContract = await pkWallet.GetAddress(); // doesn't matter here
+    var verifyingContract = await guestWallet.GetAddress(); // doesn't matter here
Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs (2)

301-351: ERC-6492 decoding slices by character count, not bytes (broken for hex strings).

You subtract 32 from the string length when trimming the magic suffix, but Take() is applied to the byte array. This corrupts the payload for nontrivial signatures.

-            var erc6492Sig = new ABIEncode().DecodeEncodedComplexType<Erc6492Signature>(signature.HexToBytes().Take(signature.Length - 32).ToArray());
+            var sigBytes = signature.HexToBytes();
+            var erc6492Sig = new ABIEncode().DecodeEncodedComplexType<Erc6492Signature>(sigBytes.Take(sigBytes.Length - 32).ToArray());

1217-1225: Account ABI hardcoded to V06 after network switch (breaks V07 accounts).

Use the entry point version to select the correct account ABI, mirroring Create().

-            this._entryPointContract = await ThirdwebContract.Create(this.Client, this._entryPointContract.Address, chainId, this._entryPointContract.Abi).ConfigureAwait(false);
-            this._factoryContract = await ThirdwebContract.Create(this.Client, this._factoryContract.Address, chainId, this._factoryContract.Abi).ConfigureAwait(false);
+            this._entryPointContract = await ThirdwebContract.Create(this.Client, this._entryPointContract.Address, chainId, this._entryPointContract.Abi).ConfigureAwait(false);
+            this._factoryContract = await ThirdwebContract.Create(this.Client, this._factoryContract.Address, chainId, this._factoryContract.Abi).ConfigureAwait(false);
 
             var personalAddress = await this._personalAccount.GetAddress().ConfigureAwait(false);
             var accountAddress = await ThirdwebContract.Read<string>(this._factoryContract, "getAddress", personalAddress, Array.Empty<byte>()).ConfigureAwait(false);
-            this._accountContract = await ThirdwebContract.Create(this._personalAccount.Client, accountAddress, chainId, Constants.ACCOUNT_V06_ABI).ConfigureAwait(false);
+            var entryPointVersion = Utils.GetEntryPointVersion(this._entryPointContract.Address);
+            var accountAbi = entryPointVersion == 6 ? Constants.ACCOUNT_V06_ABI : Constants.ACCOUNT_V07_ABI;
+            this._accountContract = await ThirdwebContract.Create(this._personalAccount.Client, accountAddress, chainId, accountAbi).ConfigureAwait(false);
Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs (1)

315-319: Persisting session with async void is unsafe; await persistence to avoid race conditions.

CreateEnclaveSession ultimately calls EmbeddedWallet.UpdateSessionData (async void). Exceptions are unobserved and writes can race subsequent reads.

Apply (in this file) to await persistence:

-            CreateEnclaveSession(this.EmbeddedWallet, result.AuthToken, this.Email, this.PhoneNumber, this.AuthProvider, result.AuthIdentifier);
+            await CreateEnclaveSessionAsync(this.EmbeddedWallet, result.AuthToken, this.Email, this.PhoneNumber, this.AuthProvider, result.AuthIdentifier);

And add an async counterpart:

private static async Task CreateEnclaveSessionAsync(EmbeddedWallet embeddedWallet, string authToken, string email, string phone, string authProvider, string authIdentifier)
{
    var data = new LocalStorage.DataStorage(authToken, null, email, phone, null, authProvider, authIdentifier);
    await embeddedWallet.UpdateSessionDataAsync(data).ConfigureAwait(false);
}

Outside this file (supporting change in EmbeddedWallet):

// EmbeddedWallet.Misc.cs
internal async Task UpdateSessionDataAsync(LocalStorage.DataStorage data)
{
    await this._localStorage.SaveDataAsync(data).ConfigureAwait(false);
}
// (Optionally keep old UpdateSessionData as a thin wrapper marked [Obsolete] calling the async version and .GetAwaiter().GetResult() for compatibility.)
🧹 Nitpick comments (33)
nswag.json (1)

67-67: Optional: align filename with class name

The generated class is ThirdwebApiClient; consider outputting ThirdwebApiClient.cs for conventional class-to-file alignment.

-      "output": "Thirdweb/Thirdweb.Api/ThirdwebApi.cs"
+      "output": "Thirdweb/Thirdweb.Api/ThirdwebApiClient.cs"
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.Types.cs (2)

36-47: Tighten visibility of LinkedAccount types (nested under an internal container)

These are declared public but are nested inside an internal type, which can be misleading. Prefer internal (and consider sealed) for clarity.

-    public class LinkedAccount
+    internal sealed class LinkedAccount
@@
-        public class LinkedAccountDetails
+        internal sealed class LinkedAccountDetails

Also applies to: 45-59


204-223: Nullable auth details to reflect optional presence across providers

Email/Phone/AuthIdentifier are optional depending on provider, but typed as non-nullable strings. Mark as nullable to avoid incorrect assumptions and future NREs.

-        internal string PhoneNumber { get; set; }
+        internal string? PhoneNumber { get; set; }
@@
-        internal string Email { get; set; }
+        internal string? Email { get; set; }
@@
-        internal string UserWalletId { get; set; }
+        internal string UserWalletId { get; set; } // required
@@
-        internal string AuthIdentifier { get; set; }
+        internal string? AuthIdentifier { get; set; }
@@
-        internal string RecoveryCode { get; set; }
+        internal string? RecoveryCode { get; set; }
@@
-        internal string RecoveryShareManagement { get; set; }
+        internal string? RecoveryShareManagement { get; set; }
Thirdweb/Thirdweb.Bridge/ThirdwebBridge.Extensions.cs (1)

76-76: Doc comment nit: stray triple-slash

There’s an extra “///” prefix.

-    /// /// <param name="bridge">The Thirdweb bridge.</param>
+    /// <param name="bridge">The Thirdweb bridge.</param>
Thirdweb/Thirdweb.Bridge/ThirdwebBridge.cs (3)

432-432: Locale-safe provider serialization

Use ToLowerInvariant() to avoid culture-specific casing issues.

-            onramp = onramp.ToString().ToLower(),
+            onramp = onramp.ToString().ToLowerInvariant(),

488-509: Add cancellable Status overload

Enable end-to-end cancellation in polling paths.

     public async Task<StatusData> Status(string transactionHash, BigInteger chainId)
     {
         if (string.IsNullOrWhiteSpace(transactionHash))
         {
             throw new ArgumentException("transactionHash cannot be null or empty", nameof(transactionHash));
         }
@@
         var result = JsonConvert.DeserializeObject<ResponseModel<StatusData>>(responseContent);
         return result.Data;
     }
+
+    public async Task<StatusData> Status(string transactionHash, BigInteger chainId, CancellationToken cancellationToken)
+    {
+        if (string.IsNullOrWhiteSpace(transactionHash))
+        {
+            throw new ArgumentException("transactionHash cannot be null or empty", nameof(transactionHash));
+        }
+        if (chainId <= 0)
+        {
+            throw new ArgumentException("chainId cannot be less than or equal to 0", nameof(chainId));
+        }
+        var url = $"{Constants.BRIDGE_API_URL}/v1/status";
+        var queryParams = new Dictionary<string, string> { { "transactionHash", transactionHash }, { "chainId", chainId.ToString() } };
+        url = AppendQueryParams(url, queryParams);
+        var response = await this._httpClient.GetAsync(url, cancellationToken).ConfigureAwait(false);
+        _ = response.EnsureSuccessStatusCode();
+        var responseContent = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
+        var result = JsonConvert.DeserializeObject<ResponseModel<StatusData>>(responseContent);
+        return result.Data;
+    }

Then switch WaitForStatusCompletion to call this overload.


513-526: URL-encode query parameters and avoid dangling '?'

Current code doesn’t escape values and appends “?” even if no params survive filtering.

-    private static string AppendQueryParams(string url, Dictionary<string, string> queryParams)
+    private static string AppendQueryParams(string url, Dictionary<string, string> queryParams)
     {
-        var query = new List<string>();
-        foreach (var param in queryParams)
-        {
-            if (string.IsNullOrEmpty(param.Value))
-            {
-                continue;
-            }
-            query.Add($"{param.Key}={param.Value}");
-        }
-
-        return url + "?" + string.Join("&", query);
+        var query = new List<string>();
+        foreach (var param in queryParams)
+        {
+            if (string.IsNullOrEmpty(param.Value)) continue;
+            var k = Uri.EscapeDataString(param.Key);
+            var v = Uri.EscapeDataString(param.Value);
+            query.Add($"{k}={v}");
+        }
+        if (query.Count == 0) return url;
+        return $"{url}?{string.Join("&", query)}";
     }
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet/EmbeddedWallet.Misc.cs (2)

5-8: Drop redundant null-coalescing and expose nullable return type

_localStorage.Data may be null; the ?? null is redundant. If nullable refs are enabled, return DataStorage?.

-    internal LocalStorage.DataStorage GetSessionData()
+    internal LocalStorage.DataStorage? GetSessionData()
     {
-        return this._localStorage.Data ?? null;
+        return this._localStorage.Data;
     }

15-18: Clear session by saving null rather than an object of nulls

This more explicitly clears state and avoids persisting a payload full of null fields.

-    public async Task SignOutAsync()
-    {
-        await this._localStorage.SaveDataAsync(new LocalStorage.DataStorage(null, null, null, null, null, null, null)).ConfigureAwait(false);
-    }
+    public Task SignOutAsync()
+    {
+        return this._localStorage.SaveDataAsync(null);
+    }

Note: if nullable refs are enabled, also update SaveDataAsync signatures to accept DataStorage? (see comment in LocalStorage.Types.cs).

Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Storage/LocalStorage.Types.cs (2)

10-29: Reduce file bloat by not emitting default values

Skip serializing nulls to shrink file size and avoid persisting meaningless fields.

-        [field: DataMember(Name = "authToken")]
+        [field: DataMember(Name = "authToken", EmitDefaultValue = false)]
         internal string AuthToken { get; }

-        [field: DataMember(Name = "deviceShare")]
+        [field: DataMember(Name = "deviceShare", EmitDefaultValue = false)]
         internal string DeviceShare { get; }

-        [field: DataMember(Name = "emailAddress")]
+        [field: DataMember(Name = "emailAddress", EmitDefaultValue = false)]
         internal string EmailAddress { get; }

-        [field: DataMember(Name = "phoneNumber")]
+        [field: DataMember(Name = "phoneNumber", EmitDefaultValue = false)]
         internal string PhoneNumber { get; }

-        [field: DataMember(Name = "walletUserId")]
+        [field: DataMember(Name = "walletUserId", EmitDefaultValue = false)]
         internal string WalletUserId { get; }

-        [field: DataMember(Name = "authProvider")]
+        [field: DataMember(Name = "authProvider", EmitDefaultValue = false)]
         internal string AuthProvider { get; }

-        [field: DataMember(Name = "authIdentifier")]
+        [field: DataMember(Name = "authIdentifier", EmitDefaultValue = false)]
         internal string AuthIdentifier { get; }

5-41: Consider encrypting at rest or using OS-protected storage

Auth token, device share, and identifiers are sensitive. Prefer DPAPI/Keychain/KeyStore or file-level encryption + ACLs.

If you want, I can sketch a thin abstraction that encrypts Storage blobs before writing and rotates keys.

Thirdweb/Thirdweb.Utils/RLP.cs (6)

168-176: Null handling for lists is surprising; prefer explicit behavior.

Treating (items.Length == 1 && items[0] == null) as an empty list is non-obvious. Either throw or explicitly encode a null element (0x80) via EncodeElement.

Apply:

-        if (items == null || (items.Length == 1 && items[0] == null))
-        {
-            return new[] { OFFSET_SHORT_LIST };
-        }
+        if (items == null)
+        {
+            return new[] { OFFSET_SHORT_LIST };
+        }
+        if (items.Any(i => i == null))
+        {
+            throw new ArgumentNullException(nameof(items), "Null entries inside a list are not allowed; encode as empty element (0x80) explicitly.");
+        }

27-39: Visibility consistency for RLP offset constants.

OFFSET_SHORT_LIST is public while other offsets are private. Expose all or keep all private for consistency.

Example options:

  • Make all four offsets public.
  • Or keep all private and expose a small API surface.

Also applies to: 48-58


12-13: Nit: fix typo in comment.

“cutof” → “cutoff”.

-    ///     - also, that's where Bitcoin's varint does the cutof
+    ///     - also, that's where Bitcoin's varint does the cutoff

60-62: Public arrays: clarify intended usage or make read-only.

EMPTY_BYTE_ARRAY and ZERO_BYTE_ARRAY are mutable references. Consider exposing as ReadOnlyMemory<byte> or document they’re constants not to be modified.


143-166: Performance: avoid repeated Contains lookup on int[].

indexOfListDataItems.Contains(i) is O(n) per iteration. Convert to HashSet<int> once for O(1) lookups.

-        for (var i = 0; i < dataItems.Length; i++)
+        var listIndexes = new HashSet<int>(indexOfListDataItems);
+        for (var i = 0; i < dataItems.Length; i++)
         {
-            if (indexOfListDataItems.Contains(i))
+            if (listIndexes.Contains(i))
             {
                 ...
             }
         }

1-231: Add RLP test vectors (correctness guard).

Add unit tests for canonical vectors: "", 0x00, 0x7f, 0x80, short/long strings, empty list, nested lists, etc. This will lock correctness.

I can add tests for: ""→80, [ ]→c0, 0x00→00, "dog"→83646f67, ["cat","dog"]→c88363617483646f67, 1024→820400.

Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs (2)

645-651: Chain-specific value scaling deserves a utility with docs.

The 295/296 special-case division by 1e10 is non-obvious and scattered. Centralize this as Utils.ScaleNativeValueForChain(...) with a comment or reference.

Would you like me to draft that helper?


358-362: Minor: Prefer using the shared constant for EIP-1271 magic value.

You hardcode the magic bytes here but use Constants.EIP_1271_MAGIC_VALUE elsewhere. Use the constant for consistency.

-                return magicValue.BytesToHex() == new byte[] { 0x16, 0x26, 0xba, 0x7e }.BytesToHex();
+                return magicValue.BytesToHex() == Constants.EIP_1271_MAGIC_VALUE;
Thirdweb.Tests/BaseTests.cs (1)

38-43: Rename variable to reflect guest account.

privateKeyAccount is misleading; it’s a guest wallet.

-        var privateKeyAccount = await this.GetGuestAccount();
-        var smartAccount = await SmartWallet.Create(personalWallet: privateKeyAccount, chainId: chainId);
+        var guestAccount = await this.GetGuestAccount();
+        var smartAccount = await SmartWallet.Create(personalWallet: guestAccount, chainId: chainId);
Thirdweb.Tests/Thirdweb.Extensions/Thirdweb.MarketplaceExtensions.Tests.cs (1)

17-19: Use the _chainId field instead of a hard-coded literal.

Keeps tests consistent and simplifies future chain changes.

-        var smartWallet = await SmartWallet.Create(personalWallet: privateKeyWallet, chainId: 421614);
+        var smartWallet = await SmartWallet.Create(personalWallet: privateKeyWallet, chainId: (int)this._chainId);
Thirdweb/Thirdweb.Wallets/SmartWallet/Thirdweb.AccountAbstraction/ThirdwebBundler.cs (1)

121-124: Minor: avoid reassigning the params array.

Reassigning the params parameter is unnecessary; create a local instead for clarity.

-        var requestMessage = new RpcRequestMessage(requestId, method, args = args.Where(a => a != null).ToArray());
+        var filteredArgs = args.Where(a => a != null).ToArray();
+        var requestMessage = new RpcRequestMessage(requestId, method, filteredArgs);
Thirdweb.Tests/Thirdweb.Contracts/Thirdweb.Contracts.Tests.cs (3)

192-205: Rename variable: it’s not a private-key account anymore.

Avoid confusion by renaming to “guestAccount” (or just “account”).

-        var privateKeyAccount = await this.GetGuestAccount();
-        var receiver = await privateKeyAccount.GetAddress();
+        var guestAccount = await this.GetGuestAccount();
+        var receiver = await guestAccount.GetAddress();
 ...
-            var res = await ThirdwebContract.Write(privateKeyAccount, contract, "claim", 0, receiver, quantity, currency, pricePerToken, allowlistProof, data);
+            var res = await ThirdwebContract.Write(guestAccount, contract, "claim", 0, receiver, quantity, currency, pricePerToken, allowlistProof, data);

215-287: Rename variable: signer is a guest wallet now.

-        var signer = await this.GetGuestAccount();
+        var guestSigner = await this.GetGuestAccount();
...
-            To = await signer.GetAddress(),
-            PrimarySaleRecipient = await signer.GetAddress(),
+            To = await guestSigner.GetAddress(),
+            PrimarySaleRecipient = await guestSigner.GetAddress(),
...
-        var signature20 = await EIP712.GenerateSignature_TokenERC20(randomDomain, randomVersion, randomChainId, randomContractAddress, mintRequest20, signer);
+        var signature20 = await EIP712.GenerateSignature_TokenERC20(randomDomain, randomVersion, randomChainId, randomContractAddress, mintRequest20, guestSigner);

(Apply similarly for 721/1155 sections.)


292-295: Rename variable: guest vs private-key terminology.

-        var privateKeyAccount = await this.GetGuestAccount();
-        var smartAccount = await SmartWallet.Create(personalWallet: privateKeyAccount, factoryAddress: "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", gasless: true, chainId: 421614);
+        var guestAccount = await this.GetGuestAccount();
+        var smartAccount = await SmartWallet.Create(personalWallet: guestAccount, factoryAddress: "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", gasless: true, chainId: 421614);
Thirdweb/Thirdweb.Client/ThirdwebClient.cs (1)

31-31: Removal of ITimeoutOptions breaks consumers; add a compatibility overload or shim if not a major version bump
No internal references to ITimeoutOptions remain—this is a source-breaking change for anyone passing an ITimeoutOptions. If you’re not targeting a MAJOR version, provide an overload accepting individual timeout parameters (or a small ITimeoutOptions shim) to ease migration.

Thirdweb.Tests/Thirdweb.Extensions/Thirdweb.Extensions.Tests.cs (1)

21-25: Misleading variable name after wallet type switch.

privateKeyWallet now holds a guest account. Rename for clarity.

Apply:

-    private async Task<IThirdwebWallet> GetSmartWallet()
+    private async Task<IThirdwebWallet> GetSmartWallet()
     {
-        var privateKeyWallet = await this.GetGuestAccount();
-        return await SmartWallet.Create(personalWallet: privateKeyWallet, chainId: 421614);
+        var guestAccount = await this.GetGuestAccount();
+        return await SmartWallet.Create(personalWallet: guestAccount, chainId: 421614);
     }
Thirdweb.Console/Program.cs (2)

19-22: Avoid redundant guest logins; use IsConnected gate.

Prevents re-login and reads address from wallet state.

-//  Create a guest wallet
-var guestWallet = await InAppWallet.Create(client, authProvider: AuthProvider.Guest);
-var walletAddress = await guestWallet.LoginWithGuest();
-Console.WriteLine($"Guest Wallet address: {walletAddress}");
+//  Create a guest wallet
+var guestWallet = await InAppWallet.Create(client, authProvider: AuthProvider.Guest);
+if (!await guestWallet.IsConnected())
+{
+    _ = await guestWallet.LoginWithGuest();
+}
+Console.WriteLine($"Guest Wallet address: {await guestWallet.GetAddress()}");

185-189: Align all commented sample wallet variables to guestWallet.

Replace every instance of myWallet or privateKeyWallet in commented code samples with guestWallet for consistent copy-paste (e.g. lines 77–80, 99–102, 109–113, 115–118, 125–136, 145–149, 164–168, 199–203, 544–548, 556–562, 572–576, 592–599, 656–660).

Thirdweb.Tests/Thirdweb.Wallets/Thirdweb.SmartWallet.Tests.cs (1)

10-12: Rename variables from privateKeyAccount → guestAccount for accuracy.

Improves readability post-migration to guest wallets.

Example fix pattern:

- var privateKeyAccount = await this.GetGuestAccount();
- var smartAccount = await SmartWallet.Create(personalWallet: privateKeyAccount, gasless: true, chainId: 421614);
+ var guestAccount = await this.GetGuestAccount();
+ var smartAccount = await SmartWallet.Create(personalWallet: guestAccount, gasless: true, chainId: 421614);

Also applies to: 25-28, 35-36, 47-49, 65-73, 95-98, 131-139, 231-233, 285-290, 302-307, 322-323, 332-333, 342-343, 352-353, 362-363, 372-376

Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs (1)

1294-1303: Poll with backoff to reduce load and improve timeout behavior.

A fixed 100ms loop can hammer the bundler and trip timeouts under load.

-                var queueId = response?.QueueId;
-                string txHash = null;
-                var ct = new CancellationTokenSource(this.Client.FetchTimeoutOptions.GetTimeout(TimeoutType.Other));
+                var queueId = response?.QueueId;
+                string txHash = null;
+                var ct = new CancellationTokenSource(this.Client.FetchTimeoutOptions.GetTimeout(TimeoutType.Other));
+                var delayMs = 100;
                 try
                 {
                     while (txHash == null)
                     {
                         ct.Token.ThrowIfCancellationRequested();
-
-                        var hashResponse = await ThirdwebBundler
+                        var hashResponse = await ThirdwebBundler
                             .TwGetTransactionHash(client: this.Client, url: $"https://{transaction.ChainId}.bundler.thirdweb.com", requestId: 7702, queueId)
                             .ConfigureAwait(false);
 
                         txHash = hashResponse?.TransactionHash;
-                        await ThirdwebTask.Delay(100, ct.Token).ConfigureAwait(false);
+                        await ThirdwebTask.Delay(delayMs, ct.Token).ConfigureAwait(false);
+                        delayMs = Math.Min(delayMs * 2, 1000);
                     }
                     return txHash;
                 }

Also applies to: 1312-1318

Thirdweb/Thirdweb.RPC/ThirdwebRPC.Types.cs (2)

64-66: Broaden RpcRequest.Params to support both array and object forms

JSON-RPC allows params to be an array or an object. Current type object[] restricts usage. Consider matching RpcRequestMessage’s flexibility.

Apply this diff:

-    [JsonProperty("params")]
-    public object[] Params { get; set; }
+    [JsonProperty("params")]
+    [JsonConverter(typeof(RpcParameterJsonConverter))]
+    public object Params { get; set; }

12-19: Minor consistency and null-safety nits

  • Consider marking required fields with [JsonProperty(Required = Required.Always)] or making string properties nullable (string?) to reflect deserialization realities.
  • Property naming varies (JsonRpcVersion vs Jsonrpc). Not wrong, but a consistent C# naming could reduce confusion.

Example:

-    [JsonProperty("jsonrpc")]
-    public string JsonRpcVersion { get; private set; }
+    [JsonProperty("jsonrpc", Required = Required.Always)]
+    public string JsonRpcVersion { get; private set; }

Also applies to: 28-39

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between df77184 and 75c1f55.

📒 Files selected for processing (79)
  • Thirdweb.Console/Program.cs (2 hunks)
  • Thirdweb.Tests/BaseTests.cs (1 hunks)
  • Thirdweb.Tests/Thirdweb.AI/Thirdweb.AI.Tests.cs (0 hunks)
  • Thirdweb.Tests/Thirdweb.Contracts/Thirdweb.Contracts.Tests.cs (3 hunks)
  • Thirdweb.Tests/Thirdweb.Extensions/Thirdweb.Extensions.Tests.cs (6 hunks)
  • Thirdweb.Tests/Thirdweb.Extensions/Thirdweb.MarketplaceExtensions.Tests.cs (2 hunks)
  • Thirdweb.Tests/Thirdweb.Transactions/Thirdweb.Transactions.Tests.cs (8 hunks)
  • Thirdweb.Tests/Thirdweb.Transactions/Thirdweb.ZkSmartWallet.Tests.cs (1 hunks)
  • Thirdweb.Tests/Thirdweb.Utils/Thirdweb.Utils.Tests.cs (1 hunks)
  • Thirdweb.Tests/Thirdweb.Wallets/Thirdweb.PrivateKeyWallet.Tests.cs (0 hunks)
  • Thirdweb.Tests/Thirdweb.Wallets/Thirdweb.SmartWallet.Tests.cs (19 hunks)
  • Thirdweb.Tests/Thirdweb.Wallets/Thirdweb.Wallets.Tests.cs (3 hunks)
  • Thirdweb/Thirdweb.AI/ChatClient.cs (0 hunks)
  • Thirdweb/Thirdweb.AI/ExecutionClient.cs (0 hunks)
  • Thirdweb/Thirdweb.AI/SessionManager.cs (0 hunks)
  • Thirdweb/Thirdweb.AI/ThirdwebNebula.Types.cs (0 hunks)
  • Thirdweb/Thirdweb.AI/ThirdwebNebula.cs (0 hunks)
  • Thirdweb/Thirdweb.Bridge/ThirdwebBridge.Extensions.cs (1 hunks)
  • Thirdweb/Thirdweb.Bridge/ThirdwebBridge.Types.cs (1 hunks)
  • Thirdweb/Thirdweb.Bridge/ThirdwebBridge.cs (1 hunks)
  • Thirdweb/Thirdweb.Client/ITimeoutOptions.cs (0 hunks)
  • Thirdweb/Thirdweb.Client/ThirdwebClient.Types.cs (2 hunks)
  • Thirdweb/Thirdweb.Client/ThirdwebClient.cs (2 hunks)
  • Thirdweb/Thirdweb.Client/TimeoutType.cs (0 hunks)
  • Thirdweb/Thirdweb.Indexer/ThirdwebInsight.Extensions.cs (0 hunks)
  • Thirdweb/Thirdweb.Indexer/ThirdwebInsight.Types.cs (0 hunks)
  • Thirdweb/Thirdweb.Indexer/ThirdwebInsight.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.BuyWithCrypto.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.BuyWithFiat.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.GetBuyHistory.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.GetBuyWithCryptoQuote.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.GetBuyWithCryptoStatus.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.GetBuyWithFiatCurrencies.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.GetBuyWithFiatQuote.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.GetBuyWithFiatStatus.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/Types.GetBuyHistory.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/Types.GetBuyWithCryptoQuote.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/Types.GetBuyWithCryptoStatus.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/Types.GetBuyWithFiatCurrencies.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/Types.GetBuyWithFiatQuote.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/Types.GetBuyWithFiatStatus.cs (0 hunks)
  • Thirdweb/Thirdweb.Pay/Types.Shared.cs (0 hunks)
  • Thirdweb/Thirdweb.RPC/RpcError.cs (0 hunks)
  • Thirdweb/Thirdweb.RPC/RpcRequest.cs (0 hunks)
  • Thirdweb/Thirdweb.RPC/RpcResponse.cs (0 hunks)
  • Thirdweb/Thirdweb.RPC/ThirdwebRPC.Types.cs (1 hunks)
  • Thirdweb/Thirdweb.RPC/ThirdwebRPC.cs (2 hunks)
  • Thirdweb/Thirdweb.Transactions/ThirdwebTransaction.Types.cs (2 hunks)
  • Thirdweb/Thirdweb.Transactions/ThirdwebTransaction.cs (0 hunks)
  • Thirdweb/Thirdweb.Transactions/ThirdwebTransactionReceipt.cs (0 hunks)
  • Thirdweb/Thirdweb.Utils/EIP712.cs (0 hunks)
  • Thirdweb/Thirdweb.Utils/RLP.cs (1 hunks)
  • Thirdweb/Thirdweb.Utils/Utils.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/EngineWallet/EngineWallet.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs (5 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Authentication/AWS.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Encryption/EmbeddedWallet.Cryptography.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Encryption/IvGenerator.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Encryption/Secrets.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Exceptions/VerificationException.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Models/User.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Models/UserStatus.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Storage/LocalStorage.Types.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet/EmbeddedWallet.Misc.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.Types.cs (1 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.cs (8 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Storage/LocalStorage.Types.cs (1 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet/EmbeddedWallet.Misc.cs (1 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet/EmbeddedWallet.OAuth.cs (1 hunks)
  • Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet/EmbeddedWallet.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/PrivateKeyWallet/PrivateKeyWallet.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/ServerWallet/ServerWallet.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs (13 hunks)
  • Thirdweb/Thirdweb.Wallets/SmartWallet/Thirdweb.AccountAbstraction/ThirdwebBundler.Types.cs (0 hunks)
  • Thirdweb/Thirdweb.Wallets/SmartWallet/Thirdweb.AccountAbstraction/ThirdwebBundler.cs (1 hunks)
  • Thirdweb/Thirdweb.csproj (0 hunks)
  • nswag.json (1 hunks)
💤 Files with no reviewable changes (51)
  • Thirdweb/Thirdweb.Utils/EIP712.cs
  • Thirdweb/Thirdweb.Pay/Types.GetBuyWithFiatCurrencies.cs
  • Thirdweb/Thirdweb.AI/ChatClient.cs
  • Thirdweb/Thirdweb.RPC/RpcError.cs
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.GetBuyWithFiatQuote.cs
  • Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet/EmbeddedWallet.cs
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Models/User.cs
  • Thirdweb/Thirdweb.Client/TimeoutType.cs
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Models/UserStatus.cs
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Encryption/Secrets.cs
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.GetBuyWithCryptoQuote.cs
  • Thirdweb/Thirdweb.Client/ITimeoutOptions.cs
  • Thirdweb/Thirdweb.Pay/Types.GetBuyHistory.cs
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.cs
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.GetBuyWithCryptoStatus.cs
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.BuyWithFiat.cs
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Authentication/AWS.cs
  • Thirdweb/Thirdweb.csproj
  • Thirdweb/Thirdweb.Transactions/ThirdwebTransaction.cs
  • Thirdweb/Thirdweb.Pay/Types.Shared.cs
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.GetBuyWithFiatCurrencies.cs
  • Thirdweb/Thirdweb.Pay/Types.GetBuyWithCryptoStatus.cs
  • Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs
  • Thirdweb/Thirdweb.RPC/RpcRequest.cs
  • Thirdweb/Thirdweb.Indexer/ThirdwebInsight.Extensions.cs
  • Thirdweb/Thirdweb.Pay/Types.GetBuyWithFiatQuote.cs
  • Thirdweb/Thirdweb.AI/ExecutionClient.cs
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Encryption/IvGenerator.cs
  • Thirdweb/Thirdweb.Transactions/ThirdwebTransactionReceipt.cs
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.GetBuyWithFiatStatus.cs
  • Thirdweb/Thirdweb.Pay/Types.GetBuyWithFiatStatus.cs
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.BuyWithCrypto.cs
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Exceptions/VerificationException.cs
  • Thirdweb/Thirdweb.RPC/RpcResponse.cs
  • Thirdweb/Thirdweb.Wallets/EngineWallet/EngineWallet.cs
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Encryption/EmbeddedWallet.Cryptography.cs
  • Thirdweb/Thirdweb.AI/ThirdwebNebula.Types.cs
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Storage/LocalStorage.Types.cs
  • Thirdweb/Thirdweb.Pay/ThirdwebPay.GetBuyHistory.cs
  • Thirdweb/Thirdweb.AI/SessionManager.cs
  • Thirdweb/Thirdweb.Indexer/ThirdwebInsight.cs
  • Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet/EmbeddedWallet.Misc.cs
  • Thirdweb/Thirdweb.Utils/Utils.cs
  • Thirdweb.Tests/Thirdweb.AI/Thirdweb.AI.Tests.cs
  • Thirdweb/Thirdweb.Wallets/ServerWallet/ServerWallet.cs
  • Thirdweb.Tests/Thirdweb.Wallets/Thirdweb.PrivateKeyWallet.Tests.cs
  • Thirdweb/Thirdweb.AI/ThirdwebNebula.cs
  • Thirdweb/Thirdweb.Indexer/ThirdwebInsight.Types.cs
  • Thirdweb/Thirdweb.Pay/Types.GetBuyWithCryptoQuote.cs
  • Thirdweb/Thirdweb.Wallets/PrivateKeyWallet/PrivateKeyWallet.cs
  • Thirdweb/Thirdweb.Wallets/SmartWallet/Thirdweb.AccountAbstraction/ThirdwebBundler.Types.cs
🧰 Additional context used
🧬 Code graph analysis (15)
Thirdweb.Tests/BaseTests.cs (2)
Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs (18)
  • Task (146-233)
  • Task (243-246)
  • Task (252-261)
  • Task (266-291)
  • Task (299-367)
  • Task (373-382)
  • Task (388-397)
  • Task (409-449)
  • Task (456-461)
  • Task (468-498)
  • Task (505-537)
  • Task (544-571)
  • Task (573-583)
  • Task (585-763)
  • Task (765-808)
  • Task (810-817)
  • SmartWallet (21-1240)
  • SmartWallet (101-128)
Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.cs (2)
  • InAppWallet (8-76)
  • InAppWallet (12-29)
Thirdweb.Tests/Thirdweb.Transactions/Thirdweb.Transactions.Tests.cs (1)
Thirdweb/Thirdweb.Transactions/ThirdwebTransaction.cs (12)
  • ThirdwebTransaction (28-521)
  • ThirdwebTransaction (34-38)
  • ThirdwebTransaction (79-83)
  • ThirdwebTransaction (90-94)
  • ThirdwebTransaction (101-105)
  • ThirdwebTransaction (112-116)
  • ThirdwebTransaction (123-127)
  • ThirdwebTransaction (134-138)
  • ThirdwebTransaction (145-149)
  • ThirdwebTransaction (156-160)
  • ThirdwebTransaction (167-171)
  • ThirdwebTransaction (178-182)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet/EmbeddedWallet.OAuth.cs (2)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.Types.cs (3)
  • Server (5-228)
  • VerifyResult (7-27)
  • VerifyResult (9-18)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.cs (5)
  • Server (32-32)
  • Server (37-399)
  • Server (48-52)
  • VerifyResult (284-288)
  • VerifyResult (292-303)
Thirdweb/Thirdweb.Wallets/SmartWallet/Thirdweb.AccountAbstraction/ThirdwebBundler.cs (1)
Thirdweb/Thirdweb.Api/ThirdwebApi.cs (1)
  • Newtonsoft (47-52)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Storage/LocalStorage.Types.cs (2)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet/EmbeddedWallet.Misc.cs (1)
  • LocalStorage (5-8)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Storage/LocalStorage.cs (3)
  • LocalStorage (12-60)
  • LocalStorage (18-37)
  • LocalStorageBase (5-10)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.Types.cs (1)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.cs (2)
  • VerifyResult (284-288)
  • VerifyResult (292-303)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet/EmbeddedWallet.Misc.cs (3)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet/EmbeddedWallet.cs (2)
  • EmbeddedWallet (3-40)
  • EmbeddedWallet (8-39)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Storage/LocalStorage.Types.cs (2)
  • LocalStorage (5-49)
  • DataStorage (31-40)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Storage/LocalStorage.cs (2)
  • LocalStorage (12-60)
  • LocalStorage (18-37)
Thirdweb/Thirdweb.RPC/ThirdwebRPC.Types.cs (2)
Thirdweb/Thirdweb.Api/ThirdwebApi.cs (1)
  • Newtonsoft (47-52)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.cs (1)
  • Serialize (388-396)
Thirdweb.Console/Program.cs (1)
Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.cs (2)
  • InAppWallet (8-76)
  • InAppWallet (12-29)
Thirdweb/Thirdweb.Transactions/ThirdwebTransaction.Types.cs (2)
Thirdweb/Thirdweb.Api/ThirdwebApi.cs (1)
  • Newtonsoft (47-52)
Thirdweb/Thirdweb.Transactions/ThirdwebTransaction.cs (1)
  • ToString (69-72)
Thirdweb/Thirdweb.Client/ThirdwebClient.cs (1)
Thirdweb/Thirdweb.Client/ThirdwebClient.Types.cs (1)
  • TimeoutOptions (12-34)
Thirdweb.Tests/Thirdweb.Wallets/Thirdweb.SmartWallet.Tests.cs (3)
Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.cs (2)
  • InAppWallet (8-76)
  • InAppWallet (12-29)
Thirdweb.Tests/Thirdweb.Wallets/Thirdweb.Wallets.Tests.cs (3)
  • Fact (10-15)
  • Fact (17-24)
  • Fact (26-33)
Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs (18)
  • Task (146-233)
  • Task (243-246)
  • Task (252-261)
  • Task (266-291)
  • Task (299-367)
  • Task (373-382)
  • Task (388-397)
  • Task (409-449)
  • Task (456-461)
  • Task (468-498)
  • Task (505-537)
  • Task (544-571)
  • Task (573-583)
  • Task (585-763)
  • Task (765-808)
  • Task (810-817)
  • SmartWallet (21-1240)
  • SmartWallet (101-128)
Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs (3)
Thirdweb/Thirdweb.Wallets/SmartWallet/Thirdweb.AccountAbstraction/ThirdwebBundler.cs (1)
  • ThirdwebBundler (5-146)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet/EmbeddedWallet.Misc.cs (1)
  • EmbeddedWallet (3-19)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet/EmbeddedWallet.OAuth.cs (1)
  • EmbeddedWallet (3-14)
Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs (4)
Thirdweb/Thirdweb.Extensions/ThirdwebExtensions.cs (1)
  • CreateCallData (36-40)
Thirdweb/Thirdweb.Utils/Utils.cs (5)
  • HexToBytes (128-131)
  • Utils (24-1206)
  • GetEntryPointVersion (461-475)
  • BigInteger (149-152)
  • BigInteger (396-410)
Thirdweb/Thirdweb.Wallets/SmartWallet/Thirdweb.AccountAbstraction/ThirdwebBundler.cs (1)
  • ThirdwebBundler (5-146)
Thirdweb/Thirdweb.Wallets/SmartWallet/Thirdweb.AccountAbstraction/ThirdwebBundler.Types.cs (1)
  • UserOperationV6 (7-41)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.cs (2)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.Types.cs (3)
  • Server (5-228)
  • VerifyResult (7-27)
  • VerifyResult (9-18)
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet/EmbeddedWallet.OAuth.cs (1)
  • Server (5-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-test-cov
🔇 Additional comments (32)
Thirdweb/Thirdweb.Bridge/ThirdwebBridge.Extensions.cs (2)

3-3: Namespace move to Thirdweb: verify extension type import sites

Callers importing Thirdweb.Bridge.ThirdwebBridgeExtensions must be updated to Thirdweb.ThirdwebBridgeExtensions or rely on extension method inference via using Thirdweb.


118-143: The above script will verify whether StatusType includes PROCESSING/CREATED and if ThirdwebBridge.Status supports cancellation. Once we have the results, I’ll update or resolve the review comment accordingly.

Thirdweb/Thirdweb.Bridge/ThirdwebBridge.cs (1)

5-5: Namespace consolidation to Thirdweb: confirm migration and public API impact

This is a breaking change for consumers using fully-qualified names. Ensure release notes, samples, and docs reflect it.

Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.cs (2)

32-32: API surface change: sync VerifyOAuthAsync — confirm intended and update all call sites

Switching from Task to VerifyResult is a breaking change for any implementers/consumers. If public, consider keeping the async signature (wrapping with Task.FromResult) or provide an adapter to avoid ripple effects.


140-141: Good consolidation via ToVerifyResult

Removing per-endpoint mapping duplication is a win. Keep this centralization.

Also applies to: 159-161, 172-173, 215-216, 239-240

Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet/EmbeddedWallet.OAuth.cs (1)

5-8: The scripts will run and we’ll inspect:

  1. The file contents to confirm the signature and body.
  2. The definition of VerifyOAuthAsync to confirm its return type.
  3. Any callers of SignInWithOauthAsync to ensure backward‐compat concerns.

Once we have that, we’ll know whether to keep the Async name and return a Task<VerifyResult> or rename the method—and whether any external callers need updating.

Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet/EmbeddedWallet.Misc.cs (2)

1-1: No import needed—implicit usings enabled
System.Threading.Tasks is already covered by the project’s enabled implicit global usings (<ImplicitUsings>enable</ImplicitUsings> in the .csproj), so no additional using directive is required.


3-19: No additional checks required for storageDirectoryPath and clientId
EcosystemWallet assigns a non-empty default storageDirectoryPath before calling new EmbeddedWallet, and ThirdwebClient guarantees a non-empty ClientId at creation—LocalStorage’s constructor will never receive null or empty values.

Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Storage/LocalStorage.Types.cs (1)

31-40: LGTM on the serialization model and ctor assignments

Constructor sets all backing fields and [field: DataMember] enables deserialization without setters.

Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs (2)

440-446: Migration to CreateCallData looks good.

Using CreateCallData to build calldata for setPermissionsForSigner reduces ABI coupling and is consistent with the new approach.

Also applies to: 489-495, 528-534


639-641: Bundler/paymaster integration updates look sound; confirm env timeouts and requestId strategy.

Calls now go through ThirdwebBundler with client-based timeouts. requestId is hardcoded to 1 in most paths; consider a per-call increment for tracing.

Do you want me to wire a simple monotonic requestId and add lightweight logging of method+requestId for troubleshooting?

Also applies to: 679-682, 747-755, 783-784, 796-799, 824-825, 835-836, 852-853

Thirdweb.Tests/BaseTests.cs (1)

33-36: LGTM: guest wallet helper simplifies tests.

Good abstraction; aligns the suite on InApp/guest flows.

Thirdweb.Tests/Thirdweb.Extensions/Thirdweb.MarketplaceExtensions.Tests.cs (1)

171-175: LGTM: guest buyer swap is correct.

Approval aligns with repo-wide migration away from PrivateKeyWallet.

Thirdweb.Tests/Thirdweb.Wallets/Thirdweb.Wallets.Tests.cs (3)

20-24: LGTM: PersonalSignRaw now uses guest wallet.


29-33: LGTM: PersonalSign now uses guest wallet.


118-119: LGTM: SwitchNetwork on guest account.

Matches new auth flow.

Thirdweb.Tests/Thirdweb.Transactions/Thirdweb.ZkSmartWallet.Tests.cs (1)

10-12: LGTM: guest personal wallet for ZK smart account.

Thirdweb/Thirdweb.Wallets/SmartWallet/Thirdweb.AccountAbstraction/ThirdwebBundler.cs (2)

5-6: Rename verification passed — no remaining BundlerClient references found.


116-145: Verify RpcRequestMessage/RpcResponseMessage definitions/imports.
Couldn’t locate type definitions or import directives for RpcRequestMessage or RpcResponseMessage in the repository. Ensure these types are defined in-repo or imported (e.g. via a global using) before merging.

Thirdweb/Thirdweb.Client/ThirdwebClient.Types.cs (2)

12-17: No action needed: LangVersion=latest supports C# 12 primary constructors
All three project files (Thirdweb.csproj, Thirdweb.Console.csproj, Thirdweb.Tests.csproj) specify <LangVersion>latest</LangVersion>, which includes C# 12 support.


36-56: No duplicate TimeoutType or ITimeoutOptions found
All timeout-related types are declared only in ThirdwebClient.Types.cs; no stale enum or interface artifacts remain.

Thirdweb.Tests/Thirdweb.Transactions/Thirdweb.Transactions.Tests.cs (8)

13-16: LGTM: sample tx uses guest wallet.


51-55: LGTM: input validation with guest wallet.


61-65: LGTM: Create_ThrowsOnNoTo now with guest wallet.


71-75: LGTM: Create_ThrowsOnNoWallet unaffected by guest switch.


81-85: LGTM: chainId zero case unchanged; guest wallet OK.


163-168: LGTM: signing with SmartWallet backed by guest wallet.


330-337: LGTM: EstimateGasFees on chain 250 with guest wallet.

Good coverage for non-zk path.


363-376: LGTM: simulate via SmartWallet backed by guest wallet.

Assertion tolerates intrinsic gas variance.

Thirdweb/Thirdweb.Transactions/ThirdwebTransaction.Types.cs (1)

224-323: Receipt type relocation approved. Consolidating ThirdwebTransactionReceipt here is fine; JSON bindings match common ETH receipt fields, and no duplicate definitions remain.

Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs (2)

121-121: Good switch to ThirdwebBundler for delegation contract.

Centralizing bundler RPCs behind ThirdwebBundler aligns with the new timeout options and error handling.


305-306: Ensure handling for missing enclave wallets
Hard‐fail on users without an enclave wallet is a breaking behavior change—verify every caller now catches the InvalidOperationException and surfaces a clear remediation path (re-auth/migration). Consider replacing the generic exception with a dedicated MissingEnclaveWalletException for precise handling and telemetry.

@@ -64,7 +64,7 @@
"generateImmutableDictionaryProperties": false,
"jsonConverters": null,
"anyType": "object",
"output": "Thirdweb/Thirdweb.Api/GeneratedClient.cs"
"output": "Thirdweb/Thirdweb.Api/ThirdwebApi.cs"
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

Path rename: verify no stale references to GeneratedClient.cs and avoid duplicate type compilation

Changing the generated file to Thirdweb/Thirdweb.Api/ThirdwebApi.cs is fine. Please ensure:

  • The old GeneratedClient.cs is removed/excluded from all projects.
  • No build/pipeline scripts or docs reference GeneratedClient.cs.
  • No .csproj explicitly includes/excludes the old path.

Run this to confirm and surface any remaining references:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Check for old/new generated files:"
fd -t f -a 'GeneratedClient.cs|ThirdwebApi.cs' || true

echo -e "\nSearch for references to the old file name:"
rg -nP --hidden --glob '!.git/' 'GeneratedClient\.cs' -C2 || true

echo -e "\nSearch for explicit Compile Include entries in project files:"
fd -t f -e csproj -e props -e targets -x rg -nP 'GeneratedClient\.cs|ThirdwebApi\.cs' -n {} || true

Length of output: 347


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Searching for stale references to 'GeneratedClient.cs':"
rg -nF --no-ignore 'GeneratedClient.cs' -C1 || true

echo -e "\nSearching for explicit <Compile Include> entries for GeneratedClient.cs in csproj files:"
rg -nP --no-ignore '<Compile\s+Include=.*GeneratedClient\.cs' -n -g '**/*.csproj' || true

echo -e "\nSearching for references in docs and scripts (md, yml, yaml, sh, ps1, json):"
rg -nF --no-ignore 'GeneratedClient.cs' -g '**/*.{md,yml,yaml,sh,ps1,json}' -C1 || true

echo -e "\nVerifying new generated file 'ThirdwebApi.cs' exists:"
rg -nF --no-ignore 'ThirdwebApi.cs' -C1 || true

echo -e "\nSearching for explicit <Compile Include> entries for ThirdwebApi.cs in csproj files:"
rg -nP --no-ignore '<Compile\s+Include=.*ThirdwebApi\.cs' -n -g '**/*.csproj' || true

Length of output: 1330


Update stale references to GeneratedClient.cs

– codecov.yml still lists "Thirdweb/Thirdweb.Api/GeneratedClient.cs" (line 4); update or remove it
– tw.bat contains checks and deletion commands for Thirdweb\Thirdweb.Api\GeneratedClient.cs (lines 21–25, 58–60, 84–86); point these at ThirdwebApi.cs instead

🤖 Prompt for AI Agents
In nswag.json around line 67, the output filename was changed to
"Thirdweb/Thirdweb.Api/ThirdwebApi.cs" but other repo files still reference the
old GeneratedClient.cs; update codecov.yml (replace
"Thirdweb/Thirdweb.Api/GeneratedClient.cs" at line ~4 with
"Thirdweb/Thirdweb.Api/ThirdwebApi.cs" or remove the entry) and edit tw.bat
(replace references and deletion/check paths at lines ~21–25, ~58–60, ~84–86 to
point to Thirdweb\Thirdweb.Api\ThirdwebApi.cs, ensuring path separators match
the script) so all tooling and CI reference the new ThirdwebApi.cs filename
consistently.

Comment on lines +1423 to 1425
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()) };
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.

Comment on lines +95 to 98
_ = ThirdwebClient.Create(clientId: this.ClientIdBundleIdOnly, bundleId: this.BundleIdBundleIdOnly);
var privateKeyAccount = await this.GetGuestAccount();
var smartAccount = await SmartWallet.Create(personalWallet: privateKeyAccount, factoryAddress: "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", gasless: true, chainId: 421614);
var tx = await smartAccount.SendTransaction(new ThirdwebTransactionInput(421614) { To = await smartAccount.GetAddress() });
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

Guarantee guest account is connected in helper to prevent null addresses.

Multiple tests assume immediate address/signing ability. If GetGuestAccount doesn’t ensure LoginWithGuest, these can intermittently fail.

Inspect helper and enforce connect if missing:

If not connected, adjust BaseTests:

public async Task<IThirdwebWallet> GetGuestAccount() {
  var wallet = await InAppWallet.Create(this.Client, authProvider: AuthProvider.Guest);
  if (!await wallet.IsConnected()) { _ = await wallet.LoginWithGuest(); }
  return wallet;
}

Also applies to: 322-323, 332-333, 342-343, 352-353, 362-363, 372-376


🏁 Script executed:

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

Length of output: 1894


Ensure guest wallet is connected before use
In Thirdweb.Tests/BaseTests.cs (lines 33–36), GetGuestAccount must call LoginWithGuest() if the wallet isn’t already connected to avoid null-address failures in downstream tests. For example:

 public async Task<IThirdwebWallet> GetGuestAccount() {
-   return await InAppWallet.Create(this.Client, authProvider: AuthProvider.Guest);
+   var wallet = await InAppWallet.Create(this.Client, authProvider: AuthProvider.Guest);
+   if (!await wallet.IsConnected()) {
+     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
_ = ThirdwebClient.Create(clientId: this.ClientIdBundleIdOnly, bundleId: this.BundleIdBundleIdOnly);
var privateKeyAccount = await this.GetGuestAccount();
var smartAccount = await SmartWallet.Create(personalWallet: privateKeyAccount, factoryAddress: "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", gasless: true, chainId: 421614);
var tx = await smartAccount.SendTransaction(new ThirdwebTransactionInput(421614) { To = await smartAccount.GetAddress() });
public async Task<IThirdwebWallet> GetGuestAccount() {
var wallet = await InAppWallet.Create(this.Client, authProvider: AuthProvider.Guest);
if (!await wallet.IsConnected()) {
await wallet.LoginWithGuest();
}
return wallet;
}
🤖 Prompt for AI Agents
In Thirdweb.Tests/BaseTests.cs around lines 33–36 and usage in
Thirdweb.Tests/Thirdweb.Wallets/Thirdweb.SmartWallet.Tests.cs lines 95–98, the
guest account may be returned before the wallet is connected causing
null-address failures; update GetGuestAccount to check whether the guest wallet
is connected and, if not, call and await LoginWithGuest() (or the equivalent
connect method) before returning the account so downstream tests using the
returned account can safely call GetAddress()/SendTransaction.

@@ -1,7 +1,7 @@
using System.Numerics;
using Newtonsoft.Json;

namespace Thirdweb.Bridge;
namespace Thirdweb;
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

❓ Verification inconclusive

Namespace consolidation to Thirdweb: confirm v3-breaking API and migration plan

This rename breaks fully-qualified type names. Ensure downstream code, samples, and docs are updated, and call out the breaking change in the v3 changelog. If you want to help users, consider temporary shim types in the old namespace marked [Obsolete] for a deprecation window.

Run to spot any lingering references:


🏁 Script executed:

#!/bin/bash
# Find old namespace usages
rg -nP 'namespace\s+Thirdweb\.Bridge\b|Thirdweb\.Bridge\.' -C2

Length of output: 0


Document v3-breaking namespace consolidation from Thirdweb.Bridge to Thirdweb
Verified no residual Thirdweb.Bridge references. Ensure all downstream code, samples, and documentation use namespace Thirdweb, call out this breaking change in the v3 changelog, and (optionally) provide [Obsolete] shim types in the old Thirdweb.Bridge namespace for a deprecation window.

🤖 Prompt for AI Agents
In Thirdweb/Thirdweb.Bridge/ThirdwebBridge.Types.cs around line 4, the file
currently uses namespace Thirdweb (consolidation from Thirdweb.Bridge), but the
project must document and propagate this breaking change: update all downstream
code, sample projects and documentation to reference namespace Thirdweb instead
of Thirdweb.Bridge; add a clear v3 changelog entry describing the breaking
change and migration notes; optionally add a small shim file under the old
Thirdweb.Bridge namespace that defines obsolete wrapper types (annotated with
[Obsolete] and forwarding to the new Thirdweb types) to provide a short
deprecation window while tests and samples are updated.

Comment on lines +210 to 211
revertMsg = rpcResponse.Error.Data.Type == JTokenType.String ? rpcResponse.Error.Data.ToString() : JsonConvert.SerializeObject(rpcResponse.Error.Data);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Defensive cast for Error.Data before accessing JToken.Type.

If Data is not a JToken, accessing .Type will throw. Safe-cast first and fall back to ToString/serialize.

-                                    revertMsg = rpcResponse.Error.Data.Type == JTokenType.String ? rpcResponse.Error.Data.ToString() : JsonConvert.SerializeObject(rpcResponse.Error.Data);
+                                    if (rpcResponse.Error.Data is JToken jt)
+                                    {
+                                        revertMsg = jt.Type == JTokenType.String ? jt.ToString() : jt.ToString(Formatting.None);
+                                    }
+                                    else
+                                    {
+                                        revertMsg = rpcResponse.Error.Data?.ToString() ?? string.Empty;
+                                    }
📝 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
revertMsg = rpcResponse.Error.Data.Type == JTokenType.String ? rpcResponse.Error.Data.ToString() : JsonConvert.SerializeObject(rpcResponse.Error.Data);
}
if (rpcResponse.Error.Data is JToken jt)
{
// For JToken data, emit the raw string if it's already a string token,
// otherwise output its compact JSON representation.
revertMsg = jt.Type == JTokenType.String
? jt.ToString()
: jt.ToString(Formatting.None);
}
else
{
// For non-JToken (or null), fall back to the object's ToString (or empty).
revertMsg = rpcResponse.Error.Data?.ToString() ?? string.Empty;
}
🤖 Prompt for AI Agents
In Thirdweb/Thirdweb.RPC/ThirdwebRPC.cs around lines 210-211, the code assumes
rpcResponse.Error.Data is a JToken and accesses .Type directly which can throw
if Data is not a JToken; change to safely cast Data to JToken (e.g. var
dataToken = rpcResponse.Error.Data as JToken), then if dataToken is non-null use
dataToken.Type to decide whether to call ToString() or
JsonConvert.SerializeObject(dataToken), otherwise fall back to calling
ToString() on rpcResponse.Error.Data or
JsonConvert.SerializeObject(rpcResponse.Error.Data) as appropriate and handle
nulls to avoid exceptions.

Comment on lines +284 to 288
internal override VerifyResult VerifyOAuthAsync(string authResultStr)
{
var authResult = JsonConvert.DeserializeObject<AuthResultType>(authResultStr);
return await this.InvokeAuthResultLambdaAsync(authResult).ConfigureAwait(false);
return this.ToVerifyResult(authResult);
}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

❓ Verification inconclusive

OAuth verify now trusts raw JSON — add validation and error handling

authResultStr is untrusted input. Handle malformed JSON and missing fields to avoid NREs and clearer errors.

Apply:

-    internal override VerifyResult VerifyOAuthAsync(string authResultStr)
-    {
-        var authResult = JsonConvert.DeserializeObject<AuthResultType>(authResultStr);
-        return this.ToVerifyResult(authResult);
-    }
+    internal override VerifyResult VerifyOAuthAsync(string authResultStr)
+    {
+        if (string.IsNullOrWhiteSpace(authResultStr))
+        {
+            throw new ArgumentException("Empty OAuth authResult payload.", nameof(authResultStr));
+        }
+        AuthResultType authResult;
+        try
+        {
+            authResult = JsonConvert.DeserializeObject<AuthResultType>(authResultStr);
+        }
+        catch (JsonException ex)
+        {
+            throw new InvalidOperationException("Failed to parse OAuth authResult payload.", ex);
+        }
+        if (authResult?.StoredToken == null)
+        {
+            throw new InvalidOperationException("Invalid OAuth payload: missing StoredToken.");
+        }
+        return this.ToVerifyResult(authResult);
+    }

Is authResultStr guaranteed to originate from a trusted Thirdweb redirect (not caller-supplied)? If not, consider a server-side verification round-trip.


Validate and handle errors in VerifyOAuthAsync (Server.cs:284-288)
Guard against empty or whitespace authResultStr, catch JsonConvert.DeserializeObject failures, and verify required fields (e.g. authResult.StoredToken) before calling ToVerifyResult to avoid null‐reference exceptions and surface clear errors. Also confirm that authResultStr is only ever set from a trusted OAuth redirect—or implement a server-side verification round-trip if it can be caller-supplied.

🤖 Prompt for AI Agents
In
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.cs
around lines 284-288, VerifyOAuthAsync currently deserializes authResultStr
without validation or error handling which can cause null-reference exceptions
and unclear failures; update the method to first guard against
null/empty/whitespace authResultStr and return a failed VerifyResult when
invalid, wrap JsonConvert.DeserializeObject in a try/catch to handle and log
deserialization errors and return a clear failure VerifyResult on exception,
validate that the deserialized authResult and required fields (e.g.
authResult.StoredToken) are present before calling ToVerifyResult and return
explicit errors if missing, and if authResultStr can be supplied by callers
ensure you perform a server-side verification round-trip or verify the OAuth
redirect/source before trusting the payload.

Comment on lines +292 to 298
private VerifyResult ToVerifyResult(AuthResultType authResult)
{
var webExchangeResult = await this.FetchCognitoIdTokenAsync(authToken).ConfigureAwait(false);
return await AWS.GenerateDataKey(webExchangeResult.IdentityId, webExchangeResult.Token, this._httpClient).ConfigureAwait(false);
}

private async Task<VerifyResult> InvokeAuthResultLambdaAsync(AuthResultType authResult)
{
var authToken = authResult.StoredToken.CookieString;
var idTokenResponse = await this.FetchCognitoIdTokenAsync(authToken).ConfigureAwait(false);

var invokePayload = Serialize(new { token = idTokenResponse.LambdaToken });
var responsePayload = await AWS.InvokeRecoverySharePasswordLambdaAsync(idTokenResponse.IdentityId, idTokenResponse.Token, invokePayload, this._httpClient).ConfigureAwait(false);

var jsonSerializer = new JsonSerializer();
var payload = jsonSerializer.Deserialize<RecoverySharePasswordResponse>(new JsonTextReader(new StreamReader(responsePayload)));
payload = jsonSerializer.Deserialize<RecoverySharePasswordResponse>(new JsonTextReader(new StringReader(payload.Body)));
return new VerifyResult(
authResult.StoredToken.AuthProvider,
authResult.StoredToken.IsNewUser,
authToken,
authResult.StoredToken.CookieString,
authResult.StoredToken.AuthDetails.UserWalletId,
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

Critical: Using CookieString as AuthToken likely breaks Authorization Bearer and downstream calls

AuthToken from ToVerifyResult is used by SendHttpWithAuthAsync as: "Authorization: Bearer embedded-wallet-token:{authToken}". A cookie string is not a bearer token and will likely fail. Other flows (VerifyJwtAsync/VerifyAuthEndpointAsync) return a JWT string. Use JwtToken for consistency.

Apply:

-            authResult.StoredToken.CookieString,
+            authResult.StoredToken.JwtToken,

Follow-ups:

  • If CookieString must also be persisted, expose/store it separately (e.g., add property or set an internal Cookie header when ShouldStoreCookieString is true).

Run to locate AuthToken consumers and ensure bearer expectations:


🏁 Script executed:

#!/bin/bash
rg -n -C3 '\bAuthToken\b' --type cs
rg -n -C2 'embedded-wallet-token:' --type cs

Length of output: 13930


🏁 Script executed:

#!/bin/bash
# Locate AuthResultType definition to inspect StoredToken structure
rg -n 'AuthResultType' -C5 --type cs Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.cs

# Locate StoredToken references within AuthResultType
rg -n 'StoredToken' -C5 --type cs Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.cs

# Verify presence of JwtToken property in the codebase
rg -n 'JwtToken' -C5 --type cs

Length of output: 6791


Use JWT for Bearer Authorization
In Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.cs’s ToVerifyResult (around line 297), replace the cookie string with the JWT so downstream calls get a valid bearer token:

-            authResult.StoredToken.CookieString,
+            authResult.StoredToken.JwtToken,

If you still need the cookie value, surface it separately (e.g. add a dedicated property or header).

🤖 Prompt for AI Agents
In
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Authentication/Server.cs
around lines 292 to 298, change the value passed for the token in VerifyResult
from the cookie string to the JWT/bearer token so downstream calls receive a
valid Authorization: Bearer token; specifically replace
authResult.StoredToken.CookieString with the JWT property on StoredToken (e.g.
StoredToken.Jwt or StoredToken.AccessToken), and if the cookie value still must
be preserved, add a separate property to VerifyResult (or another header) to
carry the cookie rather than overloading the token field.

Comment on lines +43 to +48
[DataContract]
private class Storage
{
[DataMember]
internal DataStorage Data { get; set; }
}
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

Make Storage.Data nullable (+ align base/override types)

Data can legitimately be absent. Mark it nullable and align LocalStorageBase/overrides accordingly to avoid NRT warnings and accidental assumptions.

Apply here:

-        internal DataStorage Data { get; set; }
+        internal DataStorage? Data { get; set; }

Also update the base and override (in LocalStorageBase and LocalStorage.cs):

-    internal abstract LocalStorage.DataStorage Data { get; }
-    internal abstract Task SaveDataAsync(LocalStorage.DataStorage data);
+    internal abstract LocalStorage.DataStorage? Data { get; }
+    internal abstract Task SaveDataAsync(LocalStorage.DataStorage? data);
-    internal override DataStorage Data => this._storage.Data;
+    internal override DataStorage? Data => this._storage.Data;
-    internal override Task SaveDataAsync(DataStorage data)
+    internal override Task SaveDataAsync(DataStorage? data)

Verify impact:


🏁 Script executed:

#!/bin/bash
rg -n '\b\.Data\b' Thirdweb -g '*.cs' -C2
rg -nP 'SaveDataAsync\s*\(' Thirdweb -g '*.cs' -C2

Length of output: 18509


Make Storage.Data nullable and update LocalStorage signatures & GetSessionData

  • LocalStorage.Types.cs:
    - internal DataStorage Data { get; set; }
    + internal DataStorage? Data { get; set; }
  • LocalStorageBase (Abstract):
    - internal abstract LocalStorage.DataStorage Data { get; }
    - internal abstract Task SaveDataAsync(LocalStorage.DataStorage data);
    + internal abstract LocalStorage.DataStorage? Data { get; }
    + internal abstract Task SaveDataAsync(LocalStorage.DataStorage? data);
  • LocalStorage override:
    - internal override DataStorage Data => this._storage.Data;
    - internal override Task SaveDataAsync(DataStorage data)
    + internal override DataStorage? Data => this._storage.Data;
    + internal override Task SaveDataAsync(DataStorage? data)
  • EmbeddedWallet.Misc.cs: change
    - internal LocalStorage.DataStorage GetSessionData()
    + internal LocalStorage.DataStorage? GetSessionData()
    to align the nullable return of this._localStorage.Data.
📝 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
[DataContract]
private class Storage
{
[DataMember]
internal DataStorage Data { get; set; }
}
[DataContract]
private class Storage
{
[DataMember]
internal DataStorage? Data { get; set; }
}
🤖 Prompt for AI Agents
In
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet.Storage/LocalStorage.Types.cs
around lines 43-48, change the Storage.Data property to be nullable (e.g.
DataStorage?) and then propagate that nullability: update the abstract
LocalStorageBase method/property signatures to return/accept nullable
DataStorage, update the concrete LocalStorage override implementations to match
the nullable signatures and handle null appropriately, and modify
EmbeddedWallet.Misc.cs where this._localStorage.Data is used so callers accept
and handle a possibly null return (adjust types and add null checks or fallback
logic as needed).

Comment on lines +10 to +13
internal async void UpdateSessionData(LocalStorage.DataStorage data)
{
await this._localStorage.SaveDataAsync(data).ConfigureAwait(false);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid async void; return Task to propagate errors and allow awaiting

async void hides exceptions and is not awaitable. Return Task and forward the inner task.

Apply:

-    internal async void UpdateSessionData(LocalStorage.DataStorage data)
-    {
-        await this._localStorage.SaveDataAsync(data).ConfigureAwait(false);
-    }
+    internal Task UpdateSessionData(LocalStorage.DataStorage data)
+    {
+        return this._localStorage.SaveDataAsync(data);
+    }
📝 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
internal async void UpdateSessionData(LocalStorage.DataStorage data)
{
await this._localStorage.SaveDataAsync(data).ConfigureAwait(false);
}
internal Task UpdateSessionData(LocalStorage.DataStorage data)
{
return this._localStorage.SaveDataAsync(data);
}
🤖 Prompt for AI Agents
In
Thirdweb/Thirdweb.Wallets/InAppWallet/Thirdweb.EWS/EmbeddedWallet/EmbeddedWallet.Misc.cs
around lines 10-13, the method UpdateSessionData is declared async void which
hides exceptions and cannot be awaited; change its signature to return Task
(i.e., Task UpdateSessionData(...)) and remove the async/await by returning the
inner SaveDataAsync call (or if awaiting is needed keep async and return Task)
so callers can await and exceptions propagate.

Comment on lines 703 to 709
Sender = this._accountContract.Address,
Nonce = await this.GetNonce().ConfigureAwait(false),
Factory = factory,
FactoryData = factoryData.HexToBytes(),
CallData = executeInput.Data.HexToBytes(),
CallData = executeInput.HexToBytes(),
CallGasLimit = 0,
VerificationGasLimit = 0,
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

NullRef risk when no initCode: FactoryData computed from null.

When the account is already deployed, factoryData is null; calling HexToBytes() will throw. Default to empty bytes and a zero address.

-                Factory = factory,
-                FactoryData = factoryData.HexToBytes(),
+                Factory = string.IsNullOrEmpty(factory) ? Constants.ADDRESS_ZERO : factory,
+                FactoryData = string.IsNullOrEmpty(factoryData) ? Array.Empty<byte>() : factoryData.HexToBytes(),
📝 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
Sender = this._accountContract.Address,
Nonce = await this.GetNonce().ConfigureAwait(false),
Factory = factory,
FactoryData = factoryData.HexToBytes(),
CallData = executeInput.Data.HexToBytes(),
CallData = executeInput.HexToBytes(),
CallGasLimit = 0,
VerificationGasLimit = 0,
Sender = this._accountContract.Address,
Nonce = await this.GetNonce().ConfigureAwait(false),
- Factory = factory,
Factory = string.IsNullOrEmpty(factory)
? Constants.ADDRESS_ZERO
: factory,
FactoryData = string.IsNullOrEmpty(factoryData)
? Array.Empty<byte>()
: factoryData.HexToBytes(),
CallData = executeInput.HexToBytes(),
CallGasLimit = 0,
VerificationGasLimit = 0,
🤖 Prompt for AI Agents
In Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs around lines 703-709,
the code calls HexToBytes() on factoryData which can be null when the account is
already deployed; change the assignment to guard against null by using an empty
byte[] when factoryData is null or empty and set Factory to the zero address in
that case. Specifically, only call HexToBytes() when factoryData is
non-null/non-empty and otherwise set FactoryData to a new empty byte array and
Factory to the zero address; keep existing values when factoryData is present.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant