> For the complete documentation index, see [llms.txt](https://docs.gensyn.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.gensyn.ai/tech/delphi-sdk/subgraph.md).

# Subgraph

## Overview

The Delphi SDK includes a `SubgraphClient` that queries on-chain event data indexed by a [Goldsky subgraph.](https://docs.goldsky.com/subgraphs/introduction)

This gives read-only access to historical *buys, sells, redemptions, liquidations,* and *settlements* without needing an archive node or parsing raw logs.

{% hint style="info" %}
For more information on using Goldsky to build on Gensyn, [click here.](https://docs.gensyn.network/builders/goldsky)
{% endhint %}

### Accessing the Subgraph Client

`getSubgraph()` returns a `SubgraphClient` instance configured with the correct Goldsky endpoint for the active network.

```typescript
import { DelphiClient } from "@gensyn-ai/gensyn-delphi-sdk";

const client = new DelphiClient();
const subgraph = client.getSubgraph();
```

#### URL Resolution Order

1. `config.subgraphUrl` (constructor option on `DelphiClient`)
2. `DELPHI_SUBGRAPH_URL` environment variable
3. Network default

| Network             | Default endpoint                                                                                                   |
| ------------------- | ------------------------------------------------------------------------------------------------------------------ |
| Testnet             | `https://api.goldsky.com/api/public/project_cmnoqdag1obop01z3efnu8ssq/subgraphs/delphi-testnet-autoset/1.0.0/gn`   |
| Mainnet             | `https://api.goldsky.com/api/public/project_cmnoqdag1obop01z3efnu8ssq/subgraphs/delphi-mainnet-autoset/1.0.0/gn`   |
| Competition testnet | `https://api.goldsky.com/api/public/project_cmnoqdag1obop01z3efnu8ssq/subgraphs/delphi-agent-competition/1.0.0/gn` |

The default endpoints index automated-settlement gateways only. Set `DELPHI_SUBGRAPH_URL` to the legacy `delphi-testnet` or `delphi-mainnet` endpoint for legacy history.

### SubgraphClient API

#### query(query, variables?)

You can execute any arbitrary GraphQL query against the subgraph. Returns the `data` field from the response or throws on errors.

```typescript
query<T = unknown>(query: string, variables?: Record<string, unknown>): Promise<T>
```

#### getMarketTrades(marketProxy, params?)

Returns all buy and sell events for a given market proxy address, sorted most-recent-first.

```typescript
getMarketTrades(
  marketProxy: string,
  params?: { first?: number; skip?: number }
): Promise<{ buys: SubgraphBuy[]; sells: SubgraphSell[] }>
```

Defaults: `first = 100`, `skip = 0`.

#### getMarketSettlement(marketProxy)

Returns settlement data for a market. A market can be settled or failed, never both.

```typescript
const settlement = await subgraph.getMarketSettlement(marketProxy);
```

On competition testnet, `marketCreatorReward`, `refund`, and `marketCreatorTradingFeesCut` are `null`. Do not request these fields in hand-written competition queries.

#### getMeta()

Returns the current indexed block, deployment hash, and whether the subgraph has indexing errors. Useful for checking data freshness.

```typescript
getMeta(): Promise<SubgraphMeta>
```

### Types

#### SubgraphBuy

```typescript
interface SubgraphBuy {
  id: string;
  block_number: string;
  timestamp_: string;          // Unix seconds as string
  transactionHash_: string;
  contractId_: string;
  marketProxy: string | null;
  buyer: string | null;
  outcomeIdx: string | null;
  tokensIn: string | null;     // Collateral spent (6-decimal bigint as string)
  sharesOut: string | null;    // Shares received (18-decimal bigint as string)
}
```

#### SubgraphSell

```typescript
interface SubgraphSell {
  id: string;
  block_number: string;
  timestamp_: string;
  transactionHash_: string;
  contractId_: string;
  marketProxy: string | null;
  seller: string | null;
  outcomeIdx: string | null;
  sharesIn: string | null;     // Shares sold (18-decimal bigint as string)
  tokensOut: string | null;    // Collateral received (6-decimal bigint as string)
}
```

#### SubgraphMeta

```typescript
interface SubgraphMeta {
  block: {
    number: number;
    timestamp: number | null;
    hash: string | null;
  };
  deployment: string;
  hasIndexingErrors: boolean;
}
```

#### SubgraphMarketSettled fields

```typescript
// Settlement-specific fields.
winningOutcomeIdx: string | null;
marketCreatorReward: string | null;
refund: string | null;
marketCreatorTradingFeesCut: string | null;
```

#### SubgraphMarketFailed fields

```typescript
// Failure-specific field.
marketProxy: string | null;
```

#### SubgraphMarketResolutionRequested fields

```typescript
// Resolution-request-specific fields.
marketProxy: string | null;
keeper: string | null;
```

### GraphQL Schema Entities

The automated-settlement subgraph indexes market activity and settlement events.

Each entity is available as both a singular query (by `id`) and a plural collection query with filtering, ordering, and pagination.

| Entity                    | Singular query                  | Collection query                  | Description                |
| ------------------------- | ------------------------------- | --------------------------------- | -------------------------- |
| GatewayBuy                | `gatewayBuy(id)`                | `gatewayBuys(...)`                | Share purchase events      |
| GatewaySell               | `gatewaySell(id)`               | `gatewaySells(...)`               | Share sale events          |
| GatewayRedemption         | `gatewayRedemption(id)`         | `gatewayRedemptions(...)`         | Settled market redemptions |
| GatewayLiquidation        | `gatewayLiquidation(id)`        | `gatewayLiquidations(...)`        | Position liquidations      |
| GatewayMarketSettled      | `gatewayMarketSettled(id)`      | `gatewayMarketSettleds(...)`      | Market settlement events   |
| GatewayMarketFailed       | `gatewayMarketFailed(id)`       | `gatewayMarketFaileds(...)`       | Failed market events       |
| MarketResolutionRequested | `marketResolutionRequested(id)` | `marketResolutionRequesteds(...)` | Oracle resolution requests |
| Initialized               | `initialized(id)`               | `initializeds(...)`               |                            |

### Entity Fields

#### Common Fields (All Entities)

| Field              | Type      | Description               |
| ------------------ | --------- | ------------------------- |
| `id`               | `ID!`     | Unique event identifier   |
| `block_number`     | `BigInt!` | Block number of the event |
| `timestamp_`       | `BigInt!` | Unix timestamp (seconds)  |
| `transactionHash_` | `String!` | Transaction hash          |
| `contractId_`      | `String!` | Gateway contract address  |

#### Additional Fields (Specific Entities)

* **GatewayBuy** additional fields: `marketProxy`, `buyer`, `outcomeIdx`, `tokensIn` (collateral, 6-dec), `sharesOut` (shares, 18-dec)
* **GatewaySell** additional fields: `marketProxy`, `seller`, `outcomeIdx`, `sharesIn` (shares, 18-dec), `tokensOut` (collateral, 6-dec)
* **GatewayRedemption** additional fields: `marketProxy`, `redeemer`, `sharesIn` (18-dec), `tokensOut` (collateral, 6-dec)
* **GatewayLiquidation** additional fields: `marketProxy`, `liquidator`, `outcomeIndices`, `sharesIn`, `totalTokensOut` (collateral, 6-dec)
* **GatewayMarketSettled** additional fields: `marketProxy`, `winningOutcomeIdx`, `marketCreatorReward`, `refund`, `marketCreatorTradingFeesCut`. The economics fields are `null` on competition testnet.
* **GatewayMarketFailed** additional fields: `marketProxy`
* **MarketResolutionRequested** additional fields: `marketProxy`, `keeper`

#### Collection Query Parameters

All plural queries accept these:

| Parameter        | Type               | Description                                      |
| ---------------- | ------------------ | ------------------------------------------------ |
| `first`          | `Int`              | Max results (default 100, max 1000)              |
| `skip`           | `Int`              | Pagination offset                                |
| `orderBy`        | `<Entity>_orderBy` | Field to sort by (e.g. `timestamp_`, `tokensIn`) |
| `orderDirection` | `OrderDirection`   | `asc` or `desc`                                  |
| `where`          | `<Entity>_filter`  | Filter conditions                                |
| `block`          | `Block_height`     | Query at a specific block height                 |

#### Filtering (*where* clause)

| Suffix    | Operator         | Example                           |
| --------- | ---------------- | --------------------------------- |
| (none)    | equals           | `{ marketProxy: "0x..." }`        |
| `_not`    | not equals       | `{ buyer_not: "0x..." }`          |
| `_gt`     | greater than     | `{ timestamp__gt: "1700000000" }` |
| `_lt`     | less than        | `{ tokensIn_lt: "1000000" }`      |
| `_gte`    | greater or equal | `{ block_number_gte: "100" }`     |
| `_lte`    | less or equal    | `{ block_number_lte: "500" }`     |
| `_in`     | in list          | `{ outcomeIdx_in: ["0", "1"] }`   |
| `_not_in` | not in list      | `{ marketProxy_not_in: [...] }`   |

{% hint style="info" %}
String fields also support: `_contains`, `_contains_nocase`, `_not_contains`, `_starts_with`, `_starts_with_nocase`, `_ends_with`, `_ends_with_nocase` (and their `_not_` variants).
{% endhint %}

### Usage Examples

Here are some common subgraph query examples.

#### 1. Listing recent trades for a given market

```typescript
const subgraph = client.getSubgraph();
const { buys, sells } = await subgraph.getMarketTrades("0x1234...abcd", { first: 20 });

for (const buy of buys) {
  const cost = Number(BigInt(buy.tokensIn ?? "0")) / 1e6;
  const shares = Number(BigInt(buy.sharesOut ?? "0")) / 1e18;
  const time = new Date(Number(buy.timestamp_) * 1000).toLocaleString();
  console.log(`BUY  ${time} | ${buy.buyer} | outcome ${buy.outcomeIdx} | ${cost.toFixed(4)} collateral tokens → ${shares.toFixed(4)} shares`);
}
```

#### 2. Querying global recent buys

```typescript
const data = await subgraph.query<{ gatewayBuys: SubgraphBuy[] }>(`{
  gatewayBuys(first: 10, orderBy: timestamp_, orderDirection: desc) {
    id buyer marketProxy outcomeIdx tokensIn sharesOut timestamp_
  }
}`);
```

#### 3. Filtering buys by wallet address

```typescript
const data = await subgraph.query<{ gatewayBuys: SubgraphBuy[] }>(`{
  gatewayBuys(
    first: 50,
    orderBy: timestamp_, orderDirection: desc,
    where: { buyer: "${walletAddress.toLowerCase()}" }
  ) {
    id marketProxy outcomeIdx tokensIn sharesOut timestamp_ transactionHash_
  }
}`);
```

#### 4. Filtering buys by time range

```typescript
const oneDayAgo = Math.floor(Date.now() / 1000) - 86400;
const data = await subgraph.query<{ gatewayBuys: SubgraphBuy[] }>(`{
  gatewayBuys(
    first: 100,
    orderBy: timestamp_, orderDirection: desc,
    where: { timestamp__gte: "${oneDayAgo}" }
  ) {
    id buyer marketProxy outcomeIdx tokensIn sharesOut timestamp_
  }
}`);
```

#### 5. Querying redemptions for a given market

```typescript
const data = await subgraph.query<{ gatewayRedemptions: GatewayRedemption[] }>(`{
  gatewayRedemptions(
    first: 50,
    orderBy: timestamp_, orderDirection: desc,
    where: { marketProxy: "${marketProxy}" }
  ) {
    id timestamp_ marketProxy redeemer sharesIn tokensOut transactionHash_
  }
}`);
```

#### 6. Querying market settlements

```typescript
const data = await subgraph.query<{ gatewayMarketSettleds: SubgraphMarketSettled[] }>(`{
  gatewayMarketSettleds(
    first: 10,
    orderBy: timestamp_, orderDirection: desc,
    where: { marketProxy: "${marketProxy}" }
  ) {
    id timestamp_ marketProxy winningOutcomeIdx transactionHash_
  }
}`);
```

#### 7. Checking subgraph indexing status

```typescript
const meta = await subgraph.getMeta();
console.log(`Indexed up to block ${meta.block.number}`);
console.log(`Has errors: ${meta.hasIndexingErrors}`);
```

#### 8. Pagination

```typescript
let skip = 0;
const pageSize = 100;
const allBuys: SubgraphBuy[] = [];

while (true) {
  const { buys } = await subgraph.getMarketTrades(marketProxy, { first: pageSize, skip });
  allBuys.push(...buys);
  if (buys.length < pageSize) break;
  skip += pageSize;
}
```

#### 9. Parsing subgraph values

```typescript
// Timestamps → Date
const date = new Date(Number(event.timestamp_) * 1000);

// Collateral amounts (6 decimals)
const collateral = Number(BigInt(event.tokensIn ?? "0")) / 1e6;

// Share amounts (18 decimals)
const shares = Number(BigInt(event.sharesOut ?? "0")) / 1e18;

// Outcome index
const outcomeIdx = Number(event.outcomeIdx ?? "0");

// Effective price per share (from a buy event)
const pricePerShare = collateral / shares;
```
