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:
Key
Description
Values
dappAddress
ETH address of DApp that should receive solutions
string
hash
Keccak256Hash of the dappAddress bytes
byte[]
signature
ECDSA signature of the hash signed by DApp private key
byte[]
IntentSolutionsReply fields (stream message):
Key
Description
Values
intentId
UUID of the intent
string
intentSolution
solution for the specific intent
byte[]
packagemainimport ("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 madeconst gatewayHost ="127.0.0.1:5002"// header is the authorization header of your bloXroute Accountconst header ="<YOUR-AUTHORIZATION-HEADER>"funcmain() {// Dial the gateway conn, err := grpc.Dial(gatewayHost, grpc.WithTransportCredentials(insecure.NewCredentials()), 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)) }}funcgenIntentSolutionRequest() *pb.IntentSolutionsRequest {// DApp private key used to prove the ownership of the DApp addressconst 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 hashif err !=nil { log.Fatalln("error signing with private key", err) }// Return the solution requestreturn&pb.IntentSolutionsRequest{ DappAddress: signerAddress.String(), Hash: hash, Signature: sig, }}// blxrCredentials is an implementation of PerRPCCredentialstypeblxrCredentialsstruct { authorization string}// GetRequestMetadata sets the authorization headerfunc (bc blxrCredentials) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {returnmap[string]string{"authorization": bc.authorization, }, nil}// RequireTransportSecurity is a method of the PerRPCCredentials interfacefunc (bc blxrCredentials) RequireTransportSecurity() bool {returnfalse}