Skip to content

Commit

Permalink
add a very simple go shell client for census3
Browse files Browse the repository at this point in the history
Signed-off-by: p4u <[email protected]>
  • Loading branch information
p4u committed Aug 30, 2024
1 parent 246d1ea commit 7dc3fca
Show file tree
Hide file tree
Showing 3 changed files with 235 additions and 0 deletions.
228 changes: 228 additions & 0 deletions cmd/cli/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
package main

import (
"fmt"
"log"
"net/url"
"os"
"strconv"
"strings"

"github.com/fatih/color"
"github.com/google/uuid"
"github.com/spf13/cobra"
"github.com/vocdoni/census3/api"
"github.com/vocdoni/census3/apiclient"
)

var client *apiclient.HTTPclient

func main() {
var apiUrl string
var authToken string

// Root command
rootCmd := &cobra.Command{
Use: "census3-cli",
Short: "Census3 API Interactive Client",
Long: "An interactive client to interact with the Census3 API using Go.",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
// Setup client before running commands
u, err := url.Parse(apiUrl)
if err != nil {
log.Fatalf("Invalid API URL: %v", err)
}
client, err = apiclient.NewHTTPclient(u, nil)
if err != nil {
log.Fatalf("Failed to create API client: %v", err)
}

if authToken != "" {
t := uuid.MustParse(authToken)
client.SetAuthToken(&t)
}
},
}

rootCmd.PersistentFlags().StringVar(&apiUrl, "api-url", "https://census3.vocdoni.net/api", "Census3 API URL")
rootCmd.PersistentFlags().StringVar(&authToken, "auth-token", "", "Bearer authentication token")

// Info command
infoCmd := &cobra.Command{
Use: "info",
Short: "Get API information",
Run: func(cmd *cobra.Command, args []string) {
info, err := client.Info()
if err != nil {
color.Red("Error fetching API info: %v", err)
return
}
color.Green("API Information:")
fmt.Printf(" Supported Chains: %v\n", info.SupportedChains)
},
}
rootCmd.AddCommand(infoCmd)

// Tokens command
tokensCmd := &cobra.Command{
Use: "tokens",
Short: "List all tokens",
Run: func(cmd *cobra.Command, args []string) {
tokens, err := client.Tokens(100, "", "")
if err != nil {
color.Red("Error fetching tokens: %v", err)
return
}
for _, token := range tokens {
color.Cyan("Token ID: %s\n", token.ID)
fmt.Printf(" Type: %s\n", token.Type)
fmt.Printf(" Chain ID: %d\n", token.ChainID)
fmt.Printf(" Tags: %v\n", token.Tags)
fmt.Println()
}
},
}
rootCmd.AddCommand(tokensCmd)

// Token command
tokenCmd := &cobra.Command{
Use: "token [tokenID] [chainID]",
Short: "Get information about a specific token",
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
tokenID := args[0]
chainID, err := strconv.ParseUint(args[1], 10, 64)
if err != nil {
color.Red("Invalid chain ID: %v", err)
return
}

token, err := client.Token(tokenID, chainID, "")
if err != nil {
color.Red("Error fetching token: %v", err)
return
}
color.Green("Token Details:")
fmt.Printf(" ID: %s\n", token.ID)
fmt.Printf(" Type: %s\n", token.Type)
fmt.Printf(" Chain ID: %d\n", token.ChainID)
fmt.Printf(" Start Block: %d\n", token.StartBlock)
fmt.Printf(" Tags: %v\n", token.Tags)
},
}
rootCmd.AddCommand(tokenCmd)

// Add Token command
addTokenCmd := &cobra.Command{
Use: "add_token",
Short: "Add a new token",
Run: func(cmd *cobra.Command, args []string) {
var tokenID, tokenType, chainID, startBlock, tags string

fmt.Print("Enter Token ID: ")
if _, err := fmt.Scanln(&tokenID); err != nil {
color.Red("Invalid token ID: %v", err)
return
}
fmt.Print("Enter Token Type (e.g., erc20): ")
if _, err := fmt.Scanln(&tokenType); err != nil {
color.Red("Invalid token type: %v", err)
return
}
fmt.Print("Enter Chain ID: ")
if _, err := fmt.Scanln(&chainID); err != nil {
color.Red("Invalid chain ID: %v", err)
return
}
fmt.Print("Enter Start Block: ")
fmt.Scanln(&startBlock)

Check failure on line 138 in cmd/cli/main.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `fmt.Scanln` is not checked (errcheck)
fmt.Print("Enter Tags (comma-separated): ")
fmt.Scanln(&tags)

Check failure on line 140 in cmd/cli/main.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `fmt.Scanln` is not checked (errcheck)

chainIDUint, err := strconv.ParseUint(chainID, 10, 64)
if err != nil {
color.Red("Invalid chain ID: %v", err)
return
}
startBlockUint, err := strconv.ParseUint(startBlock, 10, 64)
if err != nil {
startBlockUint = 0
}

token := &api.Token{
ID: tokenID,
Type: tokenType,
ChainID: chainIDUint,
StartBlock: startBlockUint,
Tags: tags,
}

if err := client.CreateToken(token); err != nil {
color.Red("Error creating token: %v", err)
return
}
color.Green("Token created successfully.")
},
}
rootCmd.AddCommand(addTokenCmd)

// Token command
holdersCmd := &cobra.Command{
Use: "holders <strategyID>",
Short: "Get the list of token holders for an strategy",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
strategyID, err := strconv.ParseUint(args[0], 10, 64)
if err != nil {
color.Red("Invalid strategy ID: %v", err)
return
}
holders, err := client.AllHoldersByStrategy(strategyID, true)
if err != nil {
color.Red("Error fetching holders: %v", err)
return
}
color.Green("Holders:")
for addr, amount := range holders {
fmt.Printf(" %s %s\n", addr.String(), amount.String())
}
},
}
rootCmd.AddCommand(holdersCmd)

// Strategies command
strategiesCmd := &cobra.Command{
Use: "strategies [tokenID]",
Short: "List all strategies (filter by token if provided)",
Args: cobra.MaximumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
strategies, err := client.Strategies(-1, "", "")
if err != nil {
color.Red("Error fetching strategies: %v", err)
return
}

for _, strategy := range strategies {
if args[0] != "" && !strings.Contains(strategy.Predicate, args[0]) {
continue
}
color.Cyan("Strategy ID: %d\n", strategy.ID)
fmt.Printf(" Alias: %s\n", strategy.Alias)
fmt.Printf(" Predicate: %s\n", strategy.Predicate)
tokens := ""
for _, token := range strategy.Tokens {
tokens += token.ID + ", "
}
fmt.Printf(" URI: %s\n", strategy.URI)
fmt.Println()
}
},
}
rootCmd.AddCommand(strategiesCmd)

// Run the root command
if err := rootCmd.Execute(); err != nil {
log.Fatalf("Error: %v", err)
os.Exit(1)
}
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ toolchain go1.22.4
require (
github.com/VictoriaMetrics/metrics v1.24.0
github.com/ethereum/go-ethereum v1.14.0
github.com/fatih/color v1.16.0
github.com/frankban/quicktest v1.14.6
github.com/google/uuid v1.6.0
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/ipfs/go-cid v0.4.1
github.com/mattn/go-sqlite3 v1.14.22
github.com/pressly/goose/v3 v3.20.0
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.18.2
go.vocdoni.io/dvote v1.10.2-0.20240617105531-77480ae05205
Expand Down Expand Up @@ -102,6 +104,7 @@ require (
github.com/holiman/uint256 v1.2.4 // indirect
github.com/huin/goupnp v1.3.0 // indirect
github.com/iden3/go-iden3-crypto v0.0.13 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/ipfs-shipyard/nopfs v0.0.12 // indirect
github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c // indirect
github.com/ipfs/bbloom v0.0.4 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:
github.com/iden3/go-iden3-crypto v0.0.13 h1:ixWRiaqDULNyIDdOWz2QQJG5t4PpNHkQk2P6GV94cok=
github.com/iden3/go-iden3-crypto v0.0.13/go.mod h1:swXIv0HFbJKobbQBtsB50G7IHr6PbTowutSew/iBEoo=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/ipfs-shipyard/nopfs v0.0.12 h1:mvwaoefDF5VI9jyvgWCmaoTJIJFAfrbyQV5fJz35hlk=
github.com/ipfs-shipyard/nopfs v0.0.12/go.mod h1:mQyd0BElYI2gB/kq/Oue97obP4B3os4eBmgfPZ+hnrE=
github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7UynTbtdlt+w08ggb1UGLGaGjp1mMaZhoTZSctpn5Ak=
Expand Down Expand Up @@ -1016,6 +1018,8 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
Expand Down

0 comments on commit 7dc3fca

Please sign in to comment.