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
}