Subscribe to solutions

This example demonstrates how to subscribe to solutions from the bloXroute gateway. Only a subscriber with the correct private key can receive the solution.

Name: IntentSolutions

IntentSolutions is a GRPC stream of the new solutions that match the dappAddress of the subscription as they are propagated in the BDN. IntentSolutionsRequest arguments:



ETH address of DApp that should receive solutions



Keccak256Hash of the dappAddress bytes



ECDSA signature of the hash signed by DApp private key


IntentSolutionsReply fields (stream message):



UUID of the intent



solution for the specific intent


package main

import (

	pb ""


// gatewayHost is the address of the gateway to which the subscription is being made
const gatewayHost = ""

// header is the authorization header of your bloXroute Account

func main() {
	// Dial the gateway
	conn, err := grpc.Dial(gatewayHost,
		grpc.WithPerRPCCredentials(blxrCredentials{authorization: header}))
	if err != nil {
		log.Fatalln("dial grpc", err)

	// Create a client
	client := pb.NewGatewayClient(conn)

	// Subscribe to solutions
	stream, err := client.IntentSolutions(context.Background(), genIntentSolutionRequest())
	if err != nil {
		log.Fatalln("subscribe to solutions", err)

	for {
		fmt.Printf("listening for IntentSolutions from %s ...\n", gatewayHost)

		// Receive the solution from the stream until the stream is closed
		msg, err := stream.Recv()
		if err != nil {
			log.Fatalln("receive from stream", err)

		fmt.Println("got solution:")
		fmt.Println("- id:", msg.IntentId)
		fmt.Println("- solution:", hex.EncodeToString(msg.IntentSolution))

func genIntentSolutionRequest() *pb.IntentSolutionsRequest {
	// DApp private key used to prove the ownership of the DApp address
	const privateKeyHex = "7c4a8d09ca3762af61e59520943dc26494f8941e6e5b998321d3e84b8e4d3c16"

	// Convert the hex string to a private key
	privKey, err := crypto.HexToECDSA(privateKeyHex)
	if err != nil {
		log.Fatalln("error converting hex to ECDSA", err)

	// Extract the public key
	pubKey := privKey.PublicKey
	signerAddress := crypto.PubkeyToAddress(pubKey)

	// Hash the signer address
	hash := crypto.Keccak256Hash([]byte(signerAddress.String())).Bytes() // need a hash to sign, so we're hashing the payload here
	sig, err := crypto.Sign(hash, privKey)                               // signing the hash
	if err != nil {
		log.Fatalln("error signing with private key", err)

	// Return the solution request
	return &pb.IntentSolutionsRequest{
		DappAddress: signerAddress.String(),
		Hash:        hash,
		Signature:   sig,

// blxrCredentials is an implementation of PerRPCCredentials
type blxrCredentials struct {
	authorization string

// GetRequestMetadata sets the authorization header
func (bc blxrCredentials) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
	return map[string]string{
		"authorization": bc.authorization,
	}, nil

// RequireTransportSecurity is a method of the PerRPCCredentials interface
func (bc blxrCredentials) RequireTransportSecurity() bool {
	return false

Last updated