Get the real-time product data from Coinbase Advanced Trade API (WebSocket, NodeJS)

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.