Submit quote

This example demonstrates how to submit an quote using the bloXroute Gateway gRPC API.

Name: SubmitQuote

SubmitQuote is a GRPC method that propagates quote to the BDN. SubmitQuoteRequest arguments:

Key
Description
Values

dappAddress

ETH address of the DApp that should receive quote

string

solverAddress

ETH address of the quote solver

string

qoute

quote payload

byte[]

hash

Keccak256Hash of the quote payload

byte[]

signature

ECDSA signature of the hash

byte[]

SubmitQuoteReply fields:

Key
Description
Values

quoteId

UUID of the quote

string

first_seen

timestamp when quote was first seen in BDN (for now empty)

google.protobuf.Timestamp

Examples - gRPC

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"
)

// dAppAddr is the dApp addr of the quote
const dAppAddr = "<addr>"

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

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

func main() {
	// this will use localhost CA to verify the certificate
	creds := credentials.NewClientTLSFromCert(nil, "")

	// Dial the gateway
	conn, err := grpc.Dial(gatewayHost,
		grpc.WithTransportCredentials(creds),
		grpc.WithPerRPCCredentials(blxrCredentials{authorization: authHeader}))

	if err != nil {
		log.Fatalln("dial grpc", err)
	}

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

	// Generate the quote
	quote := genQuote(dAppAddr)

	// Submit the quote
	resp, err := client.SubmitQuote(context.Background(), quote)
	if err != nil {
		log.Fatalln(err)
	}

	fmt.Printf("done submitting the quote to %s\nsolver address: %s\nquote id: %s\n", gatewayHost, quote.SolverAddress, resp.QuoteId)
}

func genQuote(dAppAddr string) *pb.SubmitQuoteRequest{
	// The sample private key of the solver
	solverPrivateKeyHex := "2b36f5c0317c13e6326e9d2e2ae39badec9d030ba44bc889318e4fa5412ad342"

	// The quote is to be submitted as a byte slice.
	// This is a sample quote, and you should replace it with your quote.
	quoteBytes := []byte(`test_quote`)

	// Decode the hex string to a byte slice
	solverPrivateKeyBytes, err := hex.DecodeString(solverPrivateKeyHex)
	if err != nil {
		log.Fatalf("invalid hex string: %v", err)
	}

	// Use the Ethereum crypto package to create an ECDSA private key
	solverPrivateKey, err := crypto.ToECDSA(solverPrivateKeyBytes)
	if err != nil {
		log.Fatalf("failed to create private key: %v", err)
	}

	// Sign the quote with the private key
	quoteHash := crypto.Keccak256Hash(quoteBytes).Bytes()     // need a hash to sign, so we're hashing the payload here
	quoteSig, err := crypto.Sign(quoteHash, solverPrivateKey) // signing the quote
	if err != nil {
		log.Fatalln("could not sign the message", err)
	}

	// Extract the address of the solver
	solverAddress := crypto.PubkeyToAddress(solverPrivateKey.PublicKey).String()

	// Return the quote request
	return &pb.SubmitQuoteRequest{
		DappAddress: dAppAddr,
		SolverAddress:  solverAddress,
		Quote: quoteHash,
		Hash:           quoteHash,
		Signature:      quoteSig,
	}
}

// blxrCredentials is a struct that implements the PerRPCCredentials interface
type blxrCredentials struct {
	authorization string
}

// GetRequestMetadata is a method of the PerRPCCredentials interface
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