From 22a611c53495d3a97d881ff94e19976ea67a87f8 Mon Sep 17 00:00:00 2001 From: marston Date: Wed, 10 Jul 2024 14:49:10 -0400 Subject: [PATCH] adding ipfs peer api --- api/ipfs.go | 24 ++++++++++++++++++++++++ api/server.go | 2 ++ api/types/responses.go | 6 ++++++ cmd/ipfs.go | 37 +++++++++++++++++++++++++++++++++++++ cmd/root.go | 2 +- file_system/ipfs.go | 7 +++++++ file_system/types.go | 11 +++++++---- ipfs/ipfs.go | 20 +++++++++++--------- 8 files changed, 95 insertions(+), 14 deletions(-) create mode 100644 api/ipfs.go create mode 100644 cmd/ipfs.go create mode 100644 file_system/ipfs.go diff --git a/api/ipfs.go b/api/ipfs.go new file mode 100644 index 0000000..18954ad --- /dev/null +++ b/api/ipfs.go @@ -0,0 +1,24 @@ +package api + +import ( + "net/http" + + "github.com/JackalLabs/sequoia/api/types" + "github.com/rs/zerolog/log" + + "github.com/JackalLabs/sequoia/file_system" +) + +func IPFSListPeers(f *file_system.FileSystem) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, req *http.Request) { + peers := f.ListPeers() + f := types.PeersResponse{ + Peers: peers, + } + + err := json.NewEncoder(w).Encode(f) + if err != nil { + log.Error().Err(err) + } + } +} diff --git a/api/server.go b/api/server.go index 9e47b08..9ff6a0d 100644 --- a/api/server.go +++ b/api/server.go @@ -44,6 +44,8 @@ func (a *API) Serve(f *file_system.FileSystem, p *proofs.Prover, wallet *wallet. r.HandleFunc("/list", ListFilesHandler(f)) r.HandleFunc("/api/data/fids", LegacyListFilesHandler(f)) + r.HandleFunc("/ipfs/peers", IPFSListPeers(f)) + r.HandleFunc("/dump", DumpDBHandler(f)) r.HandleFunc("/version", VersionHandler(wallet)) diff --git a/api/types/responses.go b/api/types/responses.go index df1b9be..40a6e48 100644 --- a/api/types/responses.go +++ b/api/types/responses.go @@ -1,5 +1,7 @@ package types +import "github.com/libp2p/go-libp2p/core/peer" + type UploadResponse struct { Merkle []byte `json:"merkle"` Owner string `json:"owner"` @@ -35,3 +37,7 @@ type LegacyAPIListValue struct { type LegacyAPIListResponse struct { Data []LegacyAPIListValue `json:"data"` } + +type PeersResponse struct { + Peers peer.IDSlice `json:"peers"` +} diff --git a/cmd/ipfs.go b/cmd/ipfs.go new file mode 100644 index 0000000..6f92797 --- /dev/null +++ b/cmd/ipfs.go @@ -0,0 +1,37 @@ +package cmd + +import ( + "fmt" + "io" + "net/http" + + "github.com/spf13/cobra" +) + +func IPFSCmd() *cobra.Command { + c := &cobra.Command{ + Use: "ipfs", + Short: "Details about the IPFS network", + } + c.AddCommand(PeersCmd()) + return c +} + +func PeersCmd() *cobra.Command { + return &cobra.Command{ + Use: "peers", + Short: "list peers on ipfs", + RunE: func(cmd *cobra.Command, args []string) error { + resp, err := http.Get("http://localhost:3333/ipfs/peers") + if err != nil { + return err + } + body, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + fmt.Println(string(body)) + return nil + }, + } +} diff --git a/cmd/root.go b/cmd/root.go index d06eb3b..9e2906d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -69,7 +69,7 @@ func RootCmd() *cobra.Command { r.PersistentFlags().String(types.FlagHome, types.DefaultHome, "sets the home directory for sequoia") r.PersistentFlags().String(types.FlagLogLevel, types.DefaultLogLevel, "log level. info|error|debug") - r.AddCommand(StartCmd(), wallet.WalletCmd(), InitCmd(), VersionCmd()) + r.AddCommand(StartCmd(), wallet.WalletCmd(), InitCmd(), VersionCmd(), IPFSCmd()) return r } diff --git a/file_system/ipfs.go b/file_system/ipfs.go new file mode 100644 index 0000000..f282226 --- /dev/null +++ b/file_system/ipfs.go @@ -0,0 +1,7 @@ +package file_system + +import "github.com/libp2p/go-libp2p/core/peer" + +func (f *FileSystem) ListPeers() peer.IDSlice { + return f.ipfsHost.Peerstore().PeersWithAddrs() +} diff --git a/file_system/types.go b/file_system/types.go index 75f590b..d026c23 100644 --- a/file_system/types.go +++ b/file_system/types.go @@ -3,22 +3,25 @@ package file_system import ( "context" + "github.com/libp2p/go-libp2p/core/host" + ipfs2 "github.com/JackalLabs/sequoia/ipfs" "github.com/dgraph-io/badger/v4" ipfslite "github.com/hsanjuan/ipfs-lite" ) type FileSystem struct { - db *badger.DB - ipfs *ipfslite.Peer + db *badger.DB + ipfs *ipfslite.Peer + ipfsHost host.Host } func NewFileSystem(ctx context.Context, db *badger.DB, ipfsPort int, ipfsDomain string) (*FileSystem, error) { - ipfs, err := ipfs2.MakeIPFS(ctx, db, ipfsPort, ipfsDomain) + ipfs, host, err := ipfs2.MakeIPFS(ctx, db, ipfsPort, ipfsDomain) if err != nil { return nil, err } - return &FileSystem{db: db, ipfs: ipfs}, nil + return &FileSystem{db: db, ipfs: ipfs, ipfsHost: host}, nil } func (f *FileSystem) Close() { diff --git a/ipfs/ipfs.go b/ipfs/ipfs.go index 609857c..818b3e3 100644 --- a/ipfs/ipfs.go +++ b/ipfs/ipfs.go @@ -5,6 +5,8 @@ import ( "fmt" "strings" + "github.com/libp2p/go-libp2p/core/host" + "github.com/dgraph-io/badger/v4" ipfslite "github.com/hsanjuan/ipfs-lite" "github.com/libp2p/go-libp2p/core/crypto" @@ -13,24 +15,24 @@ import ( bds "github.com/ipfs/go-ds-badger2" ) -func MakeIPFS(ctx context.Context, db *badger.DB, port int, customDomain string) (*ipfslite.Peer, error) { +func MakeIPFS(ctx context.Context, db *badger.DB, port int, customDomain string) (*ipfslite.Peer, host.Host, error) { ds, err := bds.NewDatastoreFromDB(db) if err != nil { - return nil, err + return nil, nil, err } priv, _, err := crypto.GenerateKeyPair(crypto.RSA, 2048) if err != nil { - return nil, err + return nil, nil, err } listen, err := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", port)) if err != nil { - return nil, fmt.Errorf("failed to make ipv4 ipfs address | %w", err) + return nil, nil, fmt.Errorf("failed to make ipv4 ipfs address | %w", err) } listen6, err := multiaddr.NewMultiaddr(fmt.Sprintf("/ip6/::/tcp/%d", port)) if err != nil { - return nil, fmt.Errorf("failed to make ipv6 ipfs address | %w", err) + return nil, nil, fmt.Errorf("failed to make ipv6 ipfs address | %w", err) } m := []multiaddr.Multiaddr{listen, listen6} @@ -41,7 +43,7 @@ func MakeIPFS(ctx context.Context, db *badger.DB, port int, customDomain string) } domainListener, err := multiaddr.NewMultiaddr(customDomain) if err != nil { - return nil, fmt.Errorf("failed to make domain based ipfs address | %w", err) + return nil, nil, fmt.Errorf("failed to make domain based ipfs address | %w", err) } m = append(m, domainListener) } @@ -55,15 +57,15 @@ func MakeIPFS(ctx context.Context, db *badger.DB, port int, customDomain string) ipfslite.Libp2pOptionsExtra..., ) if err != nil { - return nil, err + return nil, h, err } lite, err := ipfslite.New(ctx, ds, nil, h, dht, nil) if err != nil { - return nil, err + return nil, h, err } lite.Bootstrap(ipfslite.DefaultBootstrapPeers()) - return lite, nil + return lite, h, nil }