Initial Commit
This commit is contained in:
73
.gitignore
vendored
Normal file
73
.gitignore
vendored
Normal file
@@ -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
|
||||
96
README.md
Normal file
96
README.md
Normal file
@@ -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")
|
||||
26
block/block.go
Normal file
26
block/block.go
Normal file
@@ -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
|
||||
}
|
||||
144
client/client.go
Normal file
144
client/client.go
Normal file
@@ -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)
|
||||
}
|
||||
80
contract/contract.go
Normal file
80
contract/contract.go
Normal file
@@ -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
|
||||
}
|
||||
221
credentials/credentials.go
Normal file
221
credentials/credentials.go
Normal file
@@ -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
|
||||
}
|
||||
35
dragonchain.go
Normal file
35
dragonchain.go
Normal file
@@ -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
|
||||
}
|
||||
5
go.mod
Normal file
5
go.mod
Normal file
@@ -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
|
||||
4
go.sum
Normal file
4
go.sum
Normal file
@@ -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=
|
||||
159
models/models.go
Normal file
159
models/models.go
Normal file
@@ -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"`
|
||||
}
|
||||
27
system/system.go
Normal file
27
system/system.go
Normal file
@@ -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
|
||||
}
|
||||
54
transaction/transaction.go
Normal file
54
transaction/transaction.go
Normal file
@@ -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
|
||||
}
|
||||
54
transactiontype/transactiontype.go
Normal file
54
transactiontype/transactiontype.go
Normal file
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user