Skip to content

Commit df77184

Browse files
authored
Add dynamic delegation contract support for EIP-7702 (#156)
1 parent 3d9b591 commit df77184

File tree

7 files changed

+35
-16
lines changed

7 files changed

+35
-16
lines changed

Thirdweb.Console/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@
408408
// Console.WriteLine($"Transfer Receipt: {receipt.TransactionHash}");
409409

410410
// // Double check that it was upgraded
411-
// var isDelegated = await Utils.IsDelegatedAccount(client, chain, smartEoaAddress);
411+
// var isDelegated = await Utils.IsDeployed(client, chain, smartEoaAddress);
412412
// Console.WriteLine($"Is delegated: {isDelegated}");
413413

414414
// // Create a session key

Thirdweb/Thirdweb.Utils/Constants.cs

Lines changed: 1 addition & 2 deletions
Large diffs are not rendered by default.

Thirdweb/Thirdweb.Utils/Utils.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,10 +1332,10 @@ public static async Task<ThirdwebTransactionReceipt> WaitForTransactionReceipt(T
13321332
return receipt;
13331333
}
13341334

1335-
public static async Task<bool> IsDelegatedAccount(ThirdwebClient client, BigInteger chainId, string address)
1335+
public static async Task<bool> IsDelegatedAccount(ThirdwebClient client, BigInteger chainId, string address, string delegationContract)
13361336
{
13371337
var rpc = ThirdwebRPC.GetRpcInstance(client, chainId);
13381338
var code = await rpc.SendRequestAsync<string>("eth_getCode", address, "latest");
1339-
return code.Equals($"0xef0100{Constants.MINIMAL_ACCOUNT_7702[2..]}", StringComparison.OrdinalIgnoreCase);
1339+
return code.Equals($"0xef0100{delegationContract[2..]}", StringComparison.OrdinalIgnoreCase);
13401340
}
13411341
}

Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public partial class EcosystemWallet : IThirdwebWallet
3939

4040
internal string Address;
4141
internal ExecutionMode ExecutionMode;
42+
internal string DelegationContractAddress;
4243

4344
private readonly string _ecosystemId;
4445
private readonly string _ecosystemPartnerId;
@@ -60,7 +61,8 @@ internal EcosystemWallet(
6061
IThirdwebWallet siweSigner,
6162
string legacyEncryptionKey,
6263
string walletSecret,
63-
ExecutionMode executionMode
64+
ExecutionMode executionMode,
65+
string delegationContractAddress
6466
)
6567
{
6668
this.Client = client;
@@ -76,7 +78,7 @@ ExecutionMode executionMode
7678
this.WalletSecret = walletSecret;
7779
this.ExecutionMode = executionMode;
7880
this.AccountType = executionMode == ExecutionMode.EOA ? ThirdwebAccountType.PrivateKeyAccount : ThirdwebAccountType.ExternalAccount;
79-
;
81+
this.DelegationContractAddress = delegationContractAddress;
8082
}
8183

8284
#region Creation
@@ -118,6 +120,8 @@ public static async Task<EcosystemWallet> Create(
118120
throw new ArgumentNullException(nameof(client), "Client cannot be null.");
119121
}
120122

123+
var delegationContractResponse = await BundlerClient.TwGetDelegationContract(client: client, url: $"https://1.bundler.thirdweb.com", requestId: 7702);
124+
121125
if (string.IsNullOrEmpty(email) && string.IsNullOrEmpty(phoneNumber) && authProvider == Thirdweb.AuthProvider.Default)
122126
{
123127
throw new ArgumentException("Email, Phone Number, or OAuth Provider must be provided to login.");
@@ -193,7 +197,8 @@ public static async Task<EcosystemWallet> Create(
193197
siweSigner,
194198
legacyEncryptionKey,
195199
walletSecret,
196-
executionMode
200+
executionMode,
201+
delegationContractResponse.DelegationContract
197202
)
198203
{
199204
Address = userAddress,
@@ -214,7 +219,8 @@ public static async Task<EcosystemWallet> Create(
214219
siweSigner,
215220
legacyEncryptionKey,
216221
walletSecret,
217-
executionMode
222+
executionMode,
223+
delegationContractResponse.DelegationContract
218224
)
219225
{
220226
Address = null,
@@ -1294,9 +1300,9 @@ public async Task<string> SendTransaction(ThirdwebTransactionInput transaction)
12941300
{
12951301
var userWalletAddress = await this.GetAddress();
12961302
var userContract = await ThirdwebContract.Create(this.Client, userWalletAddress, transaction.ChainId, Constants.MINIMAL_ACCOUNT_7702_ABI);
1297-
var needsDelegation = !await Utils.IsDelegatedAccount(this.Client, transaction.ChainId, userWalletAddress);
1303+
var needsDelegation = !await Utils.IsDelegatedAccount(this.Client, transaction.ChainId, userWalletAddress, this.DelegationContractAddress);
12981304
EIP7702Authorization? authorization = needsDelegation
1299-
? await this.SignAuthorization(transaction.ChainId, Constants.MINIMAL_ACCOUNT_7702, willSelfExecute: this.ExecutionMode != ExecutionMode.EIP7702Sponsored)
1305+
? await this.SignAuthorization(transaction.ChainId, this.DelegationContractAddress, willSelfExecute: this.ExecutionMode != ExecutionMode.EIP7702Sponsored)
13001306
: null;
13011307

13021308
var calls = new List<Call>
@@ -1337,7 +1343,7 @@ public async Task<string> SendTransaction(ThirdwebTransactionInput transaction)
13371343
eoaAddress: userWalletAddress,
13381344
wrappedCalls: wrappedCalls,
13391345
signature: signature,
1340-
authorization: authorization != null && !await Utils.IsDelegatedAccount(this.Client, transaction.ChainId, userWalletAddress) ? authorization : null
1346+
authorization: authorization != null && !await Utils.IsDelegatedAccount(this.Client, transaction.ChainId, userWalletAddress, this.DelegationContractAddress) ? authorization : null
13411347
);
13421348
var queueId = response?.QueueId;
13431349
string txHash = null;
@@ -1473,7 +1479,7 @@ private async Task Ensure7702(BigInteger chainId, bool ensureDelegated)
14731479
throw new InvalidOperationException("This operation is only supported for EIP7702 and EIP7702Sponsored execution modes.");
14741480
}
14751481

1476-
if (!await Utils.IsDelegatedAccount(this.Client, chainId, this.Address).ConfigureAwait(false))
1482+
if (!await Utils.IsDelegatedAccount(this.Client, chainId, this.Address, this.DelegationContractAddress).ConfigureAwait(false))
14771483
{
14781484
if (ensureDelegated)
14791485
{

Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ internal InAppWallet(
2020
string address,
2121
string legacyEncryptionKey,
2222
string walletSecret,
23-
ExecutionMode executionMode
23+
ExecutionMode executionMode,
24+
string delegationContractAddress
2425
)
25-
: base(null, null, client, embeddedWallet, httpClient, email, phoneNumber, authProvider, siweSigner, legacyEncryptionKey, walletSecret, executionMode)
26+
: base(null, null, client, embeddedWallet, httpClient, email, phoneNumber, authProvider, siweSigner, legacyEncryptionKey, walletSecret, executionMode, delegationContractAddress)
2627
{
2728
this.Address = address;
2829
}
@@ -68,7 +69,8 @@ public static async Task<InAppWallet> Create(
6869
ecoWallet.Address,
6970
ecoWallet.LegacyEncryptionKey,
7071
ecoWallet.WalletSecret,
71-
ecoWallet.ExecutionMode
72+
ecoWallet.ExecutionMode,
73+
ecoWallet.DelegationContractAddress
7274
);
7375
}
7476
}

Thirdweb/Thirdweb.Wallets/SmartWallet/Thirdweb.AccountAbstraction/AATypes.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,12 @@ public class EthGetUserOperationReceiptResponse
240240
public ThirdwebTransactionReceipt Receipt { get; set; }
241241
}
242242

243+
public class TwGetDelegationContractResponse
244+
{
245+
[JsonProperty("delegationContract")]
246+
public string DelegationContract { get; set; }
247+
}
248+
243249
public class TwExecuteResponse
244250
{
245251
[JsonProperty("queueId")]

Thirdweb/Thirdweb.Wallets/SmartWallet/Thirdweb.AccountAbstraction/BundlerClient.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ namespace Thirdweb.AccountAbstraction;
66
public static class BundlerClient
77
{
88
// EIP 7702 requests
9+
public static async Task<TwGetDelegationContractResponse> TwGetDelegationContract(ThirdwebClient client, string url, int requestId)
10+
{
11+
var response = await BundlerRequest(client, url, requestId, "tw_getDelegationContract").ConfigureAwait(false);
12+
return JsonConvert.DeserializeObject<TwGetDelegationContractResponse>(response.Result.ToString());
13+
}
14+
915
public static async Task<TwExecuteResponse> TwExecute(
1016
ThirdwebClient client,
1117
string url,

0 commit comments

Comments
 (0)