diff --git a/Thirdweb.Console/Program.cs b/Thirdweb.Console/Program.cs
index de0dec3a..17b41903 100644
--- a/Thirdweb.Console/Program.cs
+++ b/Thirdweb.Console/Program.cs
@@ -13,6 +13,7 @@
using Thirdweb;
using Thirdweb.AccountAbstraction;
using Thirdweb.AI;
+using Thirdweb.Indexer;
using Thirdweb.Pay;
DotEnv.Load();
@@ -40,6 +41,45 @@
#endregion
+#region Indexer
+
+// // Create a ThirdwebInsight instance
+// var insight = await ThirdwebInsight.Create(client);
+
+// // Setup some filters
+// var address = await Utils.GetAddressFromENS(client, "vitalik.eth");
+// var chains = new BigInteger[] { 1, 137, 42161 };
+
+// // Fetch all token types
+// var tokens = await insight.GetTokens(address, chains);
+// Console.WriteLine($"ERC20 Count: {tokens.erc20Tokens.Length} | ERC721 Count: {tokens.erc721Tokens.Length} | ERC1155 Count: {tokens.erc1155Tokens.Length}");
+
+// // Fetch specific token types
+// var erc20Tokens = await insight.GetTokens_ERC20(address, chains);
+// Console.WriteLine($"ERC20 Tokens: {JsonConvert.SerializeObject(erc20Tokens, Formatting.Indented)}");
+
+// // Fetch specific token types
+// var erc721Tokens = await insight.GetTokens_ERC721(address, chains);
+// Console.WriteLine($"ERC721 Tokens: {JsonConvert.SerializeObject(erc721Tokens, Formatting.Indented)}");
+
+// // Fetch specific token types
+// var erc1155Tokens = await insight.GetTokens_ERC1155(address, chains);
+// Console.WriteLine($"ERC1155 Tokens: {JsonConvert.SerializeObject(erc1155Tokens, Formatting.Indented)}");
+
+// // Fetch events (great amount of optional filters available)
+// var events = await insight.GetEvents(
+// chainIds: new BigInteger[] { 1 }, // ethereum
+// contractAddress: "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d", // bored apes
+// eventSignature: "Transfer(address,address,uint256)", // transfer event
+// fromTimestamp: Utils.GetUnixTimeStampNow() - 3600, // last hour
+// sortBy: SortBy.TransactionIndex, // block number, block timestamp or transaction index
+// sortOrder: SortOrder.Desc, // latest first
+// limit: 5 // last 5 transfers
+// );
+// Console.WriteLine($"Events: {JsonConvert.SerializeObject(events, Formatting.Indented)}");
+
+#endregion
+
#region AI
// // Prepare some context
diff --git a/Thirdweb/Thirdweb.Indexer/ThirdwebInsight.Types.cs b/Thirdweb/Thirdweb.Indexer/ThirdwebInsight.Types.cs
new file mode 100644
index 00000000..d0474b66
--- /dev/null
+++ b/Thirdweb/Thirdweb.Indexer/ThirdwebInsight.Types.cs
@@ -0,0 +1,121 @@
+using System.Numerics;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Thirdweb.Indexer;
+
+///
+/// Represents the response model wrapping the result of an API call.
+///
+/// The type of the result.
+internal class ResponseModel
+{
+ ///
+ /// The result returned by the API.
+ ///
+ [JsonProperty("data")]
+ internal T[] Data { get; set; }
+
+ [JsonProperty("aggregations")]
+ public object Aggregations { get; set; } = null!;
+
+ [JsonProperty("meta")]
+ public Meta Meta { get; set; } = null!;
+}
+
+public class Token
+{
+ [JsonProperty("chainId", Required = Required.Always)]
+ public BigInteger ChainId { get; set; }
+
+ [JsonProperty("balance", Required = Required.Always)]
+ public BigInteger Balance { get; set; }
+
+ [JsonProperty("tokenAddress", Required = Required.Always)]
+ public string TokenAddress { get; set; }
+}
+
+public class Token_ERC20 : Token { }
+
+public class Token_ERC721 : Token { }
+
+public class Token_ERC1155 : Token
+{
+ [JsonProperty("tokenId", Required = Required.Always)]
+ public BigInteger TokenId { get; set; }
+}
+
+public class Event
+{
+ [JsonProperty("chain_id")]
+ public BigInteger ChainId { get; set; }
+
+ [JsonProperty("block_number")]
+ public string BlockNumber { get; set; } = null!;
+
+ [JsonProperty("block_hash")]
+ public string BlockHash { get; set; } = null!;
+
+ [JsonProperty("block_timestamp")]
+ public string BlockTimestamp { get; set; } = null!;
+
+ [JsonProperty("transaction_hash")]
+ public string TransactionHash { get; set; } = null!;
+
+ [JsonProperty("transaction_index")]
+ public BigInteger TransactionIndex { get; set; }
+
+ [JsonProperty("log_index")]
+ public BigInteger LogIndex { get; set; }
+
+ [JsonProperty("address")]
+ public string Address { get; set; } = null!;
+
+ [JsonProperty("data")]
+ public string Data { get; set; } = null!;
+
+ [JsonProperty("topics")]
+ public List Topics { get; set; } = new();
+
+ [JsonProperty("decoded")]
+ public Decoded Decoded { get; set; } = null!;
+}
+
+public class Decoded
+{
+ [JsonProperty("name")]
+ public string Name { get; set; } = null!;
+
+ [JsonProperty("signature")]
+ public string Signature { get; set; } = null!;
+
+ [JsonProperty("indexedParams")]
+ public JObject IndexedParams { get; set; } = new();
+
+ [JsonProperty("nonIndexedParams")]
+ public JObject NonIndexedParams { get; set; } = new();
+}
+
+public class Meta
+{
+ [JsonProperty("chain_ids", Required = Required.Always)]
+ public List ChainIds { get; set; } = new();
+
+ [JsonProperty("address")]
+ public string Address { get; set; }
+
+ [JsonProperty("signature")]
+ public string Signature { get; set; }
+
+ [JsonProperty("page", Required = Required.Always)]
+ public BigInteger Page { get; set; }
+
+ [JsonProperty("limit_per_chain", Required = Required.Always)]
+ public BigInteger LimitPerChain { get; set; }
+
+ [JsonProperty("total_items", Required = Required.Always)]
+ public BigInteger TotalItems { get; set; }
+
+ [JsonProperty("total_pages", Required = Required.Always)]
+ public BigInteger TotalPages { get; set; }
+}
diff --git a/Thirdweb/Thirdweb.Indexer/ThirdwebInsight.cs b/Thirdweb/Thirdweb.Indexer/ThirdwebInsight.cs
new file mode 100644
index 00000000..9b32bf1a
--- /dev/null
+++ b/Thirdweb/Thirdweb.Indexer/ThirdwebInsight.cs
@@ -0,0 +1,262 @@
+using System.Numerics;
+using Newtonsoft.Json;
+
+namespace Thirdweb.Indexer;
+
+public enum SortBy
+{
+ BlockNumber,
+ BlockTimestamp,
+ TransactionIndex,
+}
+
+public enum SortOrder
+{
+ Asc,
+ Desc,
+}
+
+public class InsightEvents
+{
+ public Event[] Events { get; set; }
+ public Meta Meta { get; set; }
+}
+
+public class ThirdwebInsight
+{
+ private readonly IThirdwebHttpClient _httpClient;
+
+ internal ThirdwebInsight(ThirdwebClient client)
+ {
+ this._httpClient = client.HttpClient;
+ }
+
+ ///
+ /// Create a new instance of the ThirdwebInsight class.
+ ///
+ /// The ThirdwebClient instance.
+ /// A new instance of .
+ public static Task Create(ThirdwebClient client)
+ {
+ return Task.FromResult(new ThirdwebInsight(client));
+ }
+
+ ///
+ /// Get the token balances of an address.
+ ///
+ /// The address to get the token balances of.
+ /// The chain IDs to get the token balances from.
+ /// A tuple containing the ERC20, ERC721, and ERC1155 tokens.
+ /// Thrown when the owner address is null or empty.
+ /// Thrown when no chain IDs are provided.
+ public async Task<(Token_ERC20[] erc20Tokens, Token_ERC721[] erc721Tokens, Token_ERC1155[] erc1155Tokens)> GetTokens(string ownerAddress, BigInteger[] chainIds)
+ {
+ if (string.IsNullOrEmpty(ownerAddress))
+ {
+ throw new ArgumentNullException(nameof(ownerAddress));
+ }
+
+ if (chainIds.Length == 0)
+ {
+ throw new ArgumentException("At least one chain ID must be provided.", nameof(chainIds));
+ }
+
+ var erc20Tokens = await this.GetTokens_ERC20(ownerAddress, chainIds).ConfigureAwait(false);
+ var erc721Tokens = await this.GetTokens_ERC721(ownerAddress, chainIds).ConfigureAwait(false);
+ var erc1155Tokens = await this.GetTokens_ERC1155(ownerAddress, chainIds).ConfigureAwait(false);
+ return (erc20Tokens, erc721Tokens, erc1155Tokens);
+ }
+
+ ///
+ /// Get the ERC20 tokens of an address.
+ ///
+ /// The address to get the ERC20 tokens of.
+ /// The chain IDs to get the ERC20 tokens from.
+ /// An array of ERC20 tokens.
+ /// Thrown when the owner address is null or empty.
+ /// /// Thrown when no chain IDs are provided.
+ public async Task GetTokens_ERC20(string ownerAddress, BigInteger[] chainIds)
+ {
+ if (string.IsNullOrEmpty(ownerAddress))
+ {
+ throw new ArgumentNullException(nameof(ownerAddress));
+ }
+
+ if (chainIds.Length == 0)
+ {
+ throw new ArgumentException("At least one chain ID must be provided.", nameof(chainIds));
+ }
+
+ var url = AppendChains($"{Constants.INSIGHT_API_URL}/v1/tokens/erc20/{ownerAddress}", chainIds);
+ var response = await this._httpClient.GetAsync(url).ConfigureAwait(false);
+ _ = response.EnsureSuccessStatusCode();
+ var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
+ return JsonConvert.DeserializeObject>(responseContent).Data;
+ }
+
+ ///
+ /// Get the ERC721 tokens of an address.
+ ///
+ /// The address to get the ERC721 tokens of.
+ /// The chain IDs to get the ERC721 tokens from.
+ /// An array of ERC721 tokens.
+ /// Thrown when the owner address is null or empty.
+ /// /// Thrown when no chain IDs are provided.
+ public async Task GetTokens_ERC721(string ownerAddress, BigInteger[] chainIds)
+ {
+ if (string.IsNullOrEmpty(ownerAddress))
+ {
+ throw new ArgumentNullException(nameof(ownerAddress));
+ }
+
+ if (chainIds.Length == 0)
+ {
+ throw new ArgumentException("At least one chain ID must be provided.", nameof(chainIds));
+ }
+
+ var url = AppendChains($"{Constants.INSIGHT_API_URL}/v1/tokens/erc721/{ownerAddress}", chainIds);
+ var response = await this._httpClient.GetAsync(url).ConfigureAwait(false);
+ _ = response.EnsureSuccessStatusCode();
+ var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
+ return JsonConvert.DeserializeObject>(responseContent).Data;
+ }
+
+ ///
+ /// Get the ERC1155 tokens of an address.
+ ///
+ /// The address to get the ERC1155 tokens of.
+ /// The chain IDs to get the ERC1155 tokens from.
+ /// An array of ERC1155 tokens.
+ /// Thrown when the owner address is null or empty.
+ /// /// Thrown when no chain IDs are provided.
+ public async Task GetTokens_ERC1155(string ownerAddress, BigInteger[] chainIds)
+ {
+ if (string.IsNullOrEmpty(ownerAddress))
+ {
+ throw new ArgumentNullException(nameof(ownerAddress));
+ }
+
+ if (chainIds.Length == 0)
+ {
+ throw new ArgumentException("At least one chain ID must be provided.", nameof(chainIds));
+ }
+
+ var url = AppendChains($"{Constants.INSIGHT_API_URL}/v1/tokens/erc1155/{ownerAddress}", chainIds);
+ var response = await this._httpClient.GetAsync(url).ConfigureAwait(false);
+ _ = response.EnsureSuccessStatusCode();
+ var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
+ return JsonConvert.DeserializeObject>(responseContent).Data;
+ }
+
+ ///
+ /// Get events, optionally filtered by contract address, event signature, and more.
+ ///
+ /// The chain IDs to get the events from.
+ /// The contract address to get the events from. (Optional)
+ /// The event signature to get the events from. (Optional)
+ /// The starting block number to get the events from. (Optional, if provided, said block is included in query)
+ /// The ending block number to get the events from. (Optional, if provided, said block is included in query)
+ /// The starting block timestamp to get the events from. (Optional, if provided, said block is included in query)
+ /// The ending block timestamp to get the events from. (Optional, if provided, said block is included in query)
+ /// The field to sort the events by. (Default: BlockNumber)
+ /// The order to sort the events by. (Default: Desc)
+ /// The number of events to return. (Default: 20)
+ /// The page number to return. (Default: 0)
+ /// Whether to decode the events. (Default: true)
+ /// The events and metadata as an instance of .
+ /// Thrown when an event signature is provided without a contract address.
+ /// /// Thrown when no chain IDs are provided.
+ public async Task GetEvents(
+ BigInteger[] chainIds,
+ string contractAddress = null,
+ string eventSignature = null,
+ BigInteger? fromBlock = null,
+ BigInteger? toBlock = null,
+ BigInteger? fromTimestamp = null,
+ BigInteger? toTimestamp = null,
+ SortBy sortBy = SortBy.BlockNumber,
+ SortOrder sortOrder = SortOrder.Desc,
+ int limit = 20,
+ int page = 0,
+ bool decode = true
+ )
+ {
+ if (!string.IsNullOrEmpty(eventSignature) && string.IsNullOrEmpty(contractAddress))
+ {
+ throw new ArgumentException("Contract address must be provided when event signature is provided.");
+ }
+
+ if (chainIds.Length == 0)
+ {
+ throw new ArgumentException("At least one chain ID must be provided.", nameof(chainIds));
+ }
+
+ var baseUrl = $"{Constants.INSIGHT_API_URL}/v1/events";
+ var url = AppendChains(
+ !string.IsNullOrEmpty(contractAddress)
+ ? !string.IsNullOrEmpty(eventSignature)
+ ? $"{baseUrl}/{contractAddress}/{eventSignature}"
+ : $"{baseUrl}/{contractAddress}"
+ : baseUrl,
+ chainIds
+ );
+
+ url += $"&sort_by={SortByToString(sortBy)}";
+ url += $"&sort_order={SortOrderToString(sortOrder)}";
+ url += $"&limit={limit}";
+ url += $"&page={page}";
+ url += $"&decode={decode}";
+
+ if (fromBlock.HasValue)
+ {
+ url += $"&filter_block_number_gte={fromBlock}";
+ }
+
+ if (toBlock.HasValue)
+ {
+ url += $"&filter_block_number_lte={toBlock}";
+ }
+
+ if (fromTimestamp.HasValue)
+ {
+ url += $"&filter_block_timestamp_gte={fromTimestamp}";
+ }
+
+ if (toTimestamp.HasValue)
+ {
+ url += $"&filter_block_timestamp_lte={toTimestamp}";
+ }
+
+ var response = await this._httpClient.GetAsync(url).ConfigureAwait(false);
+ _ = response.EnsureSuccessStatusCode();
+ var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
+ var result = JsonConvert.DeserializeObject>(responseContent);
+ return new InsightEvents { Events = result.Data, Meta = result.Meta, };
+ }
+
+ private static string AppendChains(string url, BigInteger[] chainIds)
+ {
+ return $"{url}?chain={string.Join("&chain=", chainIds)}";
+ }
+
+ private static string SortByToString(SortBy sortBy)
+ {
+ return sortBy switch
+ {
+ SortBy.BlockNumber => "block_number",
+ SortBy.BlockTimestamp => "block_timestamp",
+ SortBy.TransactionIndex => "transaction_index",
+ _ => throw new ArgumentOutOfRangeException(nameof(sortBy), sortBy, null),
+ };
+ }
+
+ private static string SortOrderToString(SortOrder sortOrder)
+ {
+ return sortOrder switch
+ {
+ SortOrder.Asc => "asc",
+ SortOrder.Desc => "desc",
+ _ => throw new ArgumentOutOfRangeException(nameof(sortOrder), sortOrder, null),
+ };
+ }
+}
diff --git a/Thirdweb/Thirdweb.Utils/Constants.cs b/Thirdweb/Thirdweb.Utils/Constants.cs
index ffdb4060..f4bdfedc 100644
--- a/Thirdweb/Thirdweb.Utils/Constants.cs
+++ b/Thirdweb/Thirdweb.Utils/Constants.cs
@@ -39,6 +39,8 @@ public static class Constants
internal const string NEBULA_API_URL = "https://nebula-api.thirdweb.com";
internal const string NEBULA_DEFAULT_MODEL = "t0-001";
+ internal const string INSIGHT_API_URL = "https://insight.thirdweb.com";
+
internal const string ENTRYPOINT_V06_ABI =
/*lang=json,strict*/
"[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bool\",\"name\":\"targetSuccess\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"targetResult\",\"type\":\"bytes\"}],\"name\":\"ExecutionResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"opIndex\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"name\":\"FailedOp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderAddressResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureValidationFailed\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResult\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"stakeInfo\",\"type\":\"tuple\"}],\"internalType\":\"struct IEntryPoint.AggregatorStakeInfo\",\"name\":\"aggregatorInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResultWithAggregation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"factory\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"}],\"name\":\"AccountDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"BeforeExecution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalDeposit\",\"type\":\"uint256\"}],\"name\":\"Deposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureAggregatorChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalStaked\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"name\":\"StakeLocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawTime\",\"type\":\"uint256\"}],\"name\":\"StakeUnlocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"StakeWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasUsed\",\"type\":\"uint256\"}],\"name\":\"UserOperationEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"revertReason\",\"type\":\"bytes\"}],\"name\":\"UserOperationRevertReason\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SIG_VALIDATION_FAILED\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"}],\"name\":\"_validateSenderAndPaymaster\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"}],\"name\":\"addStake\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getDepositInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"internalType\":\"struct IStakeManager.DepositInfo\",\"name\":\"info\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"}],\"name\":\"getSenderAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"getUserOpHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"userOps\",\"type\":\"tuple[]\"},{\"internalType\":\"contract IAggregator\",\"name\":\"aggregator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.UserOpsPerAggregator[]\",\"name\":\"opsPerAggregator\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleAggregatedOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"ops\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"incrementNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.MemoryUserOp\",\"name\":\"mUserOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"contextOffset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.UserOpInfo\",\"name\":\"opInfo\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"}],\"name\":\"innerHandleOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"\",\"type\":\"uint192\"}],\"name\":\"nonceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"op\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"targetCallData\",\"type\":\"bytes\"}],\"name\":\"simulateHandleOp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"simulateValidation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlockStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"}],\"name\":\"withdrawStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"withdrawAmount\",\"type\":\"uint256\"}],\"name\":\"withdrawTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]";