@@ -15,61 +15,46 @@ public class ThirdwebWallet : IThirdwebWallet
1515 public ThirdwebAccountType AccountType => ThirdwebAccountType . ExternalAccount ;
1616
1717 internal IThirdwebWallet UserWallet { get ; }
18- internal IThirdwebWallet ExecutorWallet { get ; }
1918 internal ThirdwebContract UserContract { get ; }
19+ internal BigInteger ChainId { get ; }
20+ internal bool ManagedExecution { get ; }
2021
21- internal ThirdwebWallet ( ThirdwebClient client , IThirdwebWallet userWallet , IThirdwebWallet executorWallet , ThirdwebContract userContract )
22+ private EIP7702Authorization ? Authorization { get ; set ; }
23+
24+ internal ThirdwebWallet ( ThirdwebClient client , BigInteger chainId , IThirdwebWallet userWallet , ThirdwebContract userContract , EIP7702Authorization ? authorization , bool managedExecution )
2225 {
2326 this . Client = client ;
27+ this . ChainId = chainId ;
2428 this . UserWallet = userWallet ;
25- this . ExecutorWallet = executorWallet ;
2629 this . UserContract = userContract ;
30+ this . Authorization = authorization ;
31+ this . ManagedExecution = managedExecution ;
2732 }
2833
29- public static async Task < ThirdwebWallet > Create ( ThirdwebClient client , BigInteger chainId , IThirdwebWallet userWallet , IThirdwebWallet executorWallet , SessionSpec sessionKeyParams )
34+ public static async Task < ThirdwebWallet > Create ( ThirdwebClient client , BigInteger chainId , IThirdwebWallet userWallet , bool managedExecution )
3035 {
3136 var userWalletAddress = await userWallet . GetAddress ( ) ;
32- var executorWalletAddress = await executorWallet . GetAddress ( ) ;
33- if ( sessionKeyParams != null && sessionKeyParams . Signer != executorWalletAddress )
34- {
35- throw new Exception ( "Session key signer must be the executor wallet" ) ;
36- }
37- var delegationContract = await ThirdwebContract . Create ( client , Constants . MINIMAL_ACCOUNT_7702 , chainId ) ;
38-
39- var rpc = ThirdwebRPC . GetRpcInstance ( client , chainId ) ;
40- var code = await rpc . SendRequestAsync < string > ( "eth_getCode" , userWalletAddress , "latest" ) ;
41- var needsDelegation = ! Utils . IsDelegatedAccount ( code ) ;
42-
43- // Sign authorization if needed
44- EIP7702Authorization ? authorization = needsDelegation ? await userWallet . SignAuthorization ( chainId , Constants . MINIMAL_ACCOUNT_7702 , willSelfExecute : false ) : null ;
45-
46- // TODO: We don't always need to create a session key when creating this wallet, handle with a flag or null check
47-
48- // Sign message for session key
49- var sessionKeySig = await EIP712 . GenerateSignature_SmartAccount_7702 ( "MinimalAccount" , "1" , chainId , userWalletAddress , sessionKeyParams , userWallet ) ;
50-
51- // Create call data for the session
52- var sessionKeyCallData = delegationContract . CreateCallData ( "createSessionWithSig" , sessionKeyParams , sessionKeySig . HexToBytes ( ) ) ;
53-
54- // Execute the delegation & session creation in one go
55- var delegationTx = await ThirdwebTransaction . Create (
56- executorWallet ,
57- new ThirdwebTransactionInput ( chainId : chainId , to : userWalletAddress , data : sessionKeyCallData , authorization : authorization )
58- ) ;
59- _ = await ThirdwebTransaction . SendAndWaitForTransactionReceipt ( delegationTx ) ;
60-
61- var newCode = await rpc . SendRequestAsync < string > ( "eth_getCode" , userWalletAddress , "latest" ) ;
62- if ( ! Utils . IsDelegatedAccount ( newCode ) )
63- {
64- throw new Exception ( "Delegation failed, code was not set." ) ;
65- }
66-
67- var userContract = await ThirdwebContract . Create ( client , userWalletAddress , chainId , delegationContract . Abi ) ;
68- var wallet = new ThirdwebWallet ( client , userWallet , executorWallet , userContract ) ;
37+ var userContract = await ThirdwebContract . Create ( client , userWalletAddress , chainId , Constants . MINIMAL_ACCOUNT_7702_ABI ) ;
38+ var needsDelegation = ! await Utils . IsDelegatedAccount ( client , chainId , userWalletAddress ) ;
39+ EIP7702Authorization ? authorization = needsDelegation ? await userWallet . SignAuthorization ( chainId , Constants . MINIMAL_ACCOUNT_7702 , willSelfExecute : ! managedExecution ) : null ;
40+ var wallet = new ThirdwebWallet ( client , chainId , userWallet , userContract , authorization , managedExecution ) ;
6941 Utils . TrackConnection ( wallet ) ;
7042 return wallet ;
7143 }
7244
45+ #region Wallet Specific
46+
47+ public async Task < ThirdwebTransactionReceipt > CreateSessionKey ( SessionSpec sessionKeyParams )
48+ {
49+ var userWalletAddress = await this . UserWallet . GetAddress ( ) ;
50+ var sessionKeySig = await EIP712 . GenerateSignature_SmartAccount_7702 ( "MinimalAccount" , "1" , this . ChainId , userWalletAddress , sessionKeyParams , this . UserWallet ) ;
51+ var sessionKeyCallData = this . UserContract . CreateCallData ( "createSessionWithSig" , sessionKeyParams , sessionKeySig . HexToBytes ( ) ) ;
52+ var sessionKeyTx = await ThirdwebTransaction . Create ( this , new ThirdwebTransactionInput ( chainId : this . ChainId , to : userWalletAddress , data : sessionKeyCallData ) ) ;
53+ return await ThirdwebTransaction . SendAndWaitForTransactionReceipt ( sessionKeyTx ) ;
54+ }
55+
56+ #endregion
57+
7358 #region IThirdwebWallet
7459
7560 public Task < string > GetAddress ( )
@@ -136,17 +121,50 @@ public Task<string> SignTransaction(ThirdwebTransactionInput transaction)
136121
137122 public async Task < string > SendTransaction ( ThirdwebTransactionInput transaction )
138123 {
139- var calls = new List < Call >
124+ // TODO: managed execution - executeWithSig
125+ if ( this . ManagedExecution )
126+ {
127+ throw new NotImplementedException ( "Managed execution is not yet implemented." ) ;
128+
129+ // 1. Create payload with eoa address, wrapped calls, signature and optional authorizationList
130+ // 2. Send to https://{chainId}.bundler.thirdweb.com as RpcRequest w/ method tw_execute
131+ // 3. Retrieve tx hash or queue id from response
132+ // 4. Return tx hash
133+ }
134+ else
140135 {
141- new ( )
136+ var calls = new List < Call >
142137 {
143- Target = transaction . To ,
144- Value = transaction . Value ? . Value ?? BigInteger . Zero ,
145- Data = transaction . Data . HexToBytes ( )
138+ new ( )
139+ {
140+ Target = transaction . To ,
141+ Value = transaction . Value ? . Value ?? BigInteger . Zero ,
142+ Data = transaction . Data . HexToBytes ( )
143+ }
144+ } ;
145+
146+ BigInteger totalValue = 0 ;
147+ foreach ( var call in calls )
148+ {
149+ totalValue += call . Value ;
146150 }
147- } ;
148- var tx = await this . UserContract . Prepare ( this . ExecutorWallet , "execute" , calls [ 0 ] . Value , calls ) ;
149- return await ThirdwebTransaction . Send ( tx ) ;
151+
152+ var tx = await this . UserContract . Prepare ( wallet : this . UserWallet , method : "execute" , weiValue : totalValue , parameters : new object [ ] { calls } ) ;
153+
154+ if ( this . Authorization != null )
155+ {
156+ if ( ! await Utils . IsDelegatedAccount ( this . Client , this . ChainId , await this . UserWallet . GetAddress ( ) ) )
157+ {
158+ tx . Input . AuthorizationList = new List < EIP7702Authorization > ( ) { this . Authorization . Value } ;
159+ }
160+ else
161+ {
162+ this . Authorization = null ;
163+ }
164+ }
165+
166+ return await ThirdwebTransaction . Send ( tx ) ;
167+ }
150168 }
151169
152170 public async Task < ThirdwebTransactionReceipt > ExecuteTransaction ( ThirdwebTransactionInput transaction )
0 commit comments