From f52ec0cb95462068d91a23838c524e7f09f82f2c Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Fri, 5 Sep 2025 13:39:04 -0700 Subject: [PATCH 01/18] init, blank --- .../images/tutorial-icons/ts_logo_black.svg | 1 + src/config/sidebar.ts | 9 ++-- src/content/data-streams/index.mdx | 1 + .../reference/data-streams-api/go-sdk.mdx | 7 ++++ .../reference/data-streams-api/rust-sdk.mdx | 5 +++ .../reference/data-streams-api/ts-sdk.mdx | 41 +++++++++++++++++++ .../data-streams/reference/overview.mdx | 15 +++---- .../data-streams/tutorials/go-sdk-fetch.mdx | 9 ++++ .../data-streams/tutorials/go-sdk-stream.mdx | 7 ++++ .../data-streams/tutorials/overview.mdx | 11 ++--- .../data-streams/tutorials/rust-sdk-fetch.mdx | 12 ++++++ .../tutorials/rust-sdk-stream.mdx | 10 +++++ .../data-streams/tutorials/ts-sdk-fetch.mdx | 34 +++++++++++++++ .../data-streams/tutorials/ts-sdk-stream.mdx | 39 ++++++++++++++++++ 14 files changed, 186 insertions(+), 15 deletions(-) create mode 100644 public/images/tutorial-icons/ts_logo_black.svg create mode 100644 src/content/data-streams/reference/data-streams-api/ts-sdk.mdx create mode 100644 src/content/data-streams/tutorials/ts-sdk-fetch.mdx create mode 100644 src/content/data-streams/tutorials/ts-sdk-stream.mdx diff --git a/public/images/tutorial-icons/ts_logo_black.svg b/public/images/tutorial-icons/ts_logo_black.svg new file mode 100644 index 00000000000..5e014b5172c --- /dev/null +++ b/public/images/tutorial-icons/ts_logo_black.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/config/sidebar.ts b/src/config/sidebar.ts index 1821f94fe67..4ee89df5725 100644 --- a/src/config/sidebar.ts +++ b/src/config/sidebar.ts @@ -445,12 +445,12 @@ export const SIDEBAR: Partial> = { { title: "Fetch and decode reports", url: "data-streams/tutorials/go-sdk-fetch", - highlightAsCurrent: ["data-streams/tutorials/rust-sdk-fetch"], + highlightAsCurrent: ["data-streams/tutorials/rust-sdk-fetch", "data-streams/tutorials/ts-sdk-fetch"], }, { title: "Stream and decode reports (WebSocket)", url: "data-streams/tutorials/go-sdk-stream", - highlightAsCurrent: ["data-streams/tutorials/rust-sdk-stream"], + highlightAsCurrent: ["data-streams/tutorials/rust-sdk-stream", "data-streams/tutorials/ts-sdk-stream"], }, { title: "Verify report data (EVM)", @@ -524,7 +524,10 @@ export const SIDEBAR: Partial> = { { title: "SDK References", url: "data-streams/reference/data-streams-api/go-sdk", - highlightAsCurrent: ["data-streams/reference/data-streams-api/rust-sdk"], + highlightAsCurrent: [ + "data-streams/reference/data-streams-api/rust-sdk", + "data-streams/reference/data-streams-api/ts-sdk", + ], }, { title: "Onchain report verification (EVM chains)", diff --git a/src/content/data-streams/index.mdx b/src/content/data-streams/index.mdx index 2cf5d1d24db..127417838e8 100644 --- a/src/content/data-streams/index.mdx +++ b/src/content/data-streams/index.mdx @@ -82,6 +82,7 @@ Access data directly through REST APIs or WebSocket connections using our SDKs: - **[Go SDK](/data-streams/reference/data-streams-api/go-sdk)** - Full-featured SDK with comprehensive examples - **[Rust SDK](/data-streams/reference/data-streams-api/rust-sdk)** - High-performance SDK for Rust applications +- **[TypeScript SDK](/data-streams/reference/data-streams-api/ts-sdk)** - Type-safe SDK for TypeScript applications - **[REST API](/data-streams/reference/data-streams-api/interface-api)** or **[WebSocket](/data-streams/reference/data-streams-api/interface-ws)** - Direct access to Data Streams endpoints ### Getting started diff --git a/src/content/data-streams/reference/data-streams-api/go-sdk.mdx b/src/content/data-streams/reference/data-streams-api/go-sdk.mdx index 09ceb973e4e..aeea712cbd0 100644 --- a/src/content/data-streams/reference/data-streams-api/go-sdk.mdx +++ b/src/content/data-streams/reference/data-streams-api/go-sdk.mdx @@ -32,6 +32,11 @@ import { PageTabs } from "@components" url: "/data-streams/reference/data-streams-api/rust-sdk", icon: "/images/tutorial-icons/rust_logo_blk.svg", }, + { + name: "TypeScript SDK", + url: "/data-streams/reference/data-streams-api/ts-sdk", + icon: "/images/tutorial-icons/ts_logo_black.svg", + }, ]} /> @@ -116,6 +121,7 @@ type CtxKey string ``` - Constants: + - `CustomHeadersCtxKey`: Key for passing custom HTTP headers. ```go @@ -201,6 +207,7 @@ type Stats struct { ##### Interface Methods - `Read`: Reads the next available report from the stream. This method will pause (block) the execution until one of the following occurs: + - A report is successfully received. - The provided context is canceled, typically due to a timeout or a cancel signal. - An error state is encountered in any of the underlying connections, such as a network failure. diff --git a/src/content/data-streams/reference/data-streams-api/rust-sdk.mdx b/src/content/data-streams/reference/data-streams-api/rust-sdk.mdx index 64bfbc758f8..6b6194c5c56 100644 --- a/src/content/data-streams/reference/data-streams-api/rust-sdk.mdx +++ b/src/content/data-streams/reference/data-streams-api/rust-sdk.mdx @@ -32,6 +32,11 @@ import { PageTabs } from "@components" url: "/data-streams/reference/data-streams-api/rust-sdk", icon: "/images/tutorial-icons/rust_logo_blk.svg", }, + { + name: "TypeScript SDK", + url: "/data-streams/reference/data-streams-api/ts-sdk", + icon: "/images/tutorial-icons/ts_logo_black.svg", + }, ]} /> diff --git a/src/content/data-streams/reference/data-streams-api/ts-sdk.mdx b/src/content/data-streams/reference/data-streams-api/ts-sdk.mdx new file mode 100644 index 00000000000..a6b9574cb13 --- /dev/null +++ b/src/content/data-streams/reference/data-streams-api/ts-sdk.mdx @@ -0,0 +1,41 @@ +--- +section: dataStreams +date: Last Modified +title: "Data Streams SDK (TypeScript)" +metadata: + title: "Data Streams TypeScript SDK Reference | Chainlink Documentation" + description: "Integrate with Chainlink Data Streams using the TypeScript SDK. Learn about client configuration, authentication, fetching reports, and WebSocket streaming." + keywords: ["TypeScript SDK", "Data Streams", "Integration", "API Client", "WebSocket Client", "Report Decoding"] +whatsnext: + { + "Learn how to fetch and decode Data Streams reports using the Data Streams SDK": "/data-streams/tutorials/ts-sdk-fetch", + "Learn how to stream and decode reports via a WebSocket connection using the Data Streams SDK": "/data-streams/tutorials/ts-sdk-stream", + } +--- + +import DataStreams from "@features/data-streams/common/DataStreams.astro" +import { PageTabs } from "@components" + + + + diff --git a/src/content/data-streams/reference/overview.mdx b/src/content/data-streams/reference/overview.mdx index 23005d27422..b7e8340c4e3 100644 --- a/src/content/data-streams/reference/overview.mdx +++ b/src/content/data-streams/reference/overview.mdx @@ -13,13 +13,13 @@ Chainlink Data Streams offers two distinct solutions for accessing low-latency m ### Which solution should I use? -| Feature | [Data Streams API](#data-streams-api) | [Candlestick API](#candlestick-api) | -| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Primary Use Case** | Low-latency data for smart contracts | OHLC data for analytics, charting, and dashboards | -| **Data Format** | Signed, verifiable data reports | Aggregated OHLC (candlestick) data | -| **Interfaces** | SDKs ([Go](/data-streams/reference/data-streams-api/go-sdk), [Rust](/data-streams/reference/data-streams-api/rust-sdk)), [REST API](/data-streams/reference/data-streams-api/interface-api) & [WebSocket](/data-streams/reference/data-streams-api/interface-ws) | [REST API](/data-streams/reference/candlestick-api) (including a [streaming endpoint](/data-streams/reference/candlestick-api#get-streaming-price-updates)) | -| **Authentication** | [HMAC Signature](/data-streams/reference/data-streams-api/authentication) (automatic with SDKs) | [JWT](/data-streams/reference/candlestick-api#authorize-and-get-token) (token-based) | -| **Cryptographic Proof** | āœ… Yes (See [Verification methods](#verification)) | āŒ No | +| Feature | [Data Streams API](#data-streams-api) | [Candlestick API](#candlestick-api) | +| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Primary Use Case** | Low-latency data for smart contracts | OHLC data for analytics, charting, and dashboards | +| **Data Format** | Signed, verifiable data reports | Aggregated OHLC (candlestick) data | +| **Interfaces** | SDKs ([Go](/data-streams/reference/data-streams-api/go-sdk), [Rust](/data-streams/reference/data-streams-api/rust-sdk), [TypeScript](/data-streams/reference/data-streams-api/ts-sdk)), [REST API](/data-streams/reference/data-streams-api/interface-api) & [WebSocket](/data-streams/reference/data-streams-api/interface-ws) | [REST API](/data-streams/reference/candlestick-api) (including a [streaming endpoint](/data-streams/reference/candlestick-api#get-streaming-price-updates)) | +| **Authentication** | [HMAC Signature](/data-streams/reference/data-streams-api/authentication) (automatic with SDKs) | [JWT](/data-streams/reference/candlestick-api#authorize-and-get-token) (token-based) | +| **Cryptographic Proof** | āœ… Yes (See [Verification methods](#verification)) | āŒ No | --- @@ -33,6 +33,7 @@ The [Data Streams API](/data-streams/reference/data-streams-api) provides crypto - [Go SDK](/data-streams/reference/data-streams-api/go-sdk) - Native Go language integration - [Rust SDK](/data-streams/reference/data-streams-api/rust-sdk) - Native Rust language integration +- [TypeScript SDK](/data-streams/reference/data-streams-api/ts-sdk) - Native TypeScript language integration #### Direct API Access diff --git a/src/content/data-streams/tutorials/go-sdk-fetch.mdx b/src/content/data-streams/tutorials/go-sdk-fetch.mdx index e7f4ea53e5c..ea24b6d7aff 100644 --- a/src/content/data-streams/tutorials/go-sdk-fetch.mdx +++ b/src/content/data-streams/tutorials/go-sdk-fetch.mdx @@ -31,6 +31,11 @@ import DataStreams from "@features/data-streams/common/DataStreams.astro" url: "/data-streams/tutorials/rust-sdk-fetch", icon: "/images/tutorial-icons/rust_logo_blk.svg", }, + { + name: "TypeScript SDK", + url: "/data-streams/tutorials/ts-sdk-fetch", + icon: "/images/tutorial-icons/ts_logo_black.svg", + }, ]} /> @@ -471,6 +476,7 @@ Refer to the [Verify report data onchain](/data-streams/tutorials/evm-onchain-re When working with different versions of [Data Stream reports](/data-streams/reference/report-schema-overview), you'll need to adapt your code to handle the specific report schema version they use: 1. Import the correct schema version. Examples: + - For v3 schema (as used in this example): ```go @@ -484,6 +490,7 @@ When working with different versions of [Data Stream reports](/data-streams/refe ``` 1. Update the decode function to use the correct schema version. Examples: + - For v3 schema (as used in this example): ```go @@ -516,6 +523,7 @@ The Data Streams client is initialized in two steps: ``` The configuration requires: + - `ApiKey` and `ApiSecret` for authentication (required) - `RestURL` for the API endpoint (required) - `Logger` for debugging and error tracking (optional, defaults to `streams.LogPrintf`) @@ -574,6 +582,7 @@ Reports are decoded in two steps: ``` This step: + 1. Takes the raw `FullReport` bytes from the response 1. Uses `v3.Data` schema for Crypto streams (use the appropriate schema for your stream) 1. Validates the format and decodes using Go generics diff --git a/src/content/data-streams/tutorials/go-sdk-stream.mdx b/src/content/data-streams/tutorials/go-sdk-stream.mdx index 9053b4a38e2..43d99d41d2c 100644 --- a/src/content/data-streams/tutorials/go-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/go-sdk-stream.mdx @@ -30,6 +30,11 @@ import DataStreams from "@features/data-streams/common/DataStreams.astro" url: "/data-streams/tutorials/rust-sdk-stream", icon: "/images/tutorial-icons/rust_logo_blk.svg", }, + { + name: "TypeScript SDK", + url: "/data-streams/tutorials/ts-sdk-stream", + icon: "/images/tutorial-icons/ts_logo_black.svg", + }, ]} /> @@ -333,6 +338,7 @@ Refer to the [Verify report data onchain](/data-streams/tutorials/evm-onchain-re When working with different versions of [Data Stream reports](/data-streams/reference/report-schema-overview), you'll need to adapt your code to handle the specific report schema version they use: 1. Import the correct schema version. Examples: + - For v3 schema (as used in this example): ```go @@ -346,6 +352,7 @@ When working with different versions of [Data Stream reports](/data-streams/refe ``` 1. Update the decode function to use the correct schema version. Examples: + - For v3 schema (as used in this example): ```go diff --git a/src/content/data-streams/tutorials/overview.mdx b/src/content/data-streams/tutorials/overview.mdx index 134fa664638..33883737ef2 100644 --- a/src/content/data-streams/tutorials/overview.mdx +++ b/src/content/data-streams/tutorials/overview.mdx @@ -18,13 +18,14 @@ Explore several tutorials to learn how to use the Data Streams. ## Fetch, Stream, and Decode Reports -- [Fetch and decode reports](/data-streams/tutorials/go-sdk-fetch): Learn how to fetch and decode reports from the Data Streams Aggregation Network, using the [Go](/data-streams/reference/data-streams-api/go-sdk) or [Rust](/data-streams/reference/data-streams-api/rust-sdk) SDKs. -- [Stream and decode reports (WebSocket)](/data-streams/tutorials/go-sdk-stream): Learn how to listen for real-time reports from the Data Streams Aggregation Network, decode the report data, and log their attributes, using the [Go](/data-streams/reference/data-streams-api/go-sdk) or [Rust](/data-streams/reference/data-streams-api/rust-sdk) SDKs. +- [Fetch and decode reports](/data-streams/tutorials/go-sdk-fetch): Learn how to fetch and decode reports from the Data Streams Aggregation Network, using the [Go](/data-streams/reference/data-streams-api/go-sdk), [Rust](/data-streams/reference/data-streams-api/rust-sdk), or [TypeScript](/data-streams/reference/data-streams-api/ts-sdk) SDKs. +- [Stream and decode reports (WebSocket)](/data-streams/tutorials/go-sdk-stream): Learn how to listen for real-time reports from the Data Streams Aggregation Network, decode the report data, and log their attributes, using the [Go](/data-streams/reference/data-streams-api/go-sdk), [Rust](/data-streams/reference/data-streams-api/rust-sdk), or [TypeScript](/data-streams/reference/data-streams-api/ts-sdk) SDKs. diff --git a/src/content/data-streams/tutorials/rust-sdk-fetch.mdx b/src/content/data-streams/tutorials/rust-sdk-fetch.mdx index 884cb6ce559..817bf99f74a 100644 --- a/src/content/data-streams/tutorials/rust-sdk-fetch.mdx +++ b/src/content/data-streams/tutorials/rust-sdk-fetch.mdx @@ -31,6 +31,11 @@ import DataStreams from "@features/data-streams/common/DataStreams.astro" url: "/data-streams/tutorials/rust-sdk-fetch", icon: "/images/tutorial-icons/rust_logo_blk.svg", }, + { + name: "TypeScript SDK", + url: "/data-streams/tutorials/ts-sdk-fetch", + icon: "/images/tutorial-icons/ts_logo_black.svg", + }, ]} /> @@ -234,6 +239,7 @@ Refer to the [Verify report data onchain](/data-streams/tutorials/evm-onchain-re When working with different versions of [Data Stream reports](/data-streams/reference/report-schema-overview), you'll need to adapt your code to handle the specific report schema version they use: 1. Import the correct schema version module. Examples: + - For v3 schema (as used in this example): ```rust @@ -247,6 +253,7 @@ When working with different versions of [Data Stream reports](/data-streams/refe ``` 1. Update the decode function to use the correct schema version. Examples: + - For v3 schema (as used in this example): ```rust @@ -268,6 +275,7 @@ When working with different versions of [Data Stream reports](/data-streams/refe The API client is initialized in two steps: 1. [`Config::new`](https://github.com/smartcontractkit/data-streams-sdk/blob/main/rust/crates/sdk/src/config.rs#L131) creates a configuration with your API credentials and endpoints. This function: + - Validates your API key and secret - Sets up the REST API endpoint for data retrieval - Configures optional settings like TLS verification @@ -282,6 +290,7 @@ The API client is initialized in two steps: The SDK provides several methods to fetch reports through the REST API: 1. Latest report: [`get_latest_report`](https://github.com/smartcontractkit/data-streams-sdk/blob/main/rust/crates/sdk/src/client.rs#L165) retrieves the most recent report for a feed: + - Takes a feed ID as input - Returns a single report with the latest timestamp - Useful for applications that need the most current data @@ -309,6 +318,7 @@ Reports are decoded in three stages: ``` 1. Report separation: [`decode_full_report`](https://github.com/smartcontractkit/data-streams-sdk/blob/main/rust/crates/report/src/report.rs#L83) splits the binary data: + - Extracts the report context (metadata) - Isolates the report blob (actual data) - Validates the report format @@ -325,11 +335,13 @@ Reports are decoded in three stages: The example demonstrates Rust's robust error handling: 1. Type-safe errors: + - Uses custom error types for different failure scenarios - Implements the `Error` trait for proper error propagation - Provides detailed error messages for debugging 1. Error propagation: + - Uses the `?` operator for clean error handling - Converts errors between types when needed - Bubbles up errors to the main function diff --git a/src/content/data-streams/tutorials/rust-sdk-stream.mdx b/src/content/data-streams/tutorials/rust-sdk-stream.mdx index fd2d211a3a1..ac6516285bd 100644 --- a/src/content/data-streams/tutorials/rust-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/rust-sdk-stream.mdx @@ -30,6 +30,11 @@ import DataStreams from "@features/data-streams/common/DataStreams.astro" url: "/data-streams/tutorials/rust-sdk-stream", icon: "/images/tutorial-icons/rust_logo_blk.svg", }, + { + name: "TypeScript SDK", + url: "/data-streams/tutorials/ts-sdk-stream", + icon: "/images/tutorial-icons/ts_logo_black.svg", + }, ]} /> @@ -363,6 +368,7 @@ Refer to the [Verify report data onchain](/data-streams/tutorials/evm-onchain-re When working with different versions of [Data Stream reports](/data-streams/reference/report-schema-overview), you'll need to adapt your code to handle the specific report schema version they use: 1. Import the correct schema version module. Examples: + - For v3 schema (as used in this example): ```rust @@ -376,6 +382,7 @@ When working with different versions of [Data Stream reports](/data-streams/refe ``` 1. Update the decode function to use the correct schema version. Examples: + - For v3 schema (as used in this example): ```rust @@ -408,6 +415,7 @@ The WebSocket connection is established in two steps: As data reports arrive via the WebSocket connection, they are processed in real-time through several steps: 1. Reading streams: The [`read`](https://github.com/smartcontractkit/data-streams-sdk/blob/main/rust/crates/sdk/src/stream.rs#L218) method on the Stream object is called within a loop. This asynchronous method: + - Awaits the next report from the WebSocket connection - Handles backpressure automatically - Returns a [`WebSocketReport`](https://github.com/smartcontractkit/data-streams-sdk/blob/main/rust/crates/sdk/src/stream.rs#L51) containing the report data @@ -425,11 +433,13 @@ As data reports arrive via the WebSocket connection, they are processed in real- The example demonstrates several best practices for handling the decoded data: 1. Logging: + - Uses the [`tracing`](https://github.com/tokio-rs/tracing) crate for structured logging - Configures UTC timestamps for consistent time representation - Includes both raw report data and decoded fields for debugging 2. Error handling: + - Uses Rust's `Result` type for robust error handling - Implements the `?` operator for clean error propagation - Logs errors with appropriate context using `warn!` macro diff --git a/src/content/data-streams/tutorials/ts-sdk-fetch.mdx b/src/content/data-streams/tutorials/ts-sdk-fetch.mdx new file mode 100644 index 00000000000..5971c593bc0 --- /dev/null +++ b/src/content/data-streams/tutorials/ts-sdk-fetch.mdx @@ -0,0 +1,34 @@ +--- +section: dataStreams +date: Last Modified +title: "Fetch and decode Data Streams reports using the TypeScript SDK" +metadata: + title: "Fetch and Decode Data Streams Reports with TypeScript SDK | Chainlink Data Streams" + description: "Learn how to use the TypeScript SDK to fetch and decode data reports from Chainlink Data Streams in your TypeScript applications." + keywords: ["TypeScript SDK", "JavaScript", "Cryptocurrency", "API Tutorial", "Data Streams", "Market Data"] +--- + +import { Aside, CopyText, PageTabs } from "@components" +import DataStreams from "@features/data-streams/common/DataStreams.astro" + + + + diff --git a/src/content/data-streams/tutorials/ts-sdk-stream.mdx b/src/content/data-streams/tutorials/ts-sdk-stream.mdx new file mode 100644 index 00000000000..290fcdcac0f --- /dev/null +++ b/src/content/data-streams/tutorials/ts-sdk-stream.mdx @@ -0,0 +1,39 @@ +--- +section: dataStreams +date: Last Modified +title: "Stream and decode Data Streams reports via WebSocket using the TypeScript SDK" +metadata: + title: "Stream Real-time Data Streams Reports with TypeScript SDK | WebSocket Tutorial" + description: "Learn how to use the TypeScript SDK to stream and decode real-time data streams reports via WebSocket connections from Chainlink Data Streams." + keywords: ["WebSocket", "TypeScript SDK", "JavaScript", "Real-time", "Streaming", "Data Streams"] +whatsnext: + { + "Learn how to verify your data onchain": "/data-streams/reference/data-streams-api/onchain-verification", + "Find the list of available Streams and view their schemas": "/data-streams/reference/report-schema-overview", + } +--- + +import { Aside, CopyText, PageTabs } from "@components" +import DataStreams from "@features/data-streams/common/DataStreams.astro" + + + + From a09d709219761d69d00d985c507d551c78941abb Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Mon, 22 Sep 2025 18:27:13 -0700 Subject: [PATCH 02/18] draft ts-sdk-fetch --- .../data-streams/tutorials/ts-sdk-fetch.mdx | 480 ++++++++++++++++++ 1 file changed, 480 insertions(+) diff --git a/src/content/data-streams/tutorials/ts-sdk-fetch.mdx b/src/content/data-streams/tutorials/ts-sdk-fetch.mdx index 5971c593bc0..74dee055933 100644 --- a/src/content/data-streams/tutorials/ts-sdk-fetch.mdx +++ b/src/content/data-streams/tutorials/ts-sdk-fetch.mdx @@ -32,3 +32,483 @@ import DataStreams from "@features/data-streams/common/DataStreams.astro" }, ]} /> + +In this tutorial, you'll learn how to use the [Data Streams SDK](/data-streams/reference/data-streams-api/ts-sdk) for TypeScript to fetch and decode [reports](/data-streams/reference/report-schema-overview) from the Data Streams Aggregation Network. You'll set up your TypeScript project, retrieve reports, decode them, and log their attributes. + + + +## Requirements + +- **Git**: Make sure you have Git installed. You can check your current version by running in your terminal and download the latest version from the official [Git website](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) if necessary. +- **Node.js**: Make sure you have Node.js 20.0 or higher. You can check your current version by running in your terminal and download the latest version from the official [Node.js website](https://nodejs.org/) if necessary. +- **TypeScript**: Make sure you have TypeScript 5.3 or higher. You can check your current version by running in your terminal and install or update TypeScript by running if necessary. +- **API Credentials**: Access to Data Streams requires API credentials. If you haven't already, [contact us](https://chainlinkcommunity.typeform.com/datastreams?typeform-source=docs.chain.link#ref_id=docs) to request mainnet or testnet access. + +## Tutorial + +You'll start with the set up of your TypeScript project, installing the SDK and pasting example code. This will let you decode reports for both single and multiple [streams](/data-streams/crypto-streams), logging their attributes to your terminal. + +### Set up your TypeScript project + +1. Create a new directory for your project and navigate to it: + + ```bash + mkdir my-data-streams-project + cd my-data-streams-project + ``` + +1. Initialize a new Node.js project: + + ```bash + npm init -y + ``` + +1. Install the TypeScript SDK and other required packages: + + ```bash + npm install @chainlink/data-streams-sdk dotenv + npm install -D typescript @types/node tsx + ``` + +1. Set your API credentials: + + Option 1 - Environment variables: + + ```bash + export API_KEY="your_api_key_here" + export USER_SECRET="your_user_secret_here" + ``` + + Option 2 - `.env` file: + + ```bash + # Create .env file + touch .env + + # Add your credentials + API_KEY="your_api_key_here" + USER_SECRET="your_user_secret_here" + ``` + +### Fetch and decode a report with a single stream + +1. Create a new new TypeScript file, `singleStream.ts`, in your project directory: + + ```bash + touch singleStream.ts + ``` + +1. Insert the following code example and save your `singleStream.ts` file: + + ```typescript + import { createClient, decodeReport, LogLevel, getReportVersion, formatReport } from "@chainlink/data-streams-sdk" + import "dotenv/config" + + async function main() { + if (process.argv.length < 3) { + console.error("Please provide a feed ID as an argument") + console.error( + "Example: npx ts-node examples/get-latest-report.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782" + ) + process.exit(1) + } + + const feedId = process.argv[2] + const version = getReportVersion(feedId) + + try { + const config = { + apiKey: process.env.API_KEY || "YOUR_API_KEY", + userSecret: process.env.USER_SECRET || "YOUR_USER_SECRET", + endpoint: "https://api.testnet-dataengine.chain.link", + wsEndpoint: "wss://ws.testnet-dataengine.chain.link", + // Comment to disable SDK logging: + logging: { + logger: console, + logLevel: LogLevel.INFO, + }, + } + + const client = createClient(config) + console.log(`\nFetching latest report for feed ${feedId} (${version})...\n`) + + // Get raw report data + const report = await client.getLatestReport(feedId) + console.log(`Raw Report Blob: ${report.fullReport}`) + + // Decode the report + const decodedData = decodeReport(report.fullReport, report.feedID) + + // Combine decoded data with report metadata + const decodedReport = { + ...decodedData, + feedID: report.feedID, + validFromTimestamp: report.validFromTimestamp, + observationsTimestamp: report.observationsTimestamp, + } + console.log(formatReport(decodedReport, version)) + } catch (error) { + if (error instanceof Error) { + console.error("Error:", error.message) + } else { + console.error("Unknown error:", error) + } + process.exit(1) + } + } + + main() + ``` + + + +1. Read from a [testnet crypto stream](/data-streams/crypto-streams?page=1&testnetPage=1#testnet-crypto-streams). The below example executes the application, reading from the `ETH/USD` crypto stream: + + ```bash + npx ts-node singleStream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 + ``` + + Expect output similar to the following in your terminal: + + ```bash + Fetching latest report for feed 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 (V3)... + + [2025-09-23T00:09:49.042Z] [DataStreams] Request successful: GET https://api.testnet-dataengine.chain.link/api/v1/reports/latest?feedID=0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 - 200 + Raw Report Blob: 0x00090d9e8d96765a0c49e03a6ae05c82e8f8de70cf179baa632f18313e54bd690000000000000000000000000000000000000000000000000000000001f6f486000000000000000000000000000000000000000000000000000000030000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba7820000000000000000000000000000000000000000000000000000000068d1e54c0000000000000000000000000000000000000000000000000000000068d1e54c00000000000000000000000000000000000000000000000000004539f757bc7c0000000000000000000000000000000000000000000000000034754304206ea30000000000000000000000000000000000000000000000000000000068f9724c0000000000000000000000000000000000000000000000e3e84d950bcd8d80000000000000000000000000000000000000000000000000e3e48f23626b5660000000000000000000000000000000000000000000000000e3eb7a12d8af1b00000000000000000000000000000000000000000000000000000000000000000002e7c71643e93efb8e759b1d1a8826579853d3aa2c96f59a2813e833a374c786f8f13a497a753af14c6b7329f704f148779b20aae62ed450167c61b9b5d8fcb0e100000000000000000000000000000000000000000000000000000000000000024905f1b4a6313246988a33d2aa923e3023065bbc8c874956aa5df25ec8b7b3e918a25b251713158aae6be85a188c1292e6b5288f2f96e75d632c4e6b659dfa53 + + Report Metadata: + Feed ID: 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 + Valid From: 1758586188 + Observations: 1758586188 + + Decoded Data: + Native Fee: 76115265174652 + LINK Fee: 14765629481447075 + Expires At: 1761178188 + Price: 4204150104000000000000 + Bid Price: 4203880326000000000000 + Ask Price: 4204378800000000000000 + -------------------------------------------------- + ``` + + Your application has successfully fetched and decoded data for both streams. + + [Learn more about the decoded report details](#decoded-report-details). + +### Fetch and decode reports for multiple streams + +1. Create a new TypeScript file, `multipleStreams.ts`, in your project directory: + + ```bash + touch multipleStreams.ts + ``` + +1. Insert the following code example in your `multipleStreams.ts` file: + + ```typescript + import { createClient, decodeReport, LogLevel, getReportVersion, formatReport } from "@chainlink/data-streams-sdk" + import "dotenv/config" + + async function main() { + if (process.argv.length < 3) { + console.error("Please provide feed IDs as arguments") + console.error("Get latest reports for multiple feeds:") + console.error(" npx ts-node multipleStreams.ts [feedID3...]") + console.error("\nExample:") + console.error( + " npx ts-node multipleStreams.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265" + ) + process.exit(1) + } + + const feedIds = process.argv.slice(2) + + try { + const config = { + apiKey: process.env.API_KEY || "YOUR_API_KEY", + userSecret: process.env.USER_SECRET || "YOUR_USER_SECRET", + endpoint: "https://api.testnet-dataengine.chain.link", + wsEndpoint: "wss://ws.testnet-dataengine.chain.link", + // Comment to disable SDK logging: + logging: { + logger: console, + logLevel: LogLevel.INFO, + }, + } + + const client = createClient(config) + console.log(`\nFetching latest reports for ${feedIds.length} feed(s):`) + feedIds.forEach((feedId) => { + const version = getReportVersion(feedId) + console.log(`- ${feedId} (${version})`) + }) + console.log() + + // Get latest reports for each feed ID + const reports = [] + for (const feedId of feedIds) { + try { + const report = await client.getLatestReport(feedId) + reports.push(report) + } catch (error) { + console.error(`Failed to get report for ${feedId}:`, error) + continue + } + } + + console.log(`Found ${reports.length} reports:\n`) + + // Process reports + reports.forEach((report, index) => { + const version = getReportVersion(report.feedID) + console.log(`Raw Report Blob #${index + 1}: ${report.fullReport}`) + + try { + // Decode the report + const decodedData = decodeReport(report.fullReport, report.feedID) + + // Combine decoded data with report metadata + const decodedReport = { + ...decodedData, + feedID: report.feedID, + validFromTimestamp: report.validFromTimestamp, + observationsTimestamp: report.observationsTimestamp, + } + console.log(formatReport(decodedReport, version)) + } catch (error) { + console.error(`Failed to decode report for ${report.feedID}:`, error) + } + }) + } catch (error) { + if (error instanceof Error) { + console.error("Error:", error.message) + } else { + console.error("Unknown error:", error) + } + process.exit(1) + } + } + + main() + ``` + +1. Before running the example, verify that your API credentials are still set in your current terminal session: + + ```bash + echo $API_KEY + echo $API_SECRET + ``` + + If the commands above don't show your credentials, set them again: + + ```bash + export API_KEY="" + export USER_SECRET="" + ``` + +1. Read from two testnet crypto streams (ETH/USD and LINK/USD) by running: + + ```bash + npx ts-node multipleStreams.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265 + ``` + + Expect to see the output below in your terminal: + + ```bash + [2025-09-23T00:54:43.990Z] [DataStreams] Data Streams client initialized + + Fetching latest reports for 2 feed(s): + - 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 (V3) + - 0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265 (V3) + + [2025-09-23T00:54:44.244Z] [DataStreams] Request successful: GET https://api.testnet-dataengine.chain.link/api/v1/reports/latest?feedID=0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 - 200 + [2025-09-23T00:54:44.310Z] [DataStreams] Request successful: GET https://api.testnet-dataengine.chain.link/api/v1/reports/latest?feedID=0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265 - 200 + Found 2 reports: + + Raw Report Blob #1: 0x00090d9e8d96765a0c49e03a6ae05c82e8f8de70cf179baa632f18313e54bd690000000000000000000000000000000000000000000000000000000001f71291000000000000000000000000000000000000000000000000000000030000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000028001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba7820000000000000000000000000000000000000000000000000000000068d1efd30000000000000000000000000000000000000000000000000000000068d1efd30000000000000000000000000000000000000000000000000000455f50d8377000000000000000000000000000000000000000000000000000349983c7f97bd70000000000000000000000000000000000000000000000000000000068f97cd30000000000000000000000000000000000000000000000e36d996215f00840000000000000000000000000000000000000000000000000e36835d6045c9700000000000000000000000000000000000000000000000000e36fabf5a9955e40000000000000000000000000000000000000000000000000000000000000000002d2fe013d18dcdc7d08d61c79d31ff7067487d86b6eb64b1b6c6010d31038b46d53e9324e546ea84b16d7f1b5ace563611ce5f758d11780d51ca737dade8a49dd00000000000000000000000000000000000000000000000000000000000000023da817f93c4e161d0cbb83282890dec993cd5ea1c1d8c0273f80a6553e724eef726fc2ad8a7f53c5ad0b3181ced439c17c764c04949a195dcb0d44015ae9b0a7 + + Report Metadata: + Feed ID: 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 + Valid From: 1758588883 + Observations: 1758588883 + + Decoded Data: + Native Fee: 76275680556912 + LINK Fee: 14805490063735767 + Expires At: 1761180883 + Price: 4195308356000000000000 + Bid Price: 4194920048000000000000 + Ask Price: 4195457700000000000000 + -------------------------------------------------- + Raw Report Blob #2: 0x00090d9e8d96765a0c49e03a6ae05c82e8f8de70cf179baa632f18313e54bd690000000000000000000000000000000000000000000000000000000001f71291000000000000000000000000000000000000000000000000000000030000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d02650000000000000000000000000000000000000000000000000000000068d1efd30000000000000000000000000000000000000000000000000000000068d1efd30000000000000000000000000000000000000000000000000000455f50d8377000000000000000000000000000000000000000000000000000349983c7f97bd70000000000000000000000000000000000000000000000000000000068f97cd30000000000000000000000000000000000000000000000012bf2f25e94eb68d80000000000000000000000000000000000000000000000012be4bb00ede340d00000000000000000000000000000000000000000000000012c0409033df7fc7c000000000000000000000000000000000000000000000000000000000000000271c4eaabcb5ae7335e87dcaa55851b5d40ccbb6abf6dc74c0b453274a0c2041e1099cca65a5ca74ee56733eab4d7b39868a726e3590ac1456c0cf95ed58e5f2d00000000000000000000000000000000000000000000000000000000000000027a89cf0cd8059f4803b413ceef42fce264a04d779a6283147a3d9e69b088b94d25708a4fe7434aecb3ce87f90c5dd24a1c90aa0180c7fee1b705d7db4589ef4f + + Report Metadata: + Feed ID: 0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265 + Valid From: 1758588883 + Observations: 1758588883 + + Decoded Data: + Native Fee: 76275680556912 + LINK Fee: 14805490063735767 + Expires At: 1761180883 + Price: 21613604049743735000 + Bid Price: 21609602524695970000 + Ask Price: 21618414020814437500 + -------------------------------------------------- + ``` + +### Decoded report details + +The decoded [crypto v3 report](/data-streams/reference/report-schema-v3) details include: + +| Attribute | Value | Description | +| ---------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Stream ID | `0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782` | The unique identifier for the stream. In this example, the stream is for ETH/USD. | +| Observations Timestamp | `1734216283` | The timestamp indicating when the data was captured. | +| Benchmark Price | `3865052126782320350000` | The observed price in the report, with 18 decimals. For readability: `3,865.0521267823204` USD per ETH. | +| Bid | `3864985478146740000000` | The highest price a buyer is willing to pay for an asset, with 18 decimals. For readability: `3,864.9854781467400` USD per ETH. Learn more about the [Bid price](/data-streams/concepts/liquidity-weighted-prices). (For [DEX State Price streams](/data-streams/concepts/dex-state-price-streams), this value equals `Benchmark Price`.) | +| Ask | `3865140837060103650000` | The lowest price a seller is willing to accept for an asset, with 18 decimals. For readability: `3,865.1408370601037` USD per ETH. Learn more about the [Ask price](/data-streams/concepts/liquidity-weighted-prices). (For [DEX State Price streams](/data-streams/concepts/dex-state-price-streams), this value equals `Benchmark Price`.) | +| Valid From Timestamp | `1734216283` | The start validity timestamp for the report, indicating when the data becomes relevant. | +| Expires At | `1734302683` | The expiration timestamp of the report, indicating the point at which the data becomes outdated. | +| Link Fee | `3379350941986000` | The fee to pay in LINK tokens for the onchain verification of the report data. With 18 decimals. For readability: `0.03379350941986` LINK. **Note:** This example fee is not indicative of actual fees. | +| Native Fee | `25872872271800` | The fee to pay in the native blockchain token (e.g., ETH on Ethereum) for the onchain verification of the report data. With 18 decimals. **Note:** This example fee is not indicative of actual fees. | + +### Payload for onchain verification + +In this tutorial, you logged and decoded the `full_report` payloads to extract the report data. However, in a production environment, you should verify the data to ensure its integrity and authenticity. + +Refer to the [Verify report data onchain](/data-streams/tutorials/evm-onchain-report-verification) tutorial to learn more. + +## Explanation + +### Initializing the client and configuration + +The Data Streams TypeScript client is initialized in two steps: + +1. Configure the client with a config object: + +```typescript +const config = { + apiKey: process.env.API_KEY || "YOUR_API_KEY", + userSecret: process.env.USER_SECRET || "YOUR_USER_SECRET", + endpoint: "https://api.testnet-dataengine.chain.link", + wsEndpoint: "wss://ws.testnet-dataengine.chain.link", + // Optional logging: + logging: { + logger: console, + logLevel: LogLevel.INFO, + }, +} +``` + +The configuration requires: + +- `apiKey` and `userSecret` for authentication (required) +- `endpoint` for the API endpoint (required) +- `logging` for debugging and error tracking (optional) + +See the [SDK Reference](/data-streams/reference/data-streams-api/ts-sdk) page for more configuration options. + +2. Create the client with `createClient`: + +```typescript +const client = createClient(config) +``` + +The client handles: + +- Authentication with HMAC signatures +- Connection management and timeouts +- Error handling and retries + +### Fetching reports + +The TypeScript SDK provides two main methods to fetch reports: + +1. Latest report for a single stream with `getLatestReport`: + +```typescript +const report = await client.getLatestReport(feedId) +``` + +- Takes a feed ID string +- Returns a single `ReportResponse` with the most recent data +- No timestamp parameter needed +- Useful for real-time price monitoring + +2. Latest reports for multiple streams by calling `getLatestReport` in a loop: + +```typescript +for (const feedId of feedIds) { + const report = await client.getLatestReport(feedId) + reports.push(report) +} +``` + +- Takes an array of feed ID strings +- Calls `getLatestReport` for each feed ID individually +- Returns the most recent data for each stream +- Useful for monitoring multiple assets simultaneously +- Each request gets the latest available data without timestamp constraints + +Each API request automatically: + +- Handles authentication with API credentials +- Manages request timeouts via the Node/SDK configuration +- Processes responses into structured types + +### Decoding reports + +Reports are decoded in two steps using the TypeScript SDK helper functions: + +1. Report decoding with `decodeReport` (auto-detects report version by feed ID): + +```typescript +const decodedData = decodeReport(report.fullReport, report.feedID) +``` + +This step: + +1. Takes the raw `fullReport` bytes/string from the response +2. Uses the report schema that matches the feed (SDK detects version) +3. Validates the format and decodes into a structured object +4. Returns decoded data that can be combined with report metadata and formatted using `formatReport()` + +For more details, see the [Report Format section of the SDK Reference](/data-streams/reference/data-streams-api/ts-sdk#report-format). + +### Error handling + +The TypeScript examples use standard try/catch patterns and optional timeouts: + +1. Request timeouts / cancellation + +Use your application's timeout/cancellation mechanism (for example, AbortController) when making requests to the SDK or wrap calls in a manual timeout. + +2. Error checking + +```typescript +try { + const report = await client.getLatestReport(feedId) +} catch (err) { + console.error("Failed to fetch report:", err) + process.exit(1) // fatal error +} +``` + +- Fatal errors (client creation, missing credentials) typically exit the process +- Non-fatal errors (single report decode) can be logged and skipped when processing multiple feeds +- All errors should be logged with context for easier debugging + +Learn more about SDK error handling in the [SDK Reference](/data-streams/reference/data-streams-api/ts-sdk#error-handling). + +3. SDK logging + +The SDK can log requests and responses when `logging` is enabled in the config. In the example above we pass `console` as the logger and set `LogLevel.INFO`. + +The decoded data can be used for further processing or display in your application. For production environments, you must verify the data onchain using the provided `fullReport` payload. + +For more information about SDK logging configuration and monitoring options, see the [SDK Reference](/data-streams/reference/data-streams-api/ts-sdk#observability-logs--metrics). + +> > > > > > > c98d3598 (draft ts-sdk-fetch) From e4ed46d41419aac323f0bcab7dcfa0e74dc8774e Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Mon, 22 Sep 2025 21:29:52 -0700 Subject: [PATCH 03/18] ts sdk stream draft --- .../data-streams/tutorials/ts-sdk-stream.mdx | 380 ++++++++++++++++++ 1 file changed, 380 insertions(+) diff --git a/src/content/data-streams/tutorials/ts-sdk-stream.mdx b/src/content/data-streams/tutorials/ts-sdk-stream.mdx index 290fcdcac0f..4bc946c6c6c 100644 --- a/src/content/data-streams/tutorials/ts-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/ts-sdk-stream.mdx @@ -37,3 +37,383 @@ import DataStreams from "@features/data-streams/common/DataStreams.astro" }, ]} /> + +In this tutorial, you'll learn how to use the [Data Streams SDK](/data-streams/reference/data-streams-api/ts-sdk) for TypeScript to subscribe to real-time [reports](/data-streams/reference/report-schema-overview) via a [WebSocket connection](/data-streams/reference/data-streams-api/interface-ws). You'll set up your TypeScript project, listen for real-time reports from the Data Streams Aggregation Network, decode the report data, and log their attributes to your terminal. + + + +## Requirements + +- **Git**: Make sure you have Git installed. You can check your current version by running in your terminal and download the latest version from the official [Git website](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) if necessary. +- **Node.js**: Make sure you have Node.js 20.0 or higher. You can check your current version by running in your terminal and download the latest version from the official [Node.js website](https://nodejs.org/) if necessary. +- **TypeScript**: Make sure you have TypeScript 5.3 or higher. You can check your current version by running in your terminal and install or update TypeScript by running if necessary. +- **API Credentials**: Access to Data Streams requires API credentials. If you haven't already, [contact us](https://chainlinkcommunity.typeform.com/datastreams?typeform-source=docs.chain.link#ref_id=docs) to request mainnet or testnet access. + +## Tutorial + +First, you'll set up a basic TypeScript project, installing the SDK and pasting example code. This will let you stream reports for [streams](/data-streams/crypto-streams), logging their attributes to your terminal. + +### Set up your TypeScript project + +1. Create a new directory for your project and navigate to it: + + ```bash + mkdir my-data-streams-project + cd my-data-streams-project + ``` + +1. Initialize a new Node.js project: + + ```bash + npm init -y + ``` + +1. Install the TypeScript SDK and other required packages: + + ```bash + npm install @chainlink/data-streams-sdk dotenv + npm install -D typescript @types/node tsx + ``` + +1. Set your API credentials: + + Option 1 - Environment variables: + + ```bash + export API_KEY="your_api_key_here" + export USER_SECRET="your_user_secret_here" + ``` + + Option 2 - `.env` file: + + ```bash + # Create .env file + touch .env + + # Add your credentials + API_KEY="your_api_key_here" + USER_SECRET="your_user_secret_here" + ``` + +### Establish a WebSocket connection and listen for real-time reports + +1. Create a new TypeScript file, `stream.ts`, in your project directory: + + ```bash + touch stream.ts + ``` + +1. Insert the following code example and save your `stream.ts` file: + + ```typescript + import { createClient, LogLevel, decodeReport, getReportVersion, formatReport } from "@chainlink/data-streams-sdk" + import "dotenv/config" + + async function main() { + if (process.argv.length < 3) { + console.error("Please provide one or more feed IDs as arguments") + console.error("\nExamples:") + console.error(" Single feed:") + console.error(" npx ts-node stream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782") + console.error(" Multiple feeds:") + console.error( + " npx ts-node stream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782,0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265" + ) + process.exit(1) + } + + const feedIds = process.argv[2].split(",") + + console.log("Chainlink Data Streams - Report Streaming") + console.log("=".repeat(60)) + console.log(`šŸ“Š Feeds: ${feedIds.length} feed(s)`) + console.log("=".repeat(60)) + + try { + const client = createClient({ + apiKey: process.env.API_KEY || "YOUR_API_KEY", + userSecret: process.env.USER_SECRET || "YOUR_USER_SECRET", + endpoint: "https://api.testnet-dataengine.chain.link", + wsEndpoint: "wss://ws.testnet-dataengine.chain.link", + + // Comment to disable SDK logging: + logging: { + logger: console, + logLevel: LogLevel.INFO, + enableConnectionDebug: false, // Enable WebSocket ping/pong and connection state logs (logLevel should be DEBUG) + }, + }) + + let reportCount = 0 + + // Create stream with custom options + const stream = client.createStream(feedIds, { + maxReconnectAttempts: 10, + reconnectInterval: 3000, + }) + + // Event: Process incoming reports + stream.on("report", (report) => { + reportCount++ + + try { + console.log(`\nšŸ“ˆ Report #${reportCount} - ${new Date().toISOString()}`) + + // Show raw report blob + console.log(`\nRaw Report Blob: ${report.fullReport}`) + + // Decode the report + const decodedData = decodeReport(report.fullReport, report.feedID) + const version = getReportVersion(report.feedID) + + // Combine decoded data with report metadata + const decodedReport = { + ...decodedData, + feedID: report.feedID, + validFromTimestamp: report.validFromTimestamp, + observationsTimestamp: report.observationsTimestamp, + } + + console.log(formatReport(decodedReport, version)) + } catch (error) { + console.error(`āŒ Error processing report: ${error instanceof Error ? error.message : error}`) + } + + // Display stats every 5 reports + if (reportCount % 5 === 0) { + const stats = stream.getMetrics() + console.log( + `\nšŸ“Š Stats: ${stats.accepted} reports | ${stats.activeConnections}/${stats.configuredConnections} connections` + ) + } + }) + + // Event: Handle errors + stream.on("error", (error) => { + console.error(`\nāŒ Error: ${error.message}`) + + if (error.message.includes("authentication")) { + console.error("šŸ’” Check your API_KEY and USER_SECRET environment variables") + } + }) + + // Event: Handle disconnections + stream.on("disconnected", () => { + console.log("\nšŸ”“ Stream disconnected - reconnecting...") + }) + + // Event: Monitor reconnections + stream.on("reconnecting", (info: { attempt: number; delayMs: number; origin?: string; host?: string }) => { + console.log( + `šŸ”„ Reconnecting... attempt ${info.attempt} in ~${info.delayMs}ms${info.host ? ` (${info.host})` : ""}` + ) + }) + + console.log("ā³ Connecting...\n") + await stream.connect() + console.log("āœ… Connected! Listening for reports...\n") + + // Graceful shutdown + const shutdown = async () => { + console.log("\nšŸ›‘ Shutting down...") + await stream.close() + console.log("āœ… Shutdown complete") + process.exit(0) + } + + process.on("SIGINT", shutdown) + process.on("SIGTERM", shutdown) + } catch (error) { + console.error("āŒ Failed to start stream:", error instanceof Error ? error.message : error) + process.exit(1) + } + } + + main() + ``` + + + +1. Subscribe to a [testnet crypto stream](/data-streams/crypto-streams?page=1&testnetPage=1#testnet-crypto-streams). The below example executes the application, subscribing to the `ETH/USD` crypto stream: + + ```bash + npx ts-node stream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 + ``` + + Expect output similar to the following in your terminal: + + ```bash + Chainlink Data Streams - Report Streaming + ============================================================ + šŸ“Š Feeds: 1 feed(s) + ============================================================ + ā³ Connecting... + + [2025-09-23T01:15:23.456Z] [DataStreams] Data Streams client initialized + [2025-09-23T01:15:23.789Z] [DataStreams] WebSocket connected + āœ… Connected! Listening for reports... + + šŸ“ˆ Report #1 - 2025-09-23T01:15:24.123Z + + Raw Report Blob: 0x00090d9e8d96765a0c49e03a6ae05c82e8f8de70cf179baa632f18313e54bd690000000000000000000000000000000000000000000000000000000001f71291000000000000000000000000000000000000000000000000000000030000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000028001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba7820000000000000000000000000000000000000000000000000000000068d1efd30000000000000000000000000000000000000000000000000000000068d1efd30000000000000000000000000000000000000000000000000000455f50d8377000000000000000000000000000000000000000000000000000349983c7f97bd70000000000000000000000000000000000000000000000000000000068f97cd30000000000000000000000000000000000000000000000e36d996215f00840000000000000000000000000000000000000000000000000e36835d6045c9700000000000000000000000000000000000000000000000000e36fabf5a9955e40000000000000000000000000000000000000000000000000000000000000000002d2fe013d18dcdc7d08d61c79d31ff7067487d86b6eb64b1b6c6010d31038b46d53e9324e546ea84b16d7f1b5ace563611ce5f758d11780d51ca737dade8a49dd + + Report Metadata: + Feed ID: 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 + Valid From: 1758588883 + Observations: 1758588883 + + Decoded Data: + Native Fee: 76275680556912 + LINK Fee: 14805490063735767 + Expires At: 1761180883 + Price: 4195308356000000000000 + Bid Price: 4194920048000000000000 + Ask Price: 4195457700000000000000 + -------------------------------------------------- + + šŸ“ˆ Report #2 - 2025-09-23T01:15:25.234Z + + Raw Report Blob: 0x00090d9e8d96765a0c49e03a6ae05c82e8f8de70cf179baa632f18313e54bd690000000000000000000000000000000000000000000000000000000001f71292000000000000000000000000000000000000000000000000000000030000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000028001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba7820000000000000000000000000000000000000000000000000000000068d1efd40000000000000000000000000000000000000000000000000000000068d1efd40000000000000000000000000000000000000000000000000000455f45d2349000000000000000000000000000000000000000000000000000349968c9f98bd70000000000000000000000000000000000000000000000000000000068f97cd40000000000000000000000000000000000000000000000e36d8b5b2b6084000000000000000000000000000000000000000000000000000e36824f6b8c970000000000000000000000000000000000000000000000000e36fc15a99955e400000000000000000000000000000000000000000000000000000000000000000028f3c0139b8c7d08d61c79d31ff7067487d86b6eb64b1b6c6010d31038b46d53e932 + + Report Metadata: + Feed ID: 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 + Valid From: 1758588884 + Observations: 1758588884 + + Decoded Data: + Native Fee: 76275680556912 + LINK Fee: 14805490063735767 + Expires At: 1761180884 + Price: 4195298740000000000000 + Bid Price: 4194910430000000000000 + Ask Price: 4195448050000000000000 + -------------------------------------------------- + + šŸ“Š Stats: 5 reports | 1/1 connections + + [...] + ``` + + Your application has successfully subscribed to the report data. + + [Learn more about the decoded report details](#decoded-report-details). + +### Decoded report details + +The decoded report details include: + +| Attribute | Value | Description | +| ------------------------ | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `Stream ID` | `0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782` | The unique identifier for the stream. In this example, the stream is for ETH/USD. | +| `Observations Timestamp` | `1758588884` | The timestamp indicating when the data was captured. | +| `Benchmark Price` | `4195298740000000000000` | The observed price in the report, with 18 decimals. For readability: `4,195.29874` USD per ETH. | +| `Bid` | `4194910430000000000000` | The highest price a buyer is willing to pay for an asset, with 18 decimals. For readability: `4,194.91043` USD per ETH. Learn more about the [Bid price](/data-streams/concepts/liquidity-weighted-prices). (For [DEX State Price streams](/data-streams/concepts/dex-state-price-streams), this value equals `Benchmark Price`.) | +| `Ask` | `4195448050000000000000` | The lowest price a seller is willing to accept for an asset, with 18 decimals. For readability: `4,195.44805` USD per ETH. Learn more about the [Ask price](/data-streams/concepts/liquidity-weighted-prices). (For [DEX State Price streams](/data-streams/concepts/dex-state-price-streams), this value equals `Benchmark Price`.) | +| `Valid From Timestamp` | `1758588884` | The start validity timestamp for the report, indicating when the data becomes relevant. | +| `Expires At` | `1761180884` | The expiration timestamp of the report, indicating the point at which the data becomes outdated. | +| `Link Fee` | `14805490063735767` | The fee to pay in LINK tokens for the onchain verification of the report data, with 18 decimals. For readability: `0.014805490063735767` LINK. **Note:** This example fee is not indicative of actual fees. | +| `Native Fee` | `76275680556912` | The fee to pay in the native blockchain token (e.g., ETH on Ethereum) for the onchain verification of the report data, with 18 decimals. **Note:** This example fee is not indicative of actual fees. | + +For descriptions and data types of other report schemas, see the [Report Schema Overview](/data-streams/reference/report-schema-overview). + +### High Availability (HA) mode + + + +High Availability (HA) mode creates multiple WebSocket connections to different origin endpoints for improved reliability. When enabled, the SDK automatically handles failover, deduplicates reports, and provides connection-level metrics. + +#### Enabling HA mode + +To enable HA mode in your streaming application, make these changes to the basic example: + +1. Add `haMode: true` to the client configuration. You also must use a mainnet endpoint, as HA mode is not currently supported on testnet. + +```typescript +const client = createClient({ + apiKey: process.env.API_KEY || "YOUR_API_KEY", + userSecret: process.env.USER_SECRET || "YOUR_USER_SECRET", + endpoint: "https://api.dataengine.chain.link", // Mainnet endpoint + wsEndpoint: "wss://ws.dataengine.chain.link", // Mainnet WebSocket + haMode: true, // Enable High Availability mode + + // Optional: Monitor connection status changes + connectionStatusCallback: (isConnected: boolean, host: string, origin?: string) => { + const status = isConnected ? "🟢 Connected" : "šŸ”“ Disconnected" + console.log(`${status}: ${host}${origin ? ` (${origin})` : ""}`) + }, + + logging: { + logger: console, + logLevel: LogLevel.INFO, + }, +}) +``` + +2. Optionally, monitor HA metrics using the existing `getMetrics()` calls in your report handler: + +```typescript +stream.on("report", (report) => { + // ... your report processing logic + + // HA-specific metrics + const stats = stream.getMetrics() + console.log( + `šŸ“Š HA Stats: ${stats.accepted} reports | ${stats.activeConnections}/${stats.configuredConnections} connections` + ) + console.log(`Reconnects: ${stats.partialReconnects} partial, ${stats.fullReconnects} full`) + + // Check deduplication (important for HA mode) + if (stats.totalReceived > 0) { + const deduplicationRate = ((stats.deduplicated / stats.totalReceived) * 100).toFixed(1) + console.log(`šŸ“ˆ Deduplication: ${deduplicationRate}% (${stats.deduplicated} filtered)`) + } +}) +``` + +When `haMode` is `true`, the SDK automatically discovers multiple origin endpoints behind the single URL and establishes separate connections to each origin. + +The optional `connectionStatusCallback` can be used to integrate with external monitoring systems. The SDK already provides comprehensive connection logs, so this callback is primarily useful for custom alerting or metrics collection. + +### Payload for onchain verification + +In this tutorial, you logged and decoded the `full_report` payloads to extract the report data. However, in a production environment, you should verify the data to ensure its integrity and authenticity. + +Refer to the [Verify report data onchain](/data-streams/tutorials/evm-onchain-report-verification) tutorial to learn more. + +## Explanation + +### Establishing a WebSocket connection and listening for reports + +Your application uses the `createClient` function from the [Data Streams SDK](/data-streams/reference/data-streams-api/ts-sdk) to create a client, then uses `client.createStream()` to establish a real-time WebSocket connection with the Data Streams Aggregation Network. + +Once the WebSocket connection is established, your application subscribes to one or more streams by passing an array of feed IDs to the `createStream` function. This subscription lets the client receive real-time updates whenever new report data is available for the specified streams. + +Fore further reference, see the [WebSocket Interface](/data-streams/reference/data-streams-api/interface-ws) section of the SDK Reference. + +### Event-driven streaming + +The TypeScript SDK uses an event-driven approach for handling streaming data: + +- **Connection events**: The [stream emits `connected`, `disconnected`, and `reconnecting` events](/data-streams/reference/data-streams-api/ts-sdk#streaming) to track connection status. +- **Report events**: When new reports arrive, the `report` [event is triggered](/data-streams/reference/data-streams-api/ts-sdk#streaming) with the decoded report data. +- **Error handling**: The stream [emits `error` events](/data-streams/reference/data-streams-api/ts-sdk#error-handling) for any issues that occur during streaming. +- **Metrics**: [The `getMetrics()` method provides](/data-streams/reference/data-streams-api/ts-sdk#metrics-streamgetmetrics) real-time statistics about the stream performance. + +### Decoding and processing reports + +As data reports arrive via the established WebSocket connection, they are processed in real-time: + +- **Automatic decoding**: The SDK's `decodeReport` function automatically [detects the report version](/data-streams/reference/data-streams-api/ts-sdk#report-format) and parses the raw data into a structured format. +- **Real-time processing**: Each received report triggers the `report` event handler, where you can process, log, or store the decoded data. +- **Error resilience**: Individual report processing errors don't interrupt the stream, allowing continuous operation. + +### Handling the decoded data + +In this example, the application logs the structured report data to the terminal. However, this data can be used for further processing, analysis, or display in your own application. The decoded data includes essential information such as benchmark prices, bid/ask spreads, and fee data for onchain verification. + +For more information about SDK streaming configuration and advanced options, see the [SDK Reference](/data-streams/reference/data-streams-api/ts-sdk). From 7e4c83597f6fdb584095cf763a820717ba81f0c0 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 23 Sep 2025 12:55:48 -0700 Subject: [PATCH 04/18] ts-node->tsx --- src/content/data-streams/tutorials/ts-sdk-fetch.mdx | 10 +++++----- src/content/data-streams/tutorials/ts-sdk-stream.mdx | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/content/data-streams/tutorials/ts-sdk-fetch.mdx b/src/content/data-streams/tutorials/ts-sdk-fetch.mdx index 74dee055933..abb7750852c 100644 --- a/src/content/data-streams/tutorials/ts-sdk-fetch.mdx +++ b/src/content/data-streams/tutorials/ts-sdk-fetch.mdx @@ -108,7 +108,7 @@ You'll start with the set up of your TypeScript project, installing the SDK and if (process.argv.length < 3) { console.error("Please provide a feed ID as an argument") console.error( - "Example: npx ts-node examples/get-latest-report.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782" + "Example: npx tsx examples/get-latest-report.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782" ) process.exit(1) } @@ -167,7 +167,7 @@ You'll start with the set up of your TypeScript project, installing the SDK and 1. Read from a [testnet crypto stream](/data-streams/crypto-streams?page=1&testnetPage=1#testnet-crypto-streams). The below example executes the application, reading from the `ETH/USD` crypto stream: ```bash - npx ts-node singleStream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 + npx tsx singleStream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 ``` Expect output similar to the following in your terminal: @@ -215,10 +215,10 @@ You'll start with the set up of your TypeScript project, installing the SDK and if (process.argv.length < 3) { console.error("Please provide feed IDs as arguments") console.error("Get latest reports for multiple feeds:") - console.error(" npx ts-node multipleStreams.ts [feedID3...]") + console.error(" npx tsx multipleStreams.ts [feedID3...]") console.error("\nExample:") console.error( - " npx ts-node multipleStreams.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265" + " npx tsx multipleStreams.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265" ) process.exit(1) } @@ -311,7 +311,7 @@ You'll start with the set up of your TypeScript project, installing the SDK and 1. Read from two testnet crypto streams (ETH/USD and LINK/USD) by running: ```bash - npx ts-node multipleStreams.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265 + npx tsx multipleStreams.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265 ``` Expect to see the output below in your terminal: diff --git a/src/content/data-streams/tutorials/ts-sdk-stream.mdx b/src/content/data-streams/tutorials/ts-sdk-stream.mdx index 4bc946c6c6c..a2a35840533 100644 --- a/src/content/data-streams/tutorials/ts-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/ts-sdk-stream.mdx @@ -114,10 +114,10 @@ First, you'll set up a basic TypeScript project, installing the SDK and pasting console.error("Please provide one or more feed IDs as arguments") console.error("\nExamples:") console.error(" Single feed:") - console.error(" npx ts-node stream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782") + console.error(" npx tsx stream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782") console.error(" Multiple feeds:") console.error( - " npx ts-node stream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782,0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265" + " npx tsx stream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782,0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265" ) process.exit(1) } @@ -240,7 +240,7 @@ First, you'll set up a basic TypeScript project, installing the SDK and pasting 1. Subscribe to a [testnet crypto stream](/data-streams/crypto-streams?page=1&testnetPage=1#testnet-crypto-streams). The below example executes the application, subscribing to the `ETH/USD` crypto stream: ```bash - npx ts-node stream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 + npx tsx stream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 ``` Expect output similar to the following in your terminal: From 3e31d44c3611f364904c70c5a7e43fd5b403823b Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 23 Sep 2025 15:37:03 -0700 Subject: [PATCH 05/18] updated installation instructions, avoid typescript issues --- src/content/data-streams/tutorials/ts-sdk-fetch.mdx | 4 ++-- src/content/data-streams/tutorials/ts-sdk-stream.mdx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/data-streams/tutorials/ts-sdk-fetch.mdx b/src/content/data-streams/tutorials/ts-sdk-fetch.mdx index abb7750852c..d6021e35ce2 100644 --- a/src/content/data-streams/tutorials/ts-sdk-fetch.mdx +++ b/src/content/data-streams/tutorials/ts-sdk-fetch.mdx @@ -60,14 +60,14 @@ You'll start with the set up of your TypeScript project, installing the SDK and 1. Initialize a new Node.js project: ```bash - npm init -y + npm init -y ``` 1. Install the TypeScript SDK and other required packages: ```bash npm install @chainlink/data-streams-sdk dotenv - npm install -D typescript @types/node tsx + npm install -D tsx ``` 1. Set your API credentials: diff --git a/src/content/data-streams/tutorials/ts-sdk-stream.mdx b/src/content/data-streams/tutorials/ts-sdk-stream.mdx index a2a35840533..c23f5db7920 100644 --- a/src/content/data-streams/tutorials/ts-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/ts-sdk-stream.mdx @@ -72,7 +72,7 @@ First, you'll set up a basic TypeScript project, installing the SDK and pasting ```bash npm install @chainlink/data-streams-sdk dotenv - npm install -D typescript @types/node tsx + npm install -D tsx ``` 1. Set your API credentials: From 8f01811b3f04dd14b429d52142f500f0e3b1f28c Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 23 Sep 2025 17:00:20 -0700 Subject: [PATCH 06/18] sdk reference cherrypicked from old branch --- .../reference/data-streams-api/ts-sdk.mdx | 494 +++++++++++++++++- 1 file changed, 493 insertions(+), 1 deletion(-) diff --git a/src/content/data-streams/reference/data-streams-api/ts-sdk.mdx b/src/content/data-streams/reference/data-streams-api/ts-sdk.mdx index a6b9574cb13..02d97aa9c3f 100644 --- a/src/content/data-streams/reference/data-streams-api/ts-sdk.mdx +++ b/src/content/data-streams/reference/data-streams-api/ts-sdk.mdx @@ -14,7 +14,7 @@ whatsnext: --- import DataStreams from "@features/data-streams/common/DataStreams.astro" -import { PageTabs } from "@components" +import { Aside, PageTabs } from "@components" @@ -39,3 +39,495 @@ import { PageTabs } from "@components" }, ]} /> +The Data Streams SDK for accessing Chainlink Data Streams with real-time streaming and historical data retrieval. + +## Requirements + +- Node.js >= 20.0.0 +- TypeScript >= 5.3.x +- Valid Chainlink Data Streams credentials + +## Features + +- **[Real-time streaming](#streaming)** via WebSocket connections +- **[High Availability mode](#high-availability-mode)** with multiple connections and automatic failover +- **Historical data access** via [REST API](#rest-api) +- **[Automatic report decoding](#schema-auto-detection)** for all supported formats (V2, V3, V4, V5, V6, V7, V8, V9, V10) +- **[Metrics](#observability-logs--metrics)** for monitoring and observability +- **Type-safe** with full TypeScript support +- **Event-driven architecture** for complete developer control + +## Installation + +```bash +npm install @chainlink/data-streams-sdk +``` + +## Configuration + +### Configuration Interface + +```typescript +interface Config { + // Required + apiKey: string // API key for authentication + userSecret: string // User secret for authentication + endpoint: string // REST API URL + wsEndpoint: string // WebSocket URL + + // Optional - Request & Retry + timeout?: number // Request timeout (default: 30000ms) + retryAttempts?: number // Retry attempts (default: 3) + retryDelay?: number // Retry delay (default: 1000ms) + + // Optional - High Availability + haMode?: boolean // Enable HA mode (default: false) + haConnectionTimeout?: number // HA connection timeout (default: 10000ms) + connectionStatusCallback?: (isConnected: boolean, host: string, origin: string) => void + + // Optional - Logging + logging?: LoggingConfig // See Logging Configuration section +} +``` + +### Basic Usage + +```typescript +const client = createClient({ + apiKey: process.env.API_KEY, + userSecret: process.env.USER_SECRET, + endpoint: "https://api.dataengine.chain.link", + wsEndpoint: "wss://ws.dataengine.chain.link", +}) +``` + +### High Availability Example + +```typescript +const haClient = createClient({ + apiKey: process.env.API_KEY, + userSecret: process.env.USER_SECRET, + endpoint: "https://api.dataengine.chain.link", // Mainnet only + wsEndpoint: "wss://ws.dataengine.chain.link", // Single endpoint with origin discovery + haMode: true, +}) +``` + +**Note:** [High Availability mode](#high-availability-mode) is only available on mainnet, not testnet. + +## Examples + + +**Quick Commands:** + +```bash +# Real-time streaming +npx ts-node examples/stream-reports.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 + +# High Availability streaming +npx ts-node examples/stream-reports.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 --ha + +# Get latest report +npx ts-node examples/get-latest-report.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 + +# List all available feeds +npx ts-node examples/list-feeds.ts +``` + +**Complete examples** +See the [SDK repo examples](https://github.com/smartcontractkit/data-streams-sdk/tree/main/typescript/examples) for detailed usage and setup. Available examples include: + +- **Streaming:** Basic streaming, HA mode, metrics monitoring +- **REST API:** Latest reports, historical data, bulk operations, feed management +- **Configuration:** Logging setup, debugging, monitoring integration + +## API Reference + +### Streaming + +```typescript +// Create stream +const stream = client.createStream(feedIds, options?); + +// Events +stream.on('report', (report) => { ... }); +stream.on('error', (error) => { ... }); +stream.on('disconnected', () => { ... }); +stream.on('reconnecting', (info) => { ... }); + +// Control +await stream.connect(); +await stream.close(); + +// Metrics +const metrics = stream.getMetrics(); +``` + +### Stream Options + +```typescript +interface StreamOptions { + maxReconnectAttempts?: number // Default: 5 + // Base delay (in ms) for exponential backoff. + // Actual delay grows as: base * 2^(attempt-1) with jitter, capped at 10000ms. + // Default: 1000ms; user-provided values are clamped to the safe range [200ms, 10000ms]. + reconnectInterval?: number +} +``` + +### REST API + +```typescript +// Get feeds +const feeds = await client.listFeeds(); + +// Get latest report +const report = await client.getLatestReport(feedId); + +// Get historical report +const report = await client.getReportByTimestamp(feedId, timestamp); + +// Get report page +const reports = await client.getReportsPage(feedId, startTime, limit?); + +// Get bulk reports +const reports = await client.getReportsBulk(feedIds, timestamp); +``` + +## Report Format + +### Quick Decoder Usage + +```typescript +import { decodeReport } from "@chainlink/data-streams-sdk" +const decoded = decodeReport(report.fullReport, report.feedID) +``` + +### Schema Auto-Detection + +The SDK automatically detects and decodes all report versions based on Feed ID patterns: + +- **V2**: Feed IDs starting with `0x0002` +- **V3**: Feed IDs starting with `0x0003` (Crypto Streams) +- **V4**: Feed IDs starting with `0x0004` (Real-World Assets) +- **V5**: Feed IDs starting with `0x0005` +- **V6**: Feed IDs starting with `0x0006` (Multiple Price Values) +- **V7**: Feed IDs starting with `0x0007` +- **V8**: Feed IDs starting with `0x0008` (Non-OTC RWA) +- **V9**: Feed IDs starting with `0x0009` (NAV Fund Data) +- **V10**: Feed IDs starting with `0x000a` (Tokenized Equity) + +### Common Fields + +All reports include standard metadata: + +```typescript +interface BaseFields { + version: "V2" | "V3" | "V4" | "V5" | "V6" | "V7" | "V8" | "V9" | "V10" + nativeFee: bigint + linkFee: bigint + expiresAt: number + feedID: string + validFromTimestamp: number + observationsTimestamp: number +} +``` + +### Schema-Specific Fields + +- **V2/V3/V4**: `price: bigint` - Standard price data +- **V3**: `bid: bigint, ask: bigint` - Crypto bid/ask spreads +- **V4**: `marketStatus: MarketStatus` - Real-world asset market status +- **V5**: `rate: bigint, timestamp: number, duration: number` - Interest rate data with observation timestamp and duration +- **V6**: `price: bigint, price2: bigint, price3: bigint, price4: bigint, price5: bigint` - Multiple price values in a single payload +- **V7**: `exchangeRate: bigint` - Exchange rate data +- **V8**: `midPrice: bigint, lastUpdateTimestamp: number, marketStatus: MarketStatus` - Non-OTC RWA data +- **V9**: `navPerShare: bigint, navDate: number, aum: bigint, ripcord: number` - NAV fund data +- **V10**: `price: bigint, lastUpdateTimestamp: number, marketStatus: MarketStatus, currentMultiplier: bigint, newMultiplier: bigint, activationDateTime: number, tokenizedPrice: bigint` - Tokenized equity data + +For complete field definitions, see the [complete list of available reports and their schemas](/data-streams/reference/report-schema-overview). + +## High Availability Mode + +HA mode establishes multiple simultaneous connections for zero-downtime operation: + +- **Automatic failover** between connections +- **Report deduplication** across connections +- **Automatic origin discovery** to find available endpoints +- **Per-connection monitoring** and statistics + +```typescript +const client = createClient({ + // ...config + haMode: true, + wsEndpoint: "wss://ws.dataengine.chain.link", // Single endpoint (mainnet only) +}) +``` + +**How it works:** When `haMode` is `true`, the SDK automatically discovers multiple origin endpoints behind the single URL and establishes separate connections to each origin. + +**Connection monitoring:** The optional `connectionStatusCallback` can be used to integrate with external monitoring systems. The SDK already provides comprehensive connection logs, so this callback is primarily useful for custom alerting or metrics collection. See [`examples/metrics-monitoring.ts`](https://github.com/smartcontractkit/data-streams-sdk/blob/main/typescript/examples/metrics-monitoring.ts) for a complete implementation example. + +**Important:** HA mode is only available on mainnet endpoints. + +## Error Handling + +### Error Types Overview + +| **Error Type** | **When Thrown** | **Key Properties** | +| ------------------------------- | ------------------------------------------- | --------------------------------------------- | +| `ValidationError` | Invalid feed IDs, timestamps, parameters | `message` | +| `AuthenticationError` | Invalid credentials, HMAC failures | `message` | +| `APIError` | HTTP 4xx/5xx, network timeouts, rate limits | `statusCode`, `message` | +| `ReportDecodingError` | Corrupted report data, unsupported versions | `message` | +| `WebSocketError` | Connection failures, protocol errors | `message` | +| `OriginDiscoveryError` | HA discovery failures | `cause`, `message` | +| `MultiConnectionError` | All HA connections failed | `message` | +| `PartialConnectionFailureError` | Some HA connections failed | `failedConnections`, `totalConnections` | +| `InsufficientConnectionsError` | HA degraded performance | `availableConnections`, `requiredConnections` | + +### Usage Examples + +```typescript +import { + ValidationError, + AuthenticationError, + APIError, + ReportDecodingError, + WebSocketError, + OriginDiscoveryError, + MultiConnectionError, +} from "./src" + +// REST API error handling +try { + const report = await client.getLatestReport(feedId) +} catch (error) { + if (error instanceof ValidationError) { + // Invalid feed ID or parameters + } else if (error instanceof AuthenticationError) { + // Check API credentials + } else if (error instanceof APIError) { + // Server error - check error.statusCode (429, 500, etc.) + } else if (error instanceof ReportDecodingError) { + // Corrupted or unsupported report format + } +} + +// Streaming error handling +stream.on("error", (error) => { + if (error instanceof WebSocketError) { + // Connection issues - retry or fallback + } else if (error instanceof OriginDiscoveryError) { + // HA discovery failed - falls back to static config + } else if (error instanceof MultiConnectionError) { + // All HA connections failed - critical + } +}) +``` + +**Catch-all error handling:** + +```typescript +import { DataStreamsError } from "./src" + +try { + // Any SDK operation +} catch (error) { + if (error instanceof DataStreamsError) { + // Handles ANY SDK error (base class for all error types above) + console.log("SDK error:", error.message) + } else { + // Non-SDK error (network, system, etc.) + console.log("System error:", error) + } +} +``` + +## Observability (Logs & Metrics) + +The SDK is designed to plug into your existing observability stack. + +### Logging (Pino/Winston/Console) + +Pass your logger to the SDK and choose a verbosity level. For deep WS diagnostics, enable connection debug. + +### Quick Start + +```typescript +import { createClient, LogLevel } from "@chainlink/data-streams-sdk" + +// Silent mode (default) - Zero overhead +const client = createClient({ + /* ... config without logging */ +}) + +// Basic console logging +const client = createClient({ + // ... other config + logging: { + logger: { + info: console.log, + warn: console.warn, + error: console.error, + }, + }, +}) +``` + +Using Pino (structured JSON): + +```typescript +import pino from "pino" +import { createClient, LogLevel } from "@chainlink/data-streams-sdk" + +const root = pino({ level: process.env.PINO_LEVEL || "info" }) +const sdk = root.child({ component: "sdk" }) + +const client = createClient({ + // ...config + logging: { + logger: { + info: sdk.info.bind(sdk), + warn: sdk.warn.bind(sdk), + error: sdk.error.bind(sdk), + debug: sdk.debug.bind(sdk), + }, + logLevel: LogLevel.INFO, + // For very verbose WS diagnostics, set DEBUG + enableConnectionDebug + // logLevel: LogLevel.DEBUG, + // enableConnectionDebug: true, + }, +}) +``` + +Command-line with pretty output: + +```bash +PINO_LEVEL=info npx ts-node examples/metrics-monitoring.ts | npx pino-pretty +``` + +### Log Levels + +#### šŸ”“ ERROR + +**Critical failures only** + +- Authentication failures +- Network connection errors +- Report decoding failures +- API request failures +- Unexpected crashes + +**Example Use:** Production alerts & monitoring + +--- + +#### 🟔 WARN + +**Everything in ERROR +** + +- Partial reconnections +- Fallback to static origins +- Retry attempts +- Connection timeouts +- Invalid data warnings + +**Example Use:** Production environments + +--- + +#### šŸ”µ INFO + +**Everything in WARN +** + +- Client initialization +- Successful API calls +- Stream connections +- Report retrievals +- Connection status changes +- Connection mode determination + +**Example Use:** Development & staging + +--- + +#### šŸ” DEBUG + +**Everything in INFO +** + +- Feed ID validation +- Report decoding steps +- Auth header generation +- Request/response details +- WebSocket ping/pong +- Origin discovery process +- Configuration validation +- Origin tracking (HA mode) + +**Example Use:** Debugging & development only + +### Logging Configuration Options + +```typescript +interface LoggingConfig { + /** External logger functions (console, winston, pino, etc.) */ + logger?: { + debug?: (message: string, ...args: any[]) => void + info?: (message: string, ...args: any[]) => void + warn?: (message: string, ...args: any[]) => void + error?: (message: string, ...args: any[]) => void + } + + /** Minimum logging level - filters out lower priority logs */ + logLevel?: LogLevel // DEBUG (0) | INFO (1) | WARN (2) | ERROR (3) + + /** Enable WebSocket ping/pong and connection state debugging logs */ + enableConnectionDebug?: boolean +} +``` + +**Compatible with:** console, winston, pino, and any logger with `debug/info/warn/error` methods. See `examples/logging-basic.ts` for complete integration examples. + +**For debugging:** Use `LogLevel.DEBUG` for full diagnostics and `enableConnectionDebug: true` to see WebSocket ping/pong messages and connection state transitions. + +**Origin tracking** in HA mode shows which specific endpoint received each report. + +### Metrics (`stream.getMetrics()`) + +The `stream.getMetrics()` API provides a complete snapshot for dashboards and alerts: + +```typescript +const m = stream.getMetrics() +// m.accepted, m.deduplicated, m.totalReceived +// m.partialReconnects, m.fullReconnects +// m.activeConnections, m.configuredConnections +// m.originStatus: { [origin]: ConnectionStatus } +``` + +Simple periodic print (example): + +```typescript +setInterval(() => { + const m = stream.getMetrics() + console.log(`accepted=${m.accepted} dedup=${m.deduplicated} active=${m.activeConnections}/${m.configuredConnections}`) +}, 30000) +``` + +Refer to `examples/metrics-monitoring.ts` for a full metrics dashboard example. + +## Testing + +```bash +npm test # All tests +npm run test:unit # Unit tests only +npm run test:integration # Integration tests only +``` + +## Feed IDs + +For available feed IDs, select your desired report [from the report schema overview](/data-streams/report-schema-overview). From f07732a14b885f632fcdcec8e4f9130193a24614 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 23 Sep 2025 17:10:11 -0700 Subject: [PATCH 07/18] lint + link fix --- .../data-streams/reference/data-streams-api/go-sdk.mdx | 2 -- .../data-streams/reference/data-streams-api/ts-sdk.mdx | 2 +- src/content/data-streams/tutorials/go-sdk-fetch.mdx | 4 ---- src/content/data-streams/tutorials/go-sdk-stream.mdx | 2 -- src/content/data-streams/tutorials/rust-sdk-fetch.mdx | 7 ------- src/content/data-streams/tutorials/rust-sdk-stream.mdx | 5 ----- 6 files changed, 1 insertion(+), 21 deletions(-) diff --git a/src/content/data-streams/reference/data-streams-api/go-sdk.mdx b/src/content/data-streams/reference/data-streams-api/go-sdk.mdx index aeea712cbd0..1da0efa0823 100644 --- a/src/content/data-streams/reference/data-streams-api/go-sdk.mdx +++ b/src/content/data-streams/reference/data-streams-api/go-sdk.mdx @@ -121,7 +121,6 @@ type CtxKey string ``` - Constants: - - `CustomHeadersCtxKey`: Key for passing custom HTTP headers. ```go @@ -207,7 +206,6 @@ type Stats struct { ##### Interface Methods - `Read`: Reads the next available report from the stream. This method will pause (block) the execution until one of the following occurs: - - A report is successfully received. - The provided context is canceled, typically due to a timeout or a cancel signal. - An error state is encountered in any of the underlying connections, such as a network failure. diff --git a/src/content/data-streams/reference/data-streams-api/ts-sdk.mdx b/src/content/data-streams/reference/data-streams-api/ts-sdk.mdx index 02d97aa9c3f..8163c14c426 100644 --- a/src/content/data-streams/reference/data-streams-api/ts-sdk.mdx +++ b/src/content/data-streams/reference/data-streams-api/ts-sdk.mdx @@ -530,4 +530,4 @@ npm run test:integration # Integration tests only ## Feed IDs -For available feed IDs, select your desired report [from the report schema overview](/data-streams/report-schema-overview). +For available feed IDs, select your desired report [from the report schema overview](/data-streams/reference/report-schema-overview). diff --git a/src/content/data-streams/tutorials/go-sdk-fetch.mdx b/src/content/data-streams/tutorials/go-sdk-fetch.mdx index ea24b6d7aff..7a3163b8207 100644 --- a/src/content/data-streams/tutorials/go-sdk-fetch.mdx +++ b/src/content/data-streams/tutorials/go-sdk-fetch.mdx @@ -476,7 +476,6 @@ Refer to the [Verify report data onchain](/data-streams/tutorials/evm-onchain-re When working with different versions of [Data Stream reports](/data-streams/reference/report-schema-overview), you'll need to adapt your code to handle the specific report schema version they use: 1. Import the correct schema version. Examples: - - For v3 schema (as used in this example): ```go @@ -490,7 +489,6 @@ When working with different versions of [Data Stream reports](/data-streams/refe ``` 1. Update the decode function to use the correct schema version. Examples: - - For v3 schema (as used in this example): ```go @@ -523,7 +521,6 @@ The Data Streams client is initialized in two steps: ``` The configuration requires: - - `ApiKey` and `ApiSecret` for authentication (required) - `RestURL` for the API endpoint (required) - `Logger` for debugging and error tracking (optional, defaults to `streams.LogPrintf`) @@ -582,7 +579,6 @@ Reports are decoded in two steps: ``` This step: - 1. Takes the raw `FullReport` bytes from the response 1. Uses `v3.Data` schema for Crypto streams (use the appropriate schema for your stream) 1. Validates the format and decodes using Go generics diff --git a/src/content/data-streams/tutorials/go-sdk-stream.mdx b/src/content/data-streams/tutorials/go-sdk-stream.mdx index 43d99d41d2c..27a5c2357c9 100644 --- a/src/content/data-streams/tutorials/go-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/go-sdk-stream.mdx @@ -338,7 +338,6 @@ Refer to the [Verify report data onchain](/data-streams/tutorials/evm-onchain-re When working with different versions of [Data Stream reports](/data-streams/reference/report-schema-overview), you'll need to adapt your code to handle the specific report schema version they use: 1. Import the correct schema version. Examples: - - For v3 schema (as used in this example): ```go @@ -352,7 +351,6 @@ When working with different versions of [Data Stream reports](/data-streams/refe ``` 1. Update the decode function to use the correct schema version. Examples: - - For v3 schema (as used in this example): ```go diff --git a/src/content/data-streams/tutorials/rust-sdk-fetch.mdx b/src/content/data-streams/tutorials/rust-sdk-fetch.mdx index 817bf99f74a..2c5d5a6684d 100644 --- a/src/content/data-streams/tutorials/rust-sdk-fetch.mdx +++ b/src/content/data-streams/tutorials/rust-sdk-fetch.mdx @@ -239,7 +239,6 @@ Refer to the [Verify report data onchain](/data-streams/tutorials/evm-onchain-re When working with different versions of [Data Stream reports](/data-streams/reference/report-schema-overview), you'll need to adapt your code to handle the specific report schema version they use: 1. Import the correct schema version module. Examples: - - For v3 schema (as used in this example): ```rust @@ -253,7 +252,6 @@ When working with different versions of [Data Stream reports](/data-streams/refe ``` 1. Update the decode function to use the correct schema version. Examples: - - For v3 schema (as used in this example): ```rust @@ -275,7 +273,6 @@ When working with different versions of [Data Stream reports](/data-streams/refe The API client is initialized in two steps: 1. [`Config::new`](https://github.com/smartcontractkit/data-streams-sdk/blob/main/rust/crates/sdk/src/config.rs#L131) creates a configuration with your API credentials and endpoints. This function: - - Validates your API key and secret - Sets up the REST API endpoint for data retrieval - Configures optional settings like TLS verification @@ -290,7 +287,6 @@ The API client is initialized in two steps: The SDK provides several methods to fetch reports through the REST API: 1. Latest report: [`get_latest_report`](https://github.com/smartcontractkit/data-streams-sdk/blob/main/rust/crates/sdk/src/client.rs#L165) retrieves the most recent report for a feed: - - Takes a feed ID as input - Returns a single report with the latest timestamp - Useful for applications that need the most current data @@ -318,7 +314,6 @@ Reports are decoded in three stages: ``` 1. Report separation: [`decode_full_report`](https://github.com/smartcontractkit/data-streams-sdk/blob/main/rust/crates/report/src/report.rs#L83) splits the binary data: - - Extracts the report context (metadata) - Isolates the report blob (actual data) - Validates the report format @@ -335,13 +330,11 @@ Reports are decoded in three stages: The example demonstrates Rust's robust error handling: 1. Type-safe errors: - - Uses custom error types for different failure scenarios - Implements the `Error` trait for proper error propagation - Provides detailed error messages for debugging 1. Error propagation: - - Uses the `?` operator for clean error handling - Converts errors between types when needed - Bubbles up errors to the main function diff --git a/src/content/data-streams/tutorials/rust-sdk-stream.mdx b/src/content/data-streams/tutorials/rust-sdk-stream.mdx index ac6516285bd..ba110046cc0 100644 --- a/src/content/data-streams/tutorials/rust-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/rust-sdk-stream.mdx @@ -368,7 +368,6 @@ Refer to the [Verify report data onchain](/data-streams/tutorials/evm-onchain-re When working with different versions of [Data Stream reports](/data-streams/reference/report-schema-overview), you'll need to adapt your code to handle the specific report schema version they use: 1. Import the correct schema version module. Examples: - - For v3 schema (as used in this example): ```rust @@ -382,7 +381,6 @@ When working with different versions of [Data Stream reports](/data-streams/refe ``` 1. Update the decode function to use the correct schema version. Examples: - - For v3 schema (as used in this example): ```rust @@ -415,7 +413,6 @@ The WebSocket connection is established in two steps: As data reports arrive via the WebSocket connection, they are processed in real-time through several steps: 1. Reading streams: The [`read`](https://github.com/smartcontractkit/data-streams-sdk/blob/main/rust/crates/sdk/src/stream.rs#L218) method on the Stream object is called within a loop. This asynchronous method: - - Awaits the next report from the WebSocket connection - Handles backpressure automatically - Returns a [`WebSocketReport`](https://github.com/smartcontractkit/data-streams-sdk/blob/main/rust/crates/sdk/src/stream.rs#L51) containing the report data @@ -433,13 +430,11 @@ As data reports arrive via the WebSocket connection, they are processed in real- The example demonstrates several best practices for handling the decoded data: 1. Logging: - - Uses the [`tracing`](https://github.com/tokio-rs/tracing) crate for structured logging - Configures UTC timestamps for consistent time representation - Includes both raw report data and decoded fields for debugging 2. Error handling: - - Uses Rust's `Result` type for robust error handling - Implements the `?` operator for clean error propagation - Logs errors with appropriate context using `warn!` macro From 0e7698d2462fe1196a02eb66b0284ab33ab52068 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 23 Sep 2025 18:15:57 -0700 Subject: [PATCH 08/18] update go sdk docs: ha mode, requirements, and report format+schema guidance --- .../reference/data-streams-api/go-sdk.mdx | 164 +++++++++++++++--- .../data-streams/tutorials/go-sdk-stream.mdx | 63 +++++++ .../tutorials/rust-sdk-stream.mdx | 58 +++++++ .../data-streams/tutorials/ts-sdk-stream.mdx | 2 + 4 files changed, 263 insertions(+), 24 deletions(-) diff --git a/src/content/data-streams/reference/data-streams-api/go-sdk.mdx b/src/content/data-streams/reference/data-streams-api/go-sdk.mdx index 1da0efa0823..9f90815740d 100644 --- a/src/content/data-streams/reference/data-streams-api/go-sdk.mdx +++ b/src/content/data-streams/reference/data-streams-api/go-sdk.mdx @@ -42,6 +42,26 @@ import { PageTabs } from "@components" This documentation provides a detailed reference for the Data Streams SDK for Go. It implements a client library that offers a domain-oriented abstraction for interacting with the Data Streams API and enables both point-in-time data retrieval and real-time data streaming with built-in fault tolerance capabilities. +## Requirements + +- Go 1.22.4 or later +- Valid Chainlink Data Streams credentials + +## Features + +- **REST API Client**: Fetch point-in-time data from Data Streams +- **WebSocket Client**: Stream real-time data with automatic reconnection +- **[High Availability mode](#high-availability-ha-mode)**: Multiple WebSocket connections with automatic failover +- **Report Decoding**: Built-in support for decoding multiple report formats (V1-V10) +- **Type-safe**: Full Go type safety with generics +- **Context Support**: Built on Go's context package for cancellation and timeouts + +## Installation + +```go +go get github.com/smartcontractkit/data-streams-sdk/go +``` + ## streams ### Installation @@ -61,31 +81,37 @@ import streams "github.com/smartcontractkit/data-streams-sdk/go" - `GetFeeds`: Lists all streams available to you. ```go - GetFeeds(ctx context.Context) (r []*Feed, err error) + GetFeeds(ctx context.Context) (r []*feed.Feed, err error) ``` - `GetLatestReport`: Fetches the latest report available for the specified `FeedID`. ```go - GetLatestReport(ctx context.Context, id FeedID) (r *Report, err error) + GetLatestReport(ctx context.Context, id feed.ID) (r *ReportResponse, err error) ``` - `GetReports`: Fetches reports for the specified stream IDs and a given timestamp. ```go - GetReports(ctx context.Context, ids []FeedID, timestamp uint64) ([]*Report, error) + GetReports(ctx context.Context, ids []feed.ID, timestamp uint64) ([]*ReportResponse, error) ``` - `GetReportPage`: Paginates the reports for a specified `FeedID` starting from a given timestamp. ```go - GetReportPage(ctx context.Context, id FeedID, startTS uint64) (*ReportPage, error) + GetReportPage(ctx context.Context, id feed.ID, startTS uint64) (*ReportPage, error) ``` - `Stream`: Creates a real-time report stream for specified stream IDs. ```go - Stream(ctx context.Context, feedIDs []FeedID) (Stream, error) + Stream(ctx context.Context, feedIDs []feed.ID) (Stream, error) + ``` + +- `StreamWithStatusCallback`: Creates a real-time report stream for specified stream IDs with a callback function for connection status updates. + + ```go + StreamWithStatusCallback(ctx context.Context, feedIDs []feed.ID, connStatusCallback func(isConnected bool, host string, origin string)) (Stream, error) ``` #### `Config` struct @@ -94,24 +120,24 @@ Configuration struct for the client. `Config` specifies the client configuration ```go type Config struct { - ApiKey string // Client API key - ApiSecret string // Client API secret - RestURL string // Rest API URL - - WsURL string // Websocket API URL - - WsHA bool // Use concurrent connections to multiple Streams servers - WsMaxReconnect int // Maximum number of reconnection attempts for Stream underlying connections - LogDebug bool // Log debug information - InsecureSkipVerify bool // Skip server certificate chain and host name verification + ApiKey string // Client API key + ApiSecret string // Client API secret + RestURL string // Rest API URL + WsURL string // Websocket API URL + WsHA bool // Use concurrent connections to multiple Streams servers + WsMaxReconnect int // Maximum number of reconnection attempts for Stream underlying connections + LogDebug bool // Log debug information + InsecureSkipVerify bool // Skip server certificate chain and host name verification Logger func(format string, a ...any) // Logger function - // InspectHttp intercepts http responses for rest requests. + // InspectHttpResponse intercepts http responses for rest requests. // The response object must not be modified. InspectHttpResponse func(*http.Response) } ``` +**Note**: If `WsMaxReconnect` is not specified, it defaults to 5 attempts. + #### `CtxKey` string Custom context key type used for passing additional headers. @@ -138,8 +164,8 @@ Represents a paginated response of reports. ```go type ReportPage struct { - Reports []*Report // Slice of Report, representing individual report entries. - NextPageTS uint64 // Timestamp for the next page, used for fetching subsequent pages. + Reports []*ReportResponse // Slice of ReportResponse, representing individual report entries. + NextPageTS uint64 // Timestamp for the next page, used for fetching subsequent pages. } ``` @@ -201,7 +227,9 @@ type Stats struct { #### `Stream` interface -[Interface](https://github.com/smartcontractkit/data-streams-sdk/blob/main/go/stream.go#L39) for managing a real-time data stream. +[Interface](https://github.com/smartcontractkit/data-streams-sdk/blob/main/go/stream.go#L39) for managing a real-time data stream. The Stream is safe for concurrent usage and automatically handles [High Availability scenarios](#high-availability-ha-mode) when enabled. + +When HA mode is enabled, the Stream will maintain concurrent connections to different instances to ensure high availability, fault tolerance and minimize the risk of report gaps. ##### Interface Methods @@ -211,7 +239,7 @@ type Stats struct { - An error state is encountered in any of the underlying connections, such as a network failure. ```go - Read(context.Context) (*Report, error) + Read(context.Context) (*ReportResponse, error) ``` - `Stats`: Returns statistics about the stream operations as `Stats`. @@ -226,6 +254,30 @@ type Stats struct { Close() error ``` +### High Availability (HA) Mode + +The Data Streams SDK supports High Availability mode for WebSocket connections. When enabled with `WsHA: true`, the SDK maintains concurrent connections to different instances to ensure high availability, fault tolerance and minimize the risk of report gaps. + +#### HA Mode Behavior + +When high availability mode is enabled: + +- The client queries the server for available origins using the `X-Cll-Available-Origins` header +- Multiple WebSocket connections are established to different server instances +- Reports are deduplicated when received across connections +- Partial reconnects occur when some connections fail while others remain active +- Full reconnects occur when all connections fail + +#### HA Configuration + +HA mode is controlled by the `WsHA` field in the client configuration: + +```go +config := streams.Config{ + WsHA: true, // Use concurrent connections to multiple Streams servers +} +``` + ### Functions #### `New` @@ -240,12 +292,22 @@ func New(cfg Config) (c Client, err error) #### `LogPrintf` -Utility function for logging. +Utility function for logging that implements a LogFunction using fmt.Printf. ```go func LogPrintf(format string, a ...any) ``` +### Errors + +#### `ErrStreamClosed` + +Error returned when attempting to use a closed stream. + +```go +var ErrStreamClosed = fmt.Errorf("client: use of closed Stream") +``` + ## feed ### Installation @@ -270,12 +332,25 @@ Where `ID` is the unique identifier for the stream. #### `FeedVersion` uint16 -Represents the stream [report schema](/data-streams/reference/report-schema-v3) version. +Represents the stream [report schema](/data-streams/reference/report-schema-overview) version. ```go type FeedVersion uint16 ``` +##### Constants + +- `FeedVersion1`: Version 1 schema +- `FeedVersion2`: Version 2 schema +- `FeedVersion3`: Version 3 schema +- `FeedVersion4`: Version 4 schema +- `FeedVersion5`: Version 5 schema +- `FeedVersion6`: Version 6 schema +- `FeedVersion7`: Version 7 schema +- `FeedVersion8`: Version 8 schema +- `FeedVersion9`: Version 9 schema +- `FeedVersion10`: Version 10 schema + #### `ID` [32]byte Represents a unique identifier for a stream. @@ -328,11 +403,11 @@ import report "github.com/smartcontractkit/data-streams-sdk/go/report" #### `Data` interface -[Interface](https://github.com/smartcontractkit/data-streams-sdk/blob/main/go/report/report.go#L13) that represents the actual report data and attributes. +[Interface](https://github.com/smartcontractkit/data-streams-sdk/blob/main/go/report/report.go#L20) that represents the actual report data and attributes. ```go type Data interface { - v1.Data | v2.Data | v3.Data | v4.Data | v8.Data | v9.Data + v1.Data | v2.Data | v3.Data | v4.Data | v5.Data | v6.Data | v7.Data | v8.Data | v9.Data | v10.Data Schema() abi.Arguments } ``` @@ -387,3 +462,44 @@ streams.LogPrintf( report.Data.ExpiresAt, ) ``` + +## Report Format and Schema Versions + +### Schema Versions + +The SDK supports multiple report schema versions (v1-v10), each optimized for different use cases: + +- **v2**: Feed IDs starting with `0x0002` +- **v3**: Feed IDs starting with `0x0003` (Crypto Streams) +- **v4**: Feed IDs starting with `0x0004` (Real-World Assets) +- **v5**: Feed IDs starting with `0x0005` +- **v6**: Feed IDs starting with `0x0006` (Multiple Price Values) +- **v7**: Feed IDs starting with `0x0007` (Exchange Rate) +- **v8**: Feed IDs starting with `0x0008` (Non-OTC RWA) +- **v9**: Feed IDs starting with `0x0009` (NAV Fund Data) +- **v10**: Feed IDs starting with `0x000a` (Tokenized Equity) + +### Common Fields + +All report versions include standard metadata: + +- `FeedID`: Unique identifier for the data stream +- `ValidFromTimestamp`: When the report becomes valid +- `ExpiresAt`: When the report expires +- `LinkFee`: Fee in LINK tokens +- `NativeFee`: Fee in native blockchain currency +- `ObservationsTimestamp`: When the data was observed + +### Usage Pattern + +Each version follows the same decoding pattern: + +```go +import v3 "github.com/smartcontractkit/data-streams-sdk/go/report/v3" + +report, err := report.Decode[v3.Data](fullReport) +``` + +Use the appropriate version import based on your feed's schema version, which can be determined by calling `feedID.Version()`. + +For complete field definitions and decoding examples, see the [report schema overview](/data-streams/reference/report-schema-overview) and [fetch tutorial](/data-streams/tutorials/go-sdk-fetch). diff --git a/src/content/data-streams/tutorials/go-sdk-stream.mdx b/src/content/data-streams/tutorials/go-sdk-stream.mdx index 27a5c2357c9..a7f1011f879 100644 --- a/src/content/data-streams/tutorials/go-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/go-sdk-stream.mdx @@ -327,6 +327,69 @@ The decoded report details include: For descriptions and data types of other report schemas, see the [Report Schema Overview](/data-streams/reference/report-schema-overview). +### High Availability (HA) mode + + + +High Availability (HA) mode creates multiple WebSocket connections to different origin endpoints for improved reliability. When enabled, the SDK automatically handles failover, deduplicates reports, and provides connection-level metrics. + +#### Enabling HA mode + +To enable HA mode in your streaming application, make these changes to the basic example: + +1. Add HA mode to the client configuration and use a mainnet endpoint, as HA mode is not currently supported on testnet: + +```go +cfg := streams.Config{ + ApiKey: os.Getenv("API_KEY"), + ApiSecret: os.Getenv("API_SECRET"), + WsURL: "wss://ws.dataengine.chain.link", // Use mainnet endpoint for HA mode + WsHA: true, // Enable High Availability mode + Logger: streams.LogPrintf, +} +``` + +2. Monitor HA metrics using the existing `Stats()` calls in your report handler: + +```go +// In your report processing loop +for { + reportResponse, err := stream.Read(context.Background()) + if err != nil { + cfg.Logger("Error reading from stream: %v\n", err) + continue + } + + // Process the report... + + // Monitor HA statistics (includes HA-specific metrics) + cfg.Logger("Stream Stats: %s\n", stream.Stats().String()) + // Output example: "accepted: 150, deduplicated: 3, total_received: 153, partial_reconnects: 1, full_reconnects: 0, configured_connections: 2, active_connections: 2" +} +``` + +3. Optionally, monitor individual connection status using `StreamWithStatusCallback`: + +```go +// Subscribe to the feeds with connection status monitoring +stream, err := client.StreamWithStatusCallback( + ctx, ids, + func(isConnected bool, host string, origin string) { + status := "DISCONNECTED" + if isConnected { + status = "CONNECTED" + } + cfg.Logger("Host: %s, Origin: %s, Status: %s\n", host, origin, status) + }, +) +``` + +When HA mode is enabled, the SDK maintains at least 2 concurrent connections to different instances to ensure high availability, fault tolerance, and minimize the risk of report gaps. + +See more details about HA mode in the [SDK Reference](/data-streams/reference/data-streams-api/go-sdk#high-availability-ha-mode). + ### Payload for onchain verification In this tutorial, you logged and decoded the `full_report` payloads to extract the report data. However, in a production environment, you should verify the data to ensure its integrity and authenticity. diff --git a/src/content/data-streams/tutorials/rust-sdk-stream.mdx b/src/content/data-streams/tutorials/rust-sdk-stream.mdx index ba110046cc0..8c82ddf84be 100644 --- a/src/content/data-streams/tutorials/rust-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/rust-sdk-stream.mdx @@ -357,6 +357,64 @@ The decoded report details include: For descriptions and data types of other report schemas, see the [Report Schema Overview](/data-streams/reference/report-schema-overview). +### High Availability (HA) mode + + + +High Availability (HA) mode creates multiple WebSocket connections to different origin endpoints for improved reliability. When enabled, the SDK automatically handles failover, deduplicates reports, and provides connection-level metrics. + +#### Enabling HA mode + +To enable HA mode in your streaming application, make these changes to the basic example: + +1. Add multiple WebSocket endpoints and enable HA mode in the client configuration. You also must use a mainnet endpoint, as HA mode is not currently supported on testnet. + +```rust +use chainlink_data_streams_sdk::config::{Config, WebSocketHighAvailability}; + +let config = Config::new( + api_key, + api_secret, + "https://api.dataengine.chain.link".to_string(), // Mainnet endpoint + "wss://ws1.dataengine.chain.link,wss://ws2.dataengine.chain.link".to_string(), // Multiple WebSocket endpoints +) +.with_ws_ha(WebSocketHighAvailability::Enabled) // Enable High Availability mode +.with_ws_max_reconnect(10) // Optional: Increase max reconnection attempts +.build()?; +``` + +2. Optionally, monitor HA metrics using the existing `get_stats()` calls in your report handler: + +```rust +// In your report processing loop +match stream.read().await { + Ok(report) => { + // ... your report processing logic + + // HA-specific metrics + let stats = stream.get_stats(); + info!( + "šŸ“Š Stats: {} reports | {}/{} connections", + stats.accepted, stats.active_connections, stats.configured_connections + ); + info!("Reconnects: {} partial, {} full", stats.partial_reconnects, stats.full_reconnects); + + // Check deduplication (important for HA mode) + if stats.total_received > 0 { + let dedup_rate = (stats.deduplicated as f64 / stats.total_received as f64) * 100.0; + info!("Deduplication rate: {:.1}%", dedup_rate); + } + } + Err(e) => { + warn!("Error reading from stream: {}", e); + } +} +``` + +See more details about HA mode in the [SDK Reference](/rust-sdk#websocket-features). + ### Payload for onchain verification In this tutorial, you logged and decoded the `full_report` payloads to extract the report data. However, in a production environment, you should verify the data to ensure its integrity and authenticity. diff --git a/src/content/data-streams/tutorials/ts-sdk-stream.mdx b/src/content/data-streams/tutorials/ts-sdk-stream.mdx index c23f5db7920..235c5e544b9 100644 --- a/src/content/data-streams/tutorials/ts-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/ts-sdk-stream.mdx @@ -379,6 +379,8 @@ When `haMode` is `true`, the SDK automatically discovers multiple origin endpoin The optional `connectionStatusCallback` can be used to integrate with external monitoring systems. The SDK already provides comprehensive connection logs, so this callback is primarily useful for custom alerting or metrics collection. +See more details about HA mode in the [SDK Reference](/ts-sdk#high-availability-mode). + ### Payload for onchain verification In this tutorial, you logged and decoded the `full_report` payloads to extract the report data. However, in a production environment, you should verify the data to ensure its integrity and authenticity. From 3017f875423c58e6bd8ec0fe718dc08b64565221 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 23 Sep 2025 18:29:11 -0700 Subject: [PATCH 09/18] update --- src/content/data-streams/index.mdx | 9 +++++++++ .../reference/data-streams-api/go-sdk.mdx | 15 +++------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/content/data-streams/index.mdx b/src/content/data-streams/index.mdx index 127417838e8..bc1098f1645 100644 --- a/src/content/data-streams/index.mdx +++ b/src/content/data-streams/index.mdx @@ -50,6 +50,15 @@ Chainlink Data Streams offers price points such as mid prices and [Liquidity-Wei Data Streams API services use an [active-active multi-site deployment](/data-streams/architecture#active-active-multi-site-deployment) model across multiple distributed and isolated origins. This architecture ensures continuous operations even if one origin fails, delivering robust fault tolerance and high availability. +For real-time streaming applications, the SDKs support **High Availability (HA) mode** that establishes multiple simultaneous connections for zero-downtime operation. When enabled, HA mode provides: + +- **Automatic failover** between connections +- **Report deduplication** across connections +- **Automatic origin discovery** to find available endpoints +- **Per-connection monitoring** and statistics + +**Learn more:** [Go SDK](/data-streams/reference/data-streams-api/go-sdk#high-availability-ha-mode) | [Rust SDK](/data-streams/reference/data-streams-api/rust-sdk#high-availability-mode) | [TypeScript SDK](/data-streams/reference/data-streams-api/ts-sdk#high-availability-mode) + ## Example use cases Access to low-latency, high-frequency data enables a variety of onchain applications: diff --git a/src/content/data-streams/reference/data-streams-api/go-sdk.mdx b/src/content/data-streams/reference/data-streams-api/go-sdk.mdx index 9f90815740d..fba32fbeb5c 100644 --- a/src/content/data-streams/reference/data-streams-api/go-sdk.mdx +++ b/src/content/data-streams/reference/data-streams-api/go-sdk.mdx @@ -47,15 +47,6 @@ This documentation provides a detailed reference for the Data Streams SDK for Go - Go 1.22.4 or later - Valid Chainlink Data Streams credentials -## Features - -- **REST API Client**: Fetch point-in-time data from Data Streams -- **WebSocket Client**: Stream real-time data with automatic reconnection -- **[High Availability mode](#high-availability-ha-mode)**: Multiple WebSocket connections with automatic failover -- **Report Decoding**: Built-in support for decoding multiple report formats (V1-V10) -- **Type-safe**: Full Go type safety with generics -- **Context Support**: Built on Go's context package for cancellation and timeouts - ## Installation ```go @@ -64,7 +55,7 @@ go get github.com/smartcontractkit/data-streams-sdk/go ## streams -### Installation +### Import ```go import streams "github.com/smartcontractkit/data-streams-sdk/go" @@ -310,7 +301,7 @@ var ErrStreamClosed = fmt.Errorf("client: use of closed Stream") ## feed -### Installation +### Import ```go import feed "github.com/smartcontractkit/data-streams-sdk/go/feed" @@ -393,7 +384,7 @@ type ID [32]byte ## report -### Installation +### Import ```go import report "github.com/smartcontractkit/data-streams-sdk/go/report" From 0d524ad32f426d09a452c52255747daeaf05612b Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 23 Sep 2025 18:31:32 -0700 Subject: [PATCH 10/18] trim --- .../data-streams/reference/data-streams-api/go-sdk.mdx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/content/data-streams/reference/data-streams-api/go-sdk.mdx b/src/content/data-streams/reference/data-streams-api/go-sdk.mdx index fba32fbeb5c..b55ea6dd617 100644 --- a/src/content/data-streams/reference/data-streams-api/go-sdk.mdx +++ b/src/content/data-streams/reference/data-streams-api/go-sdk.mdx @@ -218,9 +218,7 @@ type Stats struct { #### `Stream` interface -[Interface](https://github.com/smartcontractkit/data-streams-sdk/blob/main/go/stream.go#L39) for managing a real-time data stream. The Stream is safe for concurrent usage and automatically handles [High Availability scenarios](#high-availability-ha-mode) when enabled. - -When HA mode is enabled, the Stream will maintain concurrent connections to different instances to ensure high availability, fault tolerance and minimize the risk of report gaps. +[Interface](https://github.com/smartcontractkit/data-streams-sdk/blob/main/go/stream.go#L39) for managing a real-time data stream. ##### Interface Methods @@ -283,7 +281,7 @@ func New(cfg Config) (c Client, err error) #### `LogPrintf` -Utility function for logging that implements a LogFunction using fmt.Printf. +Utility function for logging. ```go func LogPrintf(format string, a ...any) From c1a18aa1ac0ea8837d2a68b56cc3f881d379998c Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 23 Sep 2025 18:48:10 -0700 Subject: [PATCH 11/18] more references --- .../data-streams-api/authentication/go-examples.mdx | 2 +- .../reference/data-streams-api/authentication/index.mdx | 6 +++--- .../data-streams-api/authentication/javascript-examples.mdx | 2 +- .../data-streams-api/authentication/rust-examples.mdx | 2 +- .../data-streams-api/authentication/typescript-examples.mdx | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/content/data-streams/reference/data-streams-api/authentication/go-examples.mdx b/src/content/data-streams/reference/data-streams-api/authentication/go-examples.mdx index e51d4aec446..dcac59ca6fc 100644 --- a/src/content/data-streams/reference/data-streams-api/authentication/go-examples.mdx +++ b/src/content/data-streams/reference/data-streams-api/authentication/go-examples.mdx @@ -17,7 +17,7 @@ Below are complete examples for authenticating with the Data Streams API in Go. To learn more about the Data Streams API authentication, see the [Data Streams Authentication](/data-streams/reference/data-streams-api/authentication) page. -**Note**: The Data Streams SDKs handle authentication automatically. If you're using the [Go SDK](/data-streams/reference/data-streams-api/go-sdk) or [Rust SDK](/data-streams/reference/data-streams-api/rust-sdk), you don't need to implement the authentication logic manually. +**Note**: The Data Streams SDKs handle authentication automatically. If you're using the [Go SDK](/data-streams/reference/data-streams-api/go-sdk), [Rust SDK](/data-streams/reference/data-streams-api/rust-sdk), or [TypeScript SDK](/data-streams/reference/data-streams-api/ts-sdk), you don't need to implement the authentication logic manually. ## API Authentication Example diff --git a/src/content/data-streams/reference/data-streams-api/authentication/index.mdx b/src/content/data-streams/reference/data-streams-api/authentication/index.mdx index e6d9e700cfe..fc2827b9027 100644 --- a/src/content/data-streams/reference/data-streams-api/authentication/index.mdx +++ b/src/content/data-streams/reference/data-streams-api/authentication/index.mdx @@ -26,9 +26,9 @@ This page explains how to authenticate with the Chainlink Data Streams API, cove ## Authentication Requirements diff --git a/src/content/data-streams/reference/data-streams-api/authentication/javascript-examples.mdx b/src/content/data-streams/reference/data-streams-api/authentication/javascript-examples.mdx index ed71c834d58..73577fca4b6 100644 --- a/src/content/data-streams/reference/data-streams-api/authentication/javascript-examples.mdx +++ b/src/content/data-streams/reference/data-streams-api/authentication/javascript-examples.mdx @@ -17,7 +17,7 @@ Below are complete examples for authenticating with the Data Streams API in Java To learn more about the Data Streams API authentication, see the [Data Streams Authentication](/data-streams/reference/data-streams-api/authentication) page. -**Note**: The Data Streams SDKs handle authentication automatically. If you're using the [Go SDK](/data-streams/reference/data-streams-api/go-sdk) or [Rust SDK](/data-streams/reference/data-streams-api/rust-sdk), you don't need to implement the authentication logic manually. +**Note**: The Data Streams SDKs handle authentication automatically. If you're using the [Go SDK](/data-streams/reference/data-streams-api/go-sdk), [Rust SDK](/data-streams/reference/data-streams-api/rust-sdk), or [TypeScript SDK](/data-streams/reference/data-streams-api/ts-sdk), you don't need to implement the authentication logic manually. ## API Authentication Example diff --git a/src/content/data-streams/reference/data-streams-api/authentication/rust-examples.mdx b/src/content/data-streams/reference/data-streams-api/authentication/rust-examples.mdx index cb5ce048b26..0f58329e59e 100644 --- a/src/content/data-streams/reference/data-streams-api/authentication/rust-examples.mdx +++ b/src/content/data-streams/reference/data-streams-api/authentication/rust-examples.mdx @@ -17,7 +17,7 @@ Below are complete examples for authenticating with the Data Streams API in Rust To learn more about the Data Streams API authentication, see the [Data Streams Authentication](/data-streams/reference/data-streams-api/authentication) page. -**Note**: The Data Streams SDKs handle authentication automatically. If you're using the [Go SDK](/data-streams/reference/data-streams-api/go-sdk) or [Rust SDK](/data-streams/reference/data-streams-api/rust-sdk), you don't need to implement the authentication logic manually. +**Note**: The Data Streams SDKs handle authentication automatically. If you're using the [Go SDK](/data-streams/reference/data-streams-api/go-sdk), [Rust SDK](/data-streams/reference/data-streams-api/rust-sdk), or [TypeScript SDK](/data-streams/reference/data-streams-api/ts-sdk), you don't need to implement the authentication logic manually. ## API Authentication Example diff --git a/src/content/data-streams/reference/data-streams-api/authentication/typescript-examples.mdx b/src/content/data-streams/reference/data-streams-api/authentication/typescript-examples.mdx index ca48796733e..d53db27034c 100644 --- a/src/content/data-streams/reference/data-streams-api/authentication/typescript-examples.mdx +++ b/src/content/data-streams/reference/data-streams-api/authentication/typescript-examples.mdx @@ -17,7 +17,7 @@ Below are complete examples for authenticating with the Data Streams API in Type To learn more about the Data Streams API authentication, see the [Data Streams Authentication](/data-streams/reference/data-streams-api/authentication) page. -**Note**: The Data Streams SDKs handle authentication automatically. If you're using the [Go SDK](/data-streams/reference/data-streams-api/go-sdk) or [Rust SDK](/data-streams/reference/data-streams-api/rust-sdk), you don't need to implement the authentication logic manually. +**Note**: The Data Streams SDKs handle authentication automatically. If you're using the [Go SDK](/data-streams/reference/data-streams-api/go-sdk), [Rust SDK](/data-streams/reference/data-streams-api/rust-sdk), or [TypeScript SDK](/data-streams/reference/data-streams-api/ts-sdk), you don't need to implement the authentication logic manually. ## API Authentication Example From 3589d81846155dee15ba8b30cf7096120f3dbee9 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 23 Sep 2025 18:55:04 -0700 Subject: [PATCH 12/18] bumped example output with vetted, real returns from npm package testing --- .../data-streams/tutorials/ts-sdk-fetch.mdx | 44 +++-------- .../data-streams/tutorials/ts-sdk-stream.mdx | 75 +++++++++++++------ 2 files changed, 63 insertions(+), 56 deletions(-) diff --git a/src/content/data-streams/tutorials/ts-sdk-fetch.mdx b/src/content/data-streams/tutorials/ts-sdk-fetch.mdx index d6021e35ce2..99c84fda31e 100644 --- a/src/content/data-streams/tutorials/ts-sdk-fetch.mdx +++ b/src/content/data-streams/tutorials/ts-sdk-fetch.mdx @@ -317,45 +317,25 @@ You'll start with the set up of your TypeScript project, installing the SDK and Expect to see the output below in your terminal: ```bash - [2025-09-23T00:54:43.990Z] [DataStreams] Data Streams client initialized + [2025-09-24T01:50:28.313Z] [DataStreams] Data Streams client initialized - Fetching latest reports for 2 feed(s): - - 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 (V3) - - 0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265 (V3) - - [2025-09-23T00:54:44.244Z] [DataStreams] Request successful: GET https://api.testnet-dataengine.chain.link/api/v1/reports/latest?feedID=0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 - 200 - [2025-09-23T00:54:44.310Z] [DataStreams] Request successful: GET https://api.testnet-dataengine.chain.link/api/v1/reports/latest?feedID=0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265 - 200 - Found 2 reports: + Fetching latest report for feed 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 (V3)... - Raw Report Blob #1: 0x00090d9e8d96765a0c49e03a6ae05c82e8f8de70cf179baa632f18313e54bd690000000000000000000000000000000000000000000000000000000001f71291000000000000000000000000000000000000000000000000000000030000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000028001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba7820000000000000000000000000000000000000000000000000000000068d1efd30000000000000000000000000000000000000000000000000000000068d1efd30000000000000000000000000000000000000000000000000000455f50d8377000000000000000000000000000000000000000000000000000349983c7f97bd70000000000000000000000000000000000000000000000000000000068f97cd30000000000000000000000000000000000000000000000e36d996215f00840000000000000000000000000000000000000000000000000e36835d6045c9700000000000000000000000000000000000000000000000000e36fabf5a9955e40000000000000000000000000000000000000000000000000000000000000000002d2fe013d18dcdc7d08d61c79d31ff7067487d86b6eb64b1b6c6010d31038b46d53e9324e546ea84b16d7f1b5ace563611ce5f758d11780d51ca737dade8a49dd00000000000000000000000000000000000000000000000000000000000000023da817f93c4e161d0cbb83282890dec993cd5ea1c1d8c0273f80a6553e724eef726fc2ad8a7f53c5ad0b3181ced439c17c764c04949a195dcb0d44015ae9b0a7 + [2025-09-24T01:50:28.607Z] [DataStreams] Request successful: GET https://api.testnet-dataengine.chain.link/api/v1/reports/latest?feedID=0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 - 200 + Raw Report Blob: 0x00090d9e8d96765a0c49e03a6ae05c82e8f8de70cf179baa632f18313e54bd690000000000000000000000000000000000000000000000000000000001fb09db000000000000000000000000000000000000000000000000000000030000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba7820000000000000000000000000000000000000000000000000000000068d34e640000000000000000000000000000000000000000000000000000000068d34e64000000000000000000000000000000000000000000000000000045686a2caed300000000000000000000000000000000000000000000000000347613062ce6c40000000000000000000000000000000000000000000000000000000068fadb640000000000000000000000000000000000000000000000e34fc8e3afa8f400000000000000000000000000000000000000000000000000e34cf02d97047e60000000000000000000000000000000000000000000000000e3533bbd1e9ba3400000000000000000000000000000000000000000000000000000000000000000021ae965e613bfb4580ea819f8c12736562222e515b412054c49ec77ded163d9ee4493fb7dfb713181ea1a0d4e1a7fc4b7a3618484f9c989c4262c201e749df2cd000000000000000000000000000000000000000000000000000000000000000217c165a50d34910db8667c1229128ea4110fba082eb0308b75282fffdb594f68467797ce8a8b515f8e3ab08e4723a1fe1a9cfa5079968cd4bb7a9ec1a7a943cc Report Metadata: Feed ID: 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 - Valid From: 1758588883 - Observations: 1758588883 - - Decoded Data: - Native Fee: 76275680556912 - LINK Fee: 14805490063735767 - Expires At: 1761180883 - Price: 4195308356000000000000 - Bid Price: 4194920048000000000000 - Ask Price: 4195457700000000000000 - -------------------------------------------------- - Raw Report Blob #2: 0x00090d9e8d96765a0c49e03a6ae05c82e8f8de70cf179baa632f18313e54bd690000000000000000000000000000000000000000000000000000000001f71291000000000000000000000000000000000000000000000000000000030000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d02650000000000000000000000000000000000000000000000000000000068d1efd30000000000000000000000000000000000000000000000000000000068d1efd30000000000000000000000000000000000000000000000000000455f50d8377000000000000000000000000000000000000000000000000000349983c7f97bd70000000000000000000000000000000000000000000000000000000068f97cd30000000000000000000000000000000000000000000000012bf2f25e94eb68d80000000000000000000000000000000000000000000000012be4bb00ede340d00000000000000000000000000000000000000000000000012c0409033df7fc7c000000000000000000000000000000000000000000000000000000000000000271c4eaabcb5ae7335e87dcaa55851b5d40ccbb6abf6dc74c0b453274a0c2041e1099cca65a5ca74ee56733eab4d7b39868a726e3590ac1456c0cf95ed58e5f2d00000000000000000000000000000000000000000000000000000000000000027a89cf0cd8059f4803b413ceef42fce264a04d779a6283147a3d9e69b088b94d25708a4fe7434aecb3ce87f90c5dd24a1c90aa0180c7fee1b705d7db4589ef4f - - Report Metadata: - Feed ID: 0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265 - Valid From: 1758588883 - Observations: 1758588883 + Valid From: 1758678628 + Observations: 1758678628 Decoded Data: - Native Fee: 76275680556912 - LINK Fee: 14805490063735767 - Expires At: 1761180883 - Price: 21613604049743735000 - Bid Price: 21609602524695970000 - Ask Price: 21618414020814437500 + Native Fee: 76314760228563 + LINK Fee: 14766522869016260 + Expires At: 1761270628 + Price: 4193160000000000000000 + Bid Price: 4192954886000000000000 + Ask Price: 4193408500000000000000 -------------------------------------------------- ``` diff --git a/src/content/data-streams/tutorials/ts-sdk-stream.mdx b/src/content/data-streams/tutorials/ts-sdk-stream.mdx index 235c5e544b9..672a36637d2 100644 --- a/src/content/data-streams/tutorials/ts-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/ts-sdk-stream.mdx @@ -250,51 +250,78 @@ First, you'll set up a basic TypeScript project, installing the SDK and pasting ============================================================ šŸ“Š Feeds: 1 feed(s) ============================================================ + [2025-09-24T01:52:36.464Z] [DataStreams] Data Streams client initialized + [2025-09-24T01:52:36.465Z] [DataStreams] Initializing stream in single mode + [2025-09-24T01:52:36.465Z] [DataStreams] Stream created successfully for 1 feed(s) ā³ Connecting... - [2025-09-23T01:15:23.456Z] [DataStreams] Data Streams client initialized - [2025-09-23T01:15:23.789Z] [DataStreams] WebSocket connected + [2025-09-24T01:52:36.465Z] [DataStreams] Connecting stream in single mode + [2025-09-24T01:52:36.465Z] [DataStreams] Initializing in single connection mode { origin: 'ws.testnet-dataengine.chain.link' } + [2025-09-24T01:52:36.919Z] [DataStreams] Connection conn-0 established to ws.testnet-dataengine.chain.link { + connectionId: 'conn-0', + host: 'ws.testnet-dataengine.chain.link', + oldState: 'connecting', + newState: 'connected', + reason: 'WebSocket connection established' + } + [2025-09-24T01:52:36.921Z] [DataStreams] Stream connected successfully with 1 origins: wss://ws.testnet-dataengine.chain.link āœ… Connected! Listening for reports... - šŸ“ˆ Report #1 - 2025-09-23T01:15:24.123Z - Raw Report Blob: 0x00090d9e8d96765a0c49e03a6ae05c82e8f8de70cf179baa632f18313e54bd690000000000000000000000000000000000000000000000000000000001f71291000000000000000000000000000000000000000000000000000000030000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000028001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba7820000000000000000000000000000000000000000000000000000000068d1efd30000000000000000000000000000000000000000000000000000000068d1efd30000000000000000000000000000000000000000000000000000455f50d8377000000000000000000000000000000000000000000000000000349983c7f97bd70000000000000000000000000000000000000000000000000000000068f97cd30000000000000000000000000000000000000000000000e36d996215f00840000000000000000000000000000000000000000000000000e36835d6045c9700000000000000000000000000000000000000000000000000e36fabf5a9955e40000000000000000000000000000000000000000000000000000000000000000002d2fe013d18dcdc7d08d61c79d31ff7067487d86b6eb64b1b6c6010d31038b46d53e9324e546ea84b16d7f1b5ace563611ce5f758d11780d51ca737dade8a49dd + šŸ“ˆ Report #1 - 2025-09-24T01:52:37.639Z + + Raw Report Blob: 0x00090d9e8d96765a0c49e03a6ae05c82e8f8de70cf179baa632f18313e54bd690000000000000000000000000000000000000000000000000000000001fb0b3d000000000000000000000000000000000000000000000000000000030000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000028001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba7820000000000000000000000000000000000000000000000000000000068d34ee50000000000000000000000000000000000000000000000000000000068d34ee500000000000000000000000000000000000000000000000000004566c7d15bf000000000000000000000000000000000000000000000000000346f5bdd1b7f7f0000000000000000000000000000000000000000000000000000000068fadbe50000000000000000000000000000000000000000000000e3535f4d688742fe400000000000000000000000000000000000000000000000e35216a3ce81ab00000000000000000000000000000000000000000000000000e355718e650ceb8c00000000000000000000000000000000000000000000000000000000000000000264deb1e4d7485843f79f802f8ffd29fa395c45a8f4c10d7771d91fb5c6c7f55bdf3b496949277bdba413cf9a07adf62d4ffac8d04572455c8707a578eec7988f000000000000000000000000000000000000000000000000000000000000000221d03f390a3a8bf14406a5026bca8a569908abd0e3bfc1152e0ee94cf8087b29648cffd6e505f392678ad3c2488862dc6016755aec3076e64fa68d13705a5980 Report Metadata: Feed ID: 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 - Valid From: 1758588883 - Observations: 1758588883 + Valid From: 1758678757 + Observations: 1758678757 Decoded Data: - Native Fee: 76275680556912 - LINK Fee: 14805490063735767 - Expires At: 1761180883 - Price: 4195308356000000000000 - Bid Price: 4194920048000000000000 - Ask Price: 4195457700000000000000 + Native Fee: 76307741367280 + LINK Fee: 14759139131228031 + Expires At: 1761270757 + Price: 4193418510271345000000 + Bid Price: 4193326000000000000000 + Ask Price: 4193567763462320000000 -------------------------------------------------- - šŸ“ˆ Report #2 - 2025-09-23T01:15:25.234Z + šŸ“ˆ Report #2 - 2025-09-24T01:52:38.352Z - Raw Report Blob: 0x00090d9e8d96765a0c49e03a6ae05c82e8f8de70cf179baa632f18313e54bd690000000000000000000000000000000000000000000000000000000001f71292000000000000000000000000000000000000000000000000000000030000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000028001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba7820000000000000000000000000000000000000000000000000000000068d1efd40000000000000000000000000000000000000000000000000000000068d1efd40000000000000000000000000000000000000000000000000000455f45d2349000000000000000000000000000000000000000000000000000349968c9f98bd70000000000000000000000000000000000000000000000000000000068f97cd40000000000000000000000000000000000000000000000e36d8b5b2b6084000000000000000000000000000000000000000000000000000e36824f6b8c970000000000000000000000000000000000000000000000000e36fc15a99955e400000000000000000000000000000000000000000000000000000000000000000028f3c0139b8c7d08d61c79d31ff7067487d86b6eb64b1b6c6010d31038b46d53e932 + Raw Report Blob: 0x00090d9e8d96765a0c49e03a6ae05c82e8f8de70cf179baa632f18313e54bd690000000000000000000000000000000000000000000000000000000001fb0b3f000000000000000000000000000000000000000000000000000000030000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000028001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba7820000000000000000000000000000000000000000000000000000000068d34ee60000000000000000000000000000000000000000000000000000000068d34ee600000000000000000000000000000000000000000000000000004567035aadb500000000000000000000000000000000000000000000000000346f5006b572370000000000000000000000000000000000000000000000000000000068fadbe60000000000000000000000000000000000000000000000e354601f8dd7842d400000000000000000000000000000000000000000000000e35343330ef5aa80000000000000000000000000000000000000000000000000e3576b7b7e0d95bc0000000000000000000000000000000000000000000000000000000000000000029bbebb9390dfd84074ef0078b3b354a8c3f53915d24b664095b4360b20e495cfc1ee156fb32ffae29390a891b905b96fec0e949dbca19b7eded60a2178a0b7570000000000000000000000000000000000000000000000000000000000000002119306af79fb631fe3d281475b32e9e2c293fd6b544d4f5d44d74d9827d8897729c2bc6d5df3033d6b90aeb22df31f484f5ed7da9602c790213d3e12144544e1 Report Metadata: Feed ID: 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 - Valid From: 1758588884 - Observations: 1758588884 + Valid From: 1758678758 + Observations: 1758678758 Decoded Data: - Native Fee: 76275680556912 - LINK Fee: 14805490063735767 - Expires At: 1761180884 - Price: 4195298740000000000000 - Bid Price: 4194910430000000000000 - Ask Price: 4195448050000000000000 + Native Fee: 76308740222389 + LINK Fee: 14759088289575479 + Expires At: 1761270758 + Price: 4193490798923085000000 + Bid Price: 4193410600000000000000 + Ask Price: 4193710169017200000000 -------------------------------------------------- - šŸ“Š Stats: 5 reports | 1/1 connections + šŸ“ˆ Report #3 - 2025-09-24T01:52:39.274Z + + Raw Report Blob: 0x00090d9e8d96765a0c49e03a6ae05c82e8f8de70cf179baa632f18313e54bd690000000000000000000000000000000000000000000000000000000001fb0b42000000000000000000000000000000000000000000000000000000030000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba7820000000000000000000000000000000000000000000000000000000068d34ee70000000000000000000000000000000000000000000000000000000068d34ee70000000000000000000000000000000000000000000000000000456689e0e86300000000000000000000000000000000000000000000000000346d7b2d006b3a0000000000000000000000000000000000000000000000000000000068fadbe70000000000000000000000000000000000000000000000e355ee07f0ab7f00000000000000000000000000000000000000000000000000e353c9352421f6e2000000000000000000000000000000000000000000000000e3565e1f7be6e49700000000000000000000000000000000000000000000000000000000000000000245ddf834b20cdd13c559fdd131c27f3c52d38ba6a456d6064a64269b703bc2012d0ffbb4ab3df623c0bdfba83004ef4db50ea351314b648153d2f6002f78cb4e00000000000000000000000000000000000000000000000000000000000000026a6bbed7e57969d56e6485682afc481f8f8127f292e4bd300f6bb0a57b77b21a2ca0e3338ba16b0afbbae567fc4a728c4b95c2092169f412ae7b8fc53c81342a + + Report Metadata: + Feed ID: 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 + Valid From: 1758678759 + Observations: 1758678759 - [...] + Decoded Data: + Native Fee: 76306702198883 + LINK Fee: 14757074592361274 + Expires At: 1761270759 + Price: 4193602800000000000000 + Bid Price: 4193448319936840000000 + Ask Price: 4193634351084156000000 + -------------------------------------------------- + [...additional reports...] ``` Your application has successfully subscribed to the report data. From 20be00eeef767d0fad7bcfdf69f70b2f632b5dc1 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 23 Sep 2025 19:14:30 -0700 Subject: [PATCH 13/18] restore section for multiple streams + normalize --- .../data-streams/tutorials/go-sdk-stream.mdx | 10 ++++ .../tutorials/rust-sdk-stream.mdx | 52 +------------------ .../data-streams/tutorials/ts-sdk-stream.mdx | 10 ++++ 3 files changed, 22 insertions(+), 50 deletions(-) diff --git a/src/content/data-streams/tutorials/go-sdk-stream.mdx b/src/content/data-streams/tutorials/go-sdk-stream.mdx index a7f1011f879..ef4f3726a4d 100644 --- a/src/content/data-streams/tutorials/go-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/go-sdk-stream.mdx @@ -390,6 +390,16 @@ When HA mode is enabled, the SDK maintains at least 2 concurrent connections to See more details about HA mode in the [SDK Reference](/data-streams/reference/data-streams-api/go-sdk#high-availability-ha-mode). +### Subscribing to multiple streams + +You can subscribe to multiple streams by providing additional stream IDs as command-line arguments: + +```bash +go run stream.go 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265 +``` + +This will subscribe to both ETH/USD and BTC/USD streams. + ### Payload for onchain verification In this tutorial, you logged and decoded the `full_report` payloads to extract the report data. However, in a production environment, you should verify the data to ensure its integrity and authenticity. diff --git a/src/content/data-streams/tutorials/rust-sdk-stream.mdx b/src/content/data-streams/tutorials/rust-sdk-stream.mdx index 8c82ddf84be..e8324eff3e3 100644 --- a/src/content/data-streams/tutorials/rust-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/rust-sdk-stream.mdx @@ -329,6 +329,8 @@ The example above demonstrates streaming data from a single crypto stream. For p When HA mode is enabled and multiple WebSocket origins are provided, the Stream will maintain concurrent connections to different instances. This ensures high availability, fault tolerance, and minimizes the risk of report gaps. +#### Subscribing to multiple streams + You can subscribe to multiple streams by providing additional stream IDs as command-line arguments: ```bash @@ -365,56 +367,6 @@ For descriptions and data types of other report schemas, see the [Report Schema High Availability (HA) mode creates multiple WebSocket connections to different origin endpoints for improved reliability. When enabled, the SDK automatically handles failover, deduplicates reports, and provides connection-level metrics. -#### Enabling HA mode - -To enable HA mode in your streaming application, make these changes to the basic example: - -1. Add multiple WebSocket endpoints and enable HA mode in the client configuration. You also must use a mainnet endpoint, as HA mode is not currently supported on testnet. - -```rust -use chainlink_data_streams_sdk::config::{Config, WebSocketHighAvailability}; - -let config = Config::new( - api_key, - api_secret, - "https://api.dataengine.chain.link".to_string(), // Mainnet endpoint - "wss://ws1.dataengine.chain.link,wss://ws2.dataengine.chain.link".to_string(), // Multiple WebSocket endpoints -) -.with_ws_ha(WebSocketHighAvailability::Enabled) // Enable High Availability mode -.with_ws_max_reconnect(10) // Optional: Increase max reconnection attempts -.build()?; -``` - -2. Optionally, monitor HA metrics using the existing `get_stats()` calls in your report handler: - -```rust -// In your report processing loop -match stream.read().await { - Ok(report) => { - // ... your report processing logic - - // HA-specific metrics - let stats = stream.get_stats(); - info!( - "šŸ“Š Stats: {} reports | {}/{} connections", - stats.accepted, stats.active_connections, stats.configured_connections - ); - info!("Reconnects: {} partial, {} full", stats.partial_reconnects, stats.full_reconnects); - - // Check deduplication (important for HA mode) - if stats.total_received > 0 { - let dedup_rate = (stats.deduplicated as f64 / stats.total_received as f64) * 100.0; - info!("Deduplication rate: {:.1}%", dedup_rate); - } - } - Err(e) => { - warn!("Error reading from stream: {}", e); - } -} -``` - -See more details about HA mode in the [SDK Reference](/rust-sdk#websocket-features). - ### Payload for onchain verification In this tutorial, you logged and decoded the `full_report` payloads to extract the report data. However, in a production environment, you should verify the data to ensure its integrity and authenticity. diff --git a/src/content/data-streams/tutorials/ts-sdk-stream.mdx b/src/content/data-streams/tutorials/ts-sdk-stream.mdx index 672a36637d2..d79f546f544 100644 --- a/src/content/data-streams/tutorials/ts-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/ts-sdk-stream.mdx @@ -408,6 +408,16 @@ The optional `connectionStatusCallback` can be used to integrate with external m See more details about HA mode in the [SDK Reference](/ts-sdk#high-availability-mode). +### Subscribing to multiple streams + +You can subscribe to multiple streams by providing additional stream IDs as command-line arguments: + +```bash +npx tsx stream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782,0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265 +``` + +This will subscribe to both ETH/USD and BTC/USD streams. + ### Payload for onchain verification In this tutorial, you logged and decoded the `full_report` payloads to extract the report data. However, in a production environment, you should verify the data to ensure its integrity and authenticity. From bd5a1743dc9869916771587efaefa2a5892d0bd9 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 23 Sep 2025 20:47:40 -0700 Subject: [PATCH 14/18] ha mode polish --- .../data-streams/tutorials/go-sdk-stream.mdx | 62 +++++++---------- .../tutorials/rust-sdk-stream.mdx | 62 +++++++++-------- .../data-streams/tutorials/ts-sdk-stream.mdx | 69 ++++++++----------- 3 files changed, 90 insertions(+), 103 deletions(-) diff --git a/src/content/data-streams/tutorials/go-sdk-stream.mdx b/src/content/data-streams/tutorials/go-sdk-stream.mdx index ef4f3726a4d..5423ac1af30 100644 --- a/src/content/data-streams/tutorials/go-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/go-sdk-stream.mdx @@ -327,21 +327,34 @@ The decoded report details include: For descriptions and data types of other report schemas, see the [Report Schema Overview](/data-streams/reference/report-schema-overview). +### Subscribing to multiple streams + +You can subscribe to multiple streams by providing additional stream IDs as command-line arguments: + +```bash +go run stream.go 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265 +``` + +This will subscribe to both ETH/USD and BTC/USD streams. + ### High Availability (HA) mode -High Availability (HA) mode creates multiple WebSocket connections to different origin endpoints for improved reliability. When enabled, the SDK automatically handles failover, deduplicates reports, and provides connection-level metrics. +The example above demonstrates streaming data from a single crypto stream. For production environments, especially when subscribing to multiple streams, it's recommended to enable [High Availability (HA) mode](/data-streams/reference/data-streams-api/go-sdk#high-availability-ha-mode). + +High Availability (HA) mode creates multiple WebSocket connections to different origin endpoints for improved reliability. When HA mode is enabled, the Stream will maintain at least 2 concurrent connections to different instances to ensure high availability, fault tolerance and minimize the risk of report gaps. #### Enabling HA mode To enable HA mode in your streaming application, make these changes to the basic example: -1. Add HA mode to the client configuration and use a mainnet endpoint, as HA mode is not currently supported on testnet: - ```go +// ... existing code ... + +// Enable HA mode with mainnet endpoint cfg := streams.Config{ ApiKey: os.Getenv("API_KEY"), ApiSecret: os.Getenv("API_SECRET"), @@ -349,31 +362,14 @@ cfg := streams.Config{ WsHA: true, // Enable High Availability mode Logger: streams.LogPrintf, } -``` - -2. Monitor HA metrics using the existing `Stats()` calls in your report handler: - -```go -// In your report processing loop -for { - reportResponse, err := stream.Read(context.Background()) - if err != nil { - cfg.Logger("Error reading from stream: %v\n", err) - continue - } - - // Process the report... - // Monitor HA statistics (includes HA-specific metrics) - cfg.Logger("Stream Stats: %s\n", stream.Stats().String()) - // Output example: "accepted: 150, deduplicated: 3, total_received: 153, partial_reconnects: 1, full_reconnects: 0, configured_connections: 2, active_connections: 2" +client, err := streams.New(cfg) +if err != nil { + cfg.Logger("Failed to create client: %v\n", err) + os.Exit(1) } -``` -3. Optionally, monitor individual connection status using `StreamWithStatusCallback`: - -```go -// Subscribe to the feeds with connection status monitoring +// Optional: Use StreamWithStatusCallback for connection monitoring stream, err := client.StreamWithStatusCallback( ctx, ids, func(isConnected bool, host string, origin string) { @@ -384,21 +380,15 @@ stream, err := client.StreamWithStatusCallback( cfg.Logger("Host: %s, Origin: %s, Status: %s\n", host, origin, status) }, ) -``` - -When HA mode is enabled, the SDK maintains at least 2 concurrent connections to different instances to ensure high availability, fault tolerance, and minimize the risk of report gaps. - -See more details about HA mode in the [SDK Reference](/data-streams/reference/data-streams-api/go-sdk#high-availability-ha-mode). -### Subscribing to multiple streams +// ... existing code ... +``` -You can subscribe to multiple streams by providing additional stream IDs as command-line arguments: +When `WsHA` is `true`, the SDK automatically discovers multiple origin endpoints behind the single URL and establishes separate connections to each origin. You also must use a mainnet endpoint, as HA mode is not currently supported on testnet. -```bash -go run stream.go 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782 0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265 -``` +The optional `StreamWithStatusCallback` can be used to monitor individual connection status. The SDK already provides comprehensive connection logs through `stream.Stats().String()`, so this callback is primarily useful for custom alerting or connection monitoring. -This will subscribe to both ETH/USD and BTC/USD streams. +See more details about HA mode in the [SDK Reference](/data-streams/reference/data-streams-api/go-sdk#high-availability-ha-mode). ### Payload for onchain verification diff --git a/src/content/data-streams/tutorials/rust-sdk-stream.mdx b/src/content/data-streams/tutorials/rust-sdk-stream.mdx index e8324eff3e3..348646c1229 100644 --- a/src/content/data-streams/tutorials/rust-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/rust-sdk-stream.mdx @@ -310,25 +310,6 @@ In this tutorial, you'll learn how to use the [Data Streams SDK](/data-streams/r [Learn more about the decoded report details](#decoded-report-details). -### High Availability (HA) Mode - -The example above demonstrates streaming data from a single crypto stream. For production environments, especially when subscribing to multiple streams, it's recommended to enable [High Availability (HA) mode](https://github.com/smartcontractkit/data-streams-sdk/blob/main/rust/docs/examples/wss_multiple.md). This can be achieved by: - -1. Adding multiple WebSocket endpoints in the configuration: - - ```rust - "wss://ws.testnet-dataengine.chain.link,wss://ws.testnet-dataengine.chain.link" - ``` - -1. Enabling HA mode in the configuration: - ```rust - use chainlink_data_streams_sdk::config::WebSocketHighAvailability; - // ... - .with_ws_ha(WebSocketHighAvailability::Enabled) - ``` - -When HA mode is enabled and multiple WebSocket origins are provided, the Stream will maintain concurrent connections to different instances. This ensures high availability, fault tolerance, and minimizes the risk of report gaps. - #### Subscribing to multiple streams You can subscribe to multiple streams by providing additional stream IDs as command-line arguments: @@ -341,6 +322,41 @@ cargo run -- \ This will subscribe to both ETH/USD and BTC/USD streams. +### High Availability (HA) mode + + + +The example above demonstrates streaming data from a single crypto stream. For production environments, especially when subscribing to multiple streams, it's recommended to enable [High Availability (HA) mode](/data-streams/reference/data-streams-api/rust-sdk#high-availability-mode). + +High Availability (HA) mode creates multiple WebSocket connections to different origin endpoints for improved reliability. When HA mode is enabled, the Stream will maintain at least 2 concurrent connections to different instances to ensure high availability, fault tolerance and minimize the risk of report gaps. + +#### Enabling HA mode + +To enable HA mode in your streaming application, make these changes to the basic example. You also must use a mainnet endpoint, as HA mode is not currently supported on testnet. + +```rust +// ... existing code ... + +use chainlink_data_streams_sdk::config::{Config, WebSocketHighAvailability}; // Import WebSocketHighAvailability + +// Initialize the configuration with HA mode +let config = Config::new( + api_key, + api_secret, + "https://api.dataengine.chain.link".to_string(), // Mainnet endpoint + "wss://ws.dataengine.chain.link,wss://ws.dataengine.chain.link".to_string(), // Multiple WebSocket endpoints +) +.with_ws_ha(WebSocketHighAvailability::Enabled) // Enable WebSocket High Availability Mode +.build()?; + + +// ... existing code ... +``` + +See more details about HA mode in the [SDK Reference](/data-streams/reference/data-streams-api/rust-sdk#high-availability-mode). + ### Decoded report details The decoded report details include: @@ -359,14 +375,6 @@ The decoded report details include: For descriptions and data types of other report schemas, see the [Report Schema Overview](/data-streams/reference/report-schema-overview). -### High Availability (HA) mode - - - -High Availability (HA) mode creates multiple WebSocket connections to different origin endpoints for improved reliability. When enabled, the SDK automatically handles failover, deduplicates reports, and provides connection-level metrics. - ### Payload for onchain verification In this tutorial, you logged and decoded the `full_report` payloads to extract the report data. However, in a production environment, you should verify the data to ensure its integrity and authenticity. diff --git a/src/content/data-streams/tutorials/ts-sdk-stream.mdx b/src/content/data-streams/tutorials/ts-sdk-stream.mdx index d79f546f544..b8002e357e1 100644 --- a/src/content/data-streams/tutorials/ts-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/ts-sdk-stream.mdx @@ -346,32 +346,50 @@ The decoded report details include: For descriptions and data types of other report schemas, see the [Report Schema Overview](/data-streams/reference/report-schema-overview). +### Subscribing to multiple streams + +You can subscribe to multiple streams by providing additional stream IDs as command-line arguments: + +```bash +npx tsx stream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782,0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265 +``` + +This will subscribe to both ETH/USD and BTC/USD streams. + ### High Availability (HA) mode -High Availability (HA) mode creates multiple WebSocket connections to different origin endpoints for improved reliability. When enabled, the SDK automatically handles failover, deduplicates reports, and provides connection-level metrics. +The example above demonstrates streaming data from a single crypto stream. For production environments, especially when subscribing to multiple streams, it's recommended to enable [High Availability (HA) mode](/data-streams/reference/data-streams-api/ts-sdk#high-availability-mode). + +High Availability (HA) mode creates multiple WebSocket connections to different origin endpoints for improved reliability. When HA mode is enabled, the Stream will maintain at least 2 concurrent connections to different instances to ensure high availability, fault tolerance and minimize the risk of report gaps. #### Enabling HA mode To enable HA mode in your streaming application, make these changes to the basic example: -1. Add `haMode: true` to the client configuration. You also must use a mainnet endpoint, as HA mode is not currently supported on testnet. - ```typescript +// ... existing code ... + const client = createClient({ apiKey: process.env.API_KEY || "YOUR_API_KEY", userSecret: process.env.USER_SECRET || "YOUR_USER_SECRET", endpoint: "https://api.dataengine.chain.link", // Mainnet endpoint - wsEndpoint: "wss://ws.dataengine.chain.link", // Mainnet WebSocket + wsEndpoint: "wss://ws.dataengine.chain.link", // Single endpoint (mainnet only) haMode: true, // Enable High Availability mode - // Optional: Monitor connection status changes - connectionStatusCallback: (isConnected: boolean, host: string, origin?: string) => { - const status = isConnected ? "🟢 Connected" : "šŸ”“ Disconnected" - console.log(`${status}: ${host}${origin ? ` (${origin})` : ""}`) + // Optional: Advanced connection monitoring with origin tracking + connectionStatusCallback: (isConnected, host, origin) => { + const timestamp = new Date().toISOString().substring(11, 19) + const status = isConnected ? "🟢 UP" : "šŸ”“ DOWN" + console.log(`[${timestamp}] ${status} ${host}${origin || ""}`) + + // Example: Send alerts for specific origins + if (!isConnected && origin) { + console.warn(`āš ļø Alert: Origin ${origin} on ${host} went offline`) + } }, logging: { @@ -379,44 +397,15 @@ const client = createClient({ logLevel: LogLevel.INFO, }, }) -``` - -2. Optionally, monitor HA metrics using the existing `getMetrics()` calls in your report handler: -```typescript -stream.on("report", (report) => { - // ... your report processing logic - - // HA-specific metrics - const stats = stream.getMetrics() - console.log( - `šŸ“Š HA Stats: ${stats.accepted} reports | ${stats.activeConnections}/${stats.configuredConnections} connections` - ) - console.log(`Reconnects: ${stats.partialReconnects} partial, ${stats.fullReconnects} full`) - - // Check deduplication (important for HA mode) - if (stats.totalReceived > 0) { - const deduplicationRate = ((stats.deduplicated / stats.totalReceived) * 100).toFixed(1) - console.log(`šŸ“ˆ Deduplication: ${deduplicationRate}% (${stats.deduplicated} filtered)`) - } -}) +// ... existing code ... ``` -When `haMode` is `true`, the SDK automatically discovers multiple origin endpoints behind the single URL and establishes separate connections to each origin. +When `haMode` is `true`, the SDK automatically discovers multiple origin endpoints behind the single URL and establishes separate connections to each origin. You also must use a mainnet endpoint, as HA mode is not currently supported on testnet. The optional `connectionStatusCallback` can be used to integrate with external monitoring systems. The SDK already provides comprehensive connection logs, so this callback is primarily useful for custom alerting or metrics collection. -See more details about HA mode in the [SDK Reference](/ts-sdk#high-availability-mode). - -### Subscribing to multiple streams - -You can subscribe to multiple streams by providing additional stream IDs as command-line arguments: - -```bash -npx tsx stream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782,0x00036fe43f87884450b4c7e093cd5ed99cac6640d8c2000e6afc02c8838d0265 -``` - -This will subscribe to both ETH/USD and BTC/USD streams. +See more details about HA mode in the [SDK Reference](/data-streams/reference/data-streams-api/ts-sdk#high-availability-ha-mode). ### Payload for onchain verification From 10c1b6333659bd6caf5f6d7ba2d0f6e0c4ba7104 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 23 Sep 2025 20:59:11 -0700 Subject: [PATCH 15/18] link fix --- src/content/data-streams/tutorials/ts-sdk-stream.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/data-streams/tutorials/ts-sdk-stream.mdx b/src/content/data-streams/tutorials/ts-sdk-stream.mdx index b8002e357e1..61ef2c1b33b 100644 --- a/src/content/data-streams/tutorials/ts-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/ts-sdk-stream.mdx @@ -405,7 +405,7 @@ When `haMode` is `true`, the SDK automatically discovers multiple origin endpoin The optional `connectionStatusCallback` can be used to integrate with external monitoring systems. The SDK already provides comprehensive connection logs, so this callback is primarily useful for custom alerting or metrics collection. -See more details about HA mode in the [SDK Reference](/data-streams/reference/data-streams-api/ts-sdk#high-availability-ha-mode). +See more details about HA mode in the [SDK Reference](/data-streams/reference/data-streams-api/ts-sdk#high-availability-mode). ### Payload for onchain verification From 10416e01a110aacdab7beeaca81b7960f216f51d Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 23 Sep 2025 21:15:09 -0700 Subject: [PATCH 16/18] heading level --- src/content/data-streams/tutorials/rust-sdk-stream.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/data-streams/tutorials/rust-sdk-stream.mdx b/src/content/data-streams/tutorials/rust-sdk-stream.mdx index 348646c1229..364f3433a44 100644 --- a/src/content/data-streams/tutorials/rust-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/rust-sdk-stream.mdx @@ -310,7 +310,7 @@ In this tutorial, you'll learn how to use the [Data Streams SDK](/data-streams/r [Learn more about the decoded report details](#decoded-report-details). -#### Subscribing to multiple streams +### Subscribing to multiple streams You can subscribe to multiple streams by providing additional stream IDs as command-line arguments: From 10e37424c7961b996ec29a98b1e5484770595c44 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 23 Sep 2025 21:46:20 -0700 Subject: [PATCH 17/18] added clarifying comments --- src/content/data-streams/tutorials/go-sdk-stream.mdx | 4 +++- src/content/data-streams/tutorials/rust-sdk-stream.mdx | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/content/data-streams/tutorials/go-sdk-stream.mdx b/src/content/data-streams/tutorials/go-sdk-stream.mdx index 5423ac1af30..d861dd07326 100644 --- a/src/content/data-streams/tutorials/go-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/go-sdk-stream.mdx @@ -369,7 +369,9 @@ if err != nil { os.Exit(1) } -// Optional: Use StreamWithStatusCallback for connection monitoring +// ... existing code ... + +// Optional: Change streams subscription to use StreamWithStatusCallback for connection monitoring stream, err := client.StreamWithStatusCallback( ctx, ids, func(isConnected bool, host string, origin string) { diff --git a/src/content/data-streams/tutorials/rust-sdk-stream.mdx b/src/content/data-streams/tutorials/rust-sdk-stream.mdx index 364f3433a44..47fef9f173d 100644 --- a/src/content/data-streams/tutorials/rust-sdk-stream.mdx +++ b/src/content/data-streams/tutorials/rust-sdk-stream.mdx @@ -341,6 +341,8 @@ To enable HA mode in your streaming application, make these changes to the basic use chainlink_data_streams_sdk::config::{Config, WebSocketHighAvailability}; // Import WebSocketHighAvailability +// ... existing code ... + // Initialize the configuration with HA mode let config = Config::new( api_key, From 4f21cc1b051c3e847e54884fa9f6b91fb75e40f9 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Thu, 9 Oct 2025 11:26:14 -0700 Subject: [PATCH 18/18] codesample update --- src/content/data-streams/tutorials/ts-sdk-fetch.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/data-streams/tutorials/ts-sdk-fetch.mdx b/src/content/data-streams/tutorials/ts-sdk-fetch.mdx index 99c84fda31e..2947743de21 100644 --- a/src/content/data-streams/tutorials/ts-sdk-fetch.mdx +++ b/src/content/data-streams/tutorials/ts-sdk-fetch.mdx @@ -108,7 +108,7 @@ You'll start with the set up of your TypeScript project, installing the SDK and if (process.argv.length < 3) { console.error("Please provide a feed ID as an argument") console.error( - "Example: npx tsx examples/get-latest-report.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782" + "Example: npx tsx singleStream.ts 0x000359843a543ee2fe414dc14c7e7920ef10f4372990b79d6361cdc0dd1ba782" ) process.exit(1) }