I recently needed to use Coinbase Advanced Trade to get real-time prices for a product. Coinbase has a WebSocket feed. Here is a snippet on how to use it. This code is not production-ready (where are the unit tests!), but it was a good starting point for me.
Lets’ say we have a config.ts
file.
export const CoinbaseConfig = { wsUrl: process.env.COINBASE_WS_URL, apiSecret: process.env.COINBASE_API_SECRET, apiKey: process.env.COINBASE_API_KEY,};
Here is the auth.ts
code required to create an authorization signature.
import { createHmac } from "node:crypto";import "./config";
const createHmacHex = ({ data, secret }: { data: string; secret: string }) => createHmac("sha256", secret).update(data).digest("hex");
const createTimestamp = () => Math.floor(Date.now() / 1000).toString();
const createData = ({ timestamp, channel, products,}: { timestamp: string; channel: string; products: string[];}) => `${timestamp}${channel}${products.join(",")}`;
const createSignature = ({ channel, products,}: { channel: string; products: string[];}) => { const timestamp = createTimestamp(); const data = createData({ timestamp, channel, products }); const signature = createHmacHex({ data, secret: CoinbaseConfig.apiSecret });
return { timestamp, data, signature, };};
Let’s create a subscription function to send messages. (subscription.ts
)
import WebSocket from "ws";import { CoinbaseConfig } from "./config";import { createSignature } from "./auth";
export const subscription = ({ type, products, channel, ws,}: { type: "subscribe" | "unsubscribe"; products: string[]; channel: string; ws: WebSocket;}) => { const message = { type, channel, api_key: CoinbaseConfig.apiKey, product_ids: products, };
const signature = createSignature({ channel, products });
ws.send(JSON.stringify({ ...message, ...signature }));};
Create a subscribe.ts
file to implement the main code for getting and sending messages.
import { CoinbaseConfig } from "./config";import { WebSocket } from "ws";import { subscription } from "./subscription";
export const subscribe = async (product: string) => { const ws = new WebSocket(CoinbaseConfig.wsUrl);
ws.on("message", async (data: string) => { // Use JSON.parse(data) to parse the product data. console.log("product data", JSON.parse(data)); });
ws.on("open", () => { subscription({ type: "subscribe", products: [product], channel: "ticker", ws, }); });
ws.on("error", () => { ws.close(); });
ws.on("close", () => { setTimeout(() => subscribe(product), 5000); });};
Now, you can use it like this.
import { subscribe } from "./subscribe";
await subscribe("NEAR-USDC");
You can read more in the official Coinbase documentation: https://docs.cloud.coinbase.com/advanced-trade-api/docs/ws-overview.