From 91119f799eab61469b8068bb5e6f46a7eeeb0296 Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Sat, 21 Jun 2025 03:44:21 +0700 Subject: [PATCH 1/5] InAppWallet EIP7702 Session Key Integration --- Thirdweb.Console/Program.cs | 84 +++++++++---------- Thirdweb/Thirdweb.Utils/Constants.cs | 2 +- .../EcosystemWallet/EcosystemWallet.cs | 28 ++++--- 3 files changed, 59 insertions(+), 55 deletions(-) diff --git a/Thirdweb.Console/Program.cs b/Thirdweb.Console/Program.cs index cf240f5..222bfe1 100644 --- a/Thirdweb.Console/Program.cs +++ b/Thirdweb.Console/Program.cs @@ -360,48 +360,48 @@ #region EIP-7702 -// var chain = 11155111; // sepolia - -// // Connect to EOA -// var smartEoa = await InAppWallet.Create(client, authProvider: AuthProvider.Google, executionMode: ExecutionMode.EIP7702Sponsored); -// if (!await smartEoa.IsConnected()) -// { -// _ = await smartEoa.LoginWithOauth( -// isMobile: false, -// (url) => -// { -// var psi = new ProcessStartInfo { FileName = url, UseShellExecute = true }; -// _ = Process.Start(psi); -// } -// ); -// } -// var smartEoaAddress = await smartEoa.GetAddress(); -// Console.WriteLine($"User Wallet address: {await smartEoa.GetAddress()}"); - -// // Upgrade EOA - This wallet explicitly uses EIP-7702 delegation to the thirdweb MinimalAccount (will delegate upon first tx) - -// // Transact, will upgrade EOA -// var receipt = await smartEoa.Transfer(chainId: chain, toAddress: await Utils.GetAddressFromENS(client, "vitalik.eth"), weiAmount: 0); -// Console.WriteLine($"Transfer Receipt: {receipt.TransactionHash}"); - -// // Double check that it was upgraded -// var isDelegated = await Utils.IsDelegatedAccount(client, chain, smartEoaAddress); -// Console.WriteLine($"Is delegated: {isDelegated}"); - -// // Create a session key -// var sessionKeyReceipt = await smartEoa.CreateSessionKey( -// chain, -// new SessionSpec() -// { -// Signer = await Utils.GetAddressFromENS(client, "0xfirekeeper.eth"), -// IsWildcard = true, -// ExpiresAt = Utils.GetUnixTimeStampNow() + 86400, // 1 day -// CallPolicies = new List(), -// TransferPolicies = new List(), -// Uid = Guid.NewGuid().ToByteArray().PadTo32Bytes() -// } -// ); -// Console.WriteLine($"Session key receipt: {sessionKeyReceipt.TransactionHash}"); +var chain = 11155111; // sepolia + +// Connect to EOA +var smartEoa = await InAppWallet.Create(client, authProvider: AuthProvider.Google, executionMode: ExecutionMode.EIP7702Sponsored); +if (!await smartEoa.IsConnected()) +{ + _ = await smartEoa.LoginWithOauth( + isMobile: false, + (url) => + { + var psi = new ProcessStartInfo { FileName = url, UseShellExecute = true }; + _ = Process.Start(psi); + } + ); +} +var smartEoaAddress = await smartEoa.GetAddress(); +Console.WriteLine($"User Wallet address: {await smartEoa.GetAddress()}"); + +// Upgrade EOA - This wallet explicitly uses EIP-7702 delegation to the thirdweb MinimalAccount (will delegate upon first tx) + +// Transact, will upgrade EOA +var receipt = await smartEoa.Transfer(chainId: chain, toAddress: await Utils.GetAddressFromENS(client, "vitalik.eth"), weiAmount: 0); +Console.WriteLine($"Transfer Receipt: {receipt.TransactionHash}"); + +// Double check that it was upgraded +var isDelegated = await Utils.IsDelegatedAccount(client, chain, smartEoaAddress); +Console.WriteLine($"Is delegated: {isDelegated}"); + +// Create a session key +var sessionKeyReceipt = await smartEoa.CreateSessionKey( + chain, + new SessionSpec() + { + Signer = await Utils.GetAddressFromENS(client, "vitalik.eth"), + IsWildcard = true, + ExpiresAt = Utils.GetUnixTimeStampNow() + 86400, // 1 day + CallPolicies = new List(), + TransferPolicies = new List(), + Uid = "my-session-key-uid".HashMessage().HexToBytes() + } +); +Console.WriteLine($"Session key receipt: {sessionKeyReceipt.TransactionHash}"); #endregion diff --git a/Thirdweb/Thirdweb.Utils/Constants.cs b/Thirdweb/Thirdweb.Utils/Constants.cs index a671616..4cc2432 100644 --- a/Thirdweb/Thirdweb.Utils/Constants.cs +++ b/Thirdweb/Thirdweb.Utils/Constants.cs @@ -35,7 +35,7 @@ public static class Constants "0x0101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000001010101010100000000000000000000000000000000000000000000000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"; internal const string ENS_REGISTRY_ADDRESS = "0xce01f8eee7E479C928F8919abD53E553a36CeF67"; - public const string MINIMAL_ACCOUNT_7702 = "0xbaC7e770af15d130Cd72838ff386f14FBF3e9a3D"; + public const string MINIMAL_ACCOUNT_7702 = "0x173217d7f8c26Dc3c01e37e1c04813CC7cC9fEc2"; public const string MINIMAL_ACCOUNT_7702_ABI = /*lang=json,strict*/ "[{\"inputs\": [{\"internalType\": \"uint256\",\"name\": \"allowanceUsage\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint64\",\"name\": \"period\",\"type\": \"uint64\"}],\"name\": \"AllowanceExceeded\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"}],\"name\": \"CallPolicyViolated\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"CallReverted\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"bytes32\",\"name\": \"param\",\"type\": \"bytes32\"},{\"internalType\": \"bytes32\",\"name\": \"refValue\",\"type\": \"bytes32\"},{\"internalType\": \"uint8\",\"name\": \"condition\",\"type\": \"uint8\"}],\"name\": \"ConditionFailed\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"FnSelectorNotRecognized\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"uint256\",\"name\": \"actualLength\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"expectedLength\",\"type\": \"uint256\"}],\"name\": \"InvalidDataLength\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"msgSender\",\"type\": \"address\"},{\"internalType\": \"address\",\"name\": \"thisAddress\",\"type\": \"address\"}],\"name\": \"InvalidSignature\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"uint256\",\"name\": \"lifetimeUsage\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"}],\"name\": \"LifetimeUsageExceeded\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"uint256\",\"name\": \"value\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"}],\"name\": \"MaxValueExceeded\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"NoCallsToExecute\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"SessionExpired\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"SessionExpiresTooSoon\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"SessionZeroSigner\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"}],\"name\": \"TransferPolicyViolated\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"UIDAlreadyProcessed\",\"type\": \"error\"},{\"anonymous\": false,\"inputs\": [{\"indexed\": true,\"internalType\": \"address\",\"name\": \"to\",\"type\": \"address\"},{\"indexed\": false,\"internalType\": \"uint256\",\"name\": \"value\",\"type\": \"uint256\"},{\"indexed\": false,\"internalType\": \"bytes\",\"name\": \"data\",\"type\": \"bytes\"}],\"name\": \"Executed\",\"type\": \"event\"},{\"anonymous\": false,\"inputs\": [{\"indexed\": true,\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"},{\"components\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"},{\"internalType\": \"bool\",\"name\": \"isWildcard\",\"type\": \"bool\"},{\"internalType\": \"uint256\",\"name\": \"expiresAt\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"},{\"components\": [{\"internalType\": \"enum SessionLib.Condition\",\"name\": \"condition\",\"type\": \"uint8\"},{\"internalType\": \"uint64\",\"name\": \"index\",\"type\": \"uint64\"},{\"internalType\": \"bytes32\",\"name\": \"refValue\",\"type\": \"bytes32\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"limit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.Constraint[]\",\"name\": \"constraints\",\"type\": \"tuple[]\"}],\"internalType\": \"struct SessionLib.CallSpec[]\",\"name\": \"callPolicies\",\"type\": \"tuple[]\"},{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.TransferSpec[]\",\"name\": \"transferPolicies\",\"type\": \"tuple[]\"},{\"internalType\": \"bytes32\",\"name\": \"uid\",\"type\": \"bytes32\"}],\"indexed\": false,\"internalType\": \"struct SessionLib.SessionSpec\",\"name\": \"sessionSpec\",\"type\": \"tuple\"}],\"name\": \"SessionCreated\",\"type\": \"event\"},{\"stateMutability\": \"payable\",\"type\": \"fallback\"},{\"inputs\": [{\"components\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"},{\"internalType\": \"bool\",\"name\": \"isWildcard\",\"type\": \"bool\"},{\"internalType\": \"uint256\",\"name\": \"expiresAt\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"},{\"components\": [{\"internalType\": \"enum SessionLib.Condition\",\"name\": \"condition\",\"type\": \"uint8\"},{\"internalType\": \"uint64\",\"name\": \"index\",\"type\": \"uint64\"},{\"internalType\": \"bytes32\",\"name\": \"refValue\",\"type\": \"bytes32\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"limit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.Constraint[]\",\"name\": \"constraints\",\"type\": \"tuple[]\"}],\"internalType\": \"struct SessionLib.CallSpec[]\",\"name\": \"callPolicies\",\"type\": \"tuple[]\"},{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.TransferSpec[]\",\"name\": \"transferPolicies\",\"type\": \"tuple[]\"},{\"internalType\": \"bytes32\",\"name\": \"uid\",\"type\": \"bytes32\"}],\"internalType\": \"struct SessionLib.SessionSpec\",\"name\": \"sessionSpec\",\"type\": \"tuple\"},{\"internalType\": \"bytes\",\"name\": \"signature\",\"type\": \"bytes\"}],\"name\": \"createSessionWithSig\",\"outputs\": [],\"stateMutability\": \"nonpayable\",\"type\": \"function\"},{\"inputs\": [],\"name\": \"eip712Domain\",\"outputs\": [{\"internalType\": \"bytes1\",\"name\": \"fields\",\"type\": \"bytes1\"},{\"internalType\": \"string\",\"name\": \"name\",\"type\": \"string\"},{\"internalType\": \"string\",\"name\": \"version\",\"type\": \"string\"},{\"internalType\": \"uint256\",\"name\": \"chainId\",\"type\": \"uint256\"},{\"internalType\": \"address\",\"name\": \"verifyingContract\",\"type\": \"address\"},{\"internalType\": \"bytes32\",\"name\": \"salt\",\"type\": \"bytes32\"},{\"internalType\": \"uint256[]\",\"name\": \"extensions\",\"type\": \"uint256[]\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"value\",\"type\": \"uint256\"},{\"internalType\": \"bytes\",\"name\": \"data\",\"type\": \"bytes\"}],\"internalType\": \"struct Call[]\",\"name\": \"calls\",\"type\": \"tuple[]\"}],\"name\": \"execute\",\"outputs\": [],\"stateMutability\": \"payable\",\"type\": \"function\"},{\"inputs\": [{\"components\": [{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"value\",\"type\": \"uint256\"},{\"internalType\": \"bytes\",\"name\": \"data\",\"type\": \"bytes\"}],\"internalType\": \"struct Call[]\",\"name\": \"calls\",\"type\": \"tuple[]\"},{\"internalType\": \"bytes32\",\"name\": \"uid\",\"type\": \"bytes32\"}],\"internalType\": \"struct WrappedCalls\",\"name\": \"wrappedCalls\",\"type\": \"tuple\"},{\"internalType\": \"bytes\",\"name\": \"signature\",\"type\": \"bytes\"}],\"name\": \"executeWithSig\",\"outputs\": [],\"stateMutability\": \"payable\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"}],\"name\": \"getCallPoliciesForSigner\",\"outputs\": [{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"},{\"components\": [{\"internalType\": \"enum SessionLib.Condition\",\"name\": \"condition\",\"type\": \"uint8\"},{\"internalType\": \"uint64\",\"name\": \"index\",\"type\": \"uint64\"},{\"internalType\": \"bytes32\",\"name\": \"refValue\",\"type\": \"bytes32\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"limit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.Constraint[]\",\"name\": \"constraints\",\"type\": \"tuple[]\"}],\"internalType\": \"struct SessionLib.CallSpec[]\",\"name\": \"\",\"type\": \"tuple[]\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"}],\"name\": \"getSessionExpirationForSigner\",\"outputs\": [{\"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"}],\"name\": \"getSessionStateForSigner\",\"outputs\": [{\"components\": [{\"components\": [{\"internalType\": \"uint256\",\"name\": \"remaining\",\"type\": \"uint256\"},{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"index\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.LimitState[]\",\"name\": \"transferValue\",\"type\": \"tuple[]\"},{\"components\": [{\"internalType\": \"uint256\",\"name\": \"remaining\",\"type\": \"uint256\"},{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"index\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.LimitState[]\",\"name\": \"callValue\",\"type\": \"tuple[]\"},{\"components\": [{\"internalType\": \"uint256\",\"name\": \"remaining\",\"type\": \"uint256\"},{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"index\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.LimitState[]\",\"name\": \"callParams\",\"type\": \"tuple[]\"}],\"internalType\": \"struct SessionLib.SessionState\",\"name\": \"\",\"type\": \"tuple\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"}],\"name\": \"getTransferPoliciesForSigner\",\"outputs\": [{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.TransferSpec[]\",\"name\": \"\",\"type\": \"tuple[]\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"}],\"name\": \"isWildcardSigner\",\"outputs\": [{\"internalType\": \"bool\",\"name\": \"\",\"type\": \"bool\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"uint256[]\",\"name\": \"\",\"type\": \"uint256[]\"},{\"internalType\": \"uint256[]\",\"name\": \"\",\"type\": \"uint256[]\"},{\"internalType\": \"bytes\",\"name\": \"\",\"type\": \"bytes\"}],\"name\": \"onERC1155BatchReceived\",\"outputs\": [{\"internalType\": \"bytes4\",\"name\": \"\",\"type\": \"bytes4\"}],\"stateMutability\": \"nonpayable\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\"},{\"internalType\": \"bytes\",\"name\": \"\",\"type\": \"bytes\"}],\"name\": \"onERC1155Received\",\"outputs\": [{\"internalType\": \"bytes4\",\"name\": \"\",\"type\": \"bytes4\"}],\"stateMutability\": \"nonpayable\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\"},{\"internalType\": \"bytes\",\"name\": \"\",\"type\": \"bytes\"}],\"name\": \"onERC721Received\",\"outputs\": [{\"internalType\": \"bytes4\",\"name\": \"\",\"type\": \"bytes4\"}],\"stateMutability\": \"nonpayable\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"bytes4\",\"name\": \"interfaceId\",\"type\": \"bytes4\"}],\"name\": \"supportsInterface\",\"outputs\": [{\"internalType\": \"bool\",\"name\": \"\",\"type\": \"bool\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"stateMutability\": \"payable\",\"type\": \"receive\"}]"; diff --git a/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs b/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs index 555c313..81cba10 100644 --- a/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs @@ -450,19 +450,23 @@ public string GenerateExternalLoginLink(string redirectUrl) return $"{redirectUrl}{queryString}"; } - public Task CreateSessionKey(BigInteger chainId, SessionSpec sessionKeyParams) + public async Task CreateSessionKey(BigInteger chainId, SessionSpec sessionKeyParams) { - throw new NotImplementedException("CreateSessionKey via EIP7702 execution modes is not implemented yet, check back in later versions."); - // if (this.ExecutionMode is not ExecutionMode.EIP7702 and not ExecutionMode.EIP7702Sponsored) - // { - // throw new InvalidOperationException("CreateSessionKey is only supported for EIP7702 and EIP7702Sponsored execution modes."); - // } - - // var userWalletAddress = await this.GetAddress(); - // var sessionKeySig = await EIP712.GenerateSignature_SmartAccount_7702("MinimalAccount", "1", chainId, userWalletAddress, sessionKeyParams, this); - // var userContract = await ThirdwebContract.Create(this.Client, userWalletAddress, chainId, Constants.MINIMAL_ACCOUNT_7702_ABI); - // var sessionKeyCallData = userContract.CreateCallData("createSessionWithSig", sessionKeyParams, sessionKeySig.HexToBytes()); - // return await this.ExecuteTransaction(new ThirdwebTransactionInput(chainId: chainId, to: userWalletAddress, value: 0, data: sessionKeyCallData)); + if (this.ExecutionMode is not ExecutionMode.EIP7702 and not ExecutionMode.EIP7702Sponsored) + { + throw new InvalidOperationException("CreateSessionKey is only supported for EIP7702 and EIP7702Sponsored execution modes."); + } + + var userWalletAddress = await this.GetAddress(); + var sessionKeySig = await EIP712.GenerateSignature_SmartAccount_7702("MinimalAccount", "1", chainId, userWalletAddress, sessionKeyParams, this); + var userContract = await ThirdwebContract.Create(this.Client, userWalletAddress, chainId, Constants.MINIMAL_ACCOUNT_7702_ABI); + var sessionKeyCallData = userContract.CreateCallData("createSessionWithSig", sessionKeyParams, sessionKeySig.HexToBytes()); + + var tx = await ThirdwebTransaction.Create(this, new ThirdwebTransactionInput(chainId: chainId, to: userWalletAddress, value: 0, data: sessionKeyCallData)); + var result = await ThirdwebTransaction.Simulate(tx).ConfigureAwait(false); + Console.WriteLine($"Simulated session key creation transaction: {result}"); + + return await this.ExecuteTransaction(new ThirdwebTransactionInput(chainId: chainId, to: userWalletAddress, value: 0, data: sessionKeyCallData)); } #endregion From ae9dbeea75fe26c06a5608cef712288306e883d3 Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Sat, 21 Jun 2025 04:23:15 +0700 Subject: [PATCH 2/5] remove sim --- Thirdweb.Console/Program.cs | 17 +++++------------ .../EcosystemWallet/EcosystemWallet.cs | 5 ----- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/Thirdweb.Console/Program.cs b/Thirdweb.Console/Program.cs index 222bfe1..efb63c2 100644 --- a/Thirdweb.Console/Program.cs +++ b/Thirdweb.Console/Program.cs @@ -360,20 +360,13 @@ #region EIP-7702 -var chain = 11155111; // sepolia +var chain = 11155111; // 7702-compatible chain // Connect to EOA -var smartEoa = await InAppWallet.Create(client, authProvider: AuthProvider.Google, executionMode: ExecutionMode.EIP7702Sponsored); +var smartEoa = await InAppWallet.Create(client, authProvider: AuthProvider.Guest, executionMode: ExecutionMode.EIP7702Sponsored); if (!await smartEoa.IsConnected()) { - _ = await smartEoa.LoginWithOauth( - isMobile: false, - (url) => - { - var psi = new ProcessStartInfo { FileName = url, UseShellExecute = true }; - _ = Process.Start(psi); - } - ); + _ = await smartEoa.LoginWithGuest(defaultSessionIdOverride: new Guid().ToString()); } var smartEoaAddress = await smartEoa.GetAddress(); Console.WriteLine($"User Wallet address: {await smartEoa.GetAddress()}"); @@ -396,8 +389,8 @@ Signer = await Utils.GetAddressFromENS(client, "vitalik.eth"), IsWildcard = true, ExpiresAt = Utils.GetUnixTimeStampNow() + 86400, // 1 day - CallPolicies = new List(), - TransferPolicies = new List(), + CallPolicies = new List() { }, + TransferPolicies = new List() { }, Uid = "my-session-key-uid".HashMessage().HexToBytes() } ); diff --git a/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs b/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs index 81cba10..dc04eaf 100644 --- a/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs @@ -461,11 +461,6 @@ public async Task CreateSessionKey(BigInteger chainI var sessionKeySig = await EIP712.GenerateSignature_SmartAccount_7702("MinimalAccount", "1", chainId, userWalletAddress, sessionKeyParams, this); var userContract = await ThirdwebContract.Create(this.Client, userWalletAddress, chainId, Constants.MINIMAL_ACCOUNT_7702_ABI); var sessionKeyCallData = userContract.CreateCallData("createSessionWithSig", sessionKeyParams, sessionKeySig.HexToBytes()); - - var tx = await ThirdwebTransaction.Create(this, new ThirdwebTransactionInput(chainId: chainId, to: userWalletAddress, value: 0, data: sessionKeyCallData)); - var result = await ThirdwebTransaction.Simulate(tx).ConfigureAwait(false); - Console.WriteLine($"Simulated session key creation transaction: {result}"); - return await this.ExecuteTransaction(new ThirdwebTransactionInput(chainId: chainId, to: userWalletAddress, value: 0, data: sessionKeyCallData)); } From 06ee56b3566d9c15443c747b45af6d5faeeb35c7 Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Tue, 24 Jun 2025 02:24:04 +0700 Subject: [PATCH 3/5] update implementation --- Thirdweb.Console/Program.cs | 4 ++-- Thirdweb/Thirdweb.Utils/Constants.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Thirdweb.Console/Program.cs b/Thirdweb.Console/Program.cs index efb63c2..db2c5de 100644 --- a/Thirdweb.Console/Program.cs +++ b/Thirdweb.Console/Program.cs @@ -389,8 +389,8 @@ Signer = await Utils.GetAddressFromENS(client, "vitalik.eth"), IsWildcard = true, ExpiresAt = Utils.GetUnixTimeStampNow() + 86400, // 1 day - CallPolicies = new List() { }, - TransferPolicies = new List() { }, + CallPolicies = new List(), + TransferPolicies = new List(), Uid = "my-session-key-uid".HashMessage().HexToBytes() } ); diff --git a/Thirdweb/Thirdweb.Utils/Constants.cs b/Thirdweb/Thirdweb.Utils/Constants.cs index 4cc2432..1f59ac5 100644 --- a/Thirdweb/Thirdweb.Utils/Constants.cs +++ b/Thirdweb/Thirdweb.Utils/Constants.cs @@ -35,10 +35,10 @@ public static class Constants "0x0101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000001010101010100000000000000000000000000000000000000000000000000000000000000000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"; internal const string ENS_REGISTRY_ADDRESS = "0xce01f8eee7E479C928F8919abD53E553a36CeF67"; - public const string MINIMAL_ACCOUNT_7702 = "0x173217d7f8c26Dc3c01e37e1c04813CC7cC9fEc2"; + public const string MINIMAL_ACCOUNT_7702 = "0xD6999651Fc0964B9c6B444307a0ab20534a66560"; public const string MINIMAL_ACCOUNT_7702_ABI = /*lang=json,strict*/ - "[{\"inputs\": [{\"internalType\": \"uint256\",\"name\": \"allowanceUsage\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint64\",\"name\": \"period\",\"type\": \"uint64\"}],\"name\": \"AllowanceExceeded\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"}],\"name\": \"CallPolicyViolated\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"CallReverted\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"bytes32\",\"name\": \"param\",\"type\": \"bytes32\"},{\"internalType\": \"bytes32\",\"name\": \"refValue\",\"type\": \"bytes32\"},{\"internalType\": \"uint8\",\"name\": \"condition\",\"type\": \"uint8\"}],\"name\": \"ConditionFailed\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"FnSelectorNotRecognized\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"uint256\",\"name\": \"actualLength\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"expectedLength\",\"type\": \"uint256\"}],\"name\": \"InvalidDataLength\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"msgSender\",\"type\": \"address\"},{\"internalType\": \"address\",\"name\": \"thisAddress\",\"type\": \"address\"}],\"name\": \"InvalidSignature\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"uint256\",\"name\": \"lifetimeUsage\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"}],\"name\": \"LifetimeUsageExceeded\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"uint256\",\"name\": \"value\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"}],\"name\": \"MaxValueExceeded\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"NoCallsToExecute\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"SessionExpired\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"SessionExpiresTooSoon\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"SessionZeroSigner\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"}],\"name\": \"TransferPolicyViolated\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"UIDAlreadyProcessed\",\"type\": \"error\"},{\"anonymous\": false,\"inputs\": [{\"indexed\": true,\"internalType\": \"address\",\"name\": \"to\",\"type\": \"address\"},{\"indexed\": false,\"internalType\": \"uint256\",\"name\": \"value\",\"type\": \"uint256\"},{\"indexed\": false,\"internalType\": \"bytes\",\"name\": \"data\",\"type\": \"bytes\"}],\"name\": \"Executed\",\"type\": \"event\"},{\"anonymous\": false,\"inputs\": [{\"indexed\": true,\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"},{\"components\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"},{\"internalType\": \"bool\",\"name\": \"isWildcard\",\"type\": \"bool\"},{\"internalType\": \"uint256\",\"name\": \"expiresAt\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"},{\"components\": [{\"internalType\": \"enum SessionLib.Condition\",\"name\": \"condition\",\"type\": \"uint8\"},{\"internalType\": \"uint64\",\"name\": \"index\",\"type\": \"uint64\"},{\"internalType\": \"bytes32\",\"name\": \"refValue\",\"type\": \"bytes32\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"limit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.Constraint[]\",\"name\": \"constraints\",\"type\": \"tuple[]\"}],\"internalType\": \"struct SessionLib.CallSpec[]\",\"name\": \"callPolicies\",\"type\": \"tuple[]\"},{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.TransferSpec[]\",\"name\": \"transferPolicies\",\"type\": \"tuple[]\"},{\"internalType\": \"bytes32\",\"name\": \"uid\",\"type\": \"bytes32\"}],\"indexed\": false,\"internalType\": \"struct SessionLib.SessionSpec\",\"name\": \"sessionSpec\",\"type\": \"tuple\"}],\"name\": \"SessionCreated\",\"type\": \"event\"},{\"stateMutability\": \"payable\",\"type\": \"fallback\"},{\"inputs\": [{\"components\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"},{\"internalType\": \"bool\",\"name\": \"isWildcard\",\"type\": \"bool\"},{\"internalType\": \"uint256\",\"name\": \"expiresAt\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"},{\"components\": [{\"internalType\": \"enum SessionLib.Condition\",\"name\": \"condition\",\"type\": \"uint8\"},{\"internalType\": \"uint64\",\"name\": \"index\",\"type\": \"uint64\"},{\"internalType\": \"bytes32\",\"name\": \"refValue\",\"type\": \"bytes32\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"limit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.Constraint[]\",\"name\": \"constraints\",\"type\": \"tuple[]\"}],\"internalType\": \"struct SessionLib.CallSpec[]\",\"name\": \"callPolicies\",\"type\": \"tuple[]\"},{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.TransferSpec[]\",\"name\": \"transferPolicies\",\"type\": \"tuple[]\"},{\"internalType\": \"bytes32\",\"name\": \"uid\",\"type\": \"bytes32\"}],\"internalType\": \"struct SessionLib.SessionSpec\",\"name\": \"sessionSpec\",\"type\": \"tuple\"},{\"internalType\": \"bytes\",\"name\": \"signature\",\"type\": \"bytes\"}],\"name\": \"createSessionWithSig\",\"outputs\": [],\"stateMutability\": \"nonpayable\",\"type\": \"function\"},{\"inputs\": [],\"name\": \"eip712Domain\",\"outputs\": [{\"internalType\": \"bytes1\",\"name\": \"fields\",\"type\": \"bytes1\"},{\"internalType\": \"string\",\"name\": \"name\",\"type\": \"string\"},{\"internalType\": \"string\",\"name\": \"version\",\"type\": \"string\"},{\"internalType\": \"uint256\",\"name\": \"chainId\",\"type\": \"uint256\"},{\"internalType\": \"address\",\"name\": \"verifyingContract\",\"type\": \"address\"},{\"internalType\": \"bytes32\",\"name\": \"salt\",\"type\": \"bytes32\"},{\"internalType\": \"uint256[]\",\"name\": \"extensions\",\"type\": \"uint256[]\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"value\",\"type\": \"uint256\"},{\"internalType\": \"bytes\",\"name\": \"data\",\"type\": \"bytes\"}],\"internalType\": \"struct Call[]\",\"name\": \"calls\",\"type\": \"tuple[]\"}],\"name\": \"execute\",\"outputs\": [],\"stateMutability\": \"payable\",\"type\": \"function\"},{\"inputs\": [{\"components\": [{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"value\",\"type\": \"uint256\"},{\"internalType\": \"bytes\",\"name\": \"data\",\"type\": \"bytes\"}],\"internalType\": \"struct Call[]\",\"name\": \"calls\",\"type\": \"tuple[]\"},{\"internalType\": \"bytes32\",\"name\": \"uid\",\"type\": \"bytes32\"}],\"internalType\": \"struct WrappedCalls\",\"name\": \"wrappedCalls\",\"type\": \"tuple\"},{\"internalType\": \"bytes\",\"name\": \"signature\",\"type\": \"bytes\"}],\"name\": \"executeWithSig\",\"outputs\": [],\"stateMutability\": \"payable\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"}],\"name\": \"getCallPoliciesForSigner\",\"outputs\": [{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"},{\"components\": [{\"internalType\": \"enum SessionLib.Condition\",\"name\": \"condition\",\"type\": \"uint8\"},{\"internalType\": \"uint64\",\"name\": \"index\",\"type\": \"uint64\"},{\"internalType\": \"bytes32\",\"name\": \"refValue\",\"type\": \"bytes32\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"limit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.Constraint[]\",\"name\": \"constraints\",\"type\": \"tuple[]\"}],\"internalType\": \"struct SessionLib.CallSpec[]\",\"name\": \"\",\"type\": \"tuple[]\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"}],\"name\": \"getSessionExpirationForSigner\",\"outputs\": [{\"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"}],\"name\": \"getSessionStateForSigner\",\"outputs\": [{\"components\": [{\"components\": [{\"internalType\": \"uint256\",\"name\": \"remaining\",\"type\": \"uint256\"},{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"index\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.LimitState[]\",\"name\": \"transferValue\",\"type\": \"tuple[]\"},{\"components\": [{\"internalType\": \"uint256\",\"name\": \"remaining\",\"type\": \"uint256\"},{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"index\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.LimitState[]\",\"name\": \"callValue\",\"type\": \"tuple[]\"},{\"components\": [{\"internalType\": \"uint256\",\"name\": \"remaining\",\"type\": \"uint256\"},{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"index\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.LimitState[]\",\"name\": \"callParams\",\"type\": \"tuple[]\"}],\"internalType\": \"struct SessionLib.SessionState\",\"name\": \"\",\"type\": \"tuple\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"}],\"name\": \"getTransferPoliciesForSigner\",\"outputs\": [{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.TransferSpec[]\",\"name\": \"\",\"type\": \"tuple[]\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"}],\"name\": \"isWildcardSigner\",\"outputs\": [{\"internalType\": \"bool\",\"name\": \"\",\"type\": \"bool\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"uint256[]\",\"name\": \"\",\"type\": \"uint256[]\"},{\"internalType\": \"uint256[]\",\"name\": \"\",\"type\": \"uint256[]\"},{\"internalType\": \"bytes\",\"name\": \"\",\"type\": \"bytes\"}],\"name\": \"onERC1155BatchReceived\",\"outputs\": [{\"internalType\": \"bytes4\",\"name\": \"\",\"type\": \"bytes4\"}],\"stateMutability\": \"nonpayable\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\"},{\"internalType\": \"bytes\",\"name\": \"\",\"type\": \"bytes\"}],\"name\": \"onERC1155Received\",\"outputs\": [{\"internalType\": \"bytes4\",\"name\": \"\",\"type\": \"bytes4\"}],\"stateMutability\": \"nonpayable\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\"},{\"internalType\": \"bytes\",\"name\": \"\",\"type\": \"bytes\"}],\"name\": \"onERC721Received\",\"outputs\": [{\"internalType\": \"bytes4\",\"name\": \"\",\"type\": \"bytes4\"}],\"stateMutability\": \"nonpayable\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"bytes4\",\"name\": \"interfaceId\",\"type\": \"bytes4\"}],\"name\": \"supportsInterface\",\"outputs\": [{\"internalType\": \"bool\",\"name\": \"\",\"type\": \"bool\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"stateMutability\": \"payable\",\"type\": \"receive\"}]"; + "[{\"inputs\": [{\"internalType\": \"uint256\",\"name\": \"allowanceUsage\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint64\",\"name\": \"period\",\"type\": \"uint64\"}],\"name\": \"AllowanceExceeded\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"}],\"name\": \"CallPolicyViolated\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"CallReverted\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"bytes32\",\"name\": \"param\",\"type\": \"bytes32\"},{\"internalType\": \"bytes32\",\"name\": \"refValue\",\"type\": \"bytes32\"},{\"internalType\": \"uint8\",\"name\": \"condition\",\"type\": \"uint8\"}],\"name\": \"ConditionFailed\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"uint256\",\"name\": \"actualLength\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"expectedLength\",\"type\": \"uint256\"}],\"name\": \"InvalidDataLength\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"msgSender\",\"type\": \"address\"},{\"internalType\": \"address\",\"name\": \"thisAddress\",\"type\": \"address\"}],\"name\": \"InvalidSignature\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"uint256\",\"name\": \"lifetimeUsage\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"}],\"name\": \"LifetimeUsageExceeded\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"uint256\",\"name\": \"value\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"}],\"name\": \"MaxValueExceeded\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"NoCallsToExecute\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"SessionExpired\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"SessionExpiresTooSoon\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"SessionZeroSigner\",\"type\": \"error\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"}],\"name\": \"TransferPolicyViolated\",\"type\": \"error\"},{\"inputs\": [],\"name\": \"UIDAlreadyProcessed\",\"type\": \"error\"},{\"anonymous\": false,\"inputs\": [{\"indexed\": true,\"internalType\": \"address\",\"name\": \"to\",\"type\": \"address\"},{\"indexed\": false,\"internalType\": \"uint256\",\"name\": \"value\",\"type\": \"uint256\"},{\"indexed\": false,\"internalType\": \"bytes\",\"name\": \"data\",\"type\": \"bytes\"}],\"name\": \"Executed\",\"type\": \"event\"},{\"anonymous\": false,\"inputs\": [{\"indexed\": true,\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"},{\"components\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"},{\"internalType\": \"bool\",\"name\": \"isWildcard\",\"type\": \"bool\"},{\"internalType\": \"uint256\",\"name\": \"expiresAt\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"},{\"components\": [{\"internalType\": \"enum SessionLib.Condition\",\"name\": \"condition\",\"type\": \"uint8\"},{\"internalType\": \"uint64\",\"name\": \"index\",\"type\": \"uint64\"},{\"internalType\": \"bytes32\",\"name\": \"refValue\",\"type\": \"bytes32\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"limit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.Constraint[]\",\"name\": \"constraints\",\"type\": \"tuple[]\"}],\"internalType\": \"struct SessionLib.CallSpec[]\",\"name\": \"callPolicies\",\"type\": \"tuple[]\"},{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.TransferSpec[]\",\"name\": \"transferPolicies\",\"type\": \"tuple[]\"},{\"internalType\": \"bytes32\",\"name\": \"uid\",\"type\": \"bytes32\"}],\"indexed\": false,\"internalType\": \"struct SessionLib.SessionSpec\",\"name\": \"sessionSpec\",\"type\": \"tuple\"}],\"name\": \"SessionCreated\",\"type\": \"event\"},{\"anonymous\": false,\"inputs\": [{\"indexed\": true,\"internalType\": \"address\",\"name\": \"from\",\"type\": \"address\"},{\"indexed\": false,\"internalType\": \"uint256\",\"name\": \"value\",\"type\": \"uint256\"}],\"name\": \"ValueReceived\",\"type\": \"event\"},{\"inputs\": [{\"components\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"},{\"internalType\": \"bool\",\"name\": \"isWildcard\",\"type\": \"bool\"},{\"internalType\": \"uint256\",\"name\": \"expiresAt\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"},{\"components\": [{\"internalType\": \"enum SessionLib.Condition\",\"name\": \"condition\",\"type\": \"uint8\"},{\"internalType\": \"uint64\",\"name\": \"index\",\"type\": \"uint64\"},{\"internalType\": \"bytes32\",\"name\": \"refValue\",\"type\": \"bytes32\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"limit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.Constraint[]\",\"name\": \"constraints\",\"type\": \"tuple[]\"}],\"internalType\": \"struct SessionLib.CallSpec[]\",\"name\": \"callPolicies\",\"type\": \"tuple[]\"},{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.TransferSpec[]\",\"name\": \"transferPolicies\",\"type\": \"tuple[]\"},{\"internalType\": \"bytes32\",\"name\": \"uid\",\"type\": \"bytes32\"}],\"internalType\": \"struct SessionLib.SessionSpec\",\"name\": \"sessionSpec\",\"type\": \"tuple\"},{\"internalType\": \"bytes\",\"name\": \"signature\",\"type\": \"bytes\"}],\"name\": \"createSessionWithSig\",\"outputs\": [],\"stateMutability\": \"nonpayable\",\"type\": \"function\"},{\"inputs\": [],\"name\": \"eip712Domain\",\"outputs\": [{\"internalType\": \"bytes1\",\"name\": \"fields\",\"type\": \"bytes1\"},{\"internalType\": \"string\",\"name\": \"name\",\"type\": \"string\"},{\"internalType\": \"string\",\"name\": \"version\",\"type\": \"string\"},{\"internalType\": \"uint256\",\"name\": \"chainId\",\"type\": \"uint256\"},{\"internalType\": \"address\",\"name\": \"verifyingContract\",\"type\": \"address\"},{\"internalType\": \"bytes32\",\"name\": \"salt\",\"type\": \"bytes32\"},{\"internalType\": \"uint256[]\",\"name\": \"extensions\",\"type\": \"uint256[]\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"value\",\"type\": \"uint256\"},{\"internalType\": \"bytes\",\"name\": \"data\",\"type\": \"bytes\"}],\"internalType\": \"struct Call[]\",\"name\": \"calls\",\"type\": \"tuple[]\"}],\"name\": \"execute\",\"outputs\": [],\"stateMutability\": \"payable\",\"type\": \"function\"},{\"inputs\": [{\"components\": [{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"value\",\"type\": \"uint256\"},{\"internalType\": \"bytes\",\"name\": \"data\",\"type\": \"bytes\"}],\"internalType\": \"struct Call[]\",\"name\": \"calls\",\"type\": \"tuple[]\"},{\"internalType\": \"bytes32\",\"name\": \"uid\",\"type\": \"bytes32\"}],\"internalType\": \"struct WrappedCalls\",\"name\": \"wrappedCalls\",\"type\": \"tuple\"},{\"internalType\": \"bytes\",\"name\": \"signature\",\"type\": \"bytes\"}],\"name\": \"executeWithSig\",\"outputs\": [],\"stateMutability\": \"payable\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"}],\"name\": \"getCallPoliciesForSigner\",\"outputs\": [{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"},{\"components\": [{\"internalType\": \"enum SessionLib.Condition\",\"name\": \"condition\",\"type\": \"uint8\"},{\"internalType\": \"uint64\",\"name\": \"index\",\"type\": \"uint64\"},{\"internalType\": \"bytes32\",\"name\": \"refValue\",\"type\": \"bytes32\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"limit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.Constraint[]\",\"name\": \"constraints\",\"type\": \"tuple[]\"}],\"internalType\": \"struct SessionLib.CallSpec[]\",\"name\": \"\",\"type\": \"tuple[]\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"}],\"name\": \"getSessionExpirationForSigner\",\"outputs\": [{\"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"}],\"name\": \"getSessionStateForSigner\",\"outputs\": [{\"components\": [{\"components\": [{\"internalType\": \"uint256\",\"name\": \"remaining\",\"type\": \"uint256\"},{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"index\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.LimitState[]\",\"name\": \"transferValue\",\"type\": \"tuple[]\"},{\"components\": [{\"internalType\": \"uint256\",\"name\": \"remaining\",\"type\": \"uint256\"},{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"index\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.LimitState[]\",\"name\": \"callValue\",\"type\": \"tuple[]\"},{\"components\": [{\"internalType\": \"uint256\",\"name\": \"remaining\",\"type\": \"uint256\"},{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"bytes4\",\"name\": \"selector\",\"type\": \"bytes4\"},{\"internalType\": \"uint256\",\"name\": \"index\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.LimitState[]\",\"name\": \"callParams\",\"type\": \"tuple[]\"}],\"internalType\": \"struct SessionLib.SessionState\",\"name\": \"\",\"type\": \"tuple\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"}],\"name\": \"getTransferPoliciesForSigner\",\"outputs\": [{\"components\": [{\"internalType\": \"address\",\"name\": \"target\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"maxValuePerUse\",\"type\": \"uint256\"},{\"components\": [{\"internalType\": \"enum SessionLib.LimitType\",\"name\": \"limitType\",\"type\": \"uint8\"},{\"internalType\": \"uint256\",\"name\": \"limit\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"period\",\"type\": \"uint256\"}],\"internalType\": \"struct SessionLib.UsageLimit\",\"name\": \"valueLimit\",\"type\": \"tuple\"}],\"internalType\": \"struct SessionLib.TransferSpec[]\",\"name\": \"\",\"type\": \"tuple[]\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"signer\",\"type\": \"address\"}],\"name\": \"isWildcardSigner\",\"outputs\": [{\"internalType\": \"bool\",\"name\": \"\",\"type\": \"bool\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"uint256[]\",\"name\": \"\",\"type\": \"uint256[]\"},{\"internalType\": \"uint256[]\",\"name\": \"\",\"type\": \"uint256[]\"},{\"internalType\": \"bytes\",\"name\": \"\",\"type\": \"bytes\"}],\"name\": \"onERC1155BatchReceived\",\"outputs\": [{\"internalType\": \"bytes4\",\"name\": \"\",\"type\": \"bytes4\"}],\"stateMutability\": \"nonpayable\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\"},{\"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\"},{\"internalType\": \"bytes\",\"name\": \"\",\"type\": \"bytes\"}],\"name\": \"onERC1155Received\",\"outputs\": [{\"internalType\": \"bytes4\",\"name\": \"\",\"type\": \"bytes4\"}],\"stateMutability\": \"nonpayable\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"address\",\"name\": \"\",\"type\": \"address\"},{\"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\"},{\"internalType\": \"bytes\",\"name\": \"\",\"type\": \"bytes\"}],\"name\": \"onERC721Received\",\"outputs\": [{\"internalType\": \"bytes4\",\"name\": \"\",\"type\": \"bytes4\"}],\"stateMutability\": \"nonpayable\",\"type\": \"function\"},{\"inputs\": [{\"internalType\": \"bytes4\",\"name\": \"interfaceId\",\"type\": \"bytes4\"}],\"name\": \"supportsInterface\",\"outputs\": [{\"internalType\": \"bool\",\"name\": \"\",\"type\": \"bool\"}],\"stateMutability\": \"view\",\"type\": \"function\"},{\"stateMutability\": \"payable\",\"type\": \"receive\"}]"; public const string MULTICALL3_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11"; public const string MULTICALL3_ABI = From 6388ff413dd7205dfd5b1ec0b69eb9fb00c1c225 Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Tue, 24 Jun 2025 03:48:31 +0700 Subject: [PATCH 4/5] Improve API and example --- Thirdweb.Console/Program.cs | 59 ++++++++----------- .../EcosystemWallet/EcosystemWallet.cs | 20 ++++++- 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/Thirdweb.Console/Program.cs b/Thirdweb.Console/Program.cs index db2c5de..0875dcd 100644 --- a/Thirdweb.Console/Program.cs +++ b/Thirdweb.Console/Program.cs @@ -360,41 +360,30 @@ #region EIP-7702 -var chain = 11155111; // 7702-compatible chain - -// Connect to EOA -var smartEoa = await InAppWallet.Create(client, authProvider: AuthProvider.Guest, executionMode: ExecutionMode.EIP7702Sponsored); -if (!await smartEoa.IsConnected()) -{ - _ = await smartEoa.LoginWithGuest(defaultSessionIdOverride: new Guid().ToString()); -} -var smartEoaAddress = await smartEoa.GetAddress(); -Console.WriteLine($"User Wallet address: {await smartEoa.GetAddress()}"); - -// Upgrade EOA - This wallet explicitly uses EIP-7702 delegation to the thirdweb MinimalAccount (will delegate upon first tx) - -// Transact, will upgrade EOA -var receipt = await smartEoa.Transfer(chainId: chain, toAddress: await Utils.GetAddressFromENS(client, "vitalik.eth"), weiAmount: 0); -Console.WriteLine($"Transfer Receipt: {receipt.TransactionHash}"); - -// Double check that it was upgraded -var isDelegated = await Utils.IsDelegatedAccount(client, chain, smartEoaAddress); -Console.WriteLine($"Is delegated: {isDelegated}"); - -// Create a session key -var sessionKeyReceipt = await smartEoa.CreateSessionKey( - chain, - new SessionSpec() - { - Signer = await Utils.GetAddressFromENS(client, "vitalik.eth"), - IsWildcard = true, - ExpiresAt = Utils.GetUnixTimeStampNow() + 86400, // 1 day - CallPolicies = new List(), - TransferPolicies = new List(), - Uid = "my-session-key-uid".HashMessage().HexToBytes() - } -); -Console.WriteLine($"Session key receipt: {sessionKeyReceipt.TransactionHash}"); +// var chain = 11155111; // 7702-compatible chain + +// // Connect to EOA +// var smartEoa = await InAppWallet.Create(client, authProvider: AuthProvider.Guest, executionMode: ExecutionMode.EIP7702Sponsored); +// if (!await smartEoa.IsConnected()) +// { +// _ = await smartEoa.LoginWithGuest(defaultSessionIdOverride: new Guid().ToString()); +// } +// var smartEoaAddress = await smartEoa.GetAddress(); +// Console.WriteLine($"User Wallet address: {await smartEoa.GetAddress()}"); + +// // Upgrade EOA - This wallet explicitly uses EIP-7702 delegation to the thirdweb MinimalAccount (will delegate upon first tx) + +// // Transact, will upgrade EOA +// var receipt = await smartEoa.Transfer(chainId: chain, toAddress: await Utils.GetAddressFromENS(client, "vitalik.eth"), weiAmount: 0); +// Console.WriteLine($"Transfer Receipt: {receipt.TransactionHash}"); + +// // Double check that it was upgraded +// var isDelegated = await Utils.IsDelegatedAccount(client, chain, smartEoaAddress); +// Console.WriteLine($"Is delegated: {isDelegated}"); + +// // Create a session key +// var sessionKeyReceipt = await smartEoa.CreateSessionKey(chainId: chain, signerAddress: await Utils.GetAddressFromENS(client, "vitalik.eth"), durationInSeconds: 86400, grantFullPermissions: true); +// Console.WriteLine($"Session key receipt: {sessionKeyReceipt.TransactionHash}"); #endregion diff --git a/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs b/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs index dc04eaf..8774529 100644 --- a/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs @@ -450,13 +450,31 @@ public string GenerateExternalLoginLink(string redirectUrl) return $"{redirectUrl}{queryString}"; } - public async Task CreateSessionKey(BigInteger chainId, SessionSpec sessionKeyParams) + public async Task CreateSessionKey( + BigInteger chainId, + string signerAddress, + long durationInSeconds, + bool grantFullPermissions = true, + List callPolicies = null, + List transferPolicies = null, + byte[] uid = null + ) { if (this.ExecutionMode is not ExecutionMode.EIP7702 and not ExecutionMode.EIP7702Sponsored) { throw new InvalidOperationException("CreateSessionKey is only supported for EIP7702 and EIP7702Sponsored execution modes."); } + var sessionKeyParams = new SessionSpec() + { + Signer = signerAddress, + IsWildcard = grantFullPermissions, + ExpiresAt = Utils.GetUnixTimeStampNow() + durationInSeconds, + CallPolicies = callPolicies ?? new List(), + TransferPolicies = transferPolicies ?? new List(), + Uid = uid ?? Guid.NewGuid().ToByteArray() + }; + var userWalletAddress = await this.GetAddress(); var sessionKeySig = await EIP712.GenerateSignature_SmartAccount_7702("MinimalAccount", "1", chainId, userWalletAddress, sessionKeyParams, this); var userContract = await ThirdwebContract.Create(this.Client, userWalletAddress, chainId, Constants.MINIMAL_ACCOUNT_7702_ABI); From f989fe0253880b5872175b282a412955d672b7fb Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Tue, 24 Jun 2025 03:51:15 +0700 Subject: [PATCH 5/5] add validation --- .../InAppWallet/EcosystemWallet/EcosystemWallet.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs b/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs index 8774529..3388028 100644 --- a/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs @@ -465,6 +465,16 @@ public async Task CreateSessionKey( throw new InvalidOperationException("CreateSessionKey is only supported for EIP7702 and EIP7702Sponsored execution modes."); } + if (string.IsNullOrEmpty(signerAddress)) + { + throw new ArgumentException("Signer address cannot be null or empty.", nameof(signerAddress)); + } + + if (durationInSeconds <= 0) + { + throw new ArgumentException("Duration must be greater than zero.", nameof(durationInSeconds)); + } + var sessionKeyParams = new SessionSpec() { Signer = signerAddress,