-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Requested Go examples #8
Comments
Transaction creation and broadcasting: import (
"bytes"
"context"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"github.com/qubic/go-node-connector/types"
"github.com/qubic/go-schnorrq"
"io"
"net/http"
"time"
)
// Create simple transaction and broadcast it to the network
const ApiURL = "https://testapi.qubic.org"
const SenderSeed = ""
const SenderID = ""
const TransactionAmount = 5
const DestinationID = ""
func CreateAndBroadcastTransaction() error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
subSeed, err := types.GetSubSeed(SenderSeed)
if err != nil {
return errors.Wrap(err, "getting sub-seed from seed")
}
latestTick, err := GetLatestTick(ctx, ApiURL)
if err != nil {
return errors.Wrap(err, "getting latest tick")
}
targetTick := latestTick + 10
transaction, err := CreateTransaction(SenderID, DestinationID, TransactionAmount, targetTick, subSeed)
if err != nil {
return errors.Wrap(err, "creating transaction")
}
err = BroadCastTransaction(ctx, transaction, ApiURL)
if err != nil {
return errors.Wrap(err, "broadcasting transaction")
}
return nil
}
func CreateTransaction(sourceID, destinationID string, amount int64, targetTick uint32, subSeed [32]byte) (*types.Transaction, error) {
transaction, err := types.NewSimpleTransferTransaction(sourceID, destinationID, amount, targetTick)
if err != nil {
return nil, errors.Wrap(err, "creating transaction")
}
unsignedDigest, err := transaction.GetUnsignedDigest()
if err != nil {
return nil, errors.Wrap(err, "getting transaction unsigned digest")
}
signature, err := schnorrq.Sign(subSeed, transaction.SourcePublicKey, unsignedDigest)
if err != nil {
return nil, errors.Wrap(err, "failed to sign transaction")
}
transaction.Signature = signature
return &transaction, nil
}
func GetLatestTick(ctx context.Context, apiUrl string) (uint32, error) {
request, err := http.NewRequestWithContext(ctx, http.MethodGet, apiUrl+"/v1/latestTick", nil)
if err != nil {
return 0, errors.Wrap(err, "creating latest tick request")
}
response, err := http.DefaultClient.Do(request)
if err != nil {
return 0, errors.Wrap(err, "performing latest tick request")
}
defer response.Body.Close()
data, err := io.ReadAll(response.Body)
if err != nil {
return 0, errors.Wrap(err, "reading latest tick response")
}
if response.StatusCode != http.StatusOK {
return 0, errors.New(fmt.Sprintf("Status not 200! Info: %s", data))
}
type LatestTickStruct struct {
LatestTick uint32 `json:"latestTick"`
}
var latestTick LatestTickStruct
err = json.Unmarshal(data, &latestTick)
if err != nil {
return 0, errors.Wrap(err, "un-marshalling latest tick response")
}
return latestTick.LatestTick, nil
}
func BroadCastTransaction(ctx context.Context, transaction *types.Transaction, apiUrl string) error {
transactionID, err := transaction.ID()
if err != nil {
return errors.Wrap(err, "getting transaction ID")
}
finalUrl := apiUrl + "/v1/broadcast-transaction"
// Encode transaction
encodedTransaction, err := transaction.EncodeToBase64()
if err != nil {
return errors.Wrap(err, "encoding transaction")
}
// Create request payload from encoded transaction
requestPayload := struct {
EncodedTransaction string `json:"encodedTransaction"`
}{
EncodedTransaction: encodedTransaction,
}
buffer := new(bytes.Buffer)
err = json.NewEncoder(buffer).Encode(requestPayload)
if err != nil {
return errors.Wrap(err, "encoding request payload")
}
//Create and send request
request, err := http.NewRequestWithContext(ctx, http.MethodPost, finalUrl, buffer)
if err != nil {
return errors.Wrap(err, "creating broadcast request")
}
response, err := http.DefaultClient.Do(request)
if err != nil {
return errors.Wrap(err, "performing broadcast request")
}
defer response.Body.Close()
data, err := io.ReadAll(response.Body)
if err != nil {
return errors.Wrap(err, "reading broadcast response")
}
if response.StatusCode != http.StatusOK {
fmt.Printf("DEBUG: %s\n", finalUrl)
return errors.New(fmt.Sprintf("Status not 200! Info: %s", data))
}
type ResponseInfo struct {
PeersBroadcasted uint32 `json:"peersBroadcasted"`
EncodedTransaction string `json:"encodedTransaction"`
}
var info ResponseInfo
err = json.Unmarshal(data, &info)
if err != nil {
return errors.Wrap(err, "un-marshalling broadcast response")
}
fmt.Printf("Broadcasted to %d peers.\n", info.PeersBroadcasted)
fmt.Printf("Transaction ID: %s\n", transactionID)
fmt.Printf("Target tick: %d\n", transaction.Tick)
return nil
} |
Query last tick and it's transactions import (
"context"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"io"
"net/http"
"time"
)
// Query the last network tick and the transactions in it
const archiverHTTPAddress = "https://testapi.qubic.org"
func RunHTTPExample() error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
httpClient := http.DefaultClient
// Get Status
status, err := FetchStatusHTTP(ctx, httpClient, archiverHTTPAddress)
if err != nil {
return errors.Wrap(err, "fetching archiver status")
}
fmt.Printf("Last processed tick: %d\n", status.LastProcessedTick.TickNumber)
fmt.Printf("Current epoch: %d\n", status.LastProcessedTick.Epoch)
// Get transactions in the latest tick
transactions, err := GetTickTransactionsHTTP(ctx, httpClient, archiverHTTPAddress, status.LastProcessedTick.TickNumber)
if err != nil {
return errors.Wrap(err, "fetching tick transactions")
}
fmt.Printf("Found %d transactions\n", len(transactions.Transactions))
for _, transaction := range transactions.Transactions {
fmt.Printf(" Transaction ID: %s\n", transaction.Transaction.TxId)
fmt.Printf(" Transfered amount: %s\n", transaction.Transaction.Amount)
fmt.Printf(" From: %s\n", transaction.Transaction.SourceId)
fmt.Printf(" To: %s\n", transaction.Transaction.DestId)
println("-------------------------------")
}
return nil
}
func FetchStatusHTTP(ctx context.Context, httpClient *http.Client, baseURL string) (*Status, error) {
statusRequest, err := http.NewRequestWithContext(ctx, "GET", baseURL+"/v1/status", nil)
if err != nil {
return nil, errors.Wrap(err, "creating status request")
}
response, err := httpClient.Do(statusRequest)
if err != nil {
return nil, errors.Wrap(err, "performing status request")
}
defer response.Body.Close()
data, err := io.ReadAll(response.Body)
if err != nil {
return nil, errors.Wrap(err, "reading status response")
}
if response.StatusCode != http.StatusOK {
return nil, errors.New(fmt.Sprintf("Status not 200! Info: %s", data))
}
var status Status
err = json.Unmarshal(data, &status)
if err != nil {
return nil, errors.Wrap(err, "un-marshalling status response")
}
return &status, nil
}
func GetTickTransactionsHTTP(ctx context.Context, httpClient *http.Client, baseURL string, tickNumber uint32) (*TickTransactions, error) {
finalURL := fmt.Sprintf(baseURL+"/v2/ticks/%d/transactions?transfers=true", tickNumber)
tickTransactionsRequest, err := http.NewRequestWithContext(ctx, "GET", finalURL, nil)
if err != nil {
return nil, errors.Wrap(err, "creating tick transactions request")
}
response, err := httpClient.Do(tickTransactionsRequest)
if err != nil {
return nil, errors.Wrap(err, "performing tick transactions request")
}
defer response.Body.Close()
data, err := io.ReadAll(response.Body)
if err != nil {
return nil, errors.Wrap(err, "reading tick transactions response")
}
if response.StatusCode != http.StatusOK {
return nil, errors.New(fmt.Sprintf("Status not 200! Info: %s", data))
}
var transactions TickTransactions
err = json.Unmarshal(data, &transactions)
if err != nil {
return nil, errors.Wrap(err, "un-marshalling tick transactions response")
}
return &transactions, nil
}
type Status struct {
LastProcessedTick struct {
TickNumber uint32 `json:"tickNumber"`
Epoch uint32 `json:"epoch"`
} `json:"lastProcessedTick"`
LastProcessedTicksPerEpoch map[string]uint32 `json:"lastProcessedTicksPerEpoch"`
SkippedTicks []struct {
StartTick uint32 `json:"startTick"`
EndTick uint32 `json:"endTick"`
} `json:"skippedTicks"`
ProcessedTickIntervalsPerEpoch []struct {
Epoch uint32 `json:"epoch"`
Intervals []struct {
InitialProcessedTick uint32 `json:"initialProcessedTick"`
LastProcessedTick uint32 `json:"lastProcessedTick"`
} `json:"intervals"`
}
EmptyTicksPerEpoch map[string]uint32 `json:"emptyTicksPerEpoch"`
}
type TickTransactions struct {
Transactions []struct {
Transaction struct {
SourceId string `json:"sourceId"`
DestId string `json:"destId"`
Amount string `json:"amount"`
TickNumber uint32 `json:"tickNumber"`
InputType uint32 `json:"inputType"`
InputSize uint32 `json:"inputSize"`
InputHex string `json:"inputHex"`
SignatureHex string `json:"signatureHex"`
TxId string `json:"txId"`
} `json:"transaction"`
Timestamp string `json:"timestamp"`
MoneyFlew bool `json:"moneyFlew"`
} `json:"transactions"`
} |
GRPC version of above example const archiverGRPCAddress = "213.170.135.5:8003"
func RunGRPCExample() error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
// GRPC client creation
connection, err := grpc.NewClient(archiverGRPCAddress, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
return errors.Wrap(err, "creating grpc connection")
}
defer connection.Close()
archiverClient := protobuff.NewArchiveServiceClient(connection)
// Get status
status, err := FetchStatusGRPC(ctx, archiverClient)
if err != nil {
return errors.Wrap(err, "fetching status")
}
fmt.Printf("Last processed tick: %d\n", status.LastProcessedTick.TickNumber)
fmt.Printf("Current epoch: %d\n", status.LastProcessedTick.Epoch)
// Get transactions in the latest tick
transactions, err := GetTickTransactionsGRPC(ctx, archiverClient, status.LastProcessedTick.TickNumber, true)
if err != nil {
return errors.Wrap(err, "fetching tick transactions")
}
fmt.Printf("Found %d transactions\n", len(transactions.Transactions))
for _, transaction := range transactions.Transactions {
fmt.Printf(" Transaction ID: %s\n", transaction.Transaction.TxId)
fmt.Printf(" Transfered amount: %d\n", transaction.Transaction.Amount)
fmt.Printf(" From: %s\n", transaction.Transaction.SourceId)
fmt.Printf(" To: %s\n", transaction.Transaction.DestId)
println("-------------------------------")
}
return nil
}
func FetchStatusGRPC(ctx context.Context, archiverClient protobuff.ArchiveServiceClient) (*protobuff.GetStatusResponse, error) {
result, err := archiverClient.GetStatus(ctx, nil)
if err != nil {
return nil, errors.Wrap(err, "performing request")
}
return result, nil
}
func GetTickTransactionsGRPC(ctx context.Context, archiverClient protobuff.ArchiveServiceClient, tickNumber uint32, transfersOnly bool) (*protobuff.GetTickTransactionsResponseV2, error) {
request := protobuff.GetTickTransactionsRequestV2{
TickNumber: tickNumber,
// Do not filter, we want to see all transactions
Approved: false,
Transfers: transfersOnly,
}
result, err := archiverClient.GetTickTransactionsV2(ctx, &request)
if err != nil {
return nil, errors.Wrap(err, "performing request")
}
return result, nil
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
No description provided.
The text was updated successfully, but these errors were encountered: