Submit intent

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

Name: SubmitIntent

SubmitIntent is a GRPC method that propagates intent to the BDN. SubmitIntentRequest arguments:

KeyDescriptionValues

dappAddress

ETH address of the DApp that should receive solution for this intent

string

senderAddress

ETH address of the intent sender

string

intent

intent payload

byte[]

hash

Keccak256Hash of the intent payload

byte[]

signature

ECDSA signature of the hash

byte[]

SubmitIntentReply fields:

KeyDescriptionValues

intentId

UUID of the intent

string

first_seen

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

google.protobuf.Timestamp

Examples - gRPC

package main

import (
	"context"
	"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"
)

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

// 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 intent
	intentRequest := genSubmitIntent()

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

	fmt.Printf("done submitting intent to %s\nsender_addr: %s\nintent_id: %s\n", gatewayHost, intentRequest.SenderAddress, resp.IntentId)
}

func genSenderCreds(intent []byte) (string, []byte, []byte) {
	// Here we use a sample private key of sender to sign the intent
	privateKeyHex := "4f3edf983ac636a65a842ce7c7aad7b7e3b1f6f6d1a91c37b1b39ce334b25554"

	// Convert the hex string to a private key
	privKey, err := crypto.HexToECDSA(privateKeyHex)
	if err != nil {
		log.Fatalln("error converting hex to ECDSA", err)
	}

	pubKey := privKey.PublicKey                     // extract the public key
	signerAddress := crypto.PubkeyToAddress(pubKey) // extract the address
	hash := crypto.Keccak256Hash(intent).Bytes()    // need a hash to sign, so we're hashing the payload here
	sig, err := crypto.Sign(hash, privKey)          // sign the hash with the private key

	if err != nil {
		log.Fatalln("error signing with private key", err)
	}

	return signerAddress.String(), hash, sig
}

func getDAppAddress() string {
	// The address of the DApp.
	// Only the DApp with the correct private key can then receive the solution for the intent.
	const dAppPrivateKeyHex = "7c4a8d09ca3762af61e59520943dc26494f8941e6e5b998321d3e84b8e4d3c16"

	// Convert the hex string to a private key
	dAppPrivKey, err := crypto.HexToECDSA(dAppPrivateKeyHex)
	if err != nil {
		log.Fatalln("error converting hex to ECDSA", err)
	}

	// Extract the public key
	dAppPubKey := dAppPrivKey.PublicKey
	dappAddress := crypto.PubkeyToAddress(dAppPubKey)

	return dappAddress.String()
}

func genSubmitIntent() *pb.SubmitIntentRequest {
	// The address of the DApp.
	dappAddress := getDAppAddress()

	// The intent to be submitted as a byte slice.
	// This is a sample intent, and you should replace it with your own intent.
	intent := []byte("i am intent")

	// Sign the intent with the private key of the sender.
	senderAddress, senderHash, senderSig := genSenderCreds(intent)

	// Return the intent request
	return &pb.SubmitIntentRequest{
		DappAddress:   dappAddress,
		SenderAddress: senderAddress,
		Intent:        intent,
		Hash:          senderHash,
		Signature:     senderSig,
	}
}

// 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