package main
import (
"context"
"crypto/tls"
"fmt"
"log"
"github.com/onflow/flow/protobuf/go/flow/access"
"github.com/onflow/flow/protobuf/go/flow/entities"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
type auth struct {
token string
}
func (a *auth) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
return map[string]string{
"x-token": a.token,
}, nil
}
func (auth) RequireTransportSecurity() bool {
return false
}
func getAccessClientWithXToken(endpoint, token string) (access.AccessAPIClient, error) {
target := endpoint + ".flow-mainnet.quiknode.pro:8999" // for TLS connections
client, err := grpc.Dial(target,
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),
grpc.WithPerRPCCredentials(&auth{
token: token,
}),
)
if err != nil {
return nil, fmt.Errorf("Unable to dial endpoint %w", err)
}
return access.NewAccessAPIClient(client), nil
}
func main() {
token := "TOKEN_GOES_HERE"
ctx := context.Background()
client, err := getAccessClientWithXToken("ENDPOINT-NAME", token)
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
script := []byte(`
transaction {
prepare(signer: AuthAccount) {
log("Transaction executed")
}
}
`)
latestBlockReq := &access.GetLatestBlockRequest{IsSealed: true}
latestBlock, err := client.GetLatestBlock(ctx, latestBlockReq)
if err != nil {
log.Fatalf("Failed to get latest block: %v", err)
}
payerAddress := []byte("PAYER_ADDRESS_BYTES")
proposalKeyAddress := []byte("PROPOSAL_KEY_ADDRESS_BYTES")
authorizerAddress := []byte("AUTHORIZER_ADDRESS_BYTES")
transaction := &entities.Transaction{
Script: script,
Arguments: [][]byte{},
ReferenceBlockId: latestBlock.Block.Id,
GasLimit: 100,
ProposalKey: &entities.Transaction_ProposalKey{
Address: proposalKeyAddress,
KeyId: 0,
SequenceNumber: 0,
},
Payer: payerAddress,
Authorizers: [][]byte{authorizerAddress},
PayloadSignatures: []*entities.Transaction_Signature{
{
Address: proposalKeyAddress,
KeyId: 0,
Signature: []byte("PAYLOAD_SIGNATURE"),
},
},
EnvelopeSignatures: []*entities.Transaction_Signature{
{
Address: payerAddress,
KeyId: 0,
Signature: []byte("ENVELOPE_SIGNATURE"),
},
},
}
sendTxResp, err := client.SendTransaction(ctx, &access.SendTransactionRequest{Transaction: transaction})
if err != nil {
log.Fatalf("Failed to send transaction: %v", err)
}
fmt.Printf("Transaction sent successfully!\n")
fmt.Printf("Transaction ID: %x\n", sendTxResp.Id)
fmt.Printf("Reference Block ID: %x\n", latestBlock.Block.Id)
}