Golang SDK
Prerequisite
The Golang Sova SDK is available at https://github.com/sova-network/sova-sdk-go.
Add the Sova SDK by running:
go get github.com/sova-network/sova-sdk-go@latest
CAUTION: By default, each searcher enforces a limit of 5 requests per second. If you need to have a higher limit, you can send a request to hello@sova.network.
Create a SovaClient Instance for Testnet
package main
import (
sova_sdk_go "github.com/sova-network/sova-sdk-go"
)
func main() {
// Create a new client instance for the testnet
var client = sova_sdk_go.NewTestnetClient()
}
Authenticate the Client
If you need authenticated access, you can sign the challenge provided by the Sova Engine using your ED25519 private key. Replace the dummy private key with your actual 32-byte ED25519 key. If you choose to skip authentication, simply do not call this method.
package main
import (
"encoding/base64"
"fmt"
"time"
"context"
sova_sdk_go "github.com/sova-network/sova-sdk-go"
)
func main() {
client := sova_sdk_go.NewTestnetClient()
// Replace with your actual 32-byte private key.
privKeyB64 := "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
privateKey, err := base64.StdEncoding.DecodeString(privKeyB64)
if err != nil {
panic(err)
}
ctx := context.Background()
// Authenticate and obtain an access token.
token, err := client.Authenticate(ctx, privateKey)
if err != nil {
fmt.Println(err)
}
searcher, err := client.Searcher(ctx)
if err != nil {
panic(err)
}
searcher.SetAccessToken(token)
// Subscription
// searcher.SubscribeByWorkchainShard(...)
// Keep the application running to receive messages
for {
time.Sleep(1 * time.Second)
}
}
Subscribe for Messages
Regardless of authentication, you can use the searcher service to subscribe to Mempool messages.
Subscribe by Workchain
// ...
mempoolCh := make(chan *types.MempoolPacket, 10)
err = searcher.SubscribeByWorkchain(ctx, 0, func(mp *types.MempoolPacket) {
fmt.Println("reseive wc packet")
mempoolCh <- mp
})
if err != nil {
panic(err)
}
// ...
Subscribe by addresses
// ...
//"0:hex_adddress1", "0:hex_address2" // 0 - workchain id, hex_address - hex encoded address
_ = searcher.SubscribeByAddress(ctx, []string{"hex_address", "hex_address"}, func(mp *types.MempoolPacket) {
fmt.Println("reseive address packet: %v", mp)
})
// ...
Subscribe by Workchain shard
// ...
shard, _ := hex.DecodeString("e000000000000000")
resultCh := make(chan *types.BundleResult, 1)
_ = searcher.SubscribeByWorkchainShard(ctx, 0, shard, func(mp *types.MempoolPacket) {
fmt.Println("reseive shard packet")
fmt.Printf("shard: %v\n", shard)
mempoolCh <- mp
})
// ...
Subscribe by external out message body opcode
// TODO
Subscribe by internal message body opcode
// ...
resultCh := make(chan *types.BundleResult, 1)
shard, _ := hex.DecodeString("e000000000000000")
_ = searcher.SubscribeByInternalMsgBodyOpcode(ctx, 0, shard, 0xf8a7ea5, func(mp *types.MempoolPacket) {
fmt.Println("reseive opcode packet")
fmt.Printf("shard: %v\n", shard)
mempoolCh <- mp
})
// ...
Bundles Submission
resultCh := make(chan *types.BundleResult, 1)
err = searcher.SubscribeBundleResult(ctx, func(br *types.BundleResult) {
fmt.Println("reseive bundle result")
resultCh <- br
})
if err != nil {
panic(err)
}
for {
select {
case msg := <-mempoolCh:
fmt.Printf("got mempool packet: %v\n", len(msg.ExternalMessages))
extMsg := msg.ExternalMessages[0]
fmt.Printf("ext msg.GasSpend: %v\n", extMsg.GasSpent)
fmt.Printf("ext msg.Shard: %v\n", hex.EncodeToString(extMsg.Shard))
fmt.Printf("ext msg.StdSmcAddress: %v\n", hex.EncodeToString(extMsg.StdSmcAddress))
// Send bundle
res, err := searcher.SendBundle(ctx, &types.Bundle{
Message: []*types.ExternalMessage{
{
Data: []byte(msg.ExternalMessages[0].Data),
},
},
ExpirationNs: nil,
})
if err != nil {
panic(err)
}
fmt.Printf("got bundle response: %v\n", res)
}
}
Bundles Results tracking
// ...
resultCh := make(chan *types.BundleResult, 1)
err = searcher.SubscribeBundleResult(ctx, func(br *types.BundleResult) {
fmt.Println("reseive bundle result")
resultCh <- br
})
if err != nil {
panic(err)
}
// ...
for {
select {
case res := <-resultCh:
fmt.Println("got bundle result")
fmt.Printf("result: %v\n", res)
return
}
// ...
}
Last updated