{
  "$schema": "https://hookforge.pages.dev/schema/hook-manifest.json",
  "slug": "x402-gate",
  "name": "X402Gate",
  "contract": "X402GateHook",
  "version": "1.0.0",
  "family": "Agent-native",
  "summary": "Makes the pool an x402 resource server: a swapper that presents a signed x402 payment gets a cheaper fee on that swap, and the payment settles atomically with the trade.",
  "description": "x402 is how autonomous agents already pay for things. An agent asks for a resource, gets back HTTP 402 with a machine-readable price, signs an EIP-3009 authorization for that amount, retries with the signature in a header, and the resource server settles it. Thousands of endpoints speak it and every agent framework has a client for it. What nothing speaks it for is liquidity, which is odd, because a fee tier is exactly the kind of thing an agent would want to buy: it is metered, it is worth different amounts to different callers, and the caller knows its own value better than the venue does. The usual way to give one class of swapper a better price is to gate on what they *are*: hold this NFT, be on this allowlist, pass this KYC check. Every one of those is a proxy for willingness to pay, maintained by hand, and wrong at the edges. This hook gates on the thing itself. Pay the pool's posted price and the swap is cheaper. Do not, and it is not. Nobody curates anything. Three properties fall out of doing this in the hook rather than over HTTP: The 402 challenge is on-chain. {quote} returns the same fields an x402 client reads out of a 402 response body: scheme, network, amount, asset, recipient, resource, timeout. An agent discovers the price with one `eth_call` against the pool it was already going to trade, with no endpoint to find, no server to be up, and no TLS. Payment and delivery are atomic, which over HTTP they are not. An x402 client that pays for an API call and then receives a 500 has paid for nothing and must argue about a refund. Here the payment settles inside `beforeSwap`, so if the swap reverts for any reason afterwards, slippage, liquidity, another hook, the payment reverts with it. The failure mode that makes x402 awkward to build on does not exist in this direction. There is no facilitator. The x402 deployment model puts a trusted service between payer and resource server to verify and broadcast the authorization. The pool can do both itself, because it is already a contract and the payment is already an on-chain object, so the trusted third party is simply absent rather than decentralized. How the discount is applied matters. The fee this hook returns is an *LP* fee, so the discount is paid for by liquidity providers taking less on that swap, and the payment is what compensates them. Providers are therefore selling cheap execution for a fixed fee up front instead of a variable one on the back end, which is a trade they can price: if the posted price is set below the fee revenue given up, the pool leaks, and setting it is the one judgement the pool creator has to get right. Payments are pulled with `receiveWithAuthorization` rather than `transferWithAuthorization`. Both are EIP-3009 and x402's own reference facilitator uses the latter, but the latter can be broadcast by anyone: a bystander could submit the payer's authorization on its own, the payment would land, the nonce would burn, and the swap that the payment was for would then revert with the payer out of pocket. Requiring `msg.sender == to` removes that. Unrecognised `hookData` is ignored rather than rejected. The payload is prefixed with {X402_PAYMENT_MAGIC}, and anything that does not start with it is treated as \"no payment offered\" and charged the base fee. A pool that reverted on hookData it did not understand would be untradeable through any router that puts its own data there, which is most of them.",
  "priorArt": "Fee discounts gated on NFT or token ownership, allowlists and KYC attestations are among the most common hook patterns, and x402 itself is a widely deployed HTTP payment protocol with an EIP-3009 settlement scheme. Neither has met the other: making an AMM pool an x402 resource server, so that the 402 challenge is an `eth_call` and settlement is atomic with the swap it paid for, is the contribution here.",
  "limitation": "A payment costs a full EIP-3009 transfer, so the discount only repays its own gas above a swap size that depends on the chain and the spread between the two fee tiers. On a mainnet-priced chain that floor is high enough that this is a hook for agents moving real size, not for retail swaps. It also inherits the hookData problem: an aggregator that does not forward hookData cannot present a payment, and its users silently pay the base fee rather than getting an error telling them why.",
  "tags": [
    "agent-native",
    "x402",
    "dynamic-fee",
    "metering"
  ],
  "recommendedChains": [
    "base",
    "arbitrum",
    "unichain",
    "robinhood",
    "ethereum",
    "optimism",
    "polygon"
  ],
  "source": "contracts/src/hooks/X402GateHook.sol",
  "docs": "https://hookforge.pages.dev/hooks/x402-gate",
  "repo": null,
  "site": null,
  "permissions": {
    "afterRemoveLiquidityReturnsDelta": false,
    "afterAddLiquidityReturnsDelta": false,
    "afterSwapReturnsDelta": false,
    "beforeSwapReturnsDelta": false,
    "afterDonate": false,
    "beforeDonate": false,
    "afterSwap": false,
    "beforeSwap": true,
    "afterRemoveLiquidity": false,
    "beforeRemoveLiquidity": false,
    "afterAddLiquidity": false,
    "beforeAddLiquidity": false,
    "afterInitialize": true,
    "beforeInitialize": false
  },
  "permissionsSource": "declaration",
  "properties": {
    "dynamicFee": true,
    "upgradeable": false,
    "requiresCustomSwapData": true,
    "vanillaSwap": true,
    "swapAccess": "none"
  },
  "configure": {
    "signature": "configure((address,address,uint24,int24,address),(address,address,uint256,uint24,uint24))",
    "fields": [
      {
        "name": "asset",
        "type": "address"
      },
      {
        "name": "payTo",
        "type": "address"
      },
      {
        "name": "price",
        "type": "uint256"
      },
      {
        "name": "baseFee",
        "type": "uint24"
      },
      {
        "name": "discountedFee",
        "type": "uint24"
      }
    ]
  },
  "errors": [
    {
      "signature": "DiscountNotADiscount(uint24,uint24)",
      "notice": "A pool posted a discounted fee that is not below its base fee, so paying would buy nothing."
    },
    {
      "signature": "FeeTooLarge(uint24)",
      "notice": "A fee was configured above the protocol maximum of 100%."
    },
    {
      "signature": "HookNotImplemented()",
      "notice": "The hook function is not implemented."
    },
    {
      "signature": "InvalidPool()",
      "notice": "The pool is not configured to use this hook."
    },
    {
      "signature": "InvalidTerms()",
      "notice": "Terms named the zero address as the payment asset or the payee."
    },
    {
      "signature": "NotDynamicFee()",
      "notice": "The hook was attempted to be initialized with a non-dynamic fee."
    },
    {
      "signature": "NothingCollected()",
      "notice": "There is nothing accrued for this pool to withdraw."
    },
    {
      "signature": "PaymentBelowPrice(uint256,uint256)",
      "notice": "The payment offered is smaller than the pool's posted price."
    },
    {
      "signature": "PoolAlreadyInitialized()",
      "notice": "The pool already exists, so its configuration is final."
    },
    {
      "signature": "PoolNotConfigured()",
      "notice": "The pool was initialized without a configuration for this hook."
    },
    {
      "signature": "PriceRequired()",
      "notice": "Terms posted a price of zero, which would make the discount free and the gate pointless."
    },
    {
      "signature": "SafeERC20FailedOperation(address)",
      "notice": "An operation with an ERC-20 token failed."
    }
  ],
  "deployments": [],
  "abi": [
    {
      "type": "constructor",
      "inputs": [
        {
          "name": "_poolManager",
          "type": "address",
          "internalType": "contract IPoolManager"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "QUOTE_TIMEOUT_SECONDS",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "X402_PAYMENT_MAGIC",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "X402_SCHEME",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "string",
          "internalType": "string"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "afterAddLiquidity",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "params",
          "type": "tuple",
          "internalType": "struct ModifyLiquidityParams",
          "components": [
            {
              "name": "tickLower",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "tickUpper",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "liquidityDelta",
              "type": "int256",
              "internalType": "int256"
            },
            {
              "name": "salt",
              "type": "bytes32",
              "internalType": "bytes32"
            }
          ]
        },
        {
          "name": "delta0",
          "type": "int256",
          "internalType": "BalanceDelta"
        },
        {
          "name": "delta1",
          "type": "int256",
          "internalType": "BalanceDelta"
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        },
        {
          "name": "",
          "type": "int256",
          "internalType": "BalanceDelta"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "afterDonate",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "amount0",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "amount1",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "afterInitialize",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "sqrtPriceX96",
          "type": "uint160",
          "internalType": "uint160"
        },
        {
          "name": "tick",
          "type": "int24",
          "internalType": "int24"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "afterRemoveLiquidity",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "params",
          "type": "tuple",
          "internalType": "struct ModifyLiquidityParams",
          "components": [
            {
              "name": "tickLower",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "tickUpper",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "liquidityDelta",
              "type": "int256",
              "internalType": "int256"
            },
            {
              "name": "salt",
              "type": "bytes32",
              "internalType": "bytes32"
            }
          ]
        },
        {
          "name": "delta0",
          "type": "int256",
          "internalType": "BalanceDelta"
        },
        {
          "name": "delta1",
          "type": "int256",
          "internalType": "BalanceDelta"
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        },
        {
          "name": "",
          "type": "int256",
          "internalType": "BalanceDelta"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "afterSwap",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "params",
          "type": "tuple",
          "internalType": "struct SwapParams",
          "components": [
            {
              "name": "zeroForOne",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "amountSpecified",
              "type": "int256",
              "internalType": "int256"
            },
            {
              "name": "sqrtPriceLimitX96",
              "type": "uint160",
              "internalType": "uint160"
            }
          ]
        },
        {
          "name": "delta",
          "type": "int256",
          "internalType": "BalanceDelta"
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        },
        {
          "name": "",
          "type": "int128",
          "internalType": "int128"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "beforeAddLiquidity",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "params",
          "type": "tuple",
          "internalType": "struct ModifyLiquidityParams",
          "components": [
            {
              "name": "tickLower",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "tickUpper",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "liquidityDelta",
              "type": "int256",
              "internalType": "int256"
            },
            {
              "name": "salt",
              "type": "bytes32",
              "internalType": "bytes32"
            }
          ]
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "beforeDonate",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "amount0",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "amount1",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "beforeInitialize",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "sqrtPriceX96",
          "type": "uint160",
          "internalType": "uint160"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "beforeRemoveLiquidity",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "params",
          "type": "tuple",
          "internalType": "struct ModifyLiquidityParams",
          "components": [
            {
              "name": "tickLower",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "tickUpper",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "liquidityDelta",
              "type": "int256",
              "internalType": "int256"
            },
            {
              "name": "salt",
              "type": "bytes32",
              "internalType": "bytes32"
            }
          ]
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "beforeSwap",
      "inputs": [
        {
          "name": "sender",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "params",
          "type": "tuple",
          "internalType": "struct SwapParams",
          "components": [
            {
              "name": "zeroForOne",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "amountSpecified",
              "type": "int256",
              "internalType": "int256"
            },
            {
              "name": "sqrtPriceLimitX96",
              "type": "uint160",
              "internalType": "uint160"
            }
          ]
        },
        {
          "name": "hookData",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes4",
          "internalType": "bytes4"
        },
        {
          "name": "",
          "type": "int256",
          "internalType": "BeforeSwapDelta"
        },
        {
          "name": "",
          "type": "uint24",
          "internalType": "uint24"
        }
      ],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "collected",
      "inputs": [
        {
          "name": "",
          "type": "bytes32",
          "internalType": "PoolId"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "uint256",
          "internalType": "uint256"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "configure",
      "inputs": [
        {
          "name": "key",
          "type": "tuple",
          "internalType": "struct PoolKey",
          "components": [
            {
              "name": "currency0",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "currency1",
              "type": "address",
              "internalType": "Currency"
            },
            {
              "name": "fee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "tickSpacing",
              "type": "int24",
              "internalType": "int24"
            },
            {
              "name": "hooks",
              "type": "address",
              "internalType": "contract IHooks"
            }
          ]
        },
        {
          "name": "terms",
          "type": "tuple",
          "internalType": "struct X402GateHook.Terms",
          "components": [
            {
              "name": "asset",
              "type": "address",
              "internalType": "address"
            },
            {
              "name": "payTo",
              "type": "address",
              "internalType": "address"
            },
            {
              "name": "price",
              "type": "uint256",
              "internalType": "uint256"
            },
            {
              "name": "baseFee",
              "type": "uint24",
              "internalType": "uint24"
            },
            {
              "name": "discountedFee",
              "type": "uint24",
              "internalType": "uint24"
            }
          ]
        }
      ],
      "outputs": [],
      "stateMutability": "nonpayable"
    },
    {
      "type": "function",
      "name": "encodePayment",
      "inputs": [
        {
          "name": "payment",
          "type": "tuple",
          "internalType": "struct X402GateHook.Payment",
          "components": [
            {
              "name": "from",
              "type": "address",
              "internalType": "address"
            },
            {
              "name": "value",
              "type": "uint256",
              "internalType": "uint256"
            },
            {
              "name": "validAfter",
              "type": "uint256",
              "internalType": "uint256"
            },
            {
              "name": "validBefore",
              "type": "uint256",
              "internalType": "uint256"
            },
            {
              "name": "nonce",
              "type": "bytes32",
              "internalType": "bytes32"
            },
            {
              "name": "signature",
              "type": "bytes",
              "internalType": "bytes"
            }
          ]
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bytes",
          "internalType": "bytes"
        }
      ],
      "stateMutability": "pure"
    },
    {
      "type": "function",
      "name": "feeTiers",
      "inputs": [
        {
          "name": "id",
          "type": "bytes32",
          "internalType": "PoolId"
        }
      ],
      "outputs": [
        {
          "name": "baseFee",
          "type": "uint24",
          "internalType": "uint24"
        },
        {
          "name": "discountedFee",
          "type": "uint24",
          "internalType": "uint24"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "getHookPermissions",
      "inputs": [],
      "outputs": [
        {
          "name": "permissions",
          "type": "tuple",
          "internalType": "struct Hooks.Permissions",
          "components": [
            {
              "name": "beforeInitialize",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterInitialize",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "beforeAddLiquidity",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterAddLiquidity",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "beforeRemoveLiquidity",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterRemoveLiquidity",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "beforeSwap",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterSwap",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "beforeDonate",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterDonate",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "beforeSwapReturnDelta",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterSwapReturnDelta",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterAddLiquidityReturnDelta",
              "type": "bool",
              "internalType": "bool"
            },
            {
              "name": "afterRemoveLiquidityReturnDelta",
              "type": "bool",
              "internalType": "bool"
            }
          ]
        }
      ],
      "stateMutability": "pure"
    },
    {
      "type": "function",
      "name": "hookName",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "string",
          "internalType": "string"
        }
      ],
      "stateMutability": "pure"
    },
    {
      "type": "function",
      "name": "hookTags",
      "inputs": [],
      "outputs": [
        {
          "name": "tags",
          "type": "string[]",
          "internalType": "string[]"
        }
      ],
      "stateMutability": "pure"
    },
    {
      "type": "function",
      "name": "hookVersion",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "string",
          "internalType": "string"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "isPoolInitialized",
      "inputs": [
        {
          "name": "id",
          "type": "bytes32",
          "internalType": "PoolId"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bool",
          "internalType": "bool"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "poolManager",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "address",
          "internalType": "contract IPoolManager"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "quote",
      "inputs": [
        {
          "name": "id",
          "type": "bytes32",
          "internalType": "PoolId"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "tuple",
          "internalType": "struct X402GateHook.PaymentRequirements",
          "components": [
            {
              "name": "scheme",
              "type": "string",
              "internalType": "string"
            },
            {
              "name": "network",
              "type": "uint256",
              "internalType": "uint256"
            },
            {
              "name": "maxAmountRequired",
              "type": "uint256",
              "internalType": "uint256"
            },
            {
              "name": "asset",
              "type": "address",
              "internalType": "address"
            },
            {
              "name": "payTo",
              "type": "address",
              "internalType": "address"
            },
            {
              "name": "resource",
              "type": "string",
              "internalType": "string"
            },
            {
              "name": "maxTimeoutSeconds",
              "type": "uint256",
              "internalType": "uint256"
            }
          ]
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "specURI",
      "inputs": [],
      "outputs": [
        {
          "name": "",
          "type": "string",
          "internalType": "string"
        }
      ],
      "stateMutability": "pure"
    },
    {
      "type": "function",
      "name": "supportsInterface",
      "inputs": [
        {
          "name": "interfaceId",
          "type": "bytes4",
          "internalType": "bytes4"
        }
      ],
      "outputs": [
        {
          "name": "",
          "type": "bool",
          "internalType": "bool"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "termsOf",
      "inputs": [
        {
          "name": "",
          "type": "bytes32",
          "internalType": "PoolId"
        }
      ],
      "outputs": [
        {
          "name": "asset",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "payTo",
          "type": "address",
          "internalType": "address"
        },
        {
          "name": "price",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "baseFee",
          "type": "uint24",
          "internalType": "uint24"
        },
        {
          "name": "discountedFee",
          "type": "uint24",
          "internalType": "uint24"
        }
      ],
      "stateMutability": "view"
    },
    {
      "type": "function",
      "name": "withdraw",
      "inputs": [
        {
          "name": "id",
          "type": "bytes32",
          "internalType": "PoolId"
        }
      ],
      "outputs": [],
      "stateMutability": "nonpayable"
    },
    {
      "type": "event",
      "name": "PaymentSettled",
      "inputs": [
        {
          "name": "id",
          "type": "bytes32",
          "indexed": true,
          "internalType": "PoolId"
        },
        {
          "name": "from",
          "type": "address",
          "indexed": true,
          "internalType": "address"
        },
        {
          "name": "value",
          "type": "uint256",
          "indexed": false,
          "internalType": "uint256"
        },
        {
          "name": "nonce",
          "type": "bytes32",
          "indexed": false,
          "internalType": "bytes32"
        }
      ],
      "anonymous": false
    },
    {
      "type": "event",
      "name": "PoolConfigured",
      "inputs": [
        {
          "name": "id",
          "type": "bytes32",
          "indexed": true,
          "internalType": "PoolId"
        },
        {
          "name": "asset",
          "type": "address",
          "indexed": false,
          "internalType": "address"
        },
        {
          "name": "payTo",
          "type": "address",
          "indexed": false,
          "internalType": "address"
        },
        {
          "name": "price",
          "type": "uint256",
          "indexed": false,
          "internalType": "uint256"
        },
        {
          "name": "baseFee",
          "type": "uint24",
          "indexed": false,
          "internalType": "uint24"
        },
        {
          "name": "discountedFee",
          "type": "uint24",
          "indexed": false,
          "internalType": "uint24"
        }
      ],
      "anonymous": false
    },
    {
      "type": "event",
      "name": "Withdrawn",
      "inputs": [
        {
          "name": "id",
          "type": "bytes32",
          "indexed": true,
          "internalType": "PoolId"
        },
        {
          "name": "payTo",
          "type": "address",
          "indexed": true,
          "internalType": "address"
        },
        {
          "name": "amount",
          "type": "uint256",
          "indexed": false,
          "internalType": "uint256"
        }
      ],
      "anonymous": false
    },
    {
      "type": "error",
      "name": "DiscountNotADiscount",
      "inputs": [
        {
          "name": "baseFee",
          "type": "uint24",
          "internalType": "uint24"
        },
        {
          "name": "discountedFee",
          "type": "uint24",
          "internalType": "uint24"
        }
      ]
    },
    {
      "type": "error",
      "name": "FeeTooLarge",
      "inputs": [
        {
          "name": "fee",
          "type": "uint24",
          "internalType": "uint24"
        }
      ]
    },
    {
      "type": "error",
      "name": "HookNotImplemented",
      "inputs": []
    },
    {
      "type": "error",
      "name": "InvalidPool",
      "inputs": []
    },
    {
      "type": "error",
      "name": "InvalidTerms",
      "inputs": []
    },
    {
      "type": "error",
      "name": "NotDynamicFee",
      "inputs": []
    },
    {
      "type": "error",
      "name": "NotPoolManager",
      "inputs": []
    },
    {
      "type": "error",
      "name": "NothingCollected",
      "inputs": []
    },
    {
      "type": "error",
      "name": "PaymentBelowPrice",
      "inputs": [
        {
          "name": "offered",
          "type": "uint256",
          "internalType": "uint256"
        },
        {
          "name": "required",
          "type": "uint256",
          "internalType": "uint256"
        }
      ]
    },
    {
      "type": "error",
      "name": "PoolAlreadyInitialized",
      "inputs": []
    },
    {
      "type": "error",
      "name": "PoolNotConfigured",
      "inputs": []
    },
    {
      "type": "error",
      "name": "PriceRequired",
      "inputs": []
    },
    {
      "type": "error",
      "name": "SafeERC20FailedOperation",
      "inputs": [
        {
          "name": "token",
          "type": "address",
          "internalType": "address"
        }
      ]
    }
  ]
}
