For the complete documentation index, see llms.txt. This page is also available as Markdown.
Base Get FlashBlockStream Integration Guide
Explore the BlockRazor Base Get FlashBlockStream service, advantage, endpoint, price, and integration guide.
What is Base Get FlashBlockStream
Get FlashBlockStream is a real-time FlashBlock data subscription interface provided by BlockRazor for Base, used to obtain earlier stages of block data on Base with lower latency. This interface supports both gRPC and WebSocket protocols, making it suitable for trading systems, and monitoring systems that are more sensitive to data arrival time.
On Base, FlashBlock can be understood as a "sub-block" data stream that occurs before the formal block is formed, typically pushed continuously at a frequency of about 200ms. Compared to the standard block time of about 2 seconds, FlashBlock can provide transaction-related feedback much earlier, making it more suitable for low-latency scenarios that require quick on-chain awareness of changes.
For trading bots, quantitative strategies, real-time monitoring platforms, and front-end trading applications, waiting for blocks often means longer response times. The value of Get FlashBlockStream is to help the system receive transaction and block change signals earlier, before the block arrives, thus buying more time for subsequent judgment and response.
Why choose Base Get FlashBlockStream
BlockRazor, based on BEF, provides access points to multiple regions on Base, including Frankfurt, Virginia, and Tokyo. According to Base Benchmark, BlockRazor demonstrates an advantage over the official Base service in FlashBlock reception latency across multiple regions, with a particularly significant lead in the mid-to-high percentile range.
What is the difference between Get BlockStream and Get FlashBlockStream
The core difference between the two lies in the different data granularity, time points, and applicable scenarios.
Get BlockStream
It is used to retrieve block that has already been formed on Base, focusing on confirmed blocks and transactions within. It is more suitable for monitoring confirmation results, block-level analysis, on-chain data processing, and data systems that need to stably consume blocks.
Get FlashBlockStream
Used to retrieve FlashBlock data on Base. FlashBlock is a "sub-block" of data pushed by Base approximately every 200ms, providing pre-confirmation information for transactions much earlier than the standard 2-second formal block time. It is more suitable for scenarios that are more sensitive to low latency and want to see on-chain changes as early as possible.
Price
The price is $25 / stream / day and $250 / stream / month. Subscribe
The number of data streams that can be subscribed to is calculated on a shared basis across all regions. For example, if you purchase one stream, you can only subscribe in one region; you will not be able to subscribe in other regions.
// GetFlashBlockStream provides a simplified example of subscribing to and processing the flash block stream.
// Note: This function attempts to connect and subscribe only once. For production use, implement your own reconnection logic.
func GetFlashBlockStream(authToken string) {
log.Printf("[FlashStream] Attempting to connect to gRPC server at %s...", grpcAddr)
// Establish a connection to the gRPC server with a timeout.
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
conn, err := grpc.DialContext(ctx, grpcAddr,
grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Printf("[FlashStream] Failed to connect to gRPC server: %v", err)
return
}
defer conn.Close()
log.Println("[FlashStream] Successfully connected to gRPC server.")
client := basepb.NewBaseApiClient(conn)
// Create a new context with authentication metadata for the stream subscription.
streamCtx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs("authorization", authToken))
stream, err := client.GetRawFlashBlockStream(streamCtx, &basepb.GetRawFlashBlocksStreamRequest{})
if err != nil {
log.Printf("[FlashStream] Failed to subscribe to stream: %v", err)
return
}
log.Println("[FlashStream] Subscription successful. Waiting for new flash blocks...")
// Loop indefinitely to receive messages from the stream.
for {
block, err := stream.Recv()
if err != nil {
if err == io.EOF {
log.Println("[FlashStream] Stream closed by the server (EOF).")
} else {
log.Printf("[FlashStream] An error occurred while receiving data: %v", err)
}
break // Exit the loop on error or stream closure.
}
// Process the received flash block data.
jsonString, err := ParseFlashBlockByte(block.Message)
if err != nil {
log.Printf("[FlashStream] Failed to parse flash block data: %v", err)
continue
}
var jsonMap map[string]interface{}
if err := json.Unmarshal([]byte(jsonString), &jsonMap); err != nil {
log.Printf("[FlashStream] Failed to unmarshal flash block JSON: %v", err)
continue
}
printPretty(jsonMap)
}
}
// GetWebSocketFlashBlockStream provides a simplified example of using the WebSocket API to subscribe to the flash block stream.
// Note: This function attempts to connect only once and will exit on a read error. For production use, implement your own reconnection logic.
func GetWebSocketFlashBlockStream(authToken string) {
// Set up the HTTP header with the authorization token.
header := http.Header{}
header.Set("Authorization", authToken)
// Dial the WebSocket server.
dialer := websocket.DefaultDialer
conn, resp, err := dialer.Dial(websocketAddr, header)
if err != nil {
if resp != nil {
log.Fatalf("[WebSocket] Dial failed: %v (HTTP status: %s)", err, resp.Status)
}
log.Fatalf("[WebSocket] Dial failed: %v", err)
}
defer conn.Close()
log.Printf("[WebSocket] Successfully connected to %s", websocketAddr)
// Prepare the JSON-RPC subscription request.
req := map[string]interface{}{
"jsonrpc": "2.0",
"method": "subscribe_FlashBlock",
"params": []interface{}{},
"id": 1,
}
reqB, _ := json.Marshal(req)
if err := conn.WriteMessage(websocket.TextMessage, reqB); err != nil {
log.Fatalf("[WebSocket] Failed to send subscription request: %v", err)
}
log.Printf("[WebSocket] Subscription request sent: %s", string(reqB))
// Loop indefinitely to read messages from the server.
for {
msgType, msg, err := conn.ReadMessage()
if err != nil {
log.Printf("[WebSocket] Error reading message: %v", err)
return // Exit the function on any read error.
}
if msgType != websocket.TextMessage && msgType != websocket.BinaryMessage {
continue // Ignore messages that are not text or binary.
}
// Parse the outer JSON-RPC response wrapper.
var outer = &FlashBlockWebSocketResponse{}
if err := json.Unmarshal(msg, &outer); err != nil {
log.Printf("[WebSocket] Failed to parse JSON from server: %v\nRaw data: %s", err, string(msg))
continue
}
// Extract the "result" field, which contains the actual flash block data, and process it.
resultRaw := outer.Result
if jsonString, err := ParseFlashBlockByte(resultRaw); err == nil {
printPretty(jsonString)
} else {
log.Printf("[WebSocket] Received message without a valid result field. Raw data: %s", string(msg))
}
}
}