Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ npx @modelcontextprotocol/inspector npm run mcp:server
| GET | `/v1/price/:assetA/:assetB` | Get aggregated price for a pair |
| GET | `/v1/premium/:assetA/:assetB` | Get on-chain vs CEX price premium and spread |
| GET | `/v1/price/:assetA/:assetB/route` | Get best swap route for a pair and amount |
| GET | `/v1/price/:assetA/:assetB/median` | Get staleness-aware median price across fresh sources with priority fallback |
| GET | `/v1/price/:asset/fiat` | Convert asset price to fiat currency with NGN support (#290) |
| GET | `/v1/price/:assetA/:assetB/history` | Get price history buckets |
| GET | `/v1/pools` | Get AMM liquidity pool reserves and spot prices |
Expand Down Expand Up @@ -204,6 +205,7 @@ the committed table differs from a fresh generation.
| How do I submit and settle an x402 payment on the Stellar network? | `POST /v1/settle` | `POST /settle` |
| How can my application receive push alerts when a price crosses a threshold? | `POST /v1/webhooks` | `POST /webhooks` |
| How do I cancel an existing price threshold alert webhook? | `DELETE /v1/webhooks/:id` | `DELETE /webhooks/wh_9f8e7d6c5b4a3a2b1c?network=testnet` |
| What is the staleness-aware median price across venues, and which sources were included or excluded? | `GET /v1/price/:assetA/:assetB/median` | `GET /price/XLM/USDC/median?freshness=300&network=testnet` |
<!-- QUESTION_INDEX_END -->
Every non-internal route above has a matching entry in [`openapi.yaml`](openapi.yaml);
`tests/openapi.test.ts` boots the server and fails if a registered route is
Expand Down
65 changes: 65 additions & 0 deletions clients/typescript/src/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,23 @@ export interface paths {
patch?: never;
trace?: never;
};
"/v1/price/{assetA}/{assetB}/median": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Get staleness-aware median price across fresh sources with priority fallback */
get: operations["getMedianPrice"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/v1/price/{asset}/fiat": {
parameters: {
query?: never;
Expand Down Expand Up @@ -2597,6 +2614,54 @@ export interface operations {
429: components["responses"]["TooManyRequests"];
};
};
getMedianPrice: {
parameters: {
query?: {
/** @description Freshness threshold in seconds (default: 300, valid range: 5 to 86400) */
freshness?: number;
/** @description Stellar network to answer for — `testnet` or `mainnet`. Defaults to this instance's configured `STELLAR_NETWORK`. An unrecognised value is rejected with 400. DB-backed reads are currently served from whichever network this instance indexes, even when another is requested. */
network?: components["parameters"]["NetworkQuery"];
};
header?: {
/** @description Formatting for decimal quantities (prices, volumes, reserves). Set to `string` to serialize high-precision `Decimal(36,18)` quantities as exact strings, preventing IEEE-754 floating-point precision loss. Defaults to `number`. Can also be negotiated via `Accept: application/json; decimals=strings` or query parameter `?decimals=strings`. */
"X-Decimal-Format"?: components["parameters"]["DecimalFormatHeader"];
};
path: {
/** @example XLM */
assetA: string;
/** @example USDC */
assetB: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Staleness-aware median price result with included and excluded sources */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": Record<string, never>;
};
};
/** @description Invalid parameters */
400: {
headers: {
[name: string]: unknown;
};
content?: never;
};
/** @description Pair not watched or no price data available */
404: {
headers: {
[name: string]: unknown;
};
content?: never;
};
429: components["responses"]["TooManyRequests"];
};
};
getFiatPrice: {
parameters: {
query?: {
Expand Down
4 changes: 3 additions & 1 deletion docs/what-lens-knows.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Instead of an arbitrary alphabetized URL list, this page organizes what Lens kno

A developer arriving at Lens does not browse by HTTP verb or path parameter. Their exploration follows a natural progression:

1. **Core Pricing & Trade Execution (Steps 1–6)**:
1. **Core Pricing & Trade Execution (Steps 1–53)**:
The universal entry question: *"What is an asset trading at right now?"* (`/price/:assetA/:assetB`). Once price is known, the immediate follow-up is execution: *"Where do I get the best return for my trade size?"* (`/price/:assetA/:assetB/route`), *"What does combined order-book depth look like?"* (`/book/:assetA/:assetB`), *"How much slippage will I incur?"* (`/price/:assetA/:assetB/depth`), and how that slippage grows with size (`/impact/:assetA/:assetB`). Pricing in a local currency rather than dollars lives here too (`/price/:asset/fiat`).

2. **Market Overview & Liquidity Pools (Steps 7–17)**:
Expand Down Expand Up @@ -89,6 +89,7 @@ A developer arriving at Lens does not browse by HTTP verb or path parameter. The
| 50 | How do I submit and settle an x402 payment on the Stellar network? | `POST /v1/settle` | `POST /settle` | Automation, Discovery & Payments |
| 51 | How can my application receive push alerts when a price crosses a threshold? | `POST /v1/webhooks` | `POST /webhooks` | Automation, Discovery & Payments |
| 52 | How do I cancel an existing price threshold alert webhook? | `DELETE /v1/webhooks/:id` | `DELETE /webhooks/wh_9f8e7d6c5b4a3a2b1c?network=testnet` | Automation, Discovery & Payments |
| 53 | What is the staleness-aware median price across venues, and which sources were included or excluded? | `GET /v1/price/:assetA/:assetB/median` | `GET /price/XLM/USDC/median?freshness=300&network=testnet` | Core Pricing & Trade Execution |

---

Expand All @@ -104,6 +105,7 @@ A developer arriving at Lens does not browse by HTTP verb or path parameter. The
| **What is the simulated order-book depth and expected slippage for a trade size?** | `GET /v1/price/:assetA/:assetB/depth` | `GET /price/XLM/USDC/depth?amount=1000&network=testnet` | Get order-book depth and execution slippage for a pair |
| **How does slippage grow as my trade size increases?** | `GET /v1/impact/:assetA/:assetB` | `GET /impact/XLM/USDC?network=testnet` | Get an adaptive slippage impact curve for a pair |
| **What is this asset worth in my local currency, such as naira?** | `GET /v1/price/:asset/fiat` | `GET /price/XLM/fiat?currency=NGN&network=testnet` | Convert asset price to fiat currency with NGN support (#290) |
| **What is the staleness-aware median price across venues, and which sources were included or excluded?** | `GET /v1/price/:assetA/:assetB/median` | `GET /price/XLM/USDC/median?freshness=300&network=testnet` | Get staleness-aware median price across fresh sources with priority fallback |

### Market Overview & Liquidity Pools

Expand Down
70 changes: 70 additions & 0 deletions openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,76 @@
}
}
},
"/v1/price/{assetA}/{assetB}/median": {
"get": {
"operationId": "getMedianPrice",
"summary": "Get staleness-aware median price across fresh sources with priority fallback",
"x-question": "What is the staleness-aware median price across venues, and which sources were included or excluded?",
"x-example": "GET /price/XLM/USDC/median?freshness=300&network=testnet",
"x-order": 53,
"x-category": "Core Pricing & Trade Execution",
"security": [],
"parameters": [
{
"name": "assetA",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"example": "XLM"
},
{
"name": "assetB",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"example": "USDC"
},
{
"name": "freshness",
"in": "query",
"required": false,
"description": "Freshness threshold in seconds (default: 300, valid range: 5 to 86400)",
"schema": {
"type": "integer",
"default": 300,
"minimum": 5,
"maximum": 86400
}
},
{
"$ref": "#/components/parameters/NetworkQuery"
},
{
"$ref": "#/components/parameters/DecimalFormatHeader"
}
],
"responses": {
"200": {
"description": "Staleness-aware median price result with included and excluded sources",
"content": {
"application/json": {
"schema": {
"type": "object"
}
}
}
},
"400": {
"description": "Invalid parameters"
},
"404": {
"description": "Pair not watched or no price data available"
},
"429": {
"$ref": "#/components/responses/TooManyRequests"
}
}
}
},
"/v1/price/{asset}/fiat": {
"get": {
"x-question": "What is this asset worth in my local currency, such as naira?",
Expand Down
47 changes: 47 additions & 0 deletions openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,53 @@ paths:
'429':
$ref: '#/components/responses/TooManyRequests'

/v1/price/{assetA}/{assetB}/median:
get:
operationId: getMedianPrice
summary: Get staleness-aware median price across fresh sources with priority fallback
x-question: "What is the staleness-aware median price across venues, and which sources were included or excluded?"
x-example: "GET /price/XLM/USDC/median?freshness=300&network=testnet"
x-order: 53
x-category: "Core Pricing & Trade Execution"
security: []
parameters:
- name: assetA
in: path
required: true
schema:
type: string
example: XLM
- name: assetB
in: path
required: true
schema:
type: string
example: USDC
- name: freshness
in: query
required: false
description: 'Freshness threshold in seconds (default: 300, valid range: 5 to 86400)'
schema:
type: integer
default: 300
minimum: 5
maximum: 86400
- $ref: '#/components/parameters/NetworkQuery'
- $ref: '#/components/parameters/DecimalFormatHeader'
responses:
'200':
description: Staleness-aware median price result with included and excluded sources
content:
application/json:
schema:
type: object
'400':
description: Invalid parameters
'404':
description: Pair not watched or no price data available
'429':
$ref: '#/components/responses/TooManyRequests'

/v1/price/{asset}/fiat:
get:
x-question: "What is this asset worth in my local currency, such as naira?"
Expand Down
Loading
Loading