/** * Paymaster helpers — PaymasterHub address resolution + org registration read. * * The PaymasterHub is a singleton shared across all orgs (one proxy per * chain), so its address comes from the infrastructure query, not the org's * module list. * * Two ways to read an org's paymaster config, and the difference matters: * * readPaymasterOrgConfig() — authoritative eth_call. Use it * wherever the answer decides whether a transaction gets broadcast * (deposit's OrgNotRegistered gate). Subgraph lag there means knowingly * sending a doomed tx. * readPaymasterOrgConfigPreferSubgraph() — subgraph first, but ONLY trusts a * POSITIVE "registered" answer; a negative one is always re-confirmed on * chain before anything is written. The subgraph can lag behind a fresh * registration, it can never invent one, so a positive is safe to trust and * a negative is not. */ import { ethers } from 'ethers'; export interface PaymasterInfra { paymasterHubAddress: string; poaManagerAddress: string | null; } /** Resolve the chain's PaymasterHub proxy (+ PoaManager) from the subgraph. */ export declare function resolvePaymasterInfra(chainId?: number): Promise; export interface PaymasterOrgConfig { adminHatId: ethers.BigNumber; operatorHatId: ethers.BigNumber; paused: boolean; registeredAt: number; bannedFromSolidarity: boolean; registered: boolean; } /** Fee caps in raw contract units (wei per gas / gas units). */ export interface PaymasterFeeCaps { maxFeePerGas: ethers.BigNumber; maxPriorityFeePerGas: ethers.BigNumber; maxCallGas: number; maxVerificationGas: number; maxPreVerificationGas: number; } /** One budget row as the subgraph has it. `totalUsed` is null on the legacy tier. */ export interface PaymasterBudgetRecord { subjectKey: string; capPerEpoch: ethers.BigNumber; usedInEpoch: ethers.BigNumber; epochLen: number; epochStart: number; totalUsed: ethers.BigNumber | null; } export interface PaymasterSubgraphState { /** Hub address the indexer knows about — cross-check before trusting the rest. */ hubAddress: string | null; /** Checksummed to match what ENTRY_POINT() would have returned. */ entryPoint: string | null; orgConfig: PaymasterOrgConfig | null; /** * All-zero when the org row exists but has no PaymasterFeeCaps edge — that is * the contract's "never configured" default, verified against getFeeCaps() on * five orgs across both live deployments. Null only when the org row itself is * missing, in which case the caller must fall back to RPC. */ feeCaps: PaymasterFeeCaps | null; /** Null (not empty) when the org row is missing, so "no budgets" stays distinguishable. */ budgets: PaymasterBudgetRecord[] | null; } /** * Read the hub state the subgraph can serve accurately: the immutable * ENTRY_POINT, the org's OrgConfig, its fee caps and ALL of its budgets. * * Never throws — every failure (unreachable subgraph, chain with no deployment, * unindexed org) degrades to nulls so the caller falls back to eth_calls. * * Financials and the solidarity fund are deliberately NOT here; see the header * of src/queries/paymaster.ts for the measurements that disqualified them. */ export declare function fetchPaymasterSubgraphState(orgId: string, chainId?: number): Promise; /** * True when the indexed hub is the hub we independently resolved. A mismatch * (redeployed hub the indexer has not caught up with, a hand-set * POP_*_SUBGRAPH pointing at another network) means the org row describes a * different contract, so the caller must ignore the whole state object. */ export declare function subgraphMatchesHub(state: PaymasterSubgraphState, hubAddress: string): boolean; /** * Read the hub's OrgConfig for an org. `registered` is derived the same way * the contract does it (adminHatId != 0 — see PaymasterHub._registerOrg). * * Authoritative eth_call. Keep using this one for revert-predicting gates. */ export declare function readPaymasterOrgConfig(provider: ethers.providers.Provider, hubAddress: string, orgId: string): Promise; /** * Registration read for callers that may go on to WRITE. * * Asymmetric on purpose: an indexed registration is trusted (saves the eth_call * on the common "already registered" path), an absent one is re-read on chain * before any decision is made. The subgraph only ever lags reality, so a * false-negative is possible and a false-positive is not — re-confirming just * the negative keeps revert prediction exactly as strong as pure RPC. */ export declare function readPaymasterOrgConfigPreferSubgraph(provider: ethers.providers.Provider, hubAddress: string, orgId: string, chainId?: number): Promise<{ config: PaymasterOrgConfig; source: 'subgraph' | 'rpc'; }>; /** Subject key for a hat-scoped paymaster budget: the hat ID as bytes32. */ export declare function hatSubjectKey(hatId: ethers.BigNumberish): string;