{"version":3,"sources":["../../../src/query/builders/base-query-builder.ts","../../../src/transformers/index.ts","../../../src/query/builders/user-operation-query-builder.ts"],"sourcesContent":["import { SubgraphClient } from '../../client/subgraph-client.js';\nimport { QueryConfig } from '../types.js';\n\n/**\n * Base query builder with common functionality\n *\n * This abstract class provides the foundation for all entity-specific query builders.\n * Each concrete builder must implement the three core methods with proper typing.\n *\n * @template TEntity - The raw entity type from GraphQL (Pool, PaymasterContract, etc.)\n * @template TSerializedEntity - The serialized entity type (SerializedPool, etc.)\n * @template TFields - Union type of available fields for the entity\n * @template TWhereInput - Type for where condition input for the entity\n * @template TOrderBy - Union type of valid orderBy fields\n */\nexport abstract class BaseQueryBuilder<\n  TEntity,\n  TSerializedEntity,\n  TFields extends string,\n  TWhereInput,\n  TOrderBy extends string,\n> {\n  protected config: QueryConfig<TWhereInput, TOrderBy> = {};\n\n  // Safety limits\n  private static readonly MAX_SAFE_LIMIT = 1000;\n  private static readonly DEFAULT_LIMIT = 100;\n\n  constructor(\n    protected client: SubgraphClient,\n    protected entityName: string,\n    defaultOrderBy: TOrderBy,\n    defaultOrderDirection: 'asc' | 'desc' = 'desc'\n  ) {\n    // Basic validation\n    if (!entityName || typeof entityName !== 'string') {\n      throw new Error('Entity name must be a non-empty string');\n    }\n\n    this.entityName = entityName;\n    this.config.orderBy = defaultOrderBy;\n    this.config.orderDirection = defaultOrderDirection;\n  }\n\n  // ========================================\n  // ABSTRACT METHODS - Each builder implements these\n  // ========================================\n\n  /**\n   * Build the GraphQL query string with proper types and validation\n   * Each builder knows its own schema and field types\n   */\n  protected abstract buildDynamicQuery(): string;\n\n  /**\n   * Build variables object with proper type conversion\n   * Each builder handles its own BigInt/string conversions\n   */\n  protected abstract buildVariables(): Record<string, any>;\n\n  /**\n   * Build where clause string with typed fields and validation\n   * Each builder validates its own where conditions\n   */\n  protected abstract buildWhereClauseString(): string;\n\n  /**\n   * Get the serializer function for this entity type\n   * Each builder provides its own serializer from transformers\n   */\n  protected abstract getSerializer(): (entity: TEntity) => TSerializedEntity;\n\n  // ========================================\n  // COMMON FLUENT API METHODS\n  // ========================================\n\n  /**\n   * Select specific fields to be returned\n   * @param fields - Array of field names to select\n   * @returns The query builder instance for chaining\n   */\n  select(fields: TFields[]): this {\n    if (!Array.isArray(fields)) {\n      throw new Error('Fields must be an array');\n    }\n\n    if (fields.length === 0) {\n      throw new Error('Fields array cannot be empty');\n    }\n\n    this.config.selectedFields = fields;\n    return this;\n  }\n\n  /**\n   * Add where conditions to the query\n   * @param where - Object representing where conditions\n   * @returns The query builder instance for chaining\n   */\n  where(where: Partial<TWhereInput>): this {\n    if (typeof where !== 'object' || where === null) {\n      throw new Error('Where conditions must be an object');\n    }\n\n    this.config.where = this.deepMergeWhereConditions(this.config.where || {}, where);\n    return this;\n  }\n\n  private deepMergeWhereConditions(existing: any, newWhere: any): any {\n    const result = { ...existing };\n\n    for (const [key, value] of Object.entries(newWhere)) {\n      if (key.endsWith('_') && typeof value === 'object' && value !== null) {\n        // Deep merge for GraphQL relationship fields (pool_, paymaster_, etc.)\n        if (typeof result[key] === 'object' && result[key] !== null) {\n          result[key] = { ...result[key], ...value };\n        } else {\n          result[key] = value;\n        }\n      } else {\n        result[key] = value;\n      }\n    }\n\n    return result;\n  }\n\n  /**\n   * Limit the number of results\n   * @param limit - Maximum number of results (capped at 1000 for safety)\n   * @returns The query builder instance for chaining\n   */\n  limit(limit: number): this {\n    if (!Number.isInteger(limit) || limit <= 0) {\n      throw new Error('Limit must be a positive integer');\n    }\n\n    const safeLimit = Math.min(limit, BaseQueryBuilder.MAX_SAFE_LIMIT);\n\n    if (safeLimit < limit) {\n      console.warn(`Limit ${limit} exceeds maximum ${BaseQueryBuilder.MAX_SAFE_LIMIT}, using ${safeLimit}`);\n    }\n\n    this.config.first = safeLimit;\n    return this;\n  }\n\n  /**\n   * Skip a number of results for pagination\n   * @param skip - Number of results to skip\n   * @returns The query builder instance for chaining\n   */\n  skip(skip: number): this {\n    if (!Number.isInteger(skip) || skip < 0) {\n      throw new Error('Skip must be a non-negative integer');\n    }\n\n    this.config.skip = skip;\n    return this;\n  }\n\n  /**\n   * Set the ordering for the results\n   * @param orderBy - Field to order by\n   * @param direction - Order direction (\"asc\" or \"desc\")\n   * @returns The query builder instance for chaining\n   */\n  orderBy(orderBy: TOrderBy, direction: 'asc' | 'desc' = 'desc'): this {\n    if (!orderBy || typeof orderBy !== 'string') {\n      throw new Error('OrderBy field must be a non-empty string');\n    }\n\n    if (direction !== 'asc' && direction !== 'desc') {\n      throw new Error('Order direction must be \"asc\" or \"desc\"');\n    }\n\n    this.config.orderBy = orderBy;\n    this.config.orderDirection = direction;\n    return this;\n  }\n\n  // ========================================\n  // EXECUTION METHODS\n  // ========================================\n\n  /**\n   * Execute the query and return raw entities\n   * @returns Promise resolving to an array of TEntity\n   */\n  async execute(): Promise<TEntity[]> {\n    // Apply default limit if none specified\n    if (!this.config.first) {\n      this.config.first = BaseQueryBuilder.DEFAULT_LIMIT;\n    }\n\n    const query = this.buildDynamicQuery();\n    const variables = this.buildVariables();\n    const result = await this.client.executeQuery<{ [key: string]: TEntity[] }>(query, variables);\n\n    const data = result[this.entityName] || [];\n\n    // Warn if hitting limits\n    if (data.length === this.config.first) {\n      console.warn(`Query returned maximum results (${this.config.first}). Consider using pagination.`);\n    }\n\n    return data;\n  }\n\n  /**\n   * Execute the query and return properly typed serialized entities\n   * @returns Promise resolving to an array of TSerializedEntity (not any!)\n   */\n  async executeAndSerialize(): Promise<TSerializedEntity[]> {\n    const rawResults = await this.execute();\n    const serializer = this.getSerializer();\n    return rawResults.map((entity) => serializer(entity));\n  }\n\n  /**\n   * Execute the query and return the first result\n   * @returns Promise resolving to the first TEntity or null\n   */\n  async first(): Promise<TEntity | null> {\n    const originalFirst = this.config.first;\n    this.config.first = 1;\n\n    try {\n      const results = await this.execute();\n      return results.length > 0 ? (results[0] ?? null) : null;\n    } finally {\n      // Always restore original limit\n      this.config.first = originalFirst;\n    }\n  }\n\n  /**\n   * Execute the query and return the first result as serialized entity\n   * @returns Promise resolving to the first TSerializedEntity or null\n   */\n  async firstSerialized(): Promise<TSerializedEntity | null> {\n    const entity = await this.first();\n    if (!entity) return null;\n\n    const serializer = this.getSerializer();\n    return serializer(entity);\n  }\n\n  /**\n   * Execute the query and check if any results exist\n   * @returns Promise resolving to true if any results exist\n   */\n  async exists(): Promise<boolean> {\n    const result = await this.first();\n    return result !== null;\n  }\n\n  /**\n   * Execute the query and return the count of results\n   * Note: This fetches all results and counts them\n   * @returns Promise resolving to the count of matching entities\n   */\n  async count(): Promise<number> {\n    const results = await this.execute();\n    return results.length;\n  }\n\n  /**\n   * Clone the current query builder instance\n   * @returns A new instance of the query builder with the same configuration\n   */\n  clone(): this {\n    // Create new instance using the same constructor\n    const cloned = new (this.constructor as any)(\n      this.client,\n      this.entityName,\n      this.config.orderBy,\n      this.config.orderDirection\n    );\n\n    // Deep clone the configuration\n    cloned.config = {\n      ...this.config,\n      where: this.config.where ? { ...this.config.where } : undefined,\n      selectedFields: this.config.selectedFields ? [...this.config.selectedFields] : undefined,\n    };\n\n    return cloned;\n  }\n\n  // ========================================\n  // UTILITY METHODS\n  // ========================================\n\n  /**\n   * Get current query configuration (for debugging)\n   * @returns Current configuration object\n   */\n  getConfig(): QueryConfig<TWhereInput, TOrderBy> {\n    return { ...this.config };\n  }\n\n  /**\n   * Reset the query builder to default state\n   * @returns The query builder instance for chaining\n   */\n  reset(): this {\n    this.config = {\n      orderBy: this.config.orderBy, // Keep default orderBy\n      orderDirection: this.config.orderDirection, // Keep default direction\n    };\n    return this;\n  }\n}\n","/**\n * Data transformers for the paymaster system (Updated)\n * For the new single-pool-per-contract architecture\n *\n * Handles BigInt serialization/deserialization for:\n * - PaymasterContract (each contract IS a pool)\n * - Activity (unified timeline)\n * - UserOperation (detailed tracking)\n */\n\nimport type {\n  PaymasterContract,\n  SerializedPaymasterContract,\n  Activity,\n  SerializedActivity,\n  UserOperation,\n  SerializedUserOperation,\n} from '../types/subgraph.js';\n\n/**\n * ========================================\n * UTILITY FUNCTIONS\n * ========================================\n */\n\n/**\n * Safely parse a BigInt from a string\n *\n * @param value - String value to parse\n * @returns BigInt value or 0n if invalid\n */\nexport function safeBigIntParse(value: string | number | bigint): bigint {\n  if (typeof value === 'bigint') {\n    return value;\n  }\n\n  if (typeof value === 'number') {\n    return BigInt(Math.floor(value));\n  }\n\n  try {\n    return BigInt(value);\n  } catch (error) {\n    console.warn(`Failed to parse BigInt from value: ${value}`, error);\n    return 0n;\n  }\n}\n\n/**\n * ========================================\n * GENERIC CONVERSION FUNCTIONS\n * ========================================\n */\n\n/**\n * Convert BigInt values to strings recursively\n *\n * @param obj - Entity object to convert\n * @returns Serialized entity with BigInt values as strings\n */\nexport function convertBigIntsToStrings<T>(obj: T): any {\n  if (typeof obj === 'bigint') {\n    return obj.toString();\n  }\n\n  if (obj === null || obj === undefined) {\n    return obj;\n  }\n\n  if (Array.isArray(obj)) {\n    return obj.map((item) => convertBigIntsToStrings(item));\n  }\n\n  if (typeof obj === 'object') {\n    const result: any = {};\n    for (const key in obj) {\n      if (Object.prototype.hasOwnProperty.call(obj, key)) {\n        result[key] = convertBigIntsToStrings(obj[key]);\n      }\n    }\n    return result;\n  }\n\n  return obj;\n}\n\n/**\n * Convert string values back to BigInt for specified fields\n *\n * @param obj - Serialized entity object\n * @param bigIntFields - Array of field names that should be converted to BigInt\n * @returns Entity with BigInt values restored\n */\nexport function convertStringsToBigInts<T>(obj: T, bigIntFields: string[]): any {\n  if (obj === null || obj === undefined) {\n    return obj;\n  }\n\n  if (Array.isArray(obj)) {\n    return obj.map((item) => convertStringsToBigInts(item, bigIntFields));\n  }\n\n  if (typeof obj === 'object') {\n    const result: any = {};\n    for (const key in obj) {\n      if (Object.prototype.hasOwnProperty.call(obj, key)) {\n        if (bigIntFields.includes(key) && typeof obj[key] === 'string') {\n          result[key] = safeBigIntParse(obj[key]);\n        } else if (typeof obj[key] === 'object') {\n          result[key] = convertStringsToBigInts(obj[key], bigIntFields);\n        } else {\n          result[key] = obj[key];\n        }\n      }\n    }\n    return result;\n  }\n\n  return obj;\n}\n\n/**\n * ========================================\n * BIGINT FIELD DEFINITIONS (Updated for new schema)\n * ========================================\n */\n\n// Define which fields are BigInt for each entity type\nconst BIGINT_FIELDS = {\n  paymasterContract: [\n    'chainId',\n    'joiningAmount',\n    'scope',\n    'totalDeposit',\n    'currentDeposit',\n    'revenue',\n    'root',\n    'rootIndex',\n    'treeDepth',\n    'treeSize',\n    'deployedBlock',\n    'deployedTimestamp',\n    'lastBlock',\n    'lastTimestamp',\n  ],\n  activity: [\n    'chainId',\n    'block',\n    'timestamp',\n    // Optional BigInt fields (based on activity type)\n    'commitment',\n    'memberIndex',\n    'newRoot',\n    'actualGasCost',\n    'amount',\n  ],\n  userOperation: ['chainId', 'actualGasCost', 'nullifier', 'block', 'timestamp'],\n};\n\n/**\n * ========================================\n * SERIALIZATION FUNCTIONS (Updated)\n * ========================================\n */\n\nexport function serializePaymasterContract(entity: PaymasterContract): SerializedPaymasterContract {\n  return convertBigIntsToStrings(entity);\n}\n\nexport function serializeActivity(entity: Activity): SerializedActivity {\n  return convertBigIntsToStrings(entity);\n}\n\nexport function serializeUserOperation(entity: UserOperation): SerializedUserOperation {\n  return convertBigIntsToStrings(entity);\n}\n\n/**\n * ========================================\n * DESERIALIZATION FUNCTIONS (Updated)\n * ========================================\n */\n\nexport function deserializePaymasterContract(entity: SerializedPaymasterContract): PaymasterContract {\n  return convertStringsToBigInts(entity, BIGINT_FIELDS.paymasterContract);\n}\n\nexport function deserializeActivity(entity: SerializedActivity): Activity {\n  return convertStringsToBigInts(entity, BIGINT_FIELDS.activity);\n}\n\nexport function deserializeUserOperation(entity: SerializedUserOperation): UserOperation {\n  return convertStringsToBigInts(entity, BIGINT_FIELDS.userOperation);\n}\n\n/**\n * ========================================\n * CONVENIENCE EXPORTS (Updated)\n * ========================================\n */\n\n/**\n * All serialization functions\n */\nexport const serializers = {\n  paymasterContract: serializePaymasterContract,\n  activity: serializeActivity,\n  userOperation: serializeUserOperation,\n};\n\n/**\n * All deserialization functions\n */\nexport const deserializers = {\n  paymasterContract: deserializePaymasterContract,\n  activity: deserializeActivity,\n  userOperation: deserializeUserOperation,\n};\n\n/**\n * ========================================\n * ACTIVITY-SPECIFIC HELPERS\n * ========================================\n */\n\n/**\n * Serialize activities with type-specific field handling\n *\n * @param activities - Array of activities to serialize\n * @returns Serialized activities with proper BigInt conversion\n */\nexport function serializeActivities(activities: Activity[]): SerializedActivity[] {\n  return activities.map(serializeActivity);\n}\n\n/**\n * Deserialize activities with type-specific field handling\n *\n * @param activities - Array of serialized activities\n * @returns Activities with BigInt fields restored\n */\nexport function deserializeActivities(activities: SerializedActivity[]): Activity[] {\n  return activities.map(deserializeActivity);\n}\n\n/**\n * ========================================\n * ANALYTICS HELPERS\n * ========================================\n */\n\n/**\n * Calculate analytics from activity data (no BigInt conversion needed)\n *\n * @param activities - Activities to analyze\n * @returns Analytics summary with proper BigInt types\n */\nexport function calculatePaymasterAnalytics(activities: Activity[]): {\n  totalDeposits: bigint;\n  totalUserOperations: bigint;\n  totalGasSponsored: bigint;\n  totalRevenueWithdrawn: bigint;\n  averageGasPerOperation: bigint;\n} {\n  let totalDeposits = 0n;\n  let totalUserOperations = 0n;\n  let totalGasSponsored = 0n;\n  let totalRevenueWithdrawn = 0n;\n\n  for (const activity of activities) {\n    switch (activity.type) {\n      case 'DEPOSIT':\n        totalDeposits++;\n        break;\n      case 'USER_OP_SPONSORED':\n        totalUserOperations++;\n        if (activity.actualGasCost) {\n          totalGasSponsored += activity.actualGasCost;\n        }\n        break;\n      case 'REVENUE_WITHDRAWN':\n        if (activity.amount) {\n          totalRevenueWithdrawn += activity.amount;\n        }\n        break;\n    }\n  }\n\n  const averageGasPerOperation = totalUserOperations > 0n ? totalGasSponsored / totalUserOperations : 0n;\n\n  return {\n    totalDeposits,\n    totalUserOperations,\n    totalGasSponsored,\n    totalRevenueWithdrawn,\n    averageGasPerOperation,\n  };\n}\n","/**\n * Query builder for UserOperation entities\n * For detailed user operation tracking and analytics\n */\n\nimport type { SubgraphClient } from '../../client/subgraph-client.js';\nimport type { UserOperation, SerializedUserOperation } from '../../types/subgraph.js';\nimport { BaseQueryBuilder } from './base-query-builder.js';\nimport { UserOperationFields, UserOperationWhereInput, UserOperationOrderBy } from '../types.js';\nimport { serializeUserOperation } from '../../transformers/index.js';\nimport { PaymasterType } from '@prepaid-gas/constants';\n\n/**\n * Query builder for UserOperation entities\n *\n * Provides a fluent interface for building complex user operation queries\n * with support for paymaster filtering, gas analysis, and nullifier tracking.\n */\nexport class UserOperationQueryBuilder extends BaseQueryBuilder<\n  UserOperation,\n  SerializedUserOperation,\n  UserOperationFields,\n  UserOperationWhereInput,\n  UserOperationOrderBy\n> {\n  constructor(private subgraphClient: SubgraphClient) {\n    super(subgraphClient, 'userOperations', 'timestamp', 'desc');\n  }\n\n  protected buildDynamicQuery(): string {\n    const fields = this.config.selectedFields?.join('\\n        ') || this.getDefaultFields();\n    const variables = this.getVariableDeclarations();\n    const whereClause = this.buildWhereClauseString();\n    const orderByClause = this.config.orderBy ? `orderBy: ${this.config.orderBy}` : '';\n    const orderDirectionClause = this.config.orderDirection ? `orderDirection: ${this.config.orderDirection}` : '';\n\n    const args = [whereClause, orderByClause, orderDirectionClause, 'first: $first', 'skip: $skip']\n      .filter(Boolean)\n      .join(', ');\n\n    const queryName = `GetUserOperations`;\n\n    return `\n      query ${queryName}(${variables}) {\n        userOperations(${args}) {\n          ${fields}\n        }\n      }\n    `;\n  }\n\n  protected buildVariables(): Record<string, any> {\n    const variables: Record<string, any> = {\n      first: this.config.first || 100,\n      skip: this.config.skip || 0,\n    };\n\n    if (this.config.where) {\n      this.addWhereVariables(this.config.where, variables);\n    }\n\n    return variables;\n  }\n\n  protected buildWhereClauseString(): string {\n    if (!this.config.where || Object.keys(this.config.where).length === 0) {\n      return '';\n    }\n\n    const conditions = this.buildWhereConditions(this.config.where);\n    return conditions.length > 0 ? `where: { ${conditions.join(', ')} }` : '';\n  }\n\n  protected getSerializer(): (entity: UserOperation) => SerializedUserOperation {\n    return serializeUserOperation;\n  }\n\n  private getVariableDeclarations(): string {\n    const declarations = ['$first: Int!', '$skip: Int!'];\n\n    if (this.config.where) {\n      this.addVariableDeclarations(this.config.where, declarations);\n    }\n\n    return declarations.join(', ');\n  }\n\n  private addVariableDeclarations(where: Partial<UserOperationWhereInput>, declarations: string[]): void {\n    for (const [key, value] of Object.entries(where)) {\n      switch (key) {\n        case 'id':\n          declarations.push('$id: ID');\n          break;\n        case 'hash':\n          declarations.push('$hash: String');\n          break;\n        case 'network':\n          declarations.push('$network: String');\n          break;\n        case 'paymaster':\n          declarations.push('$paymaster: String');\n          break;\n        case 'sender':\n          declarations.push('$sender: String');\n          break;\n        case 'nullifier':\n          declarations.push('$nullifier: String');\n          break;\n        case 'actualGasCost_gte':\n        case 'actualGasCost_lte':\n          declarations.push(`$${key}: String`);\n          break;\n        case 'block_gte':\n        case 'block_lte':\n          declarations.push(`$${key}: String`);\n          break;\n        case 'timestamp_gte':\n        case 'timestamp_lte':\n          declarations.push(`$${key}: String`);\n          break;\n        case 'paymaster_':\n          if (typeof value === 'object' && value) {\n            if ('address' in value) {\n              declarations.push('$paymasterAddress: String');\n            }\n            if ('contractType' in value) {\n              declarations.push('$paymasterContractType: String');\n            }\n            if ('network' in value) {\n              declarations.push('$paymasterNetwork: String');\n            }\n          }\n          break;\n      }\n    }\n  }\n\n  private addWhereVariables(where: Partial<UserOperationWhereInput>, variables: Record<string, any>): void {\n    for (const [key, value] of Object.entries(where)) {\n      switch (key) {\n        case 'id':\n        case 'hash':\n        case 'network':\n        case 'paymaster':\n        case 'sender':\n        case 'nullifier':\n        case 'actualGasCost_gte':\n        case 'actualGasCost_lte':\n        case 'block_gte':\n        case 'block_lte':\n        case 'timestamp_gte':\n        case 'timestamp_lte':\n          variables[key] = value;\n          break;\n        case 'paymaster_':\n          if (typeof value === 'object' && value) {\n            if ('address' in value) {\n              variables.paymasterAddress = value.address;\n            }\n            if ('contractType' in value) {\n              variables.paymasterContractType = value.contractType;\n            }\n            if ('network' in value) {\n              variables.paymasterNetwork = value.network;\n            }\n          }\n          break;\n      }\n    }\n  }\n\n  private buildWhereConditions(where: Partial<UserOperationWhereInput>): string[] {\n    const conditions: string[] = [];\n\n    for (const [key, value] of Object.entries(where)) {\n      switch (key) {\n        case 'paymaster_':\n          if (typeof value === 'object' && value) {\n            const nestedConditions: string[] = [];\n            if ('address' in value) {\n              nestedConditions.push('address: $paymasterAddress');\n            }\n            if ('contractType' in value) {\n              nestedConditions.push('contractType: $paymasterContractType');\n            }\n            if ('network' in value) {\n              nestedConditions.push('network: $paymasterNetwork');\n            }\n            if (nestedConditions.length > 0) {\n              conditions.push(`paymaster_: { ${nestedConditions.join(', ')} }`);\n            }\n          }\n          break;\n        default:\n          conditions.push(`${key}: $${key}`);\n          break;\n      }\n    }\n\n    return conditions;\n  }\n\n  /**\n   * Override default fields for UserOperation entity.\n   */\n  protected getDefaultFields(): string {\n    return `\n    id\n    hash\n    network\n    chainId\n    sender\n    actualGasCost\n    nullifier\n    block\n    transaction\n    timestamp\n    \n    # Paymaster relation\n    paymaster {\n      id\n      address\n      contractType\n      network\n    }\n  `;\n  }\n\n  /**\n   * ========================================\n   * FILTERING METHODS\n   * ========================================\n   */\n\n  /**\n   * Filter by network\n   */\n  byNetwork(network: string): this {\n    this.where({ network: network });\n    return this;\n  }\n\n  /**\n   * Filter by user operation hash\n   */\n  byHash(hash: string): this {\n    this.where({ hash: hash });\n    return this;\n  }\n\n  /**\n   * Filter by composite ID (network-contractAddress-userOpHash)\n   */\n  byId(id: string): this {\n    this.where({ id: id });\n    return this;\n  }\n\n  /**\n   * Filter by paymaster ID\n   */\n  byPaymaster(paymasterId: string): this {\n    this.where({ paymaster: paymasterId });\n    return this;\n  }\n\n  /**\n   * Filter by paymaster address\n   */\n  byPaymasterAddress(address: string): this {\n    this.where({ paymaster_: { address: address } });\n    return this;\n  }\n\n  /**\n   * Filter by paymaster contract type\n   */\n  byPaymasterType(contractType: PaymasterType): this {\n    this.where({ paymaster_: { contractType: contractType } });\n    return this;\n  }\n\n  /**\n   * Filter by sender address\n   */\n  bySender(sender: string): this {\n    this.where({ sender: sender });\n    return this;\n  }\n\n  /**\n   * Filter by nullifier\n   */\n  byNullifier(nullifier: string): this {\n    this.where({ nullifier: nullifier });\n    return this;\n  }\n\n  /**\n   * Filter by minimum gas cost\n   */\n  withMinGasCost(minGasCost: string): this {\n    this.where({ actualGasCost_gte: minGasCost });\n    return this;\n  }\n\n  /**\n   * Filter by maximum gas cost\n   */\n  withMaxGasCost(maxGasCost: string): this {\n    this.where({ actualGasCost_lte: maxGasCost });\n    return this;\n  }\n\n  /**\n   * Filter user operations after timestamp\n   */\n  afterTimestamp(timestamp: string | number): this {\n    this.where({ timestamp_gte: timestamp.toString() });\n    return this;\n  }\n\n  /**\n   * Filter user operations before timestamp\n   */\n  beforeTimestamp(timestamp: string | number): this {\n    this.where({ timestamp_lte: timestamp.toString() });\n    return this;\n  }\n\n  /**\n   * Filter user operations after block\n   */\n  afterBlock(block: string | number): this {\n    this.where({ block_gte: block.toString() });\n    return this;\n  }\n\n  /**\n   * Filter user operations before block\n   */\n  beforeBlock(block: string | number): this {\n    this.where({ block_lte: block.toString() });\n    return this;\n  }\n\n  /**\n   * Filter user operations within a time range\n   */\n  betweenTimestamps(startTimestamp: string | number, endTimestamp: string | number): this {\n    this.afterTimestamp(startTimestamp);\n    this.beforeTimestamp(endTimestamp);\n    return this;\n  }\n\n  /**\n   * Filter user operations within a block range\n   */\n  betweenBlocks(startBlock: string | number, endBlock: string | number): this {\n    this.afterBlock(startBlock);\n    this.beforeBlock(endBlock);\n    return this;\n  }\n\n  /**\n   * ========================================\n   * ORDERING METHODS\n   * ========================================\n   */\n\n  /**\n   * Order by timestamp (most recent first by default)\n   */\n  orderByTimestamp(direction: 'asc' | 'desc' = 'desc'): this {\n    this.orderBy('timestamp', direction);\n    return this;\n  }\n\n  /**\n   * Order by block number\n   */\n  orderByBlock(direction: 'asc' | 'desc' = 'desc'): this {\n    this.orderBy('block', direction);\n    return this;\n  }\n\n  /**\n   * Order by gas cost (highest first by default)\n   */\n  orderByGasCost(direction: 'asc' | 'desc' = 'desc'): this {\n    this.orderBy('actualGasCost', direction);\n    return this;\n  }\n\n  /**\n   * Order by sender address\n   */\n  orderBySender(direction: 'asc' | 'desc' = 'asc'): this {\n    this.orderBy('sender', direction);\n    return this;\n  }\n\n  /**\n   * Order by nullifier\n   */\n  orderByNullifier(direction: 'asc' | 'desc' = 'asc'): this {\n    this.orderBy('nullifier', direction);\n    return this;\n  }\n\n  /**\n   * ========================================\n   * ANALYTICS METHODS\n   * ========================================\n   */\n\n  /**\n   * Get gas statistics for user operations\n   */\n  async getGasStatistics(): Promise<{\n    totalOperations: number;\n    totalGasCost: string;\n    averageGasCost: string;\n    minGasCost: string;\n    maxGasCost: string;\n    medianGasCost: string;\n  }> {\n    const operations = await this.execute();\n\n    const totalOperations = operations.length;\n    const totalGasCost = operations.reduce((sum, op) => sum + BigInt(op.actualGasCost), 0n);\n\n    const averageGasCost = totalOperations > 0 ? totalGasCost / BigInt(totalOperations) : 0n;\n\n    // Find min and max gas costs\n    const gasCosts = operations.map((op) => BigInt(op.actualGasCost));\n    const minGasCost = gasCosts.length > 0 ? gasCosts.reduce((min, cost) => (cost < min ? cost : min)) : 0n;\n    const maxGasCost = gasCosts.length > 0 ? gasCosts.reduce((max, cost) => (cost > max ? cost : max)) : 0n;\n\n    // Calculate median gas cost\n    const sortedGasCosts = gasCosts.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n    const medianGasCost = sortedGasCosts.length > 0 ? sortedGasCosts[Math.floor(sortedGasCosts.length / 2)] : 0n;\n\n    return {\n      totalOperations,\n      totalGasCost: totalGasCost.toString(),\n      averageGasCost: averageGasCost.toString(),\n      minGasCost: minGasCost.toString(),\n      maxGasCost: maxGasCost.toString(),\n      medianGasCost: medianGasCost?.toString() ?? '0',\n    };\n  }\n\n  /**\n   * Get user operation timeline\n   */\n  async getOperationTimeline(days: number = 30): Promise<\n    Array<{\n      date: string;\n      operations: number;\n      totalGasCost: string;\n      averageGasCost: string;\n      uniqueSenders: number;\n    }>\n  > {\n    const endTime = Math.floor(Date.now() / 1000);\n    const startTime = endTime - days * 24 * 60 * 60;\n\n    const operations = await this.afterTimestamp(startTime).orderByTimestamp('asc').execute();\n\n    // Group by date\n    const timeline: Record<\n      string,\n      {\n        operations: number;\n        totalGasCost: bigint;\n        senders: Set<string>;\n      }\n    > = {};\n\n    for (const op of operations) {\n      const date = new Date(Number(op.timestamp) * 1000).toISOString().split('T')[0]!;\n\n      if (!timeline[date]) {\n        timeline[date] = {\n          operations: 0,\n          totalGasCost: 0n,\n          senders: new Set(),\n        };\n      }\n\n      timeline[date].operations += 1;\n      timeline[date].totalGasCost += BigInt(op.actualGasCost);\n      timeline[date].senders.add(op.sender);\n    }\n\n    return Object.entries(timeline).map(([date, stats]) => ({\n      date,\n      operations: stats.operations,\n      totalGasCost: stats.totalGasCost.toString(),\n      averageGasCost: stats.operations > 0 ? (stats.totalGasCost / BigInt(stats.operations)).toString() : '0',\n      uniqueSenders: stats.senders.size,\n    }));\n  }\n\n  /**\n   * Get sender analysis\n   */\n  async getSenderAnalysis(): Promise<\n    Array<{\n      sender: string;\n      operationCount: number;\n      totalGasCost: string;\n      averageGasCost: string;\n      firstOperation: string;\n      lastOperation: string;\n    }>\n  > {\n    const operations = await this.execute();\n\n    // Group by sender\n    const senderStats: Record<\n      string,\n      {\n        operationCount: number;\n        totalGasCost: bigint;\n        timestamps: number[];\n      }\n    > = {};\n\n    for (const op of operations) {\n      const currentSenderStats = senderStats[op.sender] || {\n        operationCount: 0,\n        totalGasCost: 0n,\n        timestamps: [],\n      };\n\n      currentSenderStats.operationCount += 1;\n      currentSenderStats.totalGasCost += BigInt(op.actualGasCost);\n\n      const timestamp = Number(op.timestamp);\n      if (!isNaN(timestamp)) {\n        currentSenderStats.timestamps.push(timestamp);\n      }\n\n      senderStats[op.sender] = currentSenderStats;\n    }\n\n    return Object.entries(senderStats)\n      .map(([sender, stats]) => {\n        const sortedTimestamps = (stats.timestamps ?? []).sort((a, b) => a - b);\n        const averageGasCost = stats.operationCount > 0 ? stats.totalGasCost / BigInt(stats.operationCount) : 0n;\n\n        return {\n          sender,\n          operationCount: stats.operationCount,\n          totalGasCost: stats.totalGasCost.toString(),\n          averageGasCost: averageGasCost.toString(),\n          firstOperation: sortedTimestamps.length > 0 ? (sortedTimestamps[0]?.toString() ?? '0') : '0',\n          lastOperation:\n            sortedTimestamps.length > 0 ? (sortedTimestamps[sortedTimestamps.length - 1]?.toString() ?? '0') : '0',\n        };\n      })\n      .sort((a, b) => b.operationCount - a.operationCount);\n  }\n}\n\n/**\n * ========================================\n * CONVENIENCE FUNCTIONS\n * ========================================\n */\n\n/**\n * Get user operation by hash\n */\nexport async function getUserOperationByHash(\n  client: SubgraphClient,\n  hash: string,\n  network: string\n): Promise<UserOperation | null> {\n  return new UserOperationQueryBuilder(client).byNetwork(network).byHash(hash).first();\n}\n\n/**\n * Get recent user operations\n */\nexport async function getRecentUserOperations(\n  client: SubgraphClient,\n  network: string,\n  limit: number = 10\n): Promise<UserOperation[]> {\n  return new UserOperationQueryBuilder(client).byNetwork(network).orderByTimestamp().limit(limit).execute();\n}\n\n/**\n * Get user operations by sender\n */\nexport async function getUserOperationsBySender(\n  client: SubgraphClient,\n  sender: string,\n  network: string\n): Promise<UserOperation[]> {\n  return new UserOperationQueryBuilder(client).byNetwork(network).bySender(sender).orderByTimestamp().execute();\n}\n\n/**\n * Get user operations by paymaster\n */\nexport async function getUserOperationsByPaymaster(\n  client: SubgraphClient,\n  paymasterAddress: string,\n  network: string\n): Promise<UserOperation[]> {\n  return new UserOperationQueryBuilder(client)\n    .byNetwork(network)\n    .byPaymasterAddress(paymasterAddress)\n    .orderByTimestamp()\n    .execute();\n}\n\n/**\n * Get expensive user operations (high gas cost)\n */\nexport async function getExpensiveUserOperations(\n  client: SubgraphClient,\n  network: string,\n  minGasCost: string,\n  limit: number = 10\n): Promise<UserOperation[]> {\n  return new UserOperationQueryBuilder(client)\n    .byNetwork(network)\n    .withMinGasCost(minGasCost)\n    .orderByGasCost()\n    .limit(limit)\n    .execute();\n}\n"],"mappings":"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","names":[]}