Skip to content

Releases: thirdweb-dev/dotnet

v3.0.0

27 Sep 17:55
d0009ae

Choose a tag to compare

Thirdweb .NET SDK v3 – Official Release

Why Upgrade to v3

  1. Unified client and APIs
  2. Faster, lighter, and more efficient
  3. Modern dependencies and standards
  4. Easier wallet and transaction testing
  5. Architecture ready for future features

Thirdweb .NET SDK v3 evolves from separate utilities into a cohesive, high-performance platform.

Major Architectural Changes

Unified API Client

// v2 – Separate clients
var nebula = await ThirdwebNebula.Create(client);
var pay = new ThirdwebPay();  
var bridge = await ThirdwebBridge.Create(client);
var insight = await ThirdwebInsight.Create(client);

// v3 – Unified client
var response = await client.Api.JustDoItAsync(...);

Highlights

  • Low level generated client for thirdweb API full access, will be kept updated and the time-save will be used to make higher level APIs with nicer DX similar to the remaining ThirdwebWallet, ThirdwebContract and ThirdwebTransaction APIs.
  • Consistent API design
  • Easier discovery via IntelliSense
  • Wraps the thirdweb API with all its features vs waiting for manual higher level integration
  • Wrapper customized and adapted to work across any runtime and extended for game engine use.

Note that the core thirdweb functionality of Wallets, Contracts and Transactions is effectively free of breaking changes (new features are available). In the future, they may call into ThirdwebClient.Api while maintaining the nicer DX. There will eventually be an opinionated easier to use wrapper for each service.


Wallet System Updates

Modernized Wallet Flow

// v2 – Private key wallet
var privateWallet = await PrivateKeyWallet.Generate(client);

// v3 – Guest/in-app wallets  
var wallet = await InAppWallet.Create(client, AuthProvider.Guest);
await wallet.LoginWithGuest();

Improvements

  • Removed legacy signing and recovery methods from the IThirdwebWallet interface
  • Removed obsolete LegacyEncryptionKey creaton param from In-App and Ecosystem Wallets.
  • Major internal cleanup of legacy Shamir sharding client side logic and AWS logic.
  • Better guest wallet flows
  • Smarter gas handling and bundler integration

Performance & Dependencies

  • Removed Portable.BouncyCastle and two other Nethereum dependencies.
  • Updated remaining Nethereum dependencies to Nethereum 5.0.0
  • Creating an In-App or Ecosystem wallet should feel a lot faster now.

Efficiency Gains

  • 30% less code (6,997 → 4,886 lines)
  • 41% fewer files (44 → 26)
  • Faster builds and smaller runtime

Developer Experience

Transactions

var hash = await transaction.Send();
var receipt = await transaction.SendAndWaitForTransactionReceipt();

Build System

  • Modernized for faster development and testing
  • If you want to contribute, we have a nice Makefile to help run things more easily

Account Abstraction

  • Unified bundler (ThirdwebBundler)
  • Improved gas estimation and sponsorship
  • Better EIP-7702 support
  • Better zkSync integration

Learn more

v2.25.2

11 Sep 22:47
2035299

Choose a tag to compare

What's Changed

  • Fixed a bug where users from countries with a non-gregorian calendar could experience issues signing in with In-App or Ecosystem wallets, such as users with a Thai regional system calendar.
  • EIP7702 account implementation is now fetched dynamically, the current contract implementation contains better onchain error messages and more useful contract events.

v2.25.1

26 Aug 13:51
3d9b591

Choose a tag to compare

What's Changed

  • Added AuthProvider.TikTok as a login option for In-App or Ecosystem Wallets.
var iaw = await InAppWallet.Create(client: twClient, authProvider: AuthProvider.Steam);
var iawAddy = await iaw.LoginWithOauth(...);

v2.25.0

18 Aug 22:22
6080fbe

Choose a tag to compare

What's Changed

Example

var serverWallet = await ServerWallet.Create(client: client, label: "TestFromDotnet");
var chainId = 11155111;

var abi = "[ { \"inputs\": [], \"name\": \"welcome\", \"outputs\": [ { \"internalType\": \"string\", \"name\": \"\", \"type\": \"string\" } ], \"stateMutability\": \"pure\", \"type\": \"function\" } ]";

var contractAddress = await ThirdwebContract.Deploy(
    client: client,
    chainId: chainId ,
    serverWalletAddress: await serverWallet.GetAddress(),
    bytecode: "6080604052348015600e575f5ffd5b5061014e8061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063b627cf3b1461002d575b5f5ffd5b61003561004b565b60405161004291906100f8565b60405180910390f35b60606040518060400160405280601481526020017f57656c636f6d6520746f20746869726477656221000000000000000000000000815250905090565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6100ca82610088565b6100d48185610092565b93506100e48185602086016100a2565b6100ed816100b0565b840191505092915050565b5f6020820190508181035f83015261011081846100c0565b90509291505056fea264697066735822122001498e9d7d6125ce22613ef32fdb7e8e03bf11ad361d7b00e210b82d7b7e0d4464736f6c634300081e0033",
    abi: abi
);
Console.WriteLine($"Contract deployed at: {contractAddress}");

var contract = await ThirdwebContract.Create(client: client, address: contractAddress, chain: chainId, abi: abi);
var welcomeMessage = await contract.Read<string>("welcome");
Console.WriteLine($"Welcome message from deployed contract: {welcomeMessage}");

Expect more new features to keep coming as part of the thirdweb api integration!

v2.24.1

11 Aug 11:10
59d5504

Choose a tag to compare

What's Changed

  • Introduces a forwardLocalGasFees parameter to EngineWallet (deprecated Engine v2, superseeded by ServerWallet), allowing control over whether locally calculated gas fees are forwarded to the engine. Updates the EngineWallet.Create method and transaction overrides logic to support this feature. The default for this flag is false, giving gas calculation and submission authority to Engine when using this wallet provider.

v2.24.0

18 Jul 00:40
8c8a2b4

Choose a tag to compare

What's Changed

🚀 New Feature: ServerWallet - Next-Generation Secure Backend Wallets

We're excited to introduce ServerWallet, a powerful new wallet implementation that replaces the deprecated EngineWallet. ServerWallet provides vault-based secure wallet management with advanced execution options and seamless integration with the thirdweb dashboard's Transactions feature.

Key Features

  • 🔒 Vault-Based Security: Enhanced security through server-side wallet management
  • ⚡ Multiple Execution Modes: Support for Auto, ERC-4337, EIP-7702, EOA, and zkSync native AA execution
  • 🎯 Smart Execution Strategy: Auto mode intelligently selects the optimal execution method based on your configuration
  • 🔧 Flexible Configuration: Simple label-based wallet creation with optional execution customization
  • 📊 Dashboard Integration: Full compatibility with thirdweb dashboard's Transactions tab (Engine v3)

Getting Started

// Basic usage with auto execution mode
var serverWallet = await ServerWallet.Create(
    client: client,
    label: "MyWallet"
);

// Advanced usage with custom execution options
var serverWallet = await ServerWallet.Create(
    client: client,
    label: "MyWallet",
    executionOptions: new ERC4337ExecutionOptions(chainId: 84532, signerAddress: "0x...")
);

Available Execution Options

  • AutoExecutionOptions (Default): Automatically determines the best execution strategy
  • ERC4337ExecutionOptions: Smart contract wallet execution with Account Abstraction
  • EIP7702ExecutionOptions: Temporary EOA delegation to smart contracts
  • EOAExecutionOptions: Direct externally owned account execution

Full IThirdwebWallet Compatibility

ServerWallet implements the complete IThirdwebWallet interface, supporting:

  • Signing: Personal sign, typed data v4, transaction signing
  • Transactions: Send, execute, and track transactions
  • Transfers: Simple token and ETH transfers
  • Message Signing: Support for various message formats

Usage Examples

// Get wallet address
var address = await serverWallet.GetAddress();

// Sign messages
var signature = await serverWallet.PersonalSign("Hello, Thirdweb!");

// Sign typed data
var typedDataSignature = await serverWallet.SignTypedDataV4(jsonTypedData);

// Execute transactions
var receipt = await serverWallet.Transfer(
    chainId: 84532, 
    toAddress: "0x...", 
    weiAmount: 1000000000000000000 // 1 ETH
);

// Force specific execution mode
var smartWallet = await ServerWallet.Create(
    client: client, 
    label: "MyWallet",
    executionOptions: new ERC4337ExecutionOptions(chainId: 84532, signerAddress: address)
);

🚨 Breaking Changes & Migration

EngineWallet Deprecation

EngineWallet is now deprecated and will be removed in a future version. Please migrate to ServerWallet for continued support and new features.

Migration Guide:

// Old EngineWallet approach
var engineWallet = EngineWallet.Create(
    client: client,
    engineUrl: "https://your-engine-url",
    authToken: "your-auth-token",
    walletAddress: "0x..."
);

// New ServerWallet approach
var serverWallet = await ServerWallet.Create(
    client: client,
    label: "YourWalletLabel"
);

Key Differences

  • Label-based: ServerWallet uses labels instead of direct address specification
  • Cloud Integration: Built for thirdweb dashboard integration (Engine v3)
  • Enhanced Security: Improved vault-based architecture
  • Advanced Execution: Multiple execution strategies with intelligent auto-selection

v2.23.1

25 Jun 22:16
f22a57b

Choose a tag to compare

What's Changed

Building on top of the new EIP-7702 In-App or Ecosystem Wallet CreateSessionKey functionality, new utilities were added:

v2.23.0

23 Jun 21:09
4666962

Choose a tag to compare

Session Key Support for EIP-7702 Smart EOAs

Building on the EIP-7702 Account Abstraction and transaction sponsorship introduced in v2.21.0, this release extends Session Key functionality to EIP-7702 Smart EOAs. Session Keys enable granular permission delegation to external wallets for executing transactions on your behalf.

Key Features

  • Permission Delegation: Grant time-limited access to external wallets
  • Granular Controls: Define precise execution permissions per session
  • Smart EOA Integration: Now available for EIP-7702-powered In-App Wallets, inspired by and improved from Smart Wallet session keys
  • Backend Flexibility: Delegate transaction execution to external systems while maintaining control

Usage Example

Create session keys with either full permissions or custom policies:

// Grant full permissions for 24 hours
var sessionKeyReceipt = await smartEoa.CreateSessionKey(
    chainId: chain,
    signerAddress: await Utils.GetAddressFromENS(client, "vitalik.eth"),
    durationInSeconds: 86400,
    grantFullPermissions: true
);

// Grant custom permissions
var sessionKeyReceipt = await smartEoa.CreateSessionKey(
    chainId: chain,
    signerAddress: await Utils.GetAddressFromENS(client, "vitalik.eth"),
    durationInSeconds: 86400,
    grantFullPermissions: false,
    callPolicies: new List<CallSpec>(), // Contract interaction rules
    transferPolicies: new List<TransferSpec>() // Value transfer rules
);

Implementation Workflow

const int chain = 11155111; // 7702-compatible chain

// Initialize EIP-7702 wallet
var smartEoa = await InAppWallet.Create(
    client, 
    authProvider: AuthProvider.Guest, 
    executionMode: ExecutionMode.EIP7702Sponsored
);

// Authenticate and upgrade EOA
if (!await smartEoa.IsConnected())
{
    await smartEoa.LoginWithGuest(defaultSessionIdOverride: Guid.NewGuid().ToString());
}

// Execute upgrade transaction (optional)
var receipt = await smartEoa.Transfer(
    chainId: chain, 
    toAddress: await Utils.GetAddressFromENS(client, "vitalik.eth"), 
    weiAmount: 0
);

// Verify account delegation (optional)
var isDelegated = await Utils.IsDelegatedAccount(client, chain, await smartEoa.GetAddress());

// Create session key
var sessionKeyReceipt = await smartEoa.CreateSessionKey(
    chainId: chain, 
    signerAddress: await Utils.GetAddressFromENS(client, "vitalik.eth"),
    durationInSeconds: 86400,
    grantFullPermissions: true
);

Practical Applications

Once created, these session keys can be used to:

  • Delegate transactions to backend services while maintaining security boundaries
  • Enable temporary access for third-party services
  • Create specialized roles with limited permissions
  • Automate workflows without exposing primary wallet credentials

The session key mechanism opens up numerous possibilities for secure, permissioned delegation patterns while maintaining full control over your assets and contracts.

v2.22.0

09 May 20:43
b6541d6

Choose a tag to compare

ThirdwebBridge - Onramp Integration & Improved APIs

This release brings you new Onramp APIs, as well as new QOL parameters for the general ThirdwebBridge APIs, in line with the latest changes made to the service.

Do note that some responses now have obsolete propeties. Generally the main change is that instead of returning a list of transactions, Prepare endpoints will return a set of Steps. You can still use our extensions to Execute any prepared quote you receive directly, we'll handle the steps for you as usual.

Basic example of using the new Onramp APIs in .NET

The onramp flow will return a link for you to display/open as you please. You may poll the status of that onramp by its ID.
In some cases, you may receive an additional set of onchain transactions required to get to your destination token post on-ramp, in such cases, you may use our extension IsSwapRequiredPostOnramp to check, and if a swap is indeed required, you may use our Execute extensions to execute the transactions, or manually execute them by going through each Step.

// Onramp - Get a quote for buying crypto with Fiat
var preparedOnramp = await bridge.Onramp_Prepare(
    onramp: OnrampProvider.Coinbase,
    chainId: 8453,
    tokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base
    amount: "10000000",
    receiver: await myWallet.GetAddress()
);
Console.WriteLine($"Onramp link: {preparedOnramp.Link}");
Console.WriteLine($"Full onramp quote and steps data: {JsonConvert.SerializeObject(preparedOnramp, Formatting.Indented)}");

while (true)
{
    var onrampStatus = await bridge.Onramp_Status(id: preparedOnramp.Id);
    Console.WriteLine($"Full Onramp Status: {JsonConvert.SerializeObject(onrampStatus, Formatting.Indented)}");
    if (onrampStatus.StatusType is StatusType.COMPLETED or StatusType.FAILED)
    {
        break;
    }
    await ThirdwebTask.Delay(5000);
}

if (preparedOnramp.IsSwapRequiredPostOnramp())
{
    // Execute additional steps that are required post-onramp to get to your token, manually or via the Execute extension
    var receipts = await bridge.Execute(myWallet, preparedOnramp);
    Console.WriteLine($"Onramp receipts: {JsonConvert.SerializeObject(receipts, Formatting.Indented)}");
}
else
{
    Console.WriteLine("No additional steps required post-onramp, you can use the tokens directly!");
}

v2.21.0

07 May 23:51
ea4d093

Choose a tag to compare

[Beta] Your In-App Wallets can now be upgraded directly to an EIP7702 Smart Account with a simple creation flag!

With the recent Ethereum upgrade Pectra, EIP-7702 allows you - on chains that support it - to upgrade your EOA and get SmartWallet-like functionality with:

  • Much cheaper gas costs, batching functionality
  • No account separation - your wallet address does not change, not even on zksync chains (once they implement EIP-7702)
  • Much faster execution, with the option of paying for gas yourself or having thirdweb manage gas sponsorship, similar to SmartWallet.

And here's how simple it is!

ExecutionMode.EIP7702Sponsored**

Upgrade to an EIP7702 smart account, unlocking all functionality of 4337 without the downsides, and thirdweb handles the execution and gas sponsorship for you!

var smartEoa = await InAppWallet.Create(
    client: thirdwebClient,
    authProvider: AuthProvider.Google,
    executionMode: ExecutionMode.EIP7702Sponsored
);

ExecutionMode.EIP7702

Upgrade to an EIP7702 smart account, unlocking all functionality of 4337 without the downsides, but sponsoring gas yourself.

var smartEoa = await InAppWallet.Create(
    client: thirdwebClient,
    authProvider: AuthProvider.Google,
    executionMode: ExecutionMode.EIP7702
);

ExecutionMode.EOA

Normal" EOA Execution, no smart account functionality

var basicEoa = await InAppWallet.Create(
    client: thirdwebClient,
    authProvider: AuthProvider.Google,
    // does not need to be explicitly passed, is the default but we're showing it here
    executionMode: ExecutionMode.EOA
);

When using EIP-7702 execution modes, upon your first transaction - if not already delegated to a smart account - an EIP-7702 authorization will be signed and bundled with your first transaction, similar to how 4337 works with initcode, but without the large gas costs, slower execution and chain specific requirements.

We hope you enjoy not having to pass your signers to yet another SmartWallet class, dealing with entrypoint versions, bundlers, paymasters, slow execution and higher gas fees.

This Smart EOA contract also comes with granular session keys that we'll showcase in a later release!

More chains will have support for EIP-7702 very soon with various chain stacks upgrading to Pectra, and we will support each and every one of them.

Additional updates

  • InAppWallet and EcosystemWallet's SignAuthorization low level methods have been integrated.
  • Fixed an issue where using SmartWallet on Hedera or Hedera Testnet where HBAR (native token) is involved could cause silent revets.