diff --git a/Makefile b/Makefile index ec2f376a3..72499e90f 100644 --- a/Makefile +++ b/Makefile @@ -301,7 +301,7 @@ sh-testnet: mod-tidy dwn: @echo "(dwn) Building dwn.wasm -> IPFS Vault" - GOOS=js GOARCH=wasm go build -o ./x/vault/internal/app.wasm ./x/vault/client/htmx/dwn.go + GOOS=js GOARCH=wasm go build -o ./x/vault/types/internal/app.wasm ./x/vault/client/dwn/dwn.go templ: @echo "(templ) Generating templ files" diff --git a/api/vault/v1/genesis.pulsar.go b/api/vault/v1/genesis.pulsar.go index 867b1c3e6..5f510b9e8 100644 --- a/api/vault/v1/genesis.pulsar.go +++ b/api/vault/v1/genesis.pulsar.go @@ -810,7 +810,7 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { copy(dAtA[i:], encoded) i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x22 } if x.LocalRegistrationEnabled { i-- @@ -921,7 +921,7 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { } } x.LocalRegistrationEnabled = bool(v != 0) - case 3: + case 4: if wireType != 2 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Schema", wireType) } @@ -2030,7 +2030,7 @@ type Params struct { IpfsActive bool `protobuf:"varint,1,opt,name=ipfs_active,json=ipfsActive,proto3" json:"ipfs_active,omitempty"` LocalRegistrationEnabled bool `protobuf:"varint,2,opt,name=local_registration_enabled,json=localRegistrationEnabled,proto3" json:"local_registration_enabled,omitempty"` - Schema *Schema `protobuf:"bytes,3,opt,name=schema,proto3" json:"schema,omitempty"` + Schema *Schema `protobuf:"bytes,4,opt,name=schema,proto3" json:"schema,omitempty"` } func (x *Params) Reset() { @@ -2200,7 +2200,7 @@ var file_vault_v1_genesis_proto_rawDesc = []byte{ 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x3a, 0x19, 0x98, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x0c, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x84, 0x02, 0x0a, 0x06, 0x53, diff --git a/app/proxy/command.go b/app/proxy/command.go deleted file mode 100644 index f62e80eb3..000000000 --- a/app/proxy/command.go +++ /dev/null @@ -1,22 +0,0 @@ -package proxy - -import ( - "github.com/spf13/cobra" -) - -func NewProxyCmd() *cobra.Command { - return &cobra.Command{ - Use: "dwn-proxy", - Short: "Starts the DWN proxy server for the local IPFS node", - RunE: func(cmd *cobra.Command, args []string) error { - // Load config - // c, err := LoadConfig(".") - // if err != nil { - // return err - // } - // log.Printf("Config: %+v", c) - startServer() - return nil - }, - } -} diff --git a/app/proxy/config.go b/app/proxy/config.go deleted file mode 100644 index c895f0fa9..000000000 --- a/app/proxy/config.go +++ /dev/null @@ -1,28 +0,0 @@ -package proxy - -import "github.com/spf13/viper" - -type Config struct { - Host string `mapstructure:"HOST"` - Port string `mapstructure:"PORT"` -} - -func (c *Config) GetHostname() string { - return c.Host + ":" + c.Port -} - -func LoadConfig(path string) (config Config, err error) { - viper.AddConfigPath(path) - viper.SetConfigName("app") - viper.SetConfigType("env") - - viper.AutomaticEnv() - - err = viper.ReadInConfig() - if err != nil { - return - } - - err = viper.Unmarshal(&config) - return -} diff --git a/app/proxy/proxycmd.go b/app/proxy/proxycmd.go new file mode 100644 index 000000000..739627e53 --- /dev/null +++ b/app/proxy/proxycmd.go @@ -0,0 +1,52 @@ +package proxy + +import ( + "context" + "net/http" + "os" + "os/signal" + "time" + + "github.com/labstack/echo/v4" + "github.com/labstack/gommon/log" + "github.com/onsonr/sonr/nebula" + "github.com/onsonr/sonr/nebula/pages" + "github.com/spf13/cobra" +) + +func NewProxyCmd() *cobra.Command { + return &cobra.Command{ + Use: "dwn-proxy", + Short: "Starts the DWN proxy server for the local IPFS node", + Run: func(cmd *cobra.Command, args []string) { + // Echo instance + e := echo.New() + e.Logger.SetLevel(log.INFO) + + // Configure the server + nebula.UseAssets(e) + e.GET("/", pages.Home) + e.GET("/allocate", pages.Profile) + + // Start server + ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) + defer stop() + // Start server + go func() { + if err := e.Start(":1323"); err != nil && err != http.ErrServerClosed { + e.Logger.Fatal("shutting down the server") + } + }() + + // Wait for interrupt signal to gracefully shutdown the server with a timeout of 10 seconds. + <-ctx.Done() + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + // Shutdown the server with 10 seconds timeout. + if err := e.Shutdown(ctx); err != nil { + e.Logger.Fatal(err) + } + }, + } +} diff --git a/app/proxy/server.go b/app/proxy/server.go deleted file mode 100644 index f6d503707..000000000 --- a/app/proxy/server.go +++ /dev/null @@ -1,45 +0,0 @@ -package proxy - -import ( - "context" - "net/http" - "os" - "os/signal" - "time" - - "github.com/labstack/echo/v4" - "github.com/labstack/gommon/log" - "github.com/onsonr/sonr/nebula" - "github.com/onsonr/sonr/nebula/pages" -) - -func startServer() { - // Echo instance - e := echo.New() - e.Logger.SetLevel(log.INFO) - - // Configure the server - nebula.UseAssets(e) - e.GET("/", pages.Home) - e.GET("/allocate", pages.Profile) - - // Start server - ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) - defer stop() - // Start server - go func() { - if err := e.Start(":1323"); err != nil && err != http.ErrServerClosed { - e.Logger.Fatal("shutting down the server") - } - }() - - // Wait for interrupt signal to gracefully shutdown the server with a timeout of 10 seconds. - <-ctx.Done() - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - // Shutdown the server with 10 seconds timeout. - if err := e.Shutdown(ctx); err != nil { - e.Logger.Fatal(err) - } -} diff --git a/nebula/bun.lockb b/nebula/bun.lockb index fec077aac..784492aec 100755 Binary files a/nebula/bun.lockb and b/nebula/bun.lockb differ diff --git a/nebula/package.json b/nebula/package.json index ab5bccc4b..d8282e991 100644 --- a/nebula/package.json +++ b/nebula/package.json @@ -13,6 +13,7 @@ "typescript": "^4.9.0" }, "dependencies": { + "@tailwindcss/typography": "^0.5.15", "alpinejs": "^3.14.1", "htmx.org": "^1.9.12", "node-fetch": "^3.3.2" diff --git a/nebula/tailwind.config.js b/nebula/tailwind.config.js index 823bff033..6fed7693e 100644 --- a/nebula/tailwind.config.js +++ b/nebula/tailwind.config.js @@ -1,12 +1,12 @@ // tailwind.config.js module.exports = { - content: [ - "./blocks/**/*.{templ,html}", - "./pages/**/*.{templ,html}", - "./src/**/*.ts", - ], - theme: { - extend: {}, - }, - plugins: [], + content: [ + "./blocks/**/*.{templ,html}", + "./pages/**/*.{templ,html}", + "./src/**/*.ts", + ], + theme: { + extend: {}, + }, + plugins: [require("@tailwindcss/typography")], }; diff --git a/proto/vault/v1/genesis.proto b/proto/vault/v1/genesis.proto index 350ba1c73..8b857091b 100644 --- a/proto/vault/v1/genesis.proto +++ b/proto/vault/v1/genesis.proto @@ -20,7 +20,7 @@ message Params { bool ipfs_active = 1; bool local_registration_enabled = 2; - Schema schema = 3; + Schema schema = 4; } message Schema { diff --git a/x/did/keeper/controller.go b/x/did/keeper/controller.go deleted file mode 100644 index 20f1a3763..000000000 --- a/x/did/keeper/controller.go +++ /dev/null @@ -1,27 +0,0 @@ -package keeper - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/onsonr/crypto/mpc" - "github.com/onsonr/sonr/x/did/types" -) - -func (k Keeper) NewController(ctx sdk.Context) (uint64, types.ControllerI, error) { - shares, err := mpc.GenerateKeyshares() - if err != nil { - return 0, nil, err - } - controller, err := types.NewController(shares) - if err != nil { - return 0, nil, err - } - entry, err := controller.GetTableEntry() - if err != nil { - return 0, nil, err - } - num, err := k.OrmDB.ControllerTable().InsertReturningNumber(ctx, entry) - if err != nil { - return 0, nil, err - } - return num, controller, nil -} diff --git a/x/did/keeper/keeper.go b/x/did/keeper/keeper.go index 86523a2ad..a816d939a 100644 --- a/x/did/keeper/keeper.go +++ b/x/did/keeper/keeper.go @@ -1,18 +1,24 @@ package keeper import ( + "crypto/sha256" + "fmt" + "cosmossdk.io/collections" storetypes "cosmossdk.io/core/store" "cosmossdk.io/log" "cosmossdk.io/orm/model/ormdb" nftkeeper "cosmossdk.io/x/nft/keeper" "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "gopkg.in/macaroon.v2" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" stakkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + "github.com/onsonr/crypto/mpc" apiv1 "github.com/onsonr/sonr/api/did/v1" "github.com/onsonr/sonr/x/did/types" ) @@ -86,3 +92,43 @@ func NewKeeper( k.Schema = schema return k } + +func (k Keeper) NewController(ctx sdk.Context) (uint64, types.ControllerI, error) { + shares, err := mpc.GenerateKeyshares() + if err != nil { + return 0, nil, err + } + controller, err := types.NewController(shares) + if err != nil { + return 0, nil, err + } + entry, err := controller.GetTableEntry() + if err != nil { + return 0, nil, err + } + num, err := k.OrmDB.ControllerTable().InsertReturningNumber(ctx, entry) + if err != nil { + return 0, nil, err + } + return num, controller, nil +} + +// IssueMacaroon creates a macaroon with the specified parameters. +func (k Keeper) IssueMacaroon(ctx sdk.Context, sharedMPCPubKey, location, id string, blockExpiry uint64) (*macaroon.Macaroon, error) { + // Derive the root key by hashing the shared MPC public key + rootKey := sha256.Sum256([]byte(sharedMPCPubKey)) + // Create the macaroon + m, err := macaroon.New(rootKey[:], []byte(id), location, macaroon.LatestVersion) + if err != nil { + return nil, err + } + + // Add the block expiry caveat + caveat := fmt.Sprintf("block-expiry=%d", blockExpiry) + err = m.AddFirstPartyCaveat([]byte(caveat)) + if err != nil { + return nil, err + } + + return m, nil +} diff --git a/x/did/keeper/macaroon.go b/x/did/keeper/macaroon.go deleted file mode 100644 index b2bb9dd75..000000000 --- a/x/did/keeper/macaroon.go +++ /dev/null @@ -1,29 +0,0 @@ -package keeper - -import ( - "crypto/sha256" - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" - "gopkg.in/macaroon.v2" -) - -// IssueMacaroon creates a macaroon with the specified parameters. -func (k Keeper) IssueMacaroon(ctx sdk.Context, sharedMPCPubKey, location, id string, blockExpiry uint64) (*macaroon.Macaroon, error) { - // Derive the root key by hashing the shared MPC public key - rootKey := sha256.Sum256([]byte(sharedMPCPubKey)) - // Create the macaroon - m, err := macaroon.New(rootKey[:], []byte(id), location, macaroon.LatestVersion) - if err != nil { - return nil, err - } - - // Add the block expiry caveat - caveat := fmt.Sprintf("block-expiry=%d", blockExpiry) - err = m.AddFirstPartyCaveat([]byte(caveat)) - if err != nil { - return nil, err - } - - return m, nil -} diff --git a/x/did/keeper/server.go b/x/did/keeper/rpc.go similarity index 100% rename from x/did/keeper/server.go rename to x/did/keeper/rpc.go diff --git a/x/vault/client/htmx/dwn.go b/x/vault/client/dwn/dwn.go similarity index 83% rename from x/vault/client/htmx/dwn.go rename to x/vault/client/dwn/dwn.go index a7cde6a41..26460ab1c 100644 --- a/x/vault/client/htmx/dwn.go +++ b/x/vault/client/dwn/dwn.go @@ -15,20 +15,35 @@ import ( "github.com/labstack/echo/v4" promise "github.com/nlepage/go-js-promise" "github.com/onsonr/sonr/nebula/pages" - "github.com/onsonr/sonr/x/vault/client/htmx/middleware" - "github.com/onsonr/sonr/x/vault/client/htmx/state" + "github.com/onsonr/sonr/x/vault/client/dwn/middleware" + "github.com/onsonr/sonr/x/vault/client/dwn/state" ) func main() { e := echo.New() e.Use(middleware.UseSession) + registerViews(e) + registerState(e) + Serve(e) +} + +func registerState(e *echo.Echo) { + g := e.Group("state") + g.POST("/login/:identifier", state.HandleCredentialAssertion) + // g.GET("/discovery", state.GetDiscovery) + g.GET("/jwks", state.GetJWKS) + g.GET("/token", state.GetToken) + g.POST("/:origin/grant/:subject", state.GrantAuthorization) + g.POST("/register/:subject", state.HandleCredentialCreation) + g.POST("/register/:subject/check", state.CheckSubjectIsValid) +} + +func registerViews(e *echo.Echo) { e.GET("/home", pages.Home) e.GET("/login", pages.Login) e.GET("/register", pages.Register) e.GET("/profile", pages.Profile) e.GET("/authorize", pages.Authorize) - state.RegisterHandlers(e) - Serve(e) } // Serve serves HTTP requests using handler or http.DefaultServeMux if handler is nil. diff --git a/x/vault/client/htmx/middleware/headers.go b/x/vault/client/dwn/middleware/headers.go similarity index 100% rename from x/vault/client/htmx/middleware/headers.go rename to x/vault/client/dwn/middleware/headers.go diff --git a/x/vault/client/htmx/middleware/middleware.go b/x/vault/client/dwn/middleware/middleware.go similarity index 100% rename from x/vault/client/htmx/middleware/middleware.go rename to x/vault/client/dwn/middleware/middleware.go diff --git a/x/vault/client/htmx/middleware/session.go b/x/vault/client/dwn/middleware/session.go similarity index 100% rename from x/vault/client/htmx/middleware/session.go rename to x/vault/client/dwn/middleware/session.go diff --git a/x/vault/client/htmx/middleware/token.go b/x/vault/client/dwn/middleware/token.go similarity index 100% rename from x/vault/client/htmx/middleware/token.go rename to x/vault/client/dwn/middleware/token.go diff --git a/x/vault/client/htmx/state/auth.go b/x/vault/client/dwn/state/auth.go similarity index 86% rename from x/vault/client/htmx/state/auth.go rename to x/vault/client/dwn/state/auth.go index 6aa053b12..8765d4c5a 100644 --- a/x/vault/client/htmx/state/auth.go +++ b/x/vault/client/dwn/state/auth.go @@ -8,16 +8,16 @@ import ( "github.com/labstack/echo/v4" ) -func checkSubjectIsValid(e echo.Context) error { +func CheckSubjectIsValid(e echo.Context) error { credentialID := e.FormValue("credentialID") return e.JSON(200, credentialID) } -func handleCredentialAssertion(e echo.Context) error { +func HandleCredentialAssertion(e echo.Context) error { return e.JSON(200, "HandleCredentialAssertion") } -func handleCredentialCreation(e echo.Context) error { +func HandleCredentialCreation(e echo.Context) error { // Get the serialized credential data from the form credentialDataJSON := e.FormValue("credentialData") diff --git a/x/vault/client/htmx/state/manifest.go b/x/vault/client/dwn/state/manifest.go similarity index 100% rename from x/vault/client/htmx/state/manifest.go rename to x/vault/client/dwn/state/manifest.go diff --git a/x/vault/client/htmx/state/openid.go b/x/vault/client/dwn/state/openid.go similarity index 73% rename from x/vault/client/htmx/state/openid.go rename to x/vault/client/dwn/state/openid.go index 941c3d1a3..1797220f6 100644 --- a/x/vault/client/htmx/state/openid.go +++ b/x/vault/client/dwn/state/openid.go @@ -4,19 +4,19 @@ import ( "github.com/labstack/echo/v4" ) -func grantAuthorization(e echo.Context) error { +func GrantAuthorization(e echo.Context) error { // Implement authorization endpoint using passkey authentication // Store session data in cache return nil } -func getJWKS(e echo.Context) error { +func GetJWKS(e echo.Context) error { // Implement token endpoint // Use cached session data for validation return nil } -func getToken(e echo.Context) error { +func GetToken(e echo.Context) error { // Implement token endpoint // Use cached session data for validation return nil diff --git a/x/vault/client/htmx/state/wellknown.go b/x/vault/client/dwn/state/wellknown.go similarity index 100% rename from x/vault/client/htmx/state/wellknown.go rename to x/vault/client/dwn/state/wellknown.go diff --git a/x/vault/client/htmx/state/routes.go b/x/vault/client/htmx/state/routes.go deleted file mode 100644 index a653024c2..000000000 --- a/x/vault/client/htmx/state/routes.go +++ /dev/null @@ -1,16 +0,0 @@ -package state - -import ( - "github.com/labstack/echo/v4" -) - -func RegisterHandlers(e *echo.Echo) { - g := e.Group("state") - g.POST("/login/:identifier", handleCredentialAssertion) - // g.GET("/discovery", state.GetDiscovery) - g.GET("/jwks", getJWKS) - g.GET("/token", getToken) - g.POST("/:origin/grant/:subject", grantAuthorization) - g.POST("/register/:subject", handleCredentialCreation) - g.POST("/register/:subject/check", checkSubjectIsValid) -} diff --git a/x/vault/client/htmx/state/views.go b/x/vault/client/htmx/state/views.go deleted file mode 100644 index 7bf2df5b4..000000000 --- a/x/vault/client/htmx/state/views.go +++ /dev/null @@ -1 +0,0 @@ -package state diff --git a/x/vault/keeper/assembly.go b/x/vault/keeper/assembly.go deleted file mode 100644 index 7ce5a893f..000000000 --- a/x/vault/keeper/assembly.go +++ /dev/null @@ -1,59 +0,0 @@ -package keeper - -import ( - "context" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/onsonr/sonr/config/dwn" - vault "github.com/onsonr/sonr/x/vault/internal" - "github.com/onsonr/sonr/x/vault/types" -) - -// AssembleVault assembles the initial vault -func (k Keeper) AssembleVault(ctx sdk.Context, subject string, origin string) (string, int64, error) { - _, con, err := k.DIDKeeper.NewController(ctx) - if err != nil { - return "", 0, err - } - usrKs, err := con.ExportUserKs() - if err != nil { - return "", 0, err - } - sch, err := k.CurrentSchema(ctx) - if err != nil { - return "", 0, err - } - cnfg := vault.NewConfig(usrKs, con.SonrAddress(), con.ChainID(), sch) - - v, err := types.NewVault(cnfg, "sonr-testnet") - if err != nil { - return "", 0, err - } - cid, err := k.ipfsClient.Unixfs().Add(context.Background(), v.FS) - if err != nil { - return "", 0, err - } - return cid.String(), k.CalculateExpiration(ctx, time.Second*15), nil -} - -// CurrentSchema returns the current schema -func (k Keeper) CurrentSchema(ctx sdk.Context) (*dwn.Schema, error) { - p, err := k.Params.Get(ctx) - if err != nil { - return nil, err - } - schema := p.Schema - return &dwn.Schema{ - Version: int(schema.Version), - Account: schema.Account, - Asset: schema.Asset, - Chain: schema.Chain, - Credential: schema.Credential, - Jwk: schema.Jwk, - Grant: schema.Grant, - Keyshare: schema.Keyshare, - PublicKey: schema.PublicKey, - Profile: schema.Profile, - }, nil -} diff --git a/x/vault/keeper/genesis.go b/x/vault/keeper/genesis.go new file mode 100644 index 000000000..a0b681e2c --- /dev/null +++ b/x/vault/keeper/genesis.go @@ -0,0 +1,81 @@ +package keeper + +import ( + "context" + "time" + + "cosmossdk.io/log" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ipfs/boxo/path" + "github.com/ipfs/kubo/client/rpc" + "github.com/onsonr/sonr/x/vault/types" +) + +func (k Keeper) Logger() log.Logger { + return k.logger +} + +// InitGenesis initializes the module's state from a genesis state. +func (k *Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) error { + // this line is used by starport scaffolding # genesis/module/init + if err := data.Params.Validate(); err != nil { + return err + } + + return k.Params.Set(ctx, data.Params) +} + +// ExportGenesis exports the module's state to a genesis state. +func (k *Keeper) ExportGenesis(ctx context.Context) *types.GenesisState { + params, err := k.Params.Get(ctx) + if err != nil { + panic(err) + } + + // this line is used by starport scaffolding # genesis/module/export + + return &types.GenesisState{ + Params: params, + } +} + +// IPFSConnected returns true if the IPFS client is initialized +func (c Keeper) IPFSConnected() bool { + if c.ipfsClient == nil { + ipfsClient, err := rpc.NewLocalApi() + if err != nil { + return false + } + c.ipfsClient = ipfsClient + } + return c.ipfsClient != nil +} + +// CalculateExpiration calculates the expiration time for a vault +func (k Keeper) CalculateExpiration(c sdk.Context, duration time.Duration) int64 { + blockTime := c.BlockTime() + avgBlockTime := float64(blockTime.Sub(blockTime).Seconds()) + return int64(duration.Seconds() / avgBlockTime) +} + +// HasPathInIPFS checks if a file is in the local IPFS node +func (k Keeper) HasPathInIPFS(ctx sdk.Context, cid string) (bool, error) { + path, err := path.NewPath(cid) + if err != nil { + return false, err + } + v, err := k.ipfsClient.Unixfs().Get(ctx, path) + if err != nil { + return false, err + } + + if v == nil { + return false, nil + } + return true, nil +} + +// validateSubjectOrigin checks if the subject and origin are valid +func (k Keeper) validateSubjectOrigin(ctx sdk.Context, subject string, origin string) error { + return nil +} diff --git a/x/vault/keeper/keeper.go b/x/vault/keeper/keeper.go index 0771a06d4..5c47e327e 100644 --- a/x/vault/keeper/keeper.go +++ b/x/vault/keeper/keeper.go @@ -15,9 +15,9 @@ import ( "cosmossdk.io/log" "cosmossdk.io/orm/model/ormdb" - "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/client/rpc" apiv1 "github.com/onsonr/sonr/api/vault/v1" + "github.com/onsonr/sonr/config/dwn" "github.com/onsonr/sonr/x/vault/types" @@ -89,66 +89,48 @@ func NewKeeper( return k } -func (k Keeper) Logger() log.Logger { - return k.logger -} - -// InitGenesis initializes the module's state from a genesis state. -func (k *Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) error { - // this line is used by starport scaffolding # genesis/module/init - if err := data.Params.Validate(); err != nil { - return err - } - - return k.Params.Set(ctx, data.Params) -} - -// ExportGenesis exports the module's state to a genesis state. -func (k *Keeper) ExportGenesis(ctx context.Context) *types.GenesisState { - params, err := k.Params.Get(ctx) +// currentSchema returns the current schema +func (k Keeper) CurrentSchema(ctx sdk.Context) (*dwn.Schema, error) { + p, err := k.Params.Get(ctx) if err != nil { - panic(err) - } - - // this line is used by starport scaffolding # genesis/module/export - - return &types.GenesisState{ - Params: params, + return nil, err } + schema := p.Schema + return &dwn.Schema{ + Version: int(schema.Version), + Account: schema.Account, + Asset: schema.Asset, + Chain: schema.Chain, + Credential: schema.Credential, + Jwk: schema.Jwk, + Grant: schema.Grant, + Keyshare: schema.Keyshare, + PublicKey: schema.PublicKey, + Profile: schema.Profile, + }, nil } -// IPFSConnected returns true if the IPFS client is initialized -func (c Keeper) IPFSConnected() bool { - if c.ipfsClient == nil { - ipfsClient, err := rpc.NewLocalApi() - if err != nil { - return false - } - c.ipfsClient = ipfsClient - } - return c.ipfsClient != nil -} - -// CalculateExpiration calculates the expiration time for a vault -func (k Keeper) CalculateExpiration(c sdk.Context, duration time.Duration) int64 { - blockTime := c.BlockTime() - avgBlockTime := float64(blockTime.Sub(blockTime).Seconds()) - return int64(duration.Seconds() / avgBlockTime) -} - -// HasPathInIPFS checks if a file is in the local IPFS node -func (k Keeper) HasPathInIPFS(ctx sdk.Context, cid string) (bool, error) { - path, err := path.NewPath(cid) +// assembleVault assembles the initial vault +func (k Keeper) AssembleVault(ctx sdk.Context) (string, int64, error) { + _, con, err := k.DIDKeeper.NewController(ctx) if err != nil { - return false, err + return "", 0, err } - v, err := k.ipfsClient.Unixfs().Get(ctx, path) + usrKs, err := con.ExportUserKs() if err != nil { - return false, err + return "", 0, err } - - if v == nil { - return false, nil + sch, err := k.CurrentSchema(ctx) + if err != nil { + return "", 0, err } - return true, nil + v, err := types.NewVault(usrKs, con.SonrAddress(), con.ChainID(), sch) + if err != nil { + return "", 0, err + } + cid, err := k.ipfsClient.Unixfs().Add(context.Background(), v.FS) + if err != nil { + return "", 0, err + } + return cid.String(), k.CalculateExpiration(ctx, time.Second*15), nil } diff --git a/x/vault/keeper/server.go b/x/vault/keeper/rpc.go similarity index 91% rename from x/vault/keeper/server.go rename to x/vault/keeper/rpc.go index 33c159263..8a739158a 100644 --- a/x/vault/keeper/server.go +++ b/x/vault/keeper/rpc.go @@ -34,8 +34,8 @@ func (ms msgServer) AllocateVault(goCtx context.Context, msg *types.MsgAllocateV // 1.Check if the service origin is valid ctx := sdk.UnwrapSDKContext(goCtx) - // 2.Allocate the vault - cid, expiryBlock, err := ms.k.AssembleVault(ctx, msg.GetSubject(), msg.GetOrigin()) + // 2.Allocate the vault msg.GetSubject(), msg.GetOrigin() + cid, expiryBlock, err := ms.k.AssembleVault(ctx) if err != nil { return nil, err } diff --git a/x/vault/types/genesis.pb.go b/x/vault/types/genesis.pb.go index 47a8c8042..7c51bc420 100644 --- a/x/vault/types/genesis.pb.go +++ b/x/vault/types/genesis.pb.go @@ -74,7 +74,7 @@ func (m *GenesisState) GetParams() Params { type Params struct { IpfsActive bool `protobuf:"varint,1,opt,name=ipfs_active,json=ipfsActive,proto3" json:"ipfs_active,omitempty"` LocalRegistrationEnabled bool `protobuf:"varint,2,opt,name=local_registration_enabled,json=localRegistrationEnabled,proto3" json:"local_registration_enabled,omitempty"` - Schema *Schema `protobuf:"bytes,3,opt,name=schema,proto3" json:"schema,omitempty"` + Schema *Schema `protobuf:"bytes,4,opt,name=schema,proto3" json:"schema,omitempty"` } func (m *Params) Reset() { *m = Params{} } @@ -270,11 +270,11 @@ var fileDescriptor_4c971b352fb6cc17 = []byte{ 0xfa, 0xd2, 0x8d, 0x85, 0xf4, 0xaa, 0x41, 0xfa, 0xbe, 0x5f, 0x40, 0x8b, 0x5e, 0x12, 0x61, 0x2f, 0x60, 0x58, 0x19, 0x29, 0xaa, 0xb1, 0xc5, 0x52, 0x39, 0x6f, 0x85, 0x57, 0x46, 0x8f, 0x51, 0x8b, 0x49, 0x85, 0x17, 0x7c, 0x8b, 0xf2, 0x9c, 0x12, 0xc5, 0x46, 0xe0, 0x55, 0xf0, 0xd9, 0x31, 0x24, - 0x4e, 0x4e, 0x71, 0x26, 0xf8, 0xf6, 0xdd, 0x66, 0xe7, 0xc4, 0x8b, 0xce, 0x7f, 0xfe, 0xe0, 0xeb, + 0x4e, 0x4e, 0x71, 0x26, 0xf8, 0xce, 0xdd, 0x66, 0xe7, 0xc4, 0x8b, 0xce, 0x7f, 0xfe, 0xe0, 0xeb, 0xf5, 0x28, 0xfa, 0x73, 0x3d, 0x8a, 0x3f, 0xff, 0xfe, 0xfe, 0x64, 0x3f, 0xbc, 0x55, 0x57, 0xf7, 0xd3, 0x16, 0x24, 0x21, 0xcd, 0x38, 0xec, 0x36, 0x68, 0x9d, 0x32, 0x9a, 0xaa, 0xf6, 0x8a, 0xb5, 0x6c, 0x1d, 0x21, 0xa5, 0x99, 0x6b, 0x4f, 0xa5, 0x06, 0xc5, 0x5a, 0xb2, 0x43, 0xe8, 0x09, 0xe7, - 0xd0, 0x53, 0x85, 0x41, 0x11, 0x44, 0x4b, 0xe5, 0x54, 0x28, 0xcd, 0x77, 0x02, 0x25, 0xc1, 0x52, + 0xd0, 0xf3, 0x6d, 0xe2, 0x41, 0xb4, 0x54, 0x4e, 0x85, 0xd2, 0x54, 0x6c, 0x50, 0x04, 0xc1, 0x52, 0x00, 0x69, 0xf1, 0x02, 0xb5, 0x57, 0xa2, 0xe2, 0x3d, 0xb2, 0x36, 0x08, 0x3b, 0x80, 0xed, 0xf7, 0x1f, 0xae, 0x78, 0x42, 0x46, 0x3b, 0xb6, 0x7b, 0x4a, 0x2b, 0xb4, 0xe7, 0xbb, 0x61, 0x0f, 0x09, 0x36, 0x84, 0xfe, 0x15, 0x2e, 0xdc, 0x54, 0x58, 0xe4, 0x7d, 0x32, 0xfe, 0x69, 0xf6, 0x10, 0x06, @@ -283,7 +283,7 @@ var fileDescriptor_4c971b352fb6cc17 = []byte{ 0xaf, 0x65, 0x1a, 0x7f, 0x59, 0xa5, 0xd1, 0xed, 0x2a, 0x8d, 0x7e, 0xac, 0xd2, 0xe8, 0xdd, 0xe3, 0x52, 0xf9, 0xe9, 0x7c, 0x92, 0x49, 0x33, 0xcb, 0x8d, 0x76, 0x46, 0xdb, 0x9c, 0x8e, 0x8f, 0x79, 0x78, 0x47, 0xbf, 0xa8, 0xd1, 0x4d, 0x12, 0xfa, 0x79, 0x9e, 0xfd, 0x0d, 0x00, 0x00, 0xff, 0xff, - 0xed, 0xdc, 0x3c, 0x7d, 0x89, 0x02, 0x00, 0x00, + 0x57, 0x11, 0x84, 0xf3, 0x89, 0x02, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { @@ -379,7 +379,7 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a + dAtA[i] = 0x22 } if m.LocalRegistrationEnabled { i-- @@ -742,7 +742,7 @@ func (m *Params) Unmarshal(dAtA []byte) error { } } m.LocalRegistrationEnabled = bool(v != 0) - case 3: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Schema", wireType) } diff --git a/x/vault/internal/app.wasm b/x/vault/types/internal/app.wasm similarity index 56% rename from x/vault/internal/app.wasm rename to x/vault/types/internal/app.wasm index 09f3eb496..41fbf6c4e 100755 Binary files a/x/vault/internal/app.wasm and b/x/vault/types/internal/app.wasm differ diff --git a/x/vault/internal/embed.go b/x/vault/types/internal/embed.go similarity index 64% rename from x/vault/internal/embed.go rename to x/vault/types/internal/embed.go index ebc58e3fe..d458ec105 100644 --- a/x/vault/internal/embed.go +++ b/x/vault/types/internal/embed.go @@ -26,17 +26,6 @@ var ( swJSFile = files.NewBytesFile(swJSData) ) -// NewConfig uses the config template to generate the dwn config file -func NewConfig(keyshareJSON string, adddress string, chainID string, schema *dwn.Schema) *dwn.Config { - dwnCfg := &dwn.Config{ - Motr: createMotrConfig(keyshareJSON, adddress, "sonr.id"), - Ipfs: defaultIPFSConfig(), - Sonr: defaultSonrConfig(chainID), - Schema: schema, - } - return dwnCfg -} - // NewVaultDirectory creates a new directory with the default files func NewVaultDirectory(cnfg *dwn.Config) (files.Node, error) { dwnJSON, err := json.Marshal(cnfg) @@ -86,28 +75,3 @@ func MarshalConfigFile(c *dwn.Config) (files.Node, error) { } return files.NewBytesFile(dwnConfigData), nil } - -func createMotrConfig(keyshareJSON string, adddress string, origin string) *dwn.Motr { - return &dwn.Motr{ - Keyshare: keyshareJSON, - Address: adddress, - Origin: origin, - } -} - -func defaultIPFSConfig() *dwn.IPFS { - return &dwn.IPFS{ - ApiUrl: "https://api.sonr-ipfs.land", - GatewayUrl: "https://ipfs.sonr.land", - } -} - -func defaultSonrConfig(chainID string) *dwn.Sonr { - return &dwn.Sonr{ - ApiUrl: "https://api.sonr.land", - GrpcUrl: "https://grpc.sonr.land", - RpcUrl: "https://rpc.sonr.land", - WebSocketUrl: "wss://rpc.sonr.land/ws", - ChainId: chainID, - } -} diff --git a/x/vault/internal/index.templ b/x/vault/types/internal/index.templ similarity index 100% rename from x/vault/internal/index.templ rename to x/vault/types/internal/index.templ diff --git a/x/vault/internal/index_templ.go b/x/vault/types/internal/index_templ.go similarity index 100% rename from x/vault/internal/index_templ.go rename to x/vault/types/internal/index_templ.go diff --git a/x/vault/internal/motr.mjs b/x/vault/types/internal/motr.mjs similarity index 100% rename from x/vault/internal/motr.mjs rename to x/vault/types/internal/motr.mjs diff --git a/x/vault/internal/sw.js b/x/vault/types/internal/sw.js similarity index 100% rename from x/vault/internal/sw.js rename to x/vault/types/internal/sw.js diff --git a/x/vault/types/vault.go b/x/vault/types/vault.go index ded1a50c4..e49028f10 100644 --- a/x/vault/types/vault.go +++ b/x/vault/types/vault.go @@ -4,15 +4,21 @@ import ( "github.com/ipfs/boxo/files" "github.com/onsonr/sonr/config/dwn" - vault "github.com/onsonr/sonr/x/vault/internal" + vault "github.com/onsonr/sonr/x/vault/types/internal" ) type Vault struct { FS files.Node } -func NewVault(cnfg *dwn.Config, chainID string) (*Vault, error) { - fileMap, err := vault.NewVaultDirectory(cnfg) +func NewVault(keyshareJSON string, adddress string, chainID string, schema *dwn.Schema) (*Vault, error) { + dwnCfg := &dwn.Config{ + Motr: createMotrConfig(keyshareJSON, adddress, "sonr.id"), + Ipfs: defaultIPFSConfig(), + Sonr: defaultSonrConfig(chainID), + Schema: schema, + } + fileMap, err := vault.NewVaultDirectory(dwnCfg) if err != nil { return nil, err } @@ -20,3 +26,28 @@ func NewVault(cnfg *dwn.Config, chainID string) (*Vault, error) { FS: fileMap, }, nil } + +func createMotrConfig(keyshareJSON string, adddress string, origin string) *dwn.Motr { + return &dwn.Motr{ + Keyshare: keyshareJSON, + Address: adddress, + Origin: origin, + } +} + +func defaultIPFSConfig() *dwn.IPFS { + return &dwn.IPFS{ + ApiUrl: "https://api.sonr-ipfs.land", + GatewayUrl: "https://ipfs.sonr.land", + } +} + +func defaultSonrConfig(chainID string) *dwn.Sonr { + return &dwn.Sonr{ + ApiUrl: "https://api.sonr.land", + GrpcUrl: "https://grpc.sonr.land", + RpcUrl: "https://rpc.sonr.land", + WebSocketUrl: "wss://rpc.sonr.land/ws", + ChainId: chainID, + } +}