diff --git a/cmd/portal/portal.go b/cmd/portal/portal.go index a166e47..795177a 100644 --- a/cmd/portal/portal.go +++ b/cmd/portal/portal.go @@ -6,6 +6,7 @@ import ( "git.lumeweb.com/LumeWeb/portal/config" "git.lumeweb.com/LumeWeb/portal/interfaces" "git.lumeweb.com/LumeWeb/portal/protocols" + "git.lumeweb.com/LumeWeb/portal/storage" "github.com/spf13/viper" "go.sia.tech/core/wallet" "go.uber.org/zap" @@ -23,15 +24,23 @@ type PortalImpl struct { protocolRegistry protocols.ProtocolRegistry logger *zap.Logger identity ed25519.PrivateKey + storage interfaces.StorageService } func NewPortal() interfaces.Portal { logger, _ := zap.NewDevelopment() - return &PortalImpl{ + + portal := &PortalImpl{ apiRegistry: api.NewRegistry(), protocolRegistry: protocols.NewProtocolRegistry(), logger: logger, + storage: nil, } + + storageServ := storage.NewStorageService(portal) + portal.storage = storageServ + + return portal } func (p *PortalImpl) Initialize() error { @@ -143,6 +152,10 @@ func (p *PortalImpl) getInitFuncs() []func() error { }, } } +func (p *PortalImpl) Storage() interfaces.StorageService { + return p.storage +} + func (p *PortalImpl) getStartFuncs() []func() error { return []func() error{ func() error { diff --git a/interfaces/portal.go b/interfaces/portal.go index c216916..8b1bc4a 100644 --- a/interfaces/portal.go +++ b/interfaces/portal.go @@ -15,4 +15,5 @@ type Portal interface { Db() *gorm.DB ApiRegistry() APIRegistry Identity() ed25519.PrivateKey + Storage() StorageService } diff --git a/interfaces/storage.go b/interfaces/storage.go new file mode 100644 index 0000000..742d80a --- /dev/null +++ b/interfaces/storage.go @@ -0,0 +1,7 @@ +package interfaces + +import "io" + +type StorageService interface { + PutFile(file io.ReadSeeker, bucket string, generateProof bool) ([]byte, error) +} diff --git a/storage/storage.go b/storage/storage.go new file mode 100644 index 0000000..69d70ac --- /dev/null +++ b/storage/storage.go @@ -0,0 +1,64 @@ +package storage + +import ( + "bytes" + "git.lumeweb.com/LumeWeb/libs5-go/encoding" + "git.lumeweb.com/LumeWeb/portal/interfaces" + "github.com/go-resty/resty/v2" + "io" + "lukechampine.com/blake3" +) + +var ( + _ interfaces.StorageService = (*StorageServiceImpl)(nil) +) + +type StorageServiceImpl struct { + portal interfaces.Portal + httpApi *resty.Client +} + +func NewStorageService(portal interfaces.Portal) interfaces.StorageService { + client := resty.New() + + client.SetBaseURL(portal.Config().GetString("core.sia.url")) + client.SetBasicAuth("", portal.Config().GetString("core.sia.key")) + + return &StorageServiceImpl{ + portal: portal, + httpApi: client, + } +} + +func (s StorageServiceImpl) PutFile(file io.ReadSeeker, bucket string, generateProof bool) ([]byte, error) { + buf := bytes.NewBuffer(nil) + + _, err := io.Copy(buf, file) + if err != nil { + return nil, err + } + + hash := blake3.Sum512(buf.Bytes()) + hashStr, err := encoding.NewMultihash(hash[:]).ToBase64Url() + if err != nil { + return nil, err + } + + buf.Reset() + + resp, err := s.httpApi.R(). + SetPathParam("path", hashStr). + SetFormData(map[string]string{ + "bucket": bucket, + }). + SetBody(buf).Put("/api/worker/{path}") + if err != nil { + return nil, err + } + + if resp.IsError() { + return nil, resp.Error().(error) + } + + return hash[:], nil +}