package polymarket import ( "context" "fmt" "net/http" ) // Market represents a single prediction market on Polymarket. type Market struct { ID string Question string Slug string Description string Outcomes []string OutcomePrices []float64 // probabilities 0-1 Volume float64 Volume24h float64 Liquidity float64 EndDate string Active bool Closed bool BestBid float64 BestAsk float64 LastPrice float64 } // URL returns the Polymarket web URL for this market. func (m Market) URL() string { if m.Slug == "" { return "" } return "https://polymarket.com/event/" + m.Slug } // Event represents a prediction market event on Polymarket, which may contain // one or more individual markets. type Event struct { ID string Title string Slug string Description string Markets []Market Volume float64 Volume24h float64 Liquidity float64 Active bool Closed bool } // URL returns the Polymarket web URL for this event. func (e Event) URL() string { if e.Slug == "" { return "" } return "https://polymarket.com/event/" + e.Slug } // Config holds configuration for the Polymarket extractor. type Config struct { // BaseURL overrides the Gamma API base URL. Leave empty for the default. BaseURL string // HTTPClient overrides the HTTP client used for API requests. Leave nil for default. HTTPClient *http.Client } // DefaultConfig is the default configuration. var DefaultConfig = Config{} func (c Config) validate() Config { return c } // Search finds events matching the given query string. func (c Config) Search(ctx context.Context, query string) ([]Event, error) { c = c.validate() return c.searchAPI(ctx, query) } // GetEvent retrieves an event by its slug or numeric ID. func (c Config) GetEvent(ctx context.Context, slugOrID string) (*Event, error) { c = c.validate() // Try slug first (most common from URLs) ev, err := c.getEventBySlug(ctx, slugOrID) if err == nil { return ev, nil } // Fall back to numeric ID ev, idErr := c.getEventByID(ctx, slugOrID) if idErr == nil { return ev, nil } return nil, fmt.Errorf("getting event %q: slug lookup: %w", slugOrID, err) } // GetMarket retrieves a single market by its slug. func (c Config) GetMarket(ctx context.Context, slug string) (*Market, error) { c = c.validate() return c.getMarketBySlug(ctx, slug) } // GetEventFromURL extracts the event slug from a Polymarket URL and retrieves // the event. If the URL points to a specific market within an event, the full // event is still returned. func (c Config) GetEventFromURL(ctx context.Context, rawURL string) (*Event, error) { c = c.validate() _, slug, _, err := parsePolymarketURL(rawURL) if err != nil { return nil, err } return c.getEventBySlug(ctx, slug) } // Convenience functions using DefaultConfig. func Search(ctx context.Context, query string) ([]Event, error) { return DefaultConfig.Search(ctx, query) } func GetEvent(ctx context.Context, slugOrID string) (*Event, error) { return DefaultConfig.GetEvent(ctx, slugOrID) } func GetMarket(ctx context.Context, slug string) (*Market, error) { return DefaultConfig.GetMarket(ctx, slug) } func GetEventFromURL(ctx context.Context, rawURL string) (*Event, error) { return DefaultConfig.GetEventFromURL(ctx, rawURL) }