Vibecoding an analytics dashboard on Base with GoldRush and x402 - Part 2

Zeeshan Jawed
Content Writer
Learn to monetize your analytics with crypto payments using the X402 protocol on Base. Pt 2 covers WebSocket integration, OHLCV and React UI updates

Introduction

In Part 1, we built the cash register. We implemented the X402 Protocol to gate content behind a crypto-payment wall. Now, we need to stock the shelves.

Static data in crypto is dead data. Prices move in blocks (every 2 seconds on Base), and arbitrage opportunities vanish in milliseconds. To build a dashboard worth paying for, we cannot rely on standard REST APIs that we have to poll every few seconds. We need Push Architecture.

Enter the GoldRush Streaming API by Covalent.

This is not your average API. It uses GraphQL over WebSockets, a powerful combination that allows us to subscribe to specific on-chain events—like token price updates (OHLCV) or wallet movements—and receive them the instant they are validated by the network.

In Part 2, we will build the Live Intelligence Dashboard. We will connect to the GoldRush stream, filter for high-value signal, and pipe it directly to our authenticated users.

Chapter 1: Understanding GoldRush Streaming API

Before we code, let's understand the protocol. Most developers are used to REST (GET /transactions). GoldRush Streaming uses graphql-transport-ws.

The Stack Difference

  • REST: Request -> Wait -> Response. High latency. Heavy on server resources (polling).

  • GoldRush Streaming: Handshake -> Subscribe -> Stream -> Stream -> Stream. Low latency. Event-driven.

Supported Data Types

For our dashboard, we care about three streams available on BASE_MAINNET:

  1. OHLCV (Open, High, Low, Close, Volume): Live price candles for tokens.

  2. Wallet Activity: Real-time monitoring of specific "Whale" addresses.

  3. New DEX Pairs: Detecting new liquidity pools the moment they launch (Alpha).

We will focus on OHLCV to build a live trading view.

Chapter 2: Authentication and API Keys

To access the stream, you need a GoldRush API Key.

  1. Go to the GoldRush Platform.

  2. Sign up and create a new key.

  3. Security Note: Unlike the private key in Part 1, this key is for data access. However, you should still keep it in your .env file server-side to prevent quota theft.

Update your .env file from Part 1:

# ... existing X402 config ... GOLDRUSH_API_KEY=cqt_rX...  # Your new key

Chapter 3: Project Setup for Streaming

We need a WebSocket client capable of speaking GraphQL. The industry standard is graphql-ws.

Open your terminal in the Cursor project:

npm install graphql-ws ws

We will create a new service file to handle the streaming logic separate from our Express routes. Create streamService.js

Chapter 4: Implementing WebSocket Connection

Open streamService.js. We will build a class to manage the GoldRush connection.

Prompt for Cursor: "Create a Node.js class GoldRushStream using the graphql-ws library. It should connect to wss://gr-staging-v2.streaming.covalenthq.com/graphqland authenticate using a bearer token from env variables."

The resulting code should look structurally like this:

require('dotenv').config(); const { createClient } = require('graphql-ws'); const WebSocket = require('ws'); class GoldRushStream {     constructor() {         this.client = createClient({             webSocketImpl: WebSocket,             url: 'wss://[api.covalenthq.com/graphql](https://api.covalenthq.com/graphql)',             connectionParams: {                 Authorization: `Bearer ${process.env.GOLDRUSH_API_KEY}`,             },         });                 this.unsubscribe = null;     }     // Function to start the stream     startStream(callback) {         console.log("🌊 Connecting to GoldRush Stream...");         // Subscription logic will go here     } } module.exports = new GoldRushStream();

Chapter 5: Building the Streaming Dashboard Page

Now, let's visualize what we are building. We want a professional-grade interface that displays live OHLCV (Open, High, Low, Close, Volume) data candles.

After the user passes the X402 payment gate, they will be redirected to this real-time view:

This dashboard consumes the WebSocket feed we are about to configure and renders it into a clean table, updating dynamically as new blocks are confirmed on Base Mainnet.

Chapter 6: GraphQL Subscription Setup (The Query)

This is the most critical part. We need to write the GraphQL query that tells GoldRush exactly what we want. We don't want the firehose of the entire blockchain; we want specific data.

We will subscribe to 1-minute price candles for Wrapped Ether (WETH) on Base Mainnet.

The query structure:

subscription {   ohlcv(     chain_name: "base-mainnet",     dex_name: "uniswap_v3",     pool_address: "0xd0b53d9277642d899df5f87a3966a34909ae9091", # WETH/USDC on Base     interval: "minute"   ) {     time     open     high     low     close     volume   } }

Add this query to your streamService.js inside the startStream method:

  startStream(onDataReceived) {         const query = `             subscription {                 ohlcv(                     chain_name: "base-mainnet",                     dex_name: "uniswap_v3",                     pool_address: "0xd0b53d9277642d899df5f87a3966a34909ae9091",                     interval: "minute"                 ) {                     time                     close                     volume                 }             }         `;         this.unsubscribe = this.client.subscribe(             { query },             {                 next: (data) => {                     // This callback fires every time a new block/event occurs                     onDataReceived(data);                 },                 error: (err) => console.error('Stream Error:', err),                 complete: () => console.log('Stream Closed'),             },         );     }

Chapter 7: Integration with X402 Payment (The Bridge)

Now we connect Part 1 and Part 2. We want to ensure that only paid users can access this live stream data.

In a real-world app, you would likely use WebSockets to push data to the frontend. For this tutorial, we will create a simple Buffer that holds the latest price, and our protected route will serve that latest price.

Updating server.js

  1. Import the Stream Service:
    const goldRush = require('./streamService');

  2. Initialize the Data Store:
    We need a variable to hold the latest data

let latestMarketData = { status: "Waiting for blockchain..." }; // Start the stream when the server starts goldRush.startStream((data) => {     if (data.data && data.data.ohlcv) {         console.log("Update received:", data.data.ohlcv);         latestMarketData = data.data.ohlcv;     } });

3. Update the Protected Route:
Modify the /api/premium-data route we built in Part 1 to return latestMarketData instead of static text.

app.get('/api/premium-data', paymentMiddleware(premiumContentConfig), (req, res) => {     res.json({         success: true,         source: "GoldRush Streaming API",         data: latestMarketData     }); });

Chapter 8: Real-Time Data Handling & Formatting

Raw blockchain data is often ugly. Prices might come back with 18 decimal places or scientific notation.

In server.js, let's add a formatting layer inside the stream callback before updating latestMarketData

goldRush.startStream((payload) => {     const rawData = payload.data.ohlcv[0]; // Get the first (latest) candle         if (rawData) {         latestMarketData = {             token: "WETH",             price: `$${parseFloat(rawData.close).toFixed(2)}`,             volume: parseFloat(rawData.volume).toLocaleString(),             trend: rawData.close > rawData.open ? "UP 🟢" : "DOWN 🔴",             timestamp: new Date().toLocaleTimeString()         };         console.log("Cache updated:", latestMarketData.timestamp);     } });

Chapter 9: Troubleshooting Streaming Issues

Streaming is sensitive. Here are the common pitfalls:

1. Connection Drops

WebSockets die. It happens.

  • Solution: The graphql-ws client has built-in retry logic, but you should monitor the complete or error callbacks. If the stream closes, call startStream() again after a 5-second delay.

2. Authentication Errors

  • Error: 4403: Forbidden or Connection refused.

  • Solution: Check your .env file. Ensure GOLDRUSH_API_KEY is loaded correctly. If you regenerated the key, restart the server.

3. "Keep-Alive" Timeouts

  • Symptom: Connection closes after 1 minute of silence.

  • Solution: GoldRush sends "ping" messages. Ensure your client handles PONGs (standard libraries do this automatically). Also, ensure you are subscribing to a chain with activity. Base Mainnet is active, but testnets can be quiet.

Chapter 10: Production Considerations

We are running locally, but "Vibecoding" means building for the world.

Rate Limiting

If you have 1,000 paying users, you don't want to open 1,000 WebSocket connections to GoldRush.

  • Optimization: Open ONE connection to GoldRush on your server. Cache the data in a Redis store or a local variable (as we did). Serve the 1,000 users from that local cache. This is the Multiplexer Pattern.

API Key Security

Never send your GoldRush API key to the frontend. Our architecture handles this perfectly: the key stays in server.js, and the frontend only sees the processed JSON.

Conclusion: The Final Build

Congratulations. You have vibecoded a full-stack, monetized, real-time Web3 application.

Let's recap what we built:

  1. Economic Layer: A server that demands payment via X402 and verifies transactions on Base.

  2. Intelligence Layer: A streaming service that consumes live GoldRush data via WebSockets.

  3. Integration: A unified pipeline where crypto-payments unlock real-time crypto-data.

Where to go next?

  • Expand the Stream: Subscribe to "New Pair Created" events to build a "Sniper Bot" dashboard.

  • Session Tokens: Instead of paying per request, issue a JWT (JSON Web Token) after payment that gives 24-hour access.

  • Deploy: Push this to a VPS, set up Nginx with SSL, and start earning ETH for your data

Get Started

Get started with GoldRush API in minutes. Sign up for a free API key and start building.

Support

Explore multiple support options! From FAQs for self-help to real-time interactions on Discord.

Contact Sales

Interested in our professional or enterprise plans? Contact our sales team to learn more.