MCPcopy
hub / github.com/spaceandtimefdn/SxT-Go-SDK

github.com/spaceandtimefdn/SxT-Go-SDK @v0.0.9 sqlite

repository ↗ · DeepWiki ↗ · release v0.0.9 ↗
64 symbols 202 edges 16 files 47 documented · 73%
README

go-sxt-sdk

Golang SDK for Space and Time Gateway (go version >= 1.18)

Installation instructions

go get github.com/spaceandtimelabs/SxT-Go-SDK

Running locally

Note: Before running the code, rename .env.sample to .env and ensure that your credentials are setup in the .env file properly. You will need to obtain a joinCode and endpoint before you can begin

go mod tidy

Features

  • Sessions

    The sdk can implement persistent storage in

  • File based sessions

  • AWS Secrets Manager.

It implements API V2 of Aws SDK (https://github.com/aws/aws-sdk-go-v2). Also access keys, access secrets are retrieved from sharedConfig and sharedCredentials. Read more here https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html

  • Encryption

    Support for Ed25519 public key encryption for Biscuit Authorization and Securing data in the platform.

  • SQL support

    • Support for DDL: creating own schema (namespace), tables; altering and deleting tables
    • DML: Write all CRUD operations
    • DQL: Any select operations
    • SQL Views
  • Platform Discovery For fetching meta data from the platform

    • Namespaces
    • Tables
    • Table columns
    • Table index
    • Table primary key
    • Table relations
    • Primary key references
    • Foreign key references
    • List views

Examples

  • Running all examples at once

main.go contains a complete running example. To run the file

go run main.go

To pass an existing user, use

go run main.go -userid=<USERID> -pubkey=<BASE64 STD ENCODED PUBLIC KEY WITHOUT PADDING> -privkey=<BASE64 STD ENCODED PRIVATE KEY WITHOUT PADDING>

// e.g
// pubkey=SiQrMfU+TfRrqqeo/ZDoOwSrHd9zrG1BCU4oDz+4C4Q
// privkey=ys3hQPyfojJOzNymc0eWOKUiogQFGv3G+eeEDUBB8jpKJCsx9T5N9Guqp6j9kOg7BKsd33OsbUEJTigPP7gLhA

This will bypass the userid and joincode mentioned in .env file.

For details on running the main.go file, use

go run main.go -h
  • Authentication

It is very important to save your private key used in authentication and biscuit generation. Else you will not have access to the user and tables created using the key.

The generated AccessToken is valid for 25 minutes and the refreshToken for 30 minutes.

// New Authentication.
// Generates new accessToken, refreshToken, privateKey, and publicKey
func Authenticate()(accessToken, refreshToken string, privateKey ed25519.PrivateKey, publicKey ed25519.PublicKey){

    // Read userId, joinCode from .env file
    userId, _ := helpers.ReadUserId()
    joinCode, _ := helpers.ReadJoinCode()

    var pubkey ed25519.PublicKey
    var privkey ed25519.PrivateKey

    var authCodeStruct authentication.AuthCodeStruct
    var tokenStruct authentication.TokenStruct

    sessionStruct, sessionStatus := storage.FileReadSession(userId)

    if !sessionStatus {
        // Generate Private and Public keys
        pubkey, privkey = helpers.CreateKey()
    } else {
        pubkey = sessionStruct.PublicKey
        privkey = sessionStruct.PrivateKey
    }


    // Get auth code
    authCode := authentication.GenerateAuthCode(userId, joinCode)
    json.Unmarshal([]byte(authCode), &authCodeStruct)

    // Get Keys
    encodedSignature,  base64PublicKey := authentication.GenerateKeys(authCodeStruct.AuthCode, pubkey, privkey)

    // Get Token
    tokenJson := authentication.GenerateToken(userId, authCodeStruct.AuthCode, encodedSignature, base64PublicKey)
    json.Unmarshal([]byte(tokenJson), &tokenStruct)

    // Store session data to a local file

    writeStatus := storage.FileWriteSession(userId, tokenStruct.AccessToken, tokenStruct.RefreshToken, privkey, pubkey)
    if !writeStatus{
        log.Fatal("Invalid login. Change login credentials")
    }

    return tokenStruct.AccessToken, tokenStruct.RefreshToken, privkey, publicKey
}

  • Generating Biscuits

You can create multiple biscuit tokens for a table allowing you provide different access levels for users. For the list of all the capabilities, visit https://docs.spaceandtime.io/docs/biscuit-authorization

Sample biscuit generation with permissions for select query, insert query, update query, delete query, create table

var sxtBiscuitCapabilities []authorization.SxTBiscuitStruct

// Add biscuit capabilities
sxtBiscuitCapabilities = append(sxtBiscuitCapabilities, authorization.SxTBiscuitStruct{Operation: "dql_select", Resource: "eth.testtable103"})
sxtBiscuitCapabilities = append(sxtBiscuitCapabilities, authorization.SxTBiscuitStruct{Operation: "dml_insert", Resource: "eth.testtable103"})
sxtBiscuitCapabilities = append(sxtBiscuitCapabilities, authorization.SxTBiscuitStruct{Operation: "dml_update", Resource: "eth.testtable103"})
sxtBiscuitCapabilities = append(sxtBiscuitCapabilities, authorization.SxTBiscuitStruct{Operation: "dml_delete", Resource: "eth.testtable103"})
sxtBiscuitCapabilities = append(sxtBiscuitCapabilities, authorization.SxTBiscuitStruct{Operation: "ddl_create", Resource: "eth.testtable103"})

// Generate the biscuit token
biscuit, _ := authorization.CreateBiscuitToken(sxtBiscuitCapabilities, &privateKey)

  • DDL, DML & DQL

    Note:

To generate a new schema, ddl_create permission is needed

// Create a new schema
sqlcore.CreateSchema("CREATE SCHEMA ETH")

// Only for create queries
// For ALTER and DROP, use sqlcore.DDL()
sqlcore.CreateTable("ETH.TESTTABLE103", "CREATE TABLE ETH.TESTTABLE103 (id INT PRIMARY KEY, test VARCHAR)", "permissioned", biscuit, publicKey)

// Only for ALTER and DROP queries
// For Create table queries, use sqlcore.CreateTable()
sqlcore.DDL("ETH.TESTTABLE103", "ALTER TABLE ETH.TESTTABLE103 ADD TEST2 VARCHAR", biscuit)

// DML
// use the sqlcore.DML to write insert, update, delete, and merge queries
sqlcore.DML("ETH.TESTTABLE103", "insert into ETH.TESTTABLE103 values(5, 'x5')", biscuit);

// DQL
// Select operations
// If rowCount is 0, then fetches all data without limit
sqlcore.DQL("ETH.TESTTABLE103", "select * from ETH.TESTTABLE103", biscuit, 0);
  • DISCOVERY

Discovery calls need a user to be logged in


// List Namespaces
discovery.ListNamespaces()

// List Tables in a given namespace
// Possible scope values -  ALL = all resources, PUBLIC = non-permissioned tables, PRIVATE = tables created by the requesting user
discovery.ListTables("ETH", "ALL")

// List Columns for a given table in namespace
discovery.ListColumns("ETH", "TESTTABLE103")

// List table index for a given table in namespace
discovery.ListTableIndex("ETH", "TESTTABLE103")


// List table primary key for a given table in namespace
discovery.ListTablePrimaryKey("ETH", "TESTTABLE103")

// List table relations for a namespace and scope
// Possible scope values -  ALL = all resources, PUBLIC = non-permissioned tables, PRIVATE = tables created by the requesting user
discovery.ListTableRelations("ETH", "PRIVATE")

// List table primary key references for a table and a namespace
discovery.ListPrimaryKeyReferences("ETH", "TESTTABLE103", "TEST")

// List foreign key references for a table, column and a namespace
discovery.ListForeignKeyReferences("ETH", "TESTTABLE103", "TEST")
  • Storage

For AWS and File storage, the following methods are available


// File
storage.FileWriteSession(userId, tokenStruct.AccessToken, tokenStruct.RefreshToken, privkey, pubkey)

storage.FileReadSession(userId)

storage.FileUpdateSession(userId, accessToken, refreshToken, privateKey, publicKey)

// AWS
storage.AwsWriteSession(userId, tokenStruct.AccessToken, tokenStruct.RefreshToken, privkey, pubkey)

storage.AwsReadSession(userId)

storage.AwsUpdateSession(userId, accessToken, refreshToken, privateKey, publicKey)

Configuring a project with SxT SDK

  1. Import library
go get github.com/spaceandtimelabs/SxT-Go-SDK
  1. (Optional) Create a tmp folder in the project root to save user session information (default option). The other options include AWS secrets manager which is not discussed here
mkdir tmp
  1. Copy all the .env.sample parameters to your environment file
BASEURL_GENERAL="https://<base_url>/v1" # Space and Time General API Endpoint
BASEURL_DISCOVERY="https://<base_url>/v2"  # Space and Time Discovery API Endpoint
USERID="" # UserID required for authentication and authorization
JOINCODE="" # Space and Time Join Code which can be got from the SxT release team
SCHEME="ed25519"  # The key scheme or algorithm required for key generation
  1. Integration code
func main() {

    // Load env file
    godotenv.Load(".env")

    var biscuits, resources []string

    // env variables
    inputUserID := os.Getenv("USERID")
    pubKey := os.Getenv("PUB_KEY")
    privKey := os.Getenv("PRIV_KEY")

    // Private key to byte array
    pvtKeyBytes, err := base64.StdEncoding.DecodeString(privKey)
    if err != nil {
        log.Println("Private key decoding to []bytes error", err)
    }

    // public key
    // Some languages generate a 32-byte private key while some generate 64-byte ones. For the later cases, 64-byte pvt key = 32-byte actual private key + 32-byte public key
    pubKeyBytes, err := base64.StdEncoding.DecodeString(pubKey)
    if err != nil {
        log.Println("Public key decoding to []bytes error", err)
    }
    if len(pvtKeyBytes) < 64 {
        pubKeyBytes = append(pubKeyBytes, pubKeyBytes...)
        privKey = base64.StdEncoding.EncodeToString(pvtKeyBytes)
    }

    // Authenticate and get accessToken
    accessToken, _, _, _, err := utils.Authenticate(inputUserID, pubKey, privKey)
    if err != nil {
        log.Println("Authentication error: ", err)
    }

    // Important: Save access token to env
    os.Setenv("accessToken", accessToken)

    // Preparing to call DML
    biscuits = append(biscuits, "actual_biscuit_string")
    resources = append(resources, "schema_name.table_name")

    sqlQuery :=  "INSERT INTO schema_name.tablename VALUES(....)"

    errString, status := sqlcore.DML(sqlQuery, "", biscuits, resources)
    if !status{
        log.Println("Error inserting record to Space and Time: ", errString)
    }

}

Core symbols most depended-on inside this repo

executeRequest
called by 8
discovery/discovery.go
GetDiscoverEndpoint
called by 7
helpers/endpoint.go
isFlagPassed
called by 6
main.go
GetAuthenticationEndpoint
called by 5
helpers/endpoint.go
Authenticate
called by 4
utils/utils.go
CheckUpperCase
called by 4
helpers/regexcheck.go
getEndpointByType
called by 3
helpers/endpoint.go
getSecretsManagerClient
called by 3
storage/aws.go

Shape

Function 59
Struct 5

Languages

Go100%

Modules by API surface

discovery/discovery.go16 symbols
authentication/authentication.go8 symbols
storage/aws.go6 symbols
helpers/readenvironment.go5 symbols
sqlcore/ddl.go4 symbols
helpers/endpoint.go4 symbols
utils/utils.go3 symbols
storage/file.go3 symbols
main_test.go3 symbols
sqlcore/dql.go2 symbols
sqlcore/dml.go2 symbols
main.go2 symbols

Dependencies from manifests, versioned

github.com/aws/aws-sdk-go-v2v1.17.6 · 1×
github.com/aws/aws-sdk-go-v2/configv1.18.17 · 1×
github.com/aws/aws-sdk-go-v2/credentialsv1.13.17 · 1×
github.com/aws/aws-sdk-go-v2/feature/ec2/imdsv1.13.0 · 1×
github.com/aws/aws-sdk-go-v2/internal/configsourcesv1.1.30 · 1×
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2v2.4.24 · 1×
github.com/aws/aws-sdk-go-v2/internal/iniv1.3.31 · 1×
github.com/aws/aws-sdk-go-v2/service/internal/presigned-urlv1.9.24 · 1×
github.com/aws/aws-sdk-go-v2/service/secretsmanagerv1.19.0 · 1×
github.com/aws/aws-sdk-go-v2/service/ssov1.12.5 · 1×
github.com/aws/aws-sdk-go-v2/service/ssooidcv1.14.5 · 1×

For agents

$ claude mcp add SxT-Go-SDK \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact