Subscribe to intents

This is an example of how to subscribe to intents. Anybody can subscribe to intents.

Name: Intents

Intents is a GRPC stream of all new intents as they are propagated in the BDN. IntentsRequest arguments:

KeyDescriptionValues

solverAddress

address of solver

string

hash

Keccak256Hash of the solverAddress bytes

byte[]

signature

ECDSA signature of the hash

byte[]

fromTimestamp

timestamp (optional)

google.protobuf.Timestamp

IntentsReply fields (stream message):

KeyDescriptionValues

dappAddress

ETH address of the DApp that owns the intent

string

senderAddress

ETH address of intent sender

string

intentID

UUID of the intent

string

intent

intent

byte[]

fromTimestamp

timestamp (optional)

google.protobuf.Timestamp

package main

import (
	"context"
	"encoding/hex"
	"fmt"
	"log"

	pb "github.com/bloXroute-Labs/gateway/v2/protobuf"

	"github.com/ethereum/go-ethereum/crypto"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
)

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

// authHeader is the authorization header of your bloXroute Account
const authHeader = "<YOUR-AUTHORIZATION-HEADER>"

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

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

	// Subscribe to intents
	stream, err := client.Intents(context.Background(), genIntentsRequest())
	if err != nil {
		log.Fatalln("subscribe to intents", err)
	}

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

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

		fmt.Println("------------------")
		fmt.Println("got intent:")
		fmt.Println("- dapp addr:  ", msg.DappAddress)
		fmt.Println("- sender addr:", msg.SenderAddress)
		fmt.Println("- id:         ", msg.IntentId)
		fmt.Println("- timestamp:  ", msg.Timestamp.String())
		fmt.Println("- intent:     ", hex.EncodeToString(msg.Intent))
	}

}

func genIntentsRequest() *pb.IntentsRequest {
	// Generate an ECDSA key pair using secp256k1 curve
	privKey, err := crypto.GenerateKey()
	if err != nil {
		log.Fatalln("generate key", err)
	}

	pubKey := privKey.PublicKey                                          // extract the public key
	signerAddress := crypto.PubkeyToAddress(pubKey)                      // the address of the public key
	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)                               // sign the hash
	if err != nil {
		log.Fatalln("sign privKey", err)
	}

	// Return the intent request
	return &pb.IntentsRequest{
		SolverAddress: 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