This example demonstrates how to submit a solution to an intent using the bloXroute Gateway gRPC API.
Name: SubmitIntentSolution
SubmitIntentSolution is a GRPC method that propagates the solution to the BDN.
SubmitIntentSolutionRequest arguments:
Key
Description
Values
solverAddress
ETH address of the intent solver
string
intentId
UUID of the intent to solve
string
intentSolution
solution payload for the intent
byte[]
hash
Keccak256Hash of the solution payload
byte[]
signature
ECDSA signature of the hash
byte[]
SubmitIntentSolutionReply fields:
Key
Description
Values
solutionId
UUID of the solution
string
first_seen
timestamp when the solution was first seen in BDN.
google.protobuf.Timestamp
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")// intentID is the ID of the intent to which the solution is being submitted.// replace with the actual intent ID.const intentID ="<INTENT-ID>"// gatewayHost is the address of the gateway to which the solution is being submittedconst gatewayHost ="127.0.0.1:5001"// authHeader is the authorization header of your BloxRoute Accountconst authHeader ="<YOUR-AUTHORIZATION-HEADER>"funcmain() {// 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)// Generate the solution solution :=genIntentSolution(intentID)// Submit the solution resp, err := client.SubmitIntentSolution(context.Background(), solution)if err !=nil { log.Fatalln(err) } fmt.Printf("done submitting the solution to %s\nsolver address: %s\nsolution id: %s\n", gatewayHost, solution.SolverAddress, resp.SolutionId)
}funcgenIntentSolution(intentID string) *pb.SubmitIntentSolutionRequest {// The sample private key of the solver solverPrivateKeyHex :="2b36f5c0317c13e6326e9d2e2ae39badec9d030ba44bc889318e4fa5412ad342"// The solution is to be submitted as a byte slice.// This is a sample solution, and you should replace it with your solution. solutionBytes := []byte(`{"From":"0xe34f7d4a8b5b9e5d5f4d6392b4c328e2d1a2bd9f","To":"0xa24dcbb439bfb3c37ad6cce12c92427b0358cb4ee","Value":0,"Gas":950000,"MaxFeePerGas":12000000000,"Nonce":42,"Deadline":4850000,"Solver":"0x4e2f4cb6458c1c08b55a6c362f4abf818279ee02","Control":"0x1de2276df50bd8bceefb353c1a5520bc0fecda98","UserOpHash":[52,201,174,29,78,191,148,66,213,171,223,60,212,140,236,131,174,50,90,5,197,241,205,163,228,26,79,98,140,156,72,182],"BidToken":"0x0000000000000000000000000000000000000001","BidAmount":150000000000000,"Data":"SRJ0xQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAJ6tEZqZDFXPFuIOdvTCoIJnhSWMAAAAAAAAAAAAAAAAfmECoXVr1vx0XYvklva3cQgH5hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqHvuU4AAAAAAAAAAAAAAAAAA//mXZ4LUbMBWMNH266sYsjJNaxQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI4byb8EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","Signature":"QKx9m3wSuO2bx2QOMyGweMaaXozxq5p6rc9VkpJg6pYRAKFq+diLTG8AEeYoscYpfSTGWCGHBJuQLvV/Q/fvuBw="}`)
// 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 solution with the private key solutionHash := crypto.Keccak256Hash(solutionBytes).Bytes() // need a hash to sign, so we're hashing the payload here
solutionSig, err := crypto.Sign(solutionHash, solverPrivateKey) // signing the hashif err !=nil { log.Fatalln("could not sign the message", err) }// Extract the address of the solver solverAddress := crypto.PubkeyToAddress(solverPrivateKey.PublicKey).String()// Return the solution requestreturn&pb.SubmitIntentSolutionRequest{ SolverAddress: solverAddress, IntentId: intentID, IntentSolution: solutionBytes, Hash: solutionHash, Signature: solutionSig, }}// blxrCredentials is a struct that implements the PerRPCCredentials interfacetypeblxrCredentialsstruct { authorization string}// GetRequestMetadata is a method of the PerRPCCredentials interfacefunc (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}