get_events_guide
Obtain Solidity code to subscribe to Pythia Oracle indicator alerts. The returned contract handles LINK approval, event subscription, listening, and cancellation with refund.
Instructions
Get Solidity code to subscribe to Pythia Events (indicator alerts).
Returns a complete contract that approves LINK, subscribes to an indicator alert, listens for PythiaEvent, and can cancel for a refund.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/pythia_oracle_mcp/server.py:687-789 (handler)The get_events_guide() tool function that returns Solidity code to subscribe to Pythia Events (indicator alerts). It fetches live data, extracts event registry addresses, and returns a complete Solidity integration contract.
@mcp.tool() async def get_events_guide() -> str: """Get Solidity code to subscribe to Pythia Events (indicator alerts). Returns a complete contract that approves LINK, subscribes to an indicator alert, listens for PythiaEvent, and can cancel for a refund. """ data = await _fetch_data() events = data.get("events", {}) if data else {} mainnet = _get_mainnet(data) link_token = mainnet["link_token"] registries = events.get("registries", []) mainnet_reg = next((r for r in registries if r["chain"] == "mainnet"), None) amoy_reg = next((r for r in registries if r["chain"] == "amoy"), None) mainnet_addr = mainnet_reg["address"] if mainnet_reg else "CHECK_WEBSITE" amoy_addr = amoy_reg["address"] if amoy_reg else "CHECK_WEBSITE" return f"""Pythia Events Integration — On-Chain Indicator Alerts Registry (Mainnet): {mainnet_addr} Registry (Amoy): {amoy_addr} LINK Token: {link_token} ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol"; import "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol"; interface IPythiaEventRegistry {{ function subscribe(string calldata feedName, uint16 numDays, uint8 condition, int256 threshold) external returns (uint256 eventId); function cancelSubscription(uint256 eventId) external; function getCost(uint16 numDays) external view returns (uint256); function isActive(uint256 eventId) external view returns (bool); }} contract MyEventSubscriber is ConfirmedOwner {{ LinkTokenInterface public immutable LINK; IPythiaEventRegistry public registry; uint256 public lastEventId; event Subscribed(uint256 indexed eventId, string feed); event Cancelled(uint256 indexed eventId); constructor(address _link, address _registry) ConfirmedOwner(msg.sender) {{ LINK = LinkTokenInterface(_link); registry = IPythiaEventRegistry(_registry); }} /// @notice Subscribe to an indicator alert. Fund this contract with LINK first. /// @param feedName e.g. "pol_RSI_5M_14" /// @param numDays 1-365 /// @param condition 0=ABOVE, 1=BELOW /// @param threshold 8 decimals (e.g. RSI 30 = 3000000000) function subscribe( string calldata feedName, uint16 numDays, uint8 condition, int256 threshold ) external onlyOwner returns (uint256 eventId) {{ uint256 cost = registry.getCost(numDays); LINK.approve(address(registry), cost); eventId = registry.subscribe(feedName, numDays, condition, threshold); lastEventId = eventId; emit Subscribed(eventId, feedName); }} /// @notice Cancel subscription. Remaining whole days refunded in LINK. function cancel(uint256 eventId) external onlyOwner {{ registry.cancelSubscription(eventId); emit Cancelled(eventId); }} function isActive(uint256 eventId) external view returns (bool) {{ return registry.isActive(eventId); }} function withdrawLink() external onlyOwner {{ LINK.transfer(msg.sender, LINK.balanceOf(address(this))); }} }} ``` Steps: 1. Deploy with (_link, _registry) for your target chain 2. Fund the contract with LINK (e.g. 7 LINK for 7 days) 3. Call subscribe("pol_RSI_5M_14", 7, 1, 3000000000) → condition 1 = BELOW, threshold = RSI 30 (8 decimals) 4. Note the returned eventId 5. Listen for PythiaEvent(eventId) on the registry contract via RPC 6. When fired: the condition was met, react in your protocol Conditions: 0=ABOVE, 1=BELOW (active). 2=CROSSES_ABOVE, 3=CROSSES_BELOW (future). Threshold: 8 decimal places. RSI 30 = 3000000000, RSI 70 = 7000000000. Refund: unused whole days returned in LINK on fire or cancel. Deployment addresses: Mainnet: _link={link_token}, _registry={mainnet_addr} Amoy: _link=0x0Fd9e8d3aF1aaee056EB9e802c3A762a667b1904, _registry={amoy_addr}""" - src/pythia_oracle_mcp/server.py:633-684 (registration)Registration of get_events_guide() via @mcp.tool() decorator (line 687) along with related events tools. The get_events_info() tool (registered at line 633) references get_events_guide() in its output, showing they are part of the same events tool group.
@mcp.tool() async def get_events_info() -> str: """Get overview of Pythia Events — on-chain indicator alert subscriptions. Returns pricing, supported conditions, subscriber flow, registry addresses per chain, and current subscription stats. Events let you subscribe once and get notified when an indicator crosses a threshold. """ data = await _fetch_data() events = data.get("events", {}) if data else {} if not events: return ("Pythia Events info not available. " "Visit https://pythia.c3x-solutions.com for details.") lines = ["Pythia Events — On-Chain Indicator Alerts\n"] lines.append("Subscribe once, get notified when your condition is met.") lines.append("One-shot: fires once, remaining whole days refunded in LINK.\n") lines.append(f"Pricing: {events.get('pricing', '?')}") lines.append(f"Max duration: {events.get('max_days', 365)} days") lines.append(f"Threshold scale: {events.get('threshold_scale', '?')}") lines.append(f"Refund policy: {events.get('refund', '?')}\n") conditions = events.get("conditions", {}) active = conditions.get("active", []) future = conditions.get("future", []) lines.append("Conditions:") for c in active: lines.append(f" {c} [active]") for c in future: lines.append(f" {c} [future — accepted, not yet processed]") lines.append("") lines.append("Subscriber Flow:") for i, step in enumerate(events.get("subscriber_flow", []), 1): lines.append(f" {i}. {step}") lines.append("") registries = events.get("registries", []) if registries: lines.append("Event Registry Contracts:") for reg in registries: lines.append(f" {reg['chain']}: {reg['address']}") lines.append("") stats = events.get("stats", {}) active_subs = stats.get("active_subscriptions", 0) total_subs = stats.get("total_subscriptions", 0) lines.append(f"Stats: {active_subs} active / {total_subs} total subscriptions") lines.append("\nUse get_events_guide() for Solidity integration code.") lines.append("Use subscribe_info() to plan a specific subscription.") return "\n".join(lines)