diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 86f887f..0783355 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,7 +6,7 @@ To learn more about Maestro [here](https://docs.gomaestro.org/)! ## Opening Issues -Use an [existing template](https://github.com/maestro-org/typescript-sdk/issues/new/choose) to: +Use an [existing template](https://github.com/maestro-org/go-sdk/issues/new/choose) to: - Report a bug - Update the docs - Request a new feature @@ -17,7 +17,7 @@ Accompany your issue with one or more of the following labels: - `CI`: something with Github Actions needs attention - `Docs`: something in the documentation needs to be updated - `Feature`: something new would be a nice addition to the library -- `Go`: something TypeScript related +- `Go`: something Go related - `Vulnerability`: something is vulnerability and needs attention from security - `Spike`: something new needs to be explored @@ -25,7 +25,7 @@ Accompany your issue with one or more of the following labels: After opening a pull request, please take the following steps: - Ensure your PR has one or more corresponding issues (see above) - [Link your PR](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) to those issues -- Check the [build status](https://github.com/maestro-org/typescript-sdk/actions/new) of your PR +- Check the [build status](https://github.com/maestro-org/go-sdk/actions/new) of your PR - Wait for a review and/or approval from one of the code owners - Merge and celebrate with some nice tunes! 🎼🎼🎼 diff --git a/README.md b/README.md index 0c7c26b..71cec28 100644 --- a/README.md +++ b/README.md @@ -26,4 +26,7 @@ # Documentation +* [Maestro public docs](https://docs.gomaestro.org/) + # Contributing +Meastro welcomes all contributors! Please see our [contributing guidelines](CONTRIBUTING.md) and [code of conduct](CODE_OF_CONDUCT.md). diff --git a/client/block_info.go b/client/block_info.go new file mode 100644 index 0000000..22efdb2 --- /dev/null +++ b/client/block_info.go @@ -0,0 +1,62 @@ +package client + +import ( + "fmt" + "net/http" + + "github.com/gomaestro-org/go-sdk/utils" +) + +type OperationalCertificate struct { + HotVkey string `json:"hot_vkey"` + KesPeriod int64 `json:"kes_period"` + KesSignature string `json:"kes_signature"` + SequenceNumber int64 `json:"sequence_number"` +} + +type TotalExUnits struct { + Mem int64 `json:"mem"` + Steps int64 `json:"steps"` +} + +type BlockInfo struct { + Data struct { + AbsoluteSlot int64 `json:"absolute_slot"` + BlockProducer string `json:"block_producer"` + Confirmations int64 `json:"confirmations"` + Epoch int64 `json:"epoch"` + EpochSlot int64 `json:"epoch_slot"` + Era string `json:"era"` + Hash string `json:"hash"` + Height string `json:"height"` + OperationalCertificate OperationalCertificate `json:"operational_certificate"` + PreviousBlock string `json:"previous_block"` + ProtocolVersion []int `json:"protocol_version"` + ScriptInvocations int32 `json:"script_invocations"` + Size int32 `json:"size"` + Timestamp string `json:"timestamp"` + TotalExUnits TotalExUnits `json:"total_ex_units"` + TotalFees int64 `json:"total_fees"` + TotalOutputLovelace []string `json:"total_output_lovelace"` + TxHashes []string `json:"tx_hashes"` + VrfKey string `json:"vrf_key"` + } `json:"data"` + LastUpdated utils.LastUpdated `json:"last_updated"` +} + +func (c *Client) GetBlockInfo(blockHeight int64) (*BlockInfo, error) { + req, err := http.NewRequest("GET", fmt.Sprintf("%s/blocks/%d", c.baseUrl, blockHeight), nil) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json; charset=utf-8") + + res := BlockInfo{} + if err := c.sendRequest(req, &res); err != nil { + return nil, err + } + + return &res, nil + +} diff --git a/client/client.go b/client/client.go new file mode 100644 index 0000000..9e04b13 --- /dev/null +++ b/client/client.go @@ -0,0 +1,77 @@ +package client + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "path" + "strings" + "time" + + "github.com/gomaestro-org/go-sdk/config" +) + +type Client struct { + apiKey string + network string + version string + HTTPClient *http.Client + baseUrl string +} + +func NewClient(apiKey string, network string) *Client { + cfg := config.GetConfig() + paths := []string{"https://", fmt.Sprintf("%s.gomaestro-api.org", strings.ToLower(network)), cfg.Client.Version} + return &Client{ + apiKey: apiKey, + network: network, + version: cfg.Client.Version, + HTTPClient: &http.Client{ + Timeout: time.Duration(cfg.Client.Timeout), + }, + baseUrl: path.Join(paths...), + } +} + +type errorResponse struct { + Code int `json:"code"` + Message string `json:"message"` +} + +type successResponse struct { + Code int `json:"code"` + Data interface{} `json:"data"` +} + +func (c *Client) sendRequest(req *http.Request, v interface{}) error { + req.Header.Set("Accept", "application/json; charset=utf-8") + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.apiKey)) + + res, err := c.HTTPClient.Do(req) + if err != nil { + return err + } + + defer res.Body.Close() + + // Try to unmarshall into errorResponse + if res.StatusCode != http.StatusOK { + var errRes errorResponse + if err = json.NewDecoder(res.Body).Decode(&errRes); err == nil { + return errors.New(errRes.Message) + } + + return fmt.Errorf("unknown error, status code: %d", res.StatusCode) + } + + // Unmarshall and populate v + fullResponse := successResponse{ + Data: v, + } + if err = json.NewDecoder(res.Body).Decode(&fullResponse); err != nil { + return err + } + + return nil +} diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..f8f7059 --- /dev/null +++ b/config/config.go @@ -0,0 +1,21 @@ +package config + +type Config struct { + Client ClientConfig +} + +type ClientConfig struct { + Version string + Timeout int64 +} + +var globalConfig = &Config{ + Client: ClientConfig{ + Version: "v1", + Timeout: 10, + }, +} + +func GetConfig() *Config { + return globalConfig +} diff --git a/utils/last_updated.go b/utils/last_updated.go new file mode 100644 index 0000000..089fbd3 --- /dev/null +++ b/utils/last_updated.go @@ -0,0 +1,7 @@ +package utils + +type LastUpdated struct { + BlockHash string `json:"block_hash"` + BlockSlot int64 `json:"block_slot"` + Timestamp string `json:"timestamp"` +}