commit 6decdb603c39b7390fbc1fd2a67697497eea70dc Author: Andrew Miller Date: Mon Nov 10 16:44:59 2025 -0500 Initial Commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e2eceb9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,73 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Go workspace file +go.work +go.work.sum + +# IDEs +.idea/ +.vscode/ +*.swp +*.swo +*~ +.DS_Store + +# VS Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# Credentials and local config +credentials.yaml +credentials.yml +.env +.env.local +*.key +*.pem +*.p12 + +# OS specific +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Temporary files +*.tmp +*.temp +*.log +*.pid +*.seed +*.pid.lock + +# Debug files +debug +__debug_bin + +# Air (live reload for Go) +tmp/ +.air.toml + +# GoLand +*.iml + +# Test cache +*.cover +coverage.out +coverage.html diff --git a/README.md b/README.md new file mode 100644 index 0000000..ce1349a --- /dev/null +++ b/README.md @@ -0,0 +1,96 @@ +# Dragonchain Go SDK + +A self-contained Go SDK for interacting with Dragonchain nodes. + +## Installation + +```bash +go get git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go +``` + +## Usage + +```go +package main + +import ( + "fmt" + "log" + + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go" + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/models" +) + +func main() { + // Initialize the SDK + client := sdk.NewDragonchainSDK( + "your-public-id", + "your-auth-key-id", + "your-auth-key", + "https://your-dragonchain-endpoint.com", + ) + + // Check system health + if err := client.System.Health(); err != nil { + log.Fatal("Health check failed:", err) + } + + // Get system status + status, err := client.System.Status() + if err != nil { + log.Fatal("Failed to get status:", err) + } + fmt.Printf("Chain ID: %s, Level: %d\n", status.ID, status.Level) + + // Create a transaction + txn := &models.TransactionCreateRequest{ + TxnType: "my-transaction-type", + Payload: map[string]interface{}{ + "message": "Hello Dragonchain", + }, + Tag: "example-tag", + } + + resp, err := client.Transaction.Create(txn) + if err != nil { + log.Fatal("Failed to create transaction:", err) + } + fmt.Printf("Created transaction: %s\n", resp.TransactionID) +} +``` + +## Available Endpoints + +### System +- `Health()` - Check system health +- `Status()` - Get system status + +### Transaction +- `Create(req)` - Create a new transaction +- `CreateBulk(req)` - Create multiple transactions +- `Get(transactionID)` - Get transaction by ID + +### Transaction Type +- `Create(req)` - Create a new transaction type +- `Get(txnType)` - Get transaction type by name +- `List()` - List all transaction types +- `Delete(txnType)` - Delete a transaction type + +### Smart Contract +- `Create(req)` - Create a new smart contract +- `Get(contractID)` - Get smart contract by ID +- `List()` - List all smart contracts +- `Update(contractID, req)` - Update a smart contract +- `Upload(contractID, req)` - Upload smart contract code +- `Delete(contractID)` - Delete a smart contract + +### Block +- `Get(blockID)` - Get block by ID + +## Authentication + +The SDK uses HMAC-SHA256 authentication. You need to provide: +- `publicID` - Your Dragonchain public ID +- `authKeyID` - Your authentication key ID +- `authKey` - Your authentication key +- `baseURL` - The base URL of your Dragonchain node (e.g., "https://mychain.dragonchain.com") \ No newline at end of file diff --git a/block/block.go b/block/block.go new file mode 100644 index 0000000..5d4672b --- /dev/null +++ b/block/block.go @@ -0,0 +1,26 @@ +package block + +import ( + "fmt" + + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/client" + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/models" +) + +type BlockClient struct { + client *client.Client +} + +func NewBlockClient(c *client.Client) *BlockClient { + return &BlockClient{client: c} +} + +func (bc *BlockClient) Get(blockID string) (*models.Block, error) { + var resp models.Block + path := fmt.Sprintf("/api/v1/block/%s", blockID) + err := bc.client.Get(path, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} diff --git a/client/client.go b/client/client.go new file mode 100644 index 0000000..1324aaa --- /dev/null +++ b/client/client.go @@ -0,0 +1,144 @@ +package client + +import ( + "bytes" + "crypto/hmac" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + "time" +) + +type Client struct { + publicID string + authKeyID string + authKey string + baseURL string + httpClient *http.Client +} + +func NewClient(publicID, authKeyID, authKey, baseURL string) *Client { + return &Client{ + publicID: publicID, + authKeyID: authKeyID, + authKey: authKey, + baseURL: strings.TrimSuffix(baseURL, "/"), + httpClient: &http.Client{ + Timeout: 30 * time.Second, + }, + } +} + +func (c *Client) generateAuthHeader(method, path, timestamp, contentType string, body []byte) string { + msgStr := c.hmacMessage(method, path, timestamp, contentType, body) + hmacMsg := c.createHmac(msgStr) + b64hmac := base64.StdEncoding.EncodeToString(hmacMsg) + return fmt.Sprintf("DC1-HMAC-SHA256 %s:%s", c.authKeyID, b64hmac) +} + +func (c *Client) hmacMessage(method, path, timestamp, contentType string, body []byte) string { + h := sha256.New() + h.Write(body) + hashContent := h.Sum(nil) + b64Content := base64.StdEncoding.EncodeToString(hashContent) + + return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s", + strings.ToUpper(method), + path, + c.publicID, + timestamp, + contentType, + b64Content, + ) +} + +func (c *Client) createHmac(msgStr string) []byte { + h := hmac.New(sha256.New, []byte(c.authKey)) + h.Write([]byte(msgStr)) + return h.Sum(nil) +} + +func (c *Client) doRequest(method, path, contentType string, body any, response any) error { + var bodyBytes []byte + var err error + + if body != nil { + if !checkByteSlice(body) { + bodyBytes, err = json.Marshal(body) + if err != nil { + return fmt.Errorf("failed to marshal request body: %w", err) + } + contentType = "application/json" + } else { + bodyBytes = body.([]byte) + } + } + + if len(bodyBytes) == 0 { + bodyBytes = []byte("") + } + + fullURL := c.baseURL + path + req, err := http.NewRequest(method, fullURL, bytes.NewBuffer(bodyBytes)) + if err != nil { + return fmt.Errorf("failed to create request: %w", err) + } + + timestamp := fmt.Sprintf("%d", time.Now().Unix()) + authHeader := c.generateAuthHeader(method, path, timestamp, contentType, bodyBytes) + + req.Header.Set("Authorization", authHeader) + req.Header.Set("Dragonchain", c.publicID) + req.Header.Set("Timestamp", timestamp) + if contentType != "" { + req.Header.Set("Content-Type", contentType) + } + + resp, err := c.httpClient.Do(req) + if err != nil { + return fmt.Errorf("failed to execute request: %w", err) + } + defer resp.Body.Close() + + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("failed to read response body: %w", err) + } + + if resp.StatusCode >= 400 { + return fmt.Errorf("API error (status %d): %s", resp.StatusCode, strings.TrimSpace(string(respBody))) + } + + if response != nil && len(respBody) > 0 { + if err := json.Unmarshal(respBody, response); err != nil { + return fmt.Errorf("failed to unmarshal response: %w", err) + } + } + + return nil +} + +func checkByteSlice(body interface{}) bool { + _, ok := body.([]byte) + return ok +} + +func (c *Client) Get(path string, response any) error { + return c.doRequest(http.MethodGet, path, "", nil, response) +} + +func (c *Client) Post(path, contentType string, body any, response any) error { + return c.doRequest(http.MethodPost, path, contentType, body, response) +} + +func (c *Client) Put(path, contentType string, body any, response any) error { + return c.doRequest(http.MethodPut, path, contentType, body, response) +} + +func (c *Client) Delete(path string, response any) error { + return c.doRequest(http.MethodDelete, path, "", nil, response) +} diff --git a/contract/contract.go b/contract/contract.go new file mode 100644 index 0000000..7c67b72 --- /dev/null +++ b/contract/contract.go @@ -0,0 +1,80 @@ +package contract + +import ( + "fmt" + "os" + + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/client" + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/models" +) + +type ContractClient struct { + client *client.Client +} + +func NewContractClient(c *client.Client) *ContractClient { + return &ContractClient{client: c} +} + +func (cc *ContractClient) Create(req *models.SmartContractCreateRequest) (*models.SmartContract, error) { + var resp models.SmartContract + err := cc.client.Post("/api/v1/contract", models.ContentTypeJSON, req, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (cc *ContractClient) Get(contractID string) (*models.SmartContract, error) { + var resp models.SmartContract + path := fmt.Sprintf("/api/v1/contract/%s", contractID) + err := cc.client.Get(path, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (cc *ContractClient) List() (*models.ListResponse, error) { + var resp models.ListResponse + err := cc.client.Get("/api/v1/contract", &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (cc *ContractClient) Update(contractID string, req *models.SmartContractUpdateRequest) (*models.SuccessResponse, error) { + var resp models.SuccessResponse + path := fmt.Sprintf("/api/v1/contract/%s", contractID) + err := cc.client.Put(path, models.ContentTypeJSON, req, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (cc *ContractClient) Upload(contractID string, filepath string) (*models.SuccessResponse, error) { + fileContent, err := os.ReadFile(filepath) + if err != nil { + return nil, fmt.Errorf("failed to read file: %w", err) + } + + var resp models.SuccessResponse + path := fmt.Sprintf("/api/v1/contract/%s/upload", contractID) + err = cc.client.Put(path, "application/octet-stream", fileContent, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (cc *ContractClient) Delete(contractID string) (*models.SuccessResponse, error) { + var resp models.SuccessResponse + path := fmt.Sprintf("/api/v1/contract/%s", contractID) + err := cc.client.Delete(path, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} diff --git a/credentials/credentials.go b/credentials/credentials.go new file mode 100644 index 0000000..b83f6e4 --- /dev/null +++ b/credentials/credentials.go @@ -0,0 +1,221 @@ +package credentials + +import ( + "fmt" + "io/ioutil" + "os" + + "gopkg.in/yaml.v3" +) + +// ChainConfig represents a single chain configuration +type ChainConfig struct { + Name string `yaml:"name"` + PublicId string `yaml:"publicId"` + AuthKeyId string `yaml:"authKeyId"` + AuthKey string `yaml:"authKey"` + Endpoint string `yaml:"endpoint"` +} + +// Config represents the entire configuration file structure +type Config struct { + Default string `yaml:"default"` + Chains []ChainConfig `yaml:"chains"` + node *yaml.Node // Store the original node for preserving formatting +} + +// LoadConfig reads and parses a YAML configuration file +func LoadConfig(filePath string) (*Config, error) { + // Expand the file path (handles ~/, ./, and environment variables) + expandedPath, err := expandPath(filePath) + if err != nil { + return nil, fmt.Errorf("failed to expand path %s: %w", filePath, err) + } + + // Read the file + data, err := ioutil.ReadFile(expandedPath) + if err != nil { + return nil, fmt.Errorf("failed to read config file %s: %w", expandedPath, err) + } + + // Parse YAML with Node to preserve formatting + var node yaml.Node + if err := yaml.Unmarshal(data, &node); err != nil { + return nil, fmt.Errorf("failed to parse YAML config: %w", err) + } + + var config Config + if err := node.Decode(&config); err != nil { + return nil, fmt.Errorf("failed to decode YAML config: %w", err) + } + + // Store the node for later use when saving + config.node = &node + + return &config, nil +} + +// LoadConfigFromString parses YAML configuration from a string +func LoadConfigFromString(yamlContent string) (*Config, error) { + var node yaml.Node + if err := yaml.Unmarshal([]byte(yamlContent), &node); err != nil { + return nil, fmt.Errorf("failed to parse YAML config: %w", err) + } + + var config Config + if err := node.Decode(&config); err != nil { + return nil, fmt.Errorf("failed to decode YAML config: %w", err) + } + + config.node = &node + return &config, nil +} + +// GetDefaultChain returns the chain configuration for the default publicId +func (c *Config) GetDefaultChain() *ChainConfig { + for i := range c.Chains { + if c.Chains[i].PublicId == c.Default { + return &c.Chains[i] + } + } + return nil +} + +// GetChainByPublicId returns the chain configuration for the specified publicId +func (c *Config) GetChainByPublicId(publicId string) *ChainConfig { + for i := range c.Chains { + if c.Chains[i].PublicId == publicId { + return &c.Chains[i] + } + } + return nil +} + +// ListChains returns all chain names +func (c *Config) ListChains() []string { + names := make([]string, len(c.Chains)) + for i, chain := range c.Chains { + names[i] = chain.Name + } + return names +} + +// AddChain adds a chain configuration to the configuration +func (c *Config) AddChain(chain *ChainConfig) { + c.Chains = append(c.Chains, *chain) +} + +// SetDefault sets the default chain publicId +func (c *Config) SetDefault(publicId string) { + c.Default = publicId +} + +// DeleteChain deletes a chain configuration from the configuration +func (c *Config) DeleteChain(publicId string) error { + if publicId == c.Default { + return fmt.Errorf("cannot delete default chain") + } + for i, chain := range c.Chains { + if chain.PublicId == publicId { + c.Chains = append(c.Chains[:i], c.Chains[i+1:]...) + return nil + } + } + return nil +} + +// SaveConfig writes the configuration to a YAML file +func (c *Config) SaveConfig(filePath string) error { + expandedPath, err := expandPath(filePath) + if err != nil { + return fmt.Errorf("failed to expand path %s: %w", filePath, err) + } + + var data []byte + if c.node != nil { + // Update the node with current config values while preserving formatting + if err := c.node.Encode(c); err != nil { + return fmt.Errorf("failed to encode config to node: %w", err) + } + + // Ensure newlines between chain entries + c.ensureChainSeparation() + + // Marshal the node to preserve comments and formatting + data, err = yaml.Marshal(c.node) + if err != nil { + return fmt.Errorf("failed to marshal config to YAML: %w", err) + } + } else { + // Fallback to regular marshaling if no node is available + data, err = yaml.Marshal(c) + if err != nil { + return fmt.Errorf("failed to marshal config to YAML: %w", err) + } + } + + if err := ioutil.WriteFile(expandedPath, data, 0644); err != nil { + return fmt.Errorf("failed to write config file %s: %w", expandedPath, err) + } + + return nil +} + +// ensureChainSeparation adds blank lines between chain entries in the YAML node +func (c *Config) ensureChainSeparation() { + if c.node == nil || len(c.node.Content) == 0 { + return + } + + // Navigate to the document node, then the mapping node + docNode := c.node + if docNode.Kind == yaml.DocumentNode && len(docNode.Content) > 0 { + docNode = docNode.Content[0] + } + + if docNode.Kind != yaml.MappingNode { + return + } + + // Find the "chains" key in the mapping + for i := 0; i < len(docNode.Content); i += 2 { + if i+1 >= len(docNode.Content) { + break + } + + keyNode := docNode.Content[i] + valueNode := docNode.Content[i+1] + + if keyNode.Value == "chains" && valueNode.Kind == yaml.SequenceNode { + // Add HeadComment (newline before) to each chain entry except the first + for j := 1; j < len(valueNode.Content); j++ { + chainNode := valueNode.Content[j] + if chainNode.HeadComment == "" { + chainNode.HeadComment = "\n" + } + } + break + } + } +} + +// expandPath is a simple path expansion function (you can replace this with your utils.ExpandPath) +func expandPath(path string) (string, error) { + // Expand environment variables + path = os.ExpandEnv(path) + + // Handle home directory + if len(path) > 0 && path[0] == '~' { + home, err := os.UserHomeDir() + if err != nil { + return "", err + } + if len(path) == 1 { + path = home + } else if path[1] == '/' { + path = home + path[1:] + } + } + + return path, nil +} diff --git a/dragonchain.go b/dragonchain.go new file mode 100644 index 0000000..2bebdf8 --- /dev/null +++ b/dragonchain.go @@ -0,0 +1,35 @@ +package sdk + +import ( + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/block" + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/client" + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/contract" + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/system" + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/transaction" + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/transactiontype" +) + +type DragonchainSDK struct { + client *client.Client + Transaction *transaction.TransactionClient + TransactionType *transactiontype.TransactionTypeClient + Contract *contract.ContractClient + Block *block.BlockClient + System *system.SystemClient +} + +func NewDragonchainSDK(publicID, authKeyID, authKey, baseURL string) *DragonchainSDK { + c := client.NewClient(publicID, authKeyID, authKey, baseURL) + return &DragonchainSDK{ + client: c, + Transaction: transaction.NewTransactionClient(c), + TransactionType: transactiontype.NewTransactionTypeClient(c), + Contract: contract.NewContractClient(c), + Block: block.NewBlockClient(c), + System: system.NewSystemClient(c), + } +} + +func (sdk *DragonchainSDK) GetClient() *client.Client { + return sdk.client +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..bbbb739 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go + +go 1.24.5 + +require gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..a62c313 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/models/models.go b/models/models.go new file mode 100644 index 0000000..f0adee1 --- /dev/null +++ b/models/models.go @@ -0,0 +1,159 @@ +package models + +const ( + ContentTypeJSON = "application/json" +) + +type TransactionCreateRequest struct { + Version string `json:"version,omitempty"` + TxnType string `json:"txn_type"` + Payload string `json:"payload"` + Tag string `json:"tag,omitempty"` +} + +type TransactionCreateResponse struct { + TransactionID string `json:"transaction_id"` +} + +type TransactionBulkRequest struct { + Transactions []TransactionCreateRequest `json:"transactions"` +} + +type TransactionBulkResponse struct { + TransactionIDs []string `json:"transaction_ids"` +} + +type TransactionListResponse struct { + TransactionTypes []*TransactionType `json:"transactionTypes"` +} + +type Transaction struct { + Version string `json:"version"` + Header TransactionHeader `json:"header"` + Proof TransactionProof `json:"proof"` + Payload string `json:"payload"` +} + +type TransactionHeader struct { + Tag string `json:"tag"` + DcId string `json:"dc_id"` + TxnId string `json:"txn_id"` + Invoker string `json:"invoker"` + BlockId string `json:"block_id"` + TxnType string `json:"txn_type"` + Timestamp string `json:"timestamp"` +} + +type TransactionProof struct { + Full string `json:"full"` + Stripped string `json:"stripped"` +} + +type ListTransactionsResponse struct { + Transactions []Transaction `json:"transactions"` +} + +type TransactionTypeCreateRequest struct { + Version string `json:"version,omitempty"` + TxnType string `json:"txn_type"` +} + +type TransactionTypeCreateResponse struct { + Success bool `json:"success"` +} + +type TransactionType struct { + Version string `json:"version"` + Created int64 `json:"created"` + Modified int64 `json:"modified"` + TxnType string `json:"txn_type"` + ContractID string `json:"contract_id,omitempty"` + CustomIndexes []interface{} `json:"custom_indexes"` + ActiveSinceBlock string `json:"active_since_block"` +} + +type SmartContractCreateRequest struct { + Environment string `json:"environment"` + TransactionType string `json:"transactionType"` + ExecutionOrder string `json:"executionOrder"` + EnvironmentVariables map[string]string `json:"environmentVariables,omitempty"` + Secrets map[string]string `json:"secret,omitempty"` +} + +type SmartContractUpdateRequest struct { + Version string `json:"version,omitempty"` + Enabled bool `json:"enabled"` + EnvironmentVariables map[string]string `json:"environmentVariables,omitempty"` + Secrets map[string]string `json:"secret,omitempty"` +} + +type SmartContract struct { + Id string `json:"id"` + Created uint64 `json:"created"` + Modified uint64 `json:"modified"` + + Version string `json:"version"` + Environment string `json:"environment"` + TransactionType string `json:"transactionType"` + ExecutionOrder string `json:"executionOrder"` + + ExecutionInfo *SmartContractExecutionInfo `json:"executionInfo"` + + EnvVars map[string]string `json:"envVars"` + Secrets []string `json:"secrets"` +} + +type SmartContractExecutionInfo struct { + Type string `json:"type"` + + // LocalExecutable type + ExecutablePath string `json:"executablePath"` + ExecutableWorkingDirectory string `json:"executableWorkingDirectory"` + ExecutableHash string `json:"executableHash"` +} + +type Block struct { + Version string `json:"version"` + ID string `json:"block_id"` + Timestamp string `json:"timestamp"` + PrevID string `json:"prev_id"` + PrevProof string `json:"prev_proof"` + Transactions []string `json:"transactions"` + Proof BlockProof `json:"proof"` +} + +type BlockProof struct { + Scheme string `json:"scheme"` + Proof string `json:"proof"` + Nonce int64 `json:"nonce,omitempty"` +} + +type SystemStatus struct { + ID string `json:"id"` + Level int `json:"level"` + URL string `json:"url"` + HashAlgo string `json:"hashAlgo"` + Scheme string `json:"scheme"` + Version string `json:"version"` + EncryptionAlgo string `json:"encryptionAlgo"` + IndexingEnabled bool `json:"indexingEnabled"` + + // Level 5 Node + Funded string `json:"funded,omitempty"` + BroadcastInterval string `json:"broadcastInterval,omitempty"` + Network string `json:"network,omitempty"` + InterchainWallet string `json:"interchainWallet,omitempty"` +} + +type SuccessResponse struct { + Success bool `json:"success"` +} + +type ErrorResponse struct { + Error string `json:"error"` +} + +type ListResponse struct { + Items []interface{} `json:"items"` + TotalCount int `json:"total_count"` +} diff --git a/system/system.go b/system/system.go new file mode 100644 index 0000000..14ed2dc --- /dev/null +++ b/system/system.go @@ -0,0 +1,27 @@ +package system + +import ( + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/client" + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/models" +) + +type SystemClient struct { + client *client.Client +} + +func NewSystemClient(c *client.Client) *SystemClient { + return &SystemClient{client: c} +} + +func (sc *SystemClient) Health() error { + return sc.client.Get("/api/v1/health", nil) +} + +func (sc *SystemClient) Status() (*models.SystemStatus, error) { + var resp models.SystemStatus + err := sc.client.Get("/api/v1/status", &resp) + if err != nil { + return nil, err + } + return &resp, nil +} diff --git a/transaction/transaction.go b/transaction/transaction.go new file mode 100644 index 0000000..99471c1 --- /dev/null +++ b/transaction/transaction.go @@ -0,0 +1,54 @@ +package transaction + +import ( + "fmt" + + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/client" + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/models" +) + +type TransactionClient struct { + client *client.Client +} + +func NewTransactionClient(c *client.Client) *TransactionClient { + return &TransactionClient{client: c} +} + +func (tc *TransactionClient) Create(req *models.TransactionCreateRequest) (*models.TransactionCreateResponse, error) { + var resp models.TransactionCreateResponse + err := tc.client.Post("/api/v1/transaction", models.ContentTypeJSON, req, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (tc *TransactionClient) CreateBulk(req *models.TransactionBulkRequest) (*models.TransactionBulkResponse, error) { + var resp models.TransactionBulkResponse + err := tc.client.Post("/api/v1/transaction/bulk", models.ContentTypeJSON, req, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (tc *TransactionClient) Get(transactionID string) (*models.Transaction, error) { + var resp models.Transaction + path := fmt.Sprintf("/api/v1/transaction/%s", transactionID) + err := tc.client.Get(path, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (tc *TransactionClient) List() (*models.ListTransactionsResponse, error) { + var resp models.ListTransactionsResponse + path := "/api/v1/transaction/" + err := tc.client.Get(path, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} diff --git a/transactiontype/transactiontype.go b/transactiontype/transactiontype.go new file mode 100644 index 0000000..1273079 --- /dev/null +++ b/transactiontype/transactiontype.go @@ -0,0 +1,54 @@ +package transactiontype + +import ( + "fmt" + + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/client" + "git.dragonchain.com/dragonchain/dragonchain-prime-sdk-go/models" +) + +type TransactionTypeClient struct { + client *client.Client +} + +func NewTransactionTypeClient(c *client.Client) *TransactionTypeClient { + return &TransactionTypeClient{client: c} +} + +func (ttc *TransactionTypeClient) Create(req *models.TransactionTypeCreateRequest) (*models.TransactionTypeCreateResponse, error) { + var resp models.TransactionTypeCreateResponse + err := ttc.client.Post("/api/v1/transaction-type", models.ContentTypeJSON, req, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (ttc *TransactionTypeClient) Get(txnType string) (*models.TransactionType, error) { + var resp models.TransactionType + path := fmt.Sprintf("/api/v1/transaction-type/%s", txnType) + err := ttc.client.Get(path, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (ttc *TransactionTypeClient) List() (*models.TransactionListResponse, error) { + var resp models.TransactionListResponse + err := ttc.client.Get("/api/v1/transaction-types", &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (ttc *TransactionTypeClient) Delete(txnType string) (*models.SuccessResponse, error) { + var resp models.SuccessResponse + path := fmt.Sprintf("/api/v1/transaction-type/%s", txnType) + err := ttc.client.Delete(path, &resp) + if err != nil { + return nil, err + } + return &resp, nil +}