From 1051ba8b914b3dc2923047d21d0bac8635415fd2 Mon Sep 17 00:00:00 2001 From: Raghav Sood Date: Sun, 8 Feb 2026 19:52:48 +0800 Subject: [PATCH 1/3] refactor: remove PluginID custom type, use plain string Drop the PluginID custom type from the public types package and replace all usages with plain string throughout the codebase. Plugin ID constants (fees, recurring-sends) are moved to internal/types/registry.go. PluginVultisigPayroll_0000 is removed entirely; tests now use PluginVultisigRecurringSends. Co-Authored-By: Claude (claude-opus-4-6) --- internal/api/fee.go | 8 ++-- internal/api/plugin.go | 36 ++++++++--------- internal/api/policy.go | 12 +++--- internal/api/server.go | 13 +++--- internal/fee_manager/fees.go | 8 ++-- internal/portal/images.go | 33 ++++++++-------- internal/service/auth_test.go | 48 +++++++++++------------ internal/service/plugin.go | 13 +++--- internal/service/policy.go | 18 ++++----- internal/service/report.go | 21 +++++----- internal/storage/db.go | 44 ++++++++++----------- internal/storage/postgres/db_test.go | 8 ++-- internal/storage/postgres/fees.go | 2 +- internal/storage/postgres/plugin.go | 14 +++---- internal/storage/postgres/plugin_image.go | 36 +++++++---------- internal/storage/postgres/plugin_owner.go | 13 +++--- internal/storage/postgres/policy.go | 14 +++---- internal/storage/postgres/pricing.go | 5 +-- internal/storage/postgres/reports.go | 23 ++++++----- internal/syncer/safety.go | 3 +- internal/syncer/sync.go | 13 +++--- internal/tx_indexer/indexer.go | 5 ++- internal/types/api_key.go | 4 +- internal/types/plugin.go | 4 +- internal/types/plugin_image.go | 5 +-- internal/types/plugin_owner.go | 4 +- internal/types/policy_sync.go | 3 +- internal/types/registry.go | 11 ++++++ internal/types/report.go | 8 ++-- internal/types/transaction.go | 10 ++--- plugin/policy/policy_pg/repo.go | 2 +- plugin/policy/service.go | 4 +- plugin/policy/storage.go | 2 +- plugin/server/server.go | 2 +- plugin/tx_indexer/pkg/storage/postgres.go | 5 +-- plugin/tx_indexer/pkg/storage/types.go | 9 ++--- plugin/tx_indexer/service.go | 3 +- plugin/tx_indexer/worker_test.go | 2 +- scripts/migrate-images/main.go | 7 ++-- types/keysign.go | 2 +- types/policy.go | 2 +- types/pricing.go | 4 +- types/registry.go | 19 --------- 43 files changed, 233 insertions(+), 269 deletions(-) create mode 100644 internal/types/registry.go diff --git a/internal/api/fee.go b/internal/api/fee.go index 86bef5c3..c7a00537 100644 --- a/internal/api/fee.go +++ b/internal/api/fee.go @@ -17,11 +17,11 @@ import ( ) func (s *Server) GetPublicKeyFees(c echo.Context) error { - pluginID, ok := c.Get("plugin_id").(types.PluginID) + pluginID, ok := c.Get("plugin_id").(string) if !ok || pluginID == "" { return c.JSON(http.StatusBadRequest, NewErrorResponseWithMessage(msgRequiredPluginID)) } - if pluginID != types.PluginVultisigFees_feee { + if pluginID != itypes.PluginVultisigFees { return c.JSON(http.StatusUnauthorized, NewErrorResponseWithMessage("unauthorized")) } @@ -137,7 +137,7 @@ func (s *Server) GetPluginFeeHistory(c echo.Context) error { fees, totalCount, err := s.db.GetFeesByPluginID( c.Request().Context(), - types.PluginID(pluginID), + pluginID, publicKey, skip, take, @@ -204,7 +204,7 @@ func (s *Server) GetPluginBillingSummary(c echo.Context) error { for i, row := range rows { pricings := pricingsMap[row.PluginID] summaries[i] = itypes.PluginBillingSummary{ - PluginID: types.PluginID(row.PluginID), + PluginID: row.PluginID, AppName: titleMap[row.PluginID], Pricing: formatPricings(pricings), StartDate: row.StartDate.UTC(), diff --git a/internal/api/plugin.go b/internal/api/plugin.go index 9a665416..7068d266 100644 --- a/internal/api/plugin.go +++ b/internal/api/plugin.go @@ -51,11 +51,11 @@ func (s *Server) SignPluginMessages(c echo.Context) error { // Verify authenticated plugin ID matches the requested plugin ID // This prevents a malicious plugin from impersonating another plugin - authenticatedPluginID, ok := c.Get("plugin_id").(vtypes.PluginID) + authenticatedPluginID, ok := c.Get("plugin_id").(string) if !ok { return c.JSON(http.StatusBadRequest, NewErrorResponseWithMessage(msgRequiredPluginID)) } - if authenticatedPluginID.String() != req.PluginID { + if authenticatedPluginID != req.PluginID { s.logger.Warnf("Plugin ID mismatch: authenticated=%s, requested=%s", authenticatedPluginID, req.PluginID) return c.JSON(http.StatusForbidden, NewErrorResponseWithMessage(msgPluginIDMismatch)) } @@ -70,7 +70,7 @@ func (s *Server) SignPluginMessages(c echo.Context) error { } // Get policy from database - if req.PluginID == vtypes.PluginVultisigFees_feee.String() { + if req.PluginID == types.PluginVultisigFees { s.logger.Debug("SIGN FEE PLUGIN MESSAGES") return s.validateAndSign(c, &req, types.FeeDefaultPolicy, uuid.New()) } else { @@ -88,7 +88,7 @@ func (s *Server) SignPluginMessages(c echo.Context) error { } if !isTrialActive { - filePathName := common.GetVaultBackupFilename(req.PublicKey, vtypes.PluginVultisigFees_feee.String()) + filePathName := common.GetVaultBackupFilename(req.PublicKey, types.PluginVultisigFees) exist, err := s.vaultStorage.Exist(filePathName) if err != nil { errMsg := "failed to check vault existence" @@ -111,7 +111,7 @@ func (s *Server) SignPluginMessages(c echo.Context) error { } // Validate policy matches plugin - if policy.PluginID != vtypes.PluginID(req.PluginID) { + if policy.PluginID != req.PluginID { return fmt.Errorf("policy plugin ID mismatch") } @@ -243,7 +243,7 @@ func (s *Server) validateAndSign(c echo.Context, req *vtypes.PluginKeysignReques var matchedRule *rtypes.Rule //TODO: fee plugin priority for testing purposes - if req.PluginID == vtypes.PluginVultisigFees_feee.String() { + if req.PluginID == types.PluginVultisigFees { matchedRule, err = ngn.Evaluate(types.FeeDefaultPolicy, firstKeysignMessage.Chain, txBytesEvaluate) if err != nil { return s.forbidden(c, msgTxNotAllowed, err) @@ -261,7 +261,7 @@ func (s *Server) validateAndSign(c echo.Context, req *vtypes.PluginKeysignReques toAddress := extractToAddressFromRule(matchedRule) txToTrack, err := s.txIndexerService.CreateTx(c.Request().Context(), storage.CreateTxDto{ - PluginID: vtypes.PluginID(req.PluginID), + PluginID: req.PluginID, ChainID: firstKeysignMessage.Chain, PolicyID: policyID, TokenID: tokenID, @@ -373,7 +373,7 @@ func (s *Server) applyImageToPlugin(plugin *types.Plugin, img types.PluginImageR } func (s *Server) enrichPluginWithImages(ctx context.Context, plugin *types.Plugin) { - images, err := s.db.GetPluginImagesByPluginIDs(ctx, []vtypes.PluginID{plugin.ID}) + images, err := s.db.GetPluginImagesByPluginIDs(ctx, []string{plugin.ID}) if err != nil { s.logger.WithError(err).Warn("failed to fetch plugin images for enrichment") return @@ -388,7 +388,7 @@ func (s *Server) enrichPluginsWithImages(ctx context.Context, plugins []types.Pl return } - pluginIDs := make([]vtypes.PluginID, len(plugins)) + pluginIDs := make([]string, len(plugins)) for i, p := range plugins { pluginIDs[i] = p.ID } @@ -402,9 +402,9 @@ func (s *Server) enrichPluginsWithImages(ctx context.Context, plugins []types.Pl return } - imagesByPlugin := make(map[vtypes.PluginID][]types.PluginImageRecord) + imagesByPlugin := make(map[string][]types.PluginImageRecord) for _, img := range images { - imagesByPlugin[vtypes.PluginID(img.PluginID)] = append(imagesByPlugin[vtypes.PluginID(img.PluginID)], img) + imagesByPlugin[img.PluginID] = append(imagesByPlugin[img.PluginID], img) } for i := range plugins { @@ -444,7 +444,7 @@ func (s *Server) GetInstalledPlugins(c echo.Context) error { installed.Plugins = make([]types.Plugin, 0, len(pluginList.Plugins)) for _, plugin := range pluginList.Plugins { - fileName := common.GetVaultBackupFilename(publicKey, string(plugin.ID)) + fileName := common.GetVaultBackupFilename(publicKey, plugin.ID) exist, err := s.vaultStorage.Exist(fileName) if err != nil { @@ -560,7 +560,7 @@ func (s *Server) GetPluginTransactionHistory(c echo.Context) error { // Filter by specific plugin txs, totalCount, err = s.txIndexerService.GetByPluginIDAndPublicKey( c.Request().Context(), - vtypes.PluginID(pluginID), + pluginID, publicKey, skip, take, @@ -600,7 +600,7 @@ func (s *Server) buildPluginTitleMap(ctx context.Context, txs []storage.Tx) (map // Get unique plugin IDs pluginIDSet := make(map[string]struct{}) for _, tx := range txs { - pluginIDSet[string(tx.PluginID)] = struct{}{} + pluginIDSet[tx.PluginID] = struct{}{} } if len(pluginIDSet) == 0 { @@ -763,7 +763,7 @@ func (s *Server) GetPluginInstallationsCountByID(c echo.Context) error { return c.JSON(http.StatusBadRequest, NewErrorResponseWithMessage(msgRequiredPluginID)) } - count, err := s.policyService.GetPluginInstallationsCount(c.Request().Context(), vtypes.PluginID(pluginID)) + count, err := s.policyService.GetPluginInstallationsCount(c.Request().Context(), pluginID) if err != nil { s.logger.WithError(err).Errorf("Failed to get installation count for pluginId: %s", pluginID) return c.JSON(http.StatusInternalServerError, NewErrorResponseWithMessage(msgPluginInstallationCountFailed)) @@ -952,7 +952,7 @@ func (s *Server) ReportPlugin(c echo.Context) error { reason := p.Sanitize(req.Reason) details := p.Sanitize(req.Details) - result, err := s.reportService.SubmitReport(c.Request().Context(), vtypes.PluginID(pluginID), publicKey, reason, details) + result, err := s.reportService.SubmitReport(c.Request().Context(), pluginID, publicKey, reason, details) if err != nil { if errors.Is(err, service.ErrNotEligible) { return c.JSON(http.StatusBadRequest, NewErrorResponseWithMessage(msgReportNotEligible)) @@ -1006,7 +1006,7 @@ func (s *Server) GetAvailablePlugins(c echo.Context) error { go func(idx int, p types.Plugin) { defer func() { <-sem }() // release - skills, err := s.pluginService.GetPluginSkills(ctx, string(p.ID)) + skills, err := s.pluginService.GetPluginSkills(ctx, p.ID) if err != nil { s.logger.WithError(err).Warnf("Plugin %s unavailable, excluding from available list", p.ID) results <- result{index: idx, success: false} @@ -1015,7 +1015,7 @@ func (s *Server) GetAvailablePlugins(c echo.Context) error { results <- result{ index: idx, plugin: AvailablePlugin{ - ID: string(p.ID), + ID: p.ID, Name: p.Title, SkillsMD: skills.SkillsMD, }, diff --git a/internal/api/policy.go b/internal/api/policy.go index 103b6e09..d52e8f9a 100644 --- a/internal/api/policy.go +++ b/internal/api/policy.go @@ -20,8 +20,8 @@ import ( "google.golang.org/protobuf/proto" "github.com/vultisig/verifier/internal/sigutil" + itypes "github.com/vultisig/verifier/internal/types" "github.com/vultisig/verifier/types" - vtypes "github.com/vultisig/verifier/types" "github.com/vultisig/vultisig-go/address" "github.com/vultisig/vultisig-go/common" ) @@ -42,7 +42,7 @@ func (s *Server) validatePluginPolicy(ctx context.Context, policy types.PluginPo return fmt.Errorf("fail to unmarshal recipe: %w", err) } - spec, err := s.pluginService.GetPluginRecipeSpecification(ctx, policy.PluginID.String()) + spec, err := s.pluginService.GetPluginRecipeSpecification(ctx, policy.PluginID) if err != nil { return fmt.Errorf("failed to get plugin recipe specification: %w", err) } @@ -92,7 +92,7 @@ func (s *Server) CreatePluginPolicy(c echo.Context) error { } if !isTrialActive { - filePathName := common.GetVaultBackupFilename(publicKey, vtypes.PluginVultisigFees_feee.String()) + filePathName := common.GetVaultBackupFilename(publicKey, itypes.PluginVultisigFees) exist, err := s.vaultStorage.Exist(filePathName) if err != nil { s.logger.WithError(err).Error("failed to check vault existence") @@ -151,7 +151,7 @@ func (s *Server) verifyPolicySignature(policy types.PluginPolicy) bool { s.logger.WithError(err).Error("failed to decode signature bytes") return false } - vault, err := s.getVault(policy.PublicKey, policy.PluginID.String()) + vault, err := s.getVault(policy.PublicKey, policy.PluginID) if err != nil { s.logger.WithError(err).Error("fail to get vault") return false @@ -227,7 +227,7 @@ func (s *Server) UpdatePluginPolicyById(c echo.Context) error { } if *r == types.DeactivationReasonPluginPause { - err := s.safetyMgm.EnforceKeysign(c.Request().Context(), string(oldPolicy.PluginID)) + err := s.safetyMgm.EnforceKeysign(c.Request().Context(), oldPolicy.PluginID) if err != nil { return c.JSON(http.StatusLocked, NewErrorResponseWithMessage(msgPluginPaused)) } @@ -362,7 +362,7 @@ func (s *Server) GetAllPluginPolicies(c echo.Context) error { take = 100 } - policies, err := s.policyService.GetPluginPolicies(c.Request().Context(), publicKey, vtypes.PluginID(pluginID), take, skip, activeFilter) + policies, err := s.policyService.GetPluginPolicies(c.Request().Context(), publicKey, pluginID, take, skip, activeFilter) if err != nil { s.logger.WithError(err).Errorf("Failed to get policies for public_key: %s", publicKey) return c.JSON(http.StatusInternalServerError, NewErrorResponseWithMessage(msgPoliciesGetFailed)) diff --git a/internal/api/server.go b/internal/api/server.go index 4f6951e4..ff964a27 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -30,6 +30,7 @@ import ( "github.com/vultisig/verifier/internal/service" "github.com/vultisig/verifier/internal/sigutil" "github.com/vultisig/verifier/internal/storage" + itypes "github.com/vultisig/verifier/internal/types" "github.com/vultisig/verifier/internal/storage/postgres" "github.com/vultisig/verifier/internal/syncer" "github.com/vultisig/verifier/plugin/tasks" @@ -292,7 +293,7 @@ func (s *Server) ReshareVault(c echo.Context) error { // notifyPluginServerReshare sends the reshare request to the plugin server func (s *Server) notifyPluginServerReshare(ctx context.Context, req vtypes.ReshareRequest) error { // Look up plugin server endpoint - plugin, err := s.db.FindPluginById(ctx, nil, vtypes.PluginID(req.PluginID)) + plugin, err := s.db.FindPluginById(ctx, nil, req.PluginID) if err != nil { return fmt.Errorf("failed to find plugin: %w", err) } @@ -654,13 +655,13 @@ func (s *Server) GetActiveTokens(c echo.Context) error { } // notifyPluginServerDeletePlugin user would like to delete a plugin, we need to notify the plugin server -func (s *Server) notifyPluginServerDeletePlugin(ctx context.Context, id vtypes.PluginID, publicKeyEcdsa string) error { +func (s *Server) notifyPluginServerDeletePlugin(ctx context.Context, id string, publicKeyEcdsa string) error { // Look up plugin server endpoint plugin, err := s.db.FindPluginById(ctx, nil, id) if err != nil { return fmt.Errorf("failed to find plugin: %w", err) } - keyInfo, err := s.db.GetAPIKeyByPluginId(ctx, id.String()) + keyInfo, err := s.db.GetAPIKeyByPluginId(ctx, id) if err != nil { return fmt.Errorf("failed to get api key by id: %w", err) } @@ -705,16 +706,16 @@ func (s *Server) DeletePlugin(c echo.Context) error { if !ok || publicKey == "" { return c.JSON(http.StatusInternalServerError, NewErrorResponseWithMessage(msgVaultPublicKeyGetFailed)) } - if pluginID == vtypes.PluginVultisigFees_feee.String() { + if pluginID == itypes.PluginVultisigFees { return c.JSON(http.StatusForbidden, NewErrorResponseWithMessage("Unable to uninstall due to outstanding fees")) } - if err := s.notifyPluginServerDeletePlugin(c.Request().Context(), vtypes.PluginID(pluginID), publicKey); err != nil { + if err := s.notifyPluginServerDeletePlugin(c.Request().Context(), pluginID, publicKey); err != nil { s.logger.WithError(err).Errorf("Failed to notify plugin server for deletion of plugin %s", pluginID) return c.JSON(http.StatusServiceUnavailable, NewErrorResponseWithMessage(msgPluginServerUnavailable)) } // remove plugin policies - if err := s.policyService.DeleteAllPolicies(c.Request().Context(), vtypes.PluginID(pluginID), publicKey); err != nil { + if err := s.policyService.DeleteAllPolicies(c.Request().Context(), pluginID, publicKey); err != nil { s.logger.Errorf("Failed to delete plugin policies: %v", err) return c.JSON(http.StatusInternalServerError, NewErrorResponseWithMessage(msgPoliciesDeleteFailed)) } diff --git a/internal/fee_manager/fees.go b/internal/fee_manager/fees.go index 1c4f9378..5912a55a 100644 --- a/internal/fee_manager/fees.go +++ b/internal/fee_manager/fees.go @@ -44,7 +44,7 @@ func (s *FeeManagementService) HandleReshareDKLS(ctx context.Context, t *asynq.T return fmt.Errorf("json.Unmarshal failed: %v: %w", err, asynq.SkipRetry) } - if err := s.RegisterInstallation(ctx, vtypes.PluginID(req.PluginID), req.PublicKey); err != nil { + if err := s.RegisterInstallation(ctx, req.PluginID, req.PublicKey); err != nil { s.logger.WithError(err).Error("s.RegisterInstallation failed") return fmt.Errorf("s.RegisterInstallation failed: %v: %w", err, asynq.SkipRetry) } @@ -52,7 +52,7 @@ func (s *FeeManagementService) HandleReshareDKLS(ctx context.Context, t *asynq.T return nil } -func (s *FeeManagementService) RegisterInstallation(ctx context.Context, pluginID vtypes.PluginID, publicKey string) error { +func (s *FeeManagementService) RegisterInstallation(ctx context.Context, pluginID string, publicKey string) error { return s.db.WithTransaction(ctx, func(ctx context.Context, tx pgx.Tx) error { pluginInfo, err := s.db.FindPluginById(ctx, tx, pluginID) if err != nil { @@ -79,13 +79,13 @@ func (s *FeeManagementService) RegisterInstallation(ctx context.Context, pluginI } _, err = s.db.InsertFee(ctx, tx, &vtypes.Fee{ - PluginID: pluginID.String(), + PluginID: pluginID, PublicKey: publicKey, TxType: vtypes.TxTypeDebit, Amount: installationFee, FeeType: vtypes.FeeTypeInstallationFee, UnderlyingType: "plugin", - UnderlyingID: pluginID.String(), + UnderlyingID: pluginID, }) if err != nil { return err diff --git a/internal/portal/images.go b/internal/portal/images.go index 7bc5512c..df7de40e 100644 --- a/internal/portal/images.go +++ b/internal/portal/images.go @@ -15,7 +15,6 @@ import ( "github.com/vultisig/verifier/internal/storage/postgres" "github.com/vultisig/verifier/internal/storage/postgres/queries" itypes "github.com/vultisig/verifier/internal/types" - "github.com/vultisig/verifier/types" ) const ( @@ -98,7 +97,7 @@ func (s *Server) ListPluginImages(c echo.Context) error { } images, err := s.db.ListPluginImages(ctx, postgres.ListPluginImagesParams{ - PluginID: types.PluginID(pluginID), + PluginID: string(pluginID), ImageType: imageTypeFilter, IncludeHidden: includeHidden, IncludeDeleted: includeDeleted, @@ -169,7 +168,7 @@ func (s *Server) GetImageUploadURL(c echo.Context) error { } defer tx.Rollback(ctx) - err = s.db.LockPluginForUpdate(ctx, tx, types.PluginID(pluginID)) + err = s.db.LockPluginForUpdate(ctx, tx, string(pluginID)) if err != nil { s.logger.Errorf("failed to lock plugin: %v", err) return c.JSON(http.StatusInternalServerError, map[string]string{"error": "internal server error"}) @@ -180,7 +179,7 @@ func (s *Server) GetImageUploadURL(c echo.Context) error { if maxMedia == 0 { maxMedia = defaultMaxMediaImages } - count, err := s.db.CountVisibleMediaImages(ctx, tx, types.PluginID(pluginID)) + count, err := s.db.CountVisibleMediaImages(ctx, tx, string(pluginID)) if err != nil { s.logger.Errorf("failed to count media images: %v", err) return c.JSON(http.StatusInternalServerError, map[string]string{"error": "internal server error"}) @@ -192,7 +191,7 @@ func (s *Server) GetImageUploadURL(c echo.Context) error { nextOrder := 0 if imageType == itypes.PluginImageTypeMedia { - nextOrder, err = s.db.GetNextMediaOrderTx(ctx, tx, types.PluginID(pluginID)) + nextOrder, err = s.db.GetNextMediaOrderTx(ctx, tx, string(pluginID)) if err != nil { s.logger.Errorf("failed to get next media order: %v", err) return c.JSON(http.StatusInternalServerError, map[string]string{"error": "internal server error"}) @@ -212,7 +211,7 @@ func (s *Server) GetImageUploadURL(c echo.Context) error { _, err = s.db.CreatePendingPluginImage(ctx, tx, itypes.PluginImageCreateParams{ ID: imageID, - PluginID: types.PluginID(pluginID), + PluginID: string(pluginID), ImageType: imageType, S3Path: s3Key, ImageOrder: nextOrder, @@ -268,12 +267,12 @@ func (s *Server) ConfirmImageUpload(c echo.Context) error { } markPendingDeleted := func() { - if _, delErr := s.db.SoftDeletePluginImage(ctx, types.PluginID(pluginID), imageID); delErr != nil { + if _, delErr := s.db.SoftDeletePluginImage(ctx, string(pluginID), imageID); delErr != nil { s.logger.Warnf("failed to soft-delete pending image %s: %v", imageID, delErr) } } - img, err := s.db.GetPluginImageByID(ctx, types.PluginID(pluginID), imageID) + img, err := s.db.GetPluginImageByID(ctx, string(pluginID), imageID) if err != nil { s.logger.Errorf("failed to get plugin image: %v", err) return c.JSON(http.StatusInternalServerError, map[string]string{"error": "internal server error"}) @@ -355,7 +354,7 @@ func (s *Server) ConfirmImageUpload(c echo.Context) error { } defer tx.Rollback(ctx) - err = s.db.LockPluginForUpdate(ctx, tx, types.PluginID(pluginID)) + err = s.db.LockPluginForUpdate(ctx, tx, string(pluginID)) if err != nil { s.logger.Errorf("failed to lock plugin: %v", err) return c.JSON(http.StatusInternalServerError, map[string]string{"error": "internal server error"}) @@ -366,20 +365,20 @@ func (s *Server) ConfirmImageUpload(c echo.Context) error { if maxMedia == 0 { maxMedia = defaultMaxMediaImages } - count, err := s.db.CountVisibleMediaImages(ctx, tx, types.PluginID(pluginID)) + count, err := s.db.CountVisibleMediaImages(ctx, tx, string(pluginID)) if err != nil { s.logger.Errorf("failed to count media images: %v", err) return c.JSON(http.StatusInternalServerError, map[string]string{"error": "internal server error"}) } if count >= maxMedia { - if _, err := s.db.SoftDeletePluginImageTx(ctx, tx, types.PluginID(pluginID), imageID); err != nil { + if _, err := s.db.SoftDeletePluginImageTx(ctx, tx, string(pluginID), imageID); err != nil { s.logger.Warnf("failed to soft-delete pending image %s: %v", imageID, err) } return c.JSON(http.StatusConflict, map[string]string{"error": "maximum media images limit exceeded"}) } } - confirmedImg, err := s.db.ConfirmPluginImage(ctx, tx, types.PluginID(pluginID), imageID) + confirmedImg, err := s.db.ConfirmPluginImage(ctx, tx, string(pluginID), imageID) if err != nil { s.logger.Errorf("failed to confirm plugin image: %v", err) return c.JSON(http.StatusInternalServerError, map[string]string{"error": "internal server error"}) @@ -429,7 +428,7 @@ func (s *Server) UpdatePluginImage(c echo.Context) error { } if req.ImageOrder != nil { - img, err := s.db.GetPluginImageByID(ctx, types.PluginID(pluginID), imageID) + img, err := s.db.GetPluginImageByID(ctx, string(pluginID), imageID) if err != nil { s.logger.Errorf("failed to get plugin image: %v", err) return c.JSON(http.StatusInternalServerError, map[string]string{"error": "internal server error"}) @@ -445,7 +444,7 @@ func (s *Server) UpdatePluginImage(c echo.Context) error { } } - updated, err := s.db.UpdatePluginImage(ctx, types.PluginID(pluginID), imageID, req.Visible, req.ImageOrder) + updated, err := s.db.UpdatePluginImage(ctx, string(pluginID), imageID, req.Visible, req.ImageOrder) if err != nil { if strings.Contains(err.Error(), "not found") { return c.JSON(http.StatusNotFound, map[string]string{"error": "image not found"}) @@ -482,7 +481,7 @@ func (s *Server) DeletePluginImage(c echo.Context) error { return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid image id"}) } - _, err = s.db.SoftDeletePluginImage(ctx, types.PluginID(pluginID), imageID) + _, err = s.db.SoftDeletePluginImage(ctx, string(pluginID), imageID) if err != nil { if strings.Contains(err.Error(), "not found") { return c.JSON(http.StatusNotFound, map[string]string{"error": "image not found"}) @@ -538,13 +537,13 @@ func (s *Server) ReorderPluginImages(c echo.Context) error { } defer tx.Rollback(ctx) - err = s.db.LockPluginForUpdate(ctx, tx, types.PluginID(pluginID)) + err = s.db.LockPluginForUpdate(ctx, tx, string(pluginID)) if err != nil { s.logger.Errorf("failed to lock plugin: %v", err) return c.JSON(http.StatusInternalServerError, map[string]string{"error": "internal server error"}) } - err = s.db.ReorderMediaImages(ctx, tx, types.PluginID(pluginID), imageIDs) + err = s.db.ReorderMediaImages(ctx, tx, string(pluginID), imageIDs) if err != nil { errMsg := err.Error() if strings.Contains(errMsg, "duplicate") || strings.Contains(errMsg, "not found") || strings.Contains(errMsg, "not media") { diff --git a/internal/service/auth_test.go b/internal/service/auth_test.go index 346dcd17..dad0eda2 100644 --- a/internal/service/auth_test.go +++ b/internal/service/auth_test.go @@ -31,7 +31,7 @@ type MockDatabaseStorage struct { mock.Mock } -func (m *MockDatabaseStorage) DeleteAllPolicies(ctx context.Context, dbTx pgx.Tx, pluginID types.PluginID, publicKey string) error { +func (m *MockDatabaseStorage) DeleteAllPolicies(ctx context.Context, dbTx pgx.Tx, pluginID string, publicKey string) error { args := m.Called(ctx, dbTx, pluginID, publicKey) return args.Error(0) } @@ -99,7 +99,7 @@ func (m *MockDatabaseStorage) CreatePricing(ctx context.Context, pricingDto type return args.Get(0).(*types.Pricing), args.Error(1) } -func (m *MockDatabaseStorage) GetPricingByPluginId(ctx context.Context, pluginID types.PluginID) ([]types.Pricing, error) { +func (m *MockDatabaseStorage) GetPricingByPluginId(ctx context.Context, pluginID string) ([]types.Pricing, error) { args := m.Called(ctx, pluginID) if args.Get(0) == nil { return nil, args.Error(1) @@ -107,7 +107,7 @@ func (m *MockDatabaseStorage) GetPricingByPluginId(ctx context.Context, pluginID return args.Get(0).([]types.Pricing), args.Error(1) } -func (m *MockDatabaseStorage) FindPluginById(ctx context.Context, tx pgx.Tx, pluginID types.PluginID) (*itypes.Plugin, error) { +func (m *MockDatabaseStorage) FindPluginById(ctx context.Context, tx pgx.Tx, pluginID string) (*itypes.Plugin, error) { args := m.Called(ctx, tx, pluginID) if args.Get(0) == nil { return nil, args.Error(1) @@ -131,7 +131,7 @@ func (m *MockDatabaseStorage) GetPluginPolicy(ctx context.Context, id uuid.UUID) return args.Get(0).(*types.PluginPolicy), args.Error(1) } -func (m *MockDatabaseStorage) GetPluginInstallationsCount(ctx context.Context, pluginID types.PluginID) (itypes.PluginTotalCount, error) { +func (m *MockDatabaseStorage) GetPluginInstallationsCount(ctx context.Context, pluginID string) (itypes.PluginTotalCount, error) { args := m.Called(ctx, pluginID) if args.Get(0) == nil { return itypes.PluginTotalCount{}, args.Error(1) @@ -139,7 +139,7 @@ func (m *MockDatabaseStorage) GetPluginInstallationsCount(ctx context.Context, p return args.Get(0).(itypes.PluginTotalCount), args.Error(1) } -func (m *MockDatabaseStorage) GetPluginPolicies(ctx context.Context, publicKey string, pluginIds []types.PluginID, includeInactive bool) ([]types.PluginPolicy, error) { +func (m *MockDatabaseStorage) GetPluginPolicies(ctx context.Context, publicKey string, pluginIds []string, includeInactive bool) ([]types.PluginPolicy, error) { args := m.Called(ctx, publicKey, pluginIds, includeInactive) if args.Get(0) == nil { return nil, args.Error(1) @@ -147,7 +147,7 @@ func (m *MockDatabaseStorage) GetPluginPolicies(ctx context.Context, publicKey s return args.Get(0).([]types.PluginPolicy), args.Error(1) } -func (m *MockDatabaseStorage) GetAllPluginPolicies(ctx context.Context, publicKey string, pluginID types.PluginID, take int, skip int, activeFilter *bool) (*itypes.PluginPolicyPaginatedList, error) { +func (m *MockDatabaseStorage) GetAllPluginPolicies(ctx context.Context, publicKey string, pluginID string, take int, skip int, activeFilter *bool) (*itypes.PluginPolicyPaginatedList, error) { args := m.Called(ctx, publicKey, pluginID, take, skip, activeFilter) if args.Get(0) == nil { return nil, args.Error(1) @@ -197,7 +197,7 @@ func (m *MockDatabaseStorage) GetFeesByPublicKey(ctx context.Context, publicKey return args.Get(0).([]*types.Fee), args.Error(1) } -func (m *MockDatabaseStorage) GetFeesByPluginID(ctx context.Context, pluginID types.PluginID, publicKey string, skip, take uint32) ([]itypes.FeeWithStatus, uint32, error) { +func (m *MockDatabaseStorage) GetFeesByPluginID(ctx context.Context, pluginID string, publicKey string, skip, take uint32) ([]itypes.FeeWithStatus, uint32, error) { args := m.Called(ctx, pluginID, publicKey, skip, take) if args.Get(0) == nil { return nil, 0, args.Error(2) @@ -218,7 +218,7 @@ func (m *MockDatabaseStorage) InsertFee(ctx context.Context, dbTx pgx.Tx, fee *t return args.Get(0).(uint64), args.Error(1) } -func (m *MockDatabaseStorage) InsertPluginInstallation(ctx context.Context, dbTx pgx.Tx, pluginID types.PluginID, publicKey string) error { +func (m *MockDatabaseStorage) InsertPluginInstallation(ctx context.Context, dbTx pgx.Tx, pluginID string, publicKey string) error { args := m.Called(ctx, dbTx, pluginID, publicKey) return args.Error(0) } @@ -277,7 +277,7 @@ func (m *MockDatabaseStorage) UpdatePluginPolicySync(ctx context.Context, dbTx p return args.Error(0) } -func (m *MockDatabaseStorage) AttachTagToPlugin(ctx context.Context, pluginID types.PluginID, tagID string) (*itypes.Plugin, error) { +func (m *MockDatabaseStorage) AttachTagToPlugin(ctx context.Context, pluginID string, tagID string) (*itypes.Plugin, error) { args := m.Called(ctx, pluginID, tagID) if args.Get(0) == nil { return nil, args.Error(1) @@ -395,12 +395,12 @@ func (m *MockDatabaseStorage) GetPricingsByPluginIDs(ctx context.Context, plugin return args.Get(0).(map[string][]itypes.PricingInfo), args.Error(1) } -func (m *MockDatabaseStorage) UpsertReport(ctx context.Context, pluginID types.PluginID, publicKey, reason, details string, cooldown time.Duration) error { +func (m *MockDatabaseStorage) UpsertReport(ctx context.Context, pluginID string, publicKey, reason, details string, cooldown time.Duration) error { args := m.Called(ctx, pluginID, publicKey, reason, details, cooldown) return args.Error(0) } -func (m *MockDatabaseStorage) GetReport(ctx context.Context, pluginID types.PluginID, publicKey string) (*itypes.PluginReport, error) { +func (m *MockDatabaseStorage) GetReport(ctx context.Context, pluginID string, publicKey string) (*itypes.PluginReport, error) { args := m.Called(ctx, pluginID, publicKey) if args.Get(0) == nil { return nil, args.Error(1) @@ -408,27 +408,27 @@ func (m *MockDatabaseStorage) GetReport(ctx context.Context, pluginID types.Plug return args.Get(0).(*itypes.PluginReport), args.Error(1) } -func (m *MockDatabaseStorage) CountReportsInWindow(ctx context.Context, pluginID types.PluginID, window time.Duration) (int, error) { +func (m *MockDatabaseStorage) CountReportsInWindow(ctx context.Context, pluginID string, window time.Duration) (int, error) { args := m.Called(ctx, pluginID, window) return args.Int(0), args.Error(1) } -func (m *MockDatabaseStorage) HasInstallation(ctx context.Context, pluginID types.PluginID, publicKey string) (bool, error) { +func (m *MockDatabaseStorage) HasInstallation(ctx context.Context, pluginID string, publicKey string) (bool, error) { args := m.Called(ctx, pluginID, publicKey) return args.Bool(0), args.Error(1) } -func (m *MockDatabaseStorage) CountInstallations(ctx context.Context, pluginID types.PluginID) (int, error) { +func (m *MockDatabaseStorage) CountInstallations(ctx context.Context, pluginID string) (int, error) { args := m.Called(ctx, pluginID) return args.Int(0), args.Error(1) } -func (m *MockDatabaseStorage) IsPluginPaused(ctx context.Context, pluginID types.PluginID) (bool, error) { +func (m *MockDatabaseStorage) IsPluginPaused(ctx context.Context, pluginID string) (bool, error) { args := m.Called(ctx, pluginID) return args.Bool(0), args.Error(1) } -func (m *MockDatabaseStorage) PausePlugin(ctx context.Context, pluginID types.PluginID, record itypes.PauseHistoryRecord) error { +func (m *MockDatabaseStorage) PausePlugin(ctx context.Context, pluginID string, record itypes.PauseHistoryRecord) error { args := m.Called(ctx, pluginID, record) return args.Error(0) } @@ -441,30 +441,30 @@ func (m *MockDatabaseStorage) GetControlFlags(ctx context.Context, k1, k2 string return args.Get(0).(map[string]bool), args.Error(1) } -func (m *MockDatabaseStorage) IsOwner(ctx context.Context, pluginID types.PluginID, publicKey string) (bool, error) { +func (m *MockDatabaseStorage) IsOwner(ctx context.Context, pluginID string, publicKey string) (bool, error) { args := m.Called(ctx, pluginID, publicKey) return args.Bool(0), args.Error(1) } -func (m *MockDatabaseStorage) GetPluginsByOwner(ctx context.Context, publicKey string) ([]types.PluginID, error) { +func (m *MockDatabaseStorage) GetPluginsByOwner(ctx context.Context, publicKey string) ([]string, error) { args := m.Called(ctx, publicKey) if args.Get(0) == nil { return nil, args.Error(1) } - return args.Get(0).([]types.PluginID), args.Error(1) + return args.Get(0).([]string), args.Error(1) } -func (m *MockDatabaseStorage) AddOwner(ctx context.Context, pluginID types.PluginID, publicKey string, addedVia itypes.PluginOwnerAddedVia, addedBy string) error { +func (m *MockDatabaseStorage) AddOwner(ctx context.Context, pluginID string, publicKey string, addedVia itypes.PluginOwnerAddedVia, addedBy string) error { args := m.Called(ctx, pluginID, publicKey, addedVia, addedBy) return args.Error(0) } -func (m *MockDatabaseStorage) DeactivateOwner(ctx context.Context, pluginID types.PluginID, publicKey string) error { +func (m *MockDatabaseStorage) DeactivateOwner(ctx context.Context, pluginID string, publicKey string) error { args := m.Called(ctx, pluginID, publicKey) return args.Error(0) } -func (m *MockDatabaseStorage) GetPluginImagesByPluginIDs(ctx context.Context, pluginIDs []types.PluginID) ([]itypes.PluginImageRecord, error) { +func (m *MockDatabaseStorage) GetPluginImagesByPluginIDs(ctx context.Context, pluginIDs []string) ([]itypes.PluginImageRecord, error) { args := m.Called(ctx, pluginIDs) if args.Get(0) == nil { return nil, args.Error(1) @@ -472,7 +472,7 @@ func (m *MockDatabaseStorage) GetPluginImagesByPluginIDs(ctx context.Context, pl return args.Get(0).([]itypes.PluginImageRecord), args.Error(1) } -func (m *MockDatabaseStorage) GetPluginImageByType(ctx context.Context, pluginID types.PluginID, imageType itypes.PluginImageType) (*itypes.PluginImageRecord, error) { +func (m *MockDatabaseStorage) GetPluginImageByType(ctx context.Context, pluginID string, imageType itypes.PluginImageType) (*itypes.PluginImageRecord, error) { args := m.Called(ctx, pluginID, imageType) if args.Get(0) == nil { return nil, args.Error(1) @@ -480,7 +480,7 @@ func (m *MockDatabaseStorage) GetPluginImageByType(ctx context.Context, pluginID return args.Get(0).(*itypes.PluginImageRecord), args.Error(1) } -func (m *MockDatabaseStorage) GetNextMediaOrder(ctx context.Context, pluginID types.PluginID) (int, error) { +func (m *MockDatabaseStorage) GetNextMediaOrder(ctx context.Context, pluginID string) (int, error) { args := m.Called(ctx, pluginID) return args.Int(0), args.Error(1) } diff --git a/internal/service/plugin.go b/internal/service/plugin.go index 4c899497..6d672dba 100644 --- a/internal/service/plugin.go +++ b/internal/service/plugin.go @@ -18,7 +18,6 @@ import ( "github.com/vultisig/verifier/internal/storage" "github.com/vultisig/verifier/internal/types" "github.com/vultisig/verifier/internal/util" - ptypes "github.com/vultisig/verifier/types" ) // PluginSkills represents the skills returned from a plugin's /skills endpoint. @@ -56,7 +55,7 @@ type PluginServiceStorage interface { FindReviewById(ctx context.Context, db pgx.Tx, id string) (*types.ReviewDto, error) FindReviewByUserAndPlugin(ctx context.Context, dbTx pgx.Tx, pluginId string, userAddress string) (*types.ReviewDto, error) - FindPluginById(ctx context.Context, dbTx pgx.Tx, id ptypes.PluginID) (*types.Plugin, error) + FindPluginById(ctx context.Context, dbTx pgx.Tx, id string) (*types.Plugin, error) GetAPIKeyByPluginId(ctx context.Context, pluginId string) (*types.APIKey, error) GetPluginTitlesByIDs(ctx context.Context, ids []string) (map[string]string, error) } @@ -84,7 +83,7 @@ func (s *PluginService) GetPluginWithRating(ctx context.Context, pluginId string var err error // Find plugin - plugin, err := s.db.FindPluginById(ctx, tx, ptypes.PluginID(pluginId)) + plugin, err := s.db.FindPluginById(ctx, tx, pluginId) if err != nil { return fmt.Errorf("failed to get plugin: %w", err) } @@ -207,7 +206,7 @@ func (s *PluginService) GetPluginRecipeSpecification(ctx context.Context, plugin } // Get plugin from database to get server endpoint - plugin, err := s.db.FindPluginById(ctx, nil, ptypes.PluginID(pluginID)) + plugin, err := s.db.FindPluginById(ctx, nil, pluginID) if err != nil { return nil, fmt.Errorf("failed to find plugin: %w", err) } @@ -246,7 +245,7 @@ func (s *PluginService) GetPluginRecipeSpecificationSuggest( pluginID string, configuration map[string]any, ) (*rtypes.PolicySuggest, error) { - plugin, err := s.db.FindPluginById(ctx, nil, ptypes.PluginID(pluginID)) + plugin, err := s.db.FindPluginById(ctx, nil, pluginID) if err != nil { return nil, fmt.Errorf("failed to find plugin: %w", err) } @@ -317,7 +316,7 @@ func (s *PluginService) GetPluginRecipeFunctions(ctx context.Context, pluginID s funcs = append(funcs, f) } sort.Strings(funcs) - plugin, err := s.db.FindPluginById(ctx, nil, ptypes.PluginID(pluginID)) + plugin, err := s.db.FindPluginById(ctx, nil, pluginID) if err != nil { return types.RecipeFunctions{}, fmt.Errorf("failed to find plugin: %w", err) } @@ -401,7 +400,7 @@ func (s *PluginService) GetPluginSkills(ctx context.Context, pluginID string) (* } // Get plugin from database to get server endpoint - plugin, err := s.db.FindPluginById(ctx, nil, ptypes.PluginID(pluginID)) + plugin, err := s.db.FindPluginById(ctx, nil, pluginID) if err != nil { return nil, fmt.Errorf("failed to find plugin: %w", err) } diff --git a/internal/service/policy.go b/internal/service/policy.go index 8f32b13e..01fc8add 100644 --- a/internal/service/policy.go +++ b/internal/service/policy.go @@ -18,11 +18,11 @@ import ( type Policy interface { CreatePolicy(ctx context.Context, policy types.PluginPolicy) (*types.PluginPolicy, error) UpdatePolicy(ctx context.Context, policy types.PluginPolicy) (*types.PluginPolicy, error) - DeletePolicy(ctx context.Context, policyID uuid.UUID, pluginID types.PluginID, signature string) error - GetPluginPolicies(ctx context.Context, publicKey string, pluginID types.PluginID, take int, skip int, activeFilter *bool) (*itypes.PluginPolicyPaginatedList, error) + DeletePolicy(ctx context.Context, policyID uuid.UUID, pluginID string, signature string) error + GetPluginPolicies(ctx context.Context, publicKey string, pluginID string, take int, skip int, activeFilter *bool) (*itypes.PluginPolicyPaginatedList, error) GetPluginPolicy(ctx context.Context, policyID uuid.UUID) (*types.PluginPolicy, error) - GetPluginInstallationsCount(ctx context.Context, pluginID types.PluginID) (itypes.PluginTotalCount, error) - DeleteAllPolicies(ctx context.Context, pluginID types.PluginID, publicKey string) error + GetPluginInstallationsCount(ctx context.Context, pluginID string) (itypes.PluginTotalCount, error) + DeleteAllPolicies(ctx context.Context, pluginID string, publicKey string) error } var _ Policy = (*PolicyService)(nil) @@ -101,7 +101,7 @@ func (s *PolicyService) validateBillingInformation(ctx context.Context, tx pgx.T } func (s *PolicyService) isFeePolicyInstalled(ctx context.Context, publicKey string) (bool, error) { - pluginData, err := s.db.GetPluginPolicies(ctx, publicKey, []types.PluginID{types.PluginVultisigFees_feee}, false) + pluginData, err := s.db.GetPluginPolicies(ctx, publicKey, []string{itypes.PluginVultisigFees}, false) if err != nil { return false, fmt.Errorf("failed to get plugin policy: %w", err) } @@ -197,7 +197,7 @@ func (s *PolicyService) handleRollback(tx pgx.Tx) { } } -func (s *PolicyService) DeletePolicy(ctx context.Context, policyID uuid.UUID, pluginID types.PluginID, signature string) error { +func (s *PolicyService) DeletePolicy(ctx context.Context, policyID uuid.UUID, pluginID string, signature string) error { tx, err := s.db.Pool().Begin(ctx) if err != nil { return fmt.Errorf("failed to begin transaction: %w", err) @@ -232,7 +232,7 @@ func (s *PolicyService) DeletePolicy(ctx context.Context, policyID uuid.UUID, pl return nil } -func (s *PolicyService) GetPluginPolicies(ctx context.Context, publicKey string, pluginID types.PluginID, take int, skip int, activeFilter *bool) (*itypes.PluginPolicyPaginatedList, error) { +func (s *PolicyService) GetPluginPolicies(ctx context.Context, publicKey string, pluginID string, take int, skip int, activeFilter *bool) (*itypes.PluginPolicyPaginatedList, error) { policies, err := s.db.GetAllPluginPolicies(ctx, publicKey, pluginID, take, skip, activeFilter) if err != nil { return nil, fmt.Errorf("failed to get policies: %w", err) @@ -248,7 +248,7 @@ func (s *PolicyService) GetPluginPolicy(ctx context.Context, policyID uuid.UUID) return policy, nil } -func (s *PolicyService) GetPluginInstallationsCount(ctx context.Context, pluginID types.PluginID) (itypes.PluginTotalCount, error) { +func (s *PolicyService) GetPluginInstallationsCount(ctx context.Context, pluginID string) (itypes.PluginTotalCount, error) { count, err := s.db.GetPluginInstallationsCount(ctx, pluginID) if err != nil { return itypes.PluginTotalCount{}, fmt.Errorf("failed to get plugin installations count: %w", err) @@ -256,7 +256,7 @@ func (s *PolicyService) GetPluginInstallationsCount(ctx context.Context, pluginI return count, nil } -func (s *PolicyService) DeleteAllPolicies(ctx context.Context, pluginID types.PluginID, publicKey string) error { +func (s *PolicyService) DeleteAllPolicies(ctx context.Context, pluginID string, publicKey string) error { tx, err := s.db.Pool().Begin(ctx) if err != nil { return fmt.Errorf("failed to begin transaction: %w", err) diff --git a/internal/service/report.go b/internal/service/report.go index 856b51e3..9e7ad361 100644 --- a/internal/service/report.go +++ b/internal/service/report.go @@ -11,7 +11,6 @@ import ( "github.com/vultisig/verifier/internal/safety" itypes "github.com/vultisig/verifier/internal/types" psafety "github.com/vultisig/verifier/plugin/safety" - "github.com/vultisig/verifier/types" ) var ( @@ -20,17 +19,17 @@ var ( ) type ReportServiceStorage interface { - UpsertReport(ctx context.Context, pluginID types.PluginID, publicKey, reason, details string, cooldown time.Duration) error - GetReport(ctx context.Context, pluginID types.PluginID, publicKey string) (*itypes.PluginReport, error) - CountReportsInWindow(ctx context.Context, pluginID types.PluginID, window time.Duration) (int, error) - HasInstallation(ctx context.Context, pluginID types.PluginID, publicKey string) (bool, error) - CountInstallations(ctx context.Context, pluginID types.PluginID) (int, error) - IsPluginPaused(ctx context.Context, pluginID types.PluginID) (bool, error) - PausePlugin(ctx context.Context, pluginID types.PluginID, record itypes.PauseHistoryRecord) error + UpsertReport(ctx context.Context, pluginID string, publicKey, reason, details string, cooldown time.Duration) error + GetReport(ctx context.Context, pluginID string, publicKey string) (*itypes.PluginReport, error) + CountReportsInWindow(ctx context.Context, pluginID string, window time.Duration) (int, error) + HasInstallation(ctx context.Context, pluginID string, publicKey string) (bool, error) + CountInstallations(ctx context.Context, pluginID string) (int, error) + IsPluginPaused(ctx context.Context, pluginID string) (bool, error) + PausePlugin(ctx context.Context, pluginID string, record itypes.PauseHistoryRecord) error } type SafetySyncer interface { - SyncSafetyToPlugin(ctx context.Context, pluginID types.PluginID, flags []psafety.ControlFlag) error + SyncSafetyToPlugin(ctx context.Context, pluginID string, flags []psafety.ControlFlag) error } type ReportService struct { @@ -53,7 +52,7 @@ func NewReportService(db ReportServiceStorage, syncer SafetySyncer, logger *logr }, nil } -func (s *ReportService) SubmitReport(ctx context.Context, pluginID types.PluginID, publicKey, reason, details string) (*itypes.ReportSubmitResult, error) { +func (s *ReportService) SubmitReport(ctx context.Context, pluginID string, publicKey, reason, details string) (*itypes.ReportSubmitResult, error) { hasInstallation, err := s.db.HasInstallation(ctx, pluginID, publicKey) if err != nil { return nil, fmt.Errorf("failed to check installation: %w", err) @@ -110,7 +109,7 @@ func (s *ReportService) SubmitReport(ctx context.Context, pluginID types.PluginI }, nil } -func (s *ReportService) evaluateAndPause(ctx context.Context, pluginID types.PluginID) error { +func (s *ReportService) evaluateAndPause(ctx context.Context, pluginID string) error { isPaused, err := s.db.IsPluginPaused(ctx, pluginID) if err != nil { return fmt.Errorf("failed to check pause status: %w", err) diff --git a/internal/storage/db.go b/internal/storage/db.go index 4c48cd24..6755f130 100644 --- a/internal/storage/db.go +++ b/internal/storage/db.go @@ -43,23 +43,23 @@ type DatabaseStorage interface { type PolicyRepository interface { GetPluginPolicy(ctx context.Context, id uuid.UUID) (*types.PluginPolicy, error) - GetPluginPolicies(ctx context.Context, publicKey string, pluginIds []types.PluginID, includeInactive bool) ([]types.PluginPolicy, error) - GetPluginInstallationsCount(ctx context.Context, pluginID types.PluginID) (itypes.PluginTotalCount, error) - GetAllPluginPolicies(ctx context.Context, publicKey string, pluginID types.PluginID, take int, skip int, activeFilter *bool) (*itypes.PluginPolicyPaginatedList, error) + GetPluginPolicies(ctx context.Context, publicKey string, pluginIds []string, includeInactive bool) ([]types.PluginPolicy, error) + GetPluginInstallationsCount(ctx context.Context, pluginID string) (itypes.PluginTotalCount, error) + GetAllPluginPolicies(ctx context.Context, publicKey string, pluginID string, take int, skip int, activeFilter *bool) (*itypes.PluginPolicyPaginatedList, error) DeletePluginPolicyTx(ctx context.Context, dbTx pgx.Tx, id uuid.UUID) error InsertPluginPolicyTx(ctx context.Context, dbTx pgx.Tx, policy types.PluginPolicy) (*types.PluginPolicy, error) UpdatePluginPolicyTx(ctx context.Context, dbTx pgx.Tx, policy types.PluginPolicy) (*types.PluginPolicy, error) - DeleteAllPolicies(ctx context.Context, dbTx pgx.Tx, pluginID types.PluginID, publicKey string) error + DeleteAllPolicies(ctx context.Context, dbTx pgx.Tx, pluginID string, publicKey string) error } type FeeRepository interface { GetFeeById(ctx context.Context, id uint64) (*types.Fee, error) GetFeesByPublicKey(ctx context.Context, publicKey string) ([]*types.Fee, error) - GetFeesByPluginID(ctx context.Context, pluginID types.PluginID, publicKey string, skip, take uint32) ([]itypes.FeeWithStatus, uint32, error) + GetFeesByPluginID(ctx context.Context, pluginID string, publicKey string, skip, take uint32) ([]itypes.FeeWithStatus, uint32, error) GetPluginBillingSummary(ctx context.Context, publicKey string) ([]itypes.PluginBillingSummaryRow, error) GetPricingsByPluginIDs(ctx context.Context, pluginIDs []string) (map[string][]itypes.PricingInfo, error) InsertFee(ctx context.Context, dbTx pgx.Tx, fee *types.Fee) (uint64, error) - InsertPluginInstallation(ctx context.Context, dbTx pgx.Tx, pluginID types.PluginID, publicKey string) error + InsertPluginInstallation(ctx context.Context, dbTx pgx.Tx, pluginID string, publicKey string) error MarkFeesCollected(ctx context.Context, dbTx pgx.Tx, feeIDs []uint64, txHash string, totalAmount uint64) error GetUserFees(ctx context.Context, publicKey string) (*types.UserFeeStatus, error) UpdateBatchStatus(ctx context.Context, dbTx pgx.Tx, txHash string, status *rpc.TxOnChainStatus) error @@ -75,7 +75,7 @@ type PluginPolicySyncRepository interface { } type PricingRepository interface { - GetPricingByPluginId(ctx context.Context, pluginId types.PluginID) ([]types.Pricing, error) + GetPricingByPluginId(ctx context.Context, pluginId string) ([]types.Pricing, error) FindPricingById(ctx context.Context, id uuid.UUID) (*types.Pricing, error) CreatePricing(ctx context.Context, pricingDto types.PricingCreateDto) (*types.Pricing, error) DeletePricingById(ctx context.Context, id uuid.UUID) error @@ -83,23 +83,23 @@ type PricingRepository interface { type PluginRepository interface { FindPlugins(ctx context.Context, filters itypes.PluginFilters, take int, skip int, sort string) (*itypes.PluginsPaginatedList, error) - FindPluginById(ctx context.Context, dbTx pgx.Tx, id types.PluginID) (*itypes.Plugin, error) + FindPluginById(ctx context.Context, dbTx pgx.Tx, id string) (*itypes.Plugin, error) GetPluginTitlesByIDs(ctx context.Context, ids []string) (map[string]string, error) Pool() *pgxpool.Pool } type PluginOwnerRepository interface { - IsOwner(ctx context.Context, pluginID types.PluginID, publicKey string) (bool, error) - GetPluginsByOwner(ctx context.Context, publicKey string) ([]types.PluginID, error) - AddOwner(ctx context.Context, pluginID types.PluginID, publicKey string, addedVia itypes.PluginOwnerAddedVia, addedBy string) error - DeactivateOwner(ctx context.Context, pluginID types.PluginID, publicKey string) error + IsOwner(ctx context.Context, pluginID string, publicKey string) (bool, error) + GetPluginsByOwner(ctx context.Context, publicKey string) ([]string, error) + AddOwner(ctx context.Context, pluginID string, publicKey string, addedVia itypes.PluginOwnerAddedVia, addedBy string) error + DeactivateOwner(ctx context.Context, pluginID string, publicKey string) error } type PluginImageRepository interface { - GetPluginImagesByPluginIDs(ctx context.Context, pluginIDs []types.PluginID) ([]itypes.PluginImageRecord, error) - GetPluginImageByType(ctx context.Context, pluginID types.PluginID, imageType itypes.PluginImageType) (*itypes.PluginImageRecord, error) - GetNextMediaOrder(ctx context.Context, pluginID types.PluginID) (int, error) + GetPluginImagesByPluginIDs(ctx context.Context, pluginIDs []string) ([]itypes.PluginImageRecord, error) + GetPluginImageByType(ctx context.Context, pluginID string, imageType itypes.PluginImageType) (*itypes.PluginImageRecord, error) + GetNextMediaOrder(ctx context.Context, pluginID string) (int, error) } type VaultTokenRepository interface { @@ -140,11 +140,11 @@ type ControlFlagsRepository interface { } type ReportRepository interface { - UpsertReport(ctx context.Context, pluginID types.PluginID, publicKey, reason, details string, cooldown time.Duration) error - GetReport(ctx context.Context, pluginID types.PluginID, publicKey string) (*itypes.PluginReport, error) - CountReportsInWindow(ctx context.Context, pluginID types.PluginID, window time.Duration) (int, error) - HasInstallation(ctx context.Context, pluginID types.PluginID, publicKey string) (bool, error) - CountInstallations(ctx context.Context, pluginID types.PluginID) (int, error) - IsPluginPaused(ctx context.Context, pluginID types.PluginID) (bool, error) - PausePlugin(ctx context.Context, pluginID types.PluginID, record itypes.PauseHistoryRecord) error + UpsertReport(ctx context.Context, pluginID string, publicKey, reason, details string, cooldown time.Duration) error + GetReport(ctx context.Context, pluginID string, publicKey string) (*itypes.PluginReport, error) + CountReportsInWindow(ctx context.Context, pluginID string, window time.Duration) (int, error) + HasInstallation(ctx context.Context, pluginID string, publicKey string) (bool, error) + CountInstallations(ctx context.Context, pluginID string) (int, error) + IsPluginPaused(ctx context.Context, pluginID string) (bool, error) + PausePlugin(ctx context.Context, pluginID string, record itypes.PauseHistoryRecord) error } diff --git a/internal/storage/postgres/db_test.go b/internal/storage/postgres/db_test.go index 14f86a5d..b7468749 100644 --- a/internal/storage/postgres/db_test.go +++ b/internal/storage/postgres/db_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" itypes "github.com/vultisig/verifier/internal/types" - ptypes "github.com/vultisig/verifier/types" + "github.com/vultisig/verifier/types" ) func TestAddPluginPolicySync(t *testing.T) { @@ -19,9 +19,9 @@ func TestAddPluginPolicySync(t *testing.T) { tx, err := db.Pool().Begin(ctx) assert.NoError(t, err) syncID := uuid.New() - policy, err := db.InsertPluginPolicyTx(ctx, tx, ptypes.PluginPolicy{ + policy, err := db.InsertPluginPolicyTx(ctx, tx, types.PluginPolicy{ ID: uuid.New(), - PluginID: ptypes.PluginVultisigPayroll_0000, + PluginID: itypes.PluginVultisigRecurringSends, PublicKey: "publicKey", Signature: "signature", Recipe: "recipe", @@ -37,7 +37,7 @@ func TestAddPluginPolicySync(t *testing.T) { err = db.AddPluginPolicySync(ctx, tx, itypes.PluginPolicySync{ ID: syncID, PolicyID: policy.ID, - PluginID: ptypes.PluginVultisigPayroll_0000, + PluginID: itypes.PluginVultisigRecurringSends, SyncType: itypes.AddPolicy, Signature: "signature", Status: itypes.NotSynced, diff --git a/internal/storage/postgres/fees.go b/internal/storage/postgres/fees.go index 1b7bab2d..173f9921 100644 --- a/internal/storage/postgres/fees.go +++ b/internal/storage/postgres/fees.go @@ -475,7 +475,7 @@ func (p *PostgresBackend) IsTrialActive( func (p *PostgresBackend) GetFeesByPluginID( ctx context.Context, - pluginID types.PluginID, + pluginID string, publicKey string, skip, take uint32, ) ([]itypes.FeeWithStatus, uint32, error) { diff --git a/internal/storage/postgres/plugin.go b/internal/storage/postgres/plugin.go index cd65db8d..1f824ca8 100644 --- a/internal/storage/postgres/plugin.go +++ b/internal/storage/postgres/plugin.go @@ -55,7 +55,7 @@ func convertNullablePricing(np *nullablePricing) *types.Pricing { Amount: *np.Amount, Asset: types.PricingAsset(*np.Asset), Metric: types.PricingMetric(*np.Metric), - PluginID: types.PluginID(*np.PluginID), + PluginID: *np.PluginID, CreatedAt: *np.CreatedAt, UpdatedAt: *np.UpdatedAt, } @@ -65,8 +65,8 @@ func (p *PostgresBackend) collectPlugins(rows pgx.Rows) ([]itypes.Plugin, error) defer rows.Close() // Use a map to group plugins by ID and collect their pricing records - pluginMap := make(map[types.PluginID]*itypes.Plugin) - pluginIDs := []types.PluginID{} + pluginMap := make(map[string]*itypes.Plugin) + pluginIDs := []string{} for rows.Next() { var plugin itypes.Plugin @@ -181,7 +181,7 @@ func (p *PostgresBackend) collectPlugins(rows pgx.Rows) ([]itypes.Plugin, error) return plugins, nil } -func (p *PostgresBackend) FindPluginById(ctx context.Context, dbTx pgx.Tx, id types.PluginID) (*itypes.Plugin, error) { +func (p *PostgresBackend) FindPluginById(ctx context.Context, dbTx pgx.Tx, id string) (*itypes.Plugin, error) { query := fmt.Sprintf(` SELECT p.*, @@ -588,7 +588,7 @@ func (p *PostgresBackend) CreateReview(ctx context.Context, dbTx pgx.Tx, reviewD return createdId, nil } -func (p *PostgresBackend) InsertPluginInstallation(ctx context.Context, dbTx pgx.Tx, pluginID types.PluginID, publicKey string) error { +func (p *PostgresBackend) InsertPluginInstallation(ctx context.Context, dbTx pgx.Tx, pluginID string, publicKey string) error { if p.pool == nil { return fmt.Errorf("database pool is nil") } @@ -610,7 +610,7 @@ func (p *PostgresBackend) InsertPluginInstallation(ctx context.Context, dbTx pgx return nil } -func (p *PostgresBackend) GetPluginInstallationsCount(ctx context.Context, pluginID types.PluginID) (itypes.PluginTotalCount, error) { +func (p *PostgresBackend) GetPluginInstallationsCount(ctx context.Context, pluginID string) (itypes.PluginTotalCount, error) { if p.pool == nil { return itypes.PluginTotalCount{}, fmt.Errorf("database pool is nil") } @@ -666,7 +666,7 @@ func (p *PostgresBackend) GetControlFlags(ctx context.Context, k1, k2 string) (m } func EnrichPluginsWithImages(plugins []itypes.Plugin, imageRecords []itypes.PluginImageRecord, assetBaseURL string) { - imagesByPlugin := make(map[types.PluginID][]itypes.PluginImageRecord) + imagesByPlugin := make(map[string][]itypes.PluginImageRecord) for _, rec := range imageRecords { imagesByPlugin[rec.PluginID] = append(imagesByPlugin[rec.PluginID], rec) } diff --git a/internal/storage/postgres/plugin_image.go b/internal/storage/postgres/plugin_image.go index f1ddbe76..1f131ce3 100644 --- a/internal/storage/postgres/plugin_image.go +++ b/internal/storage/postgres/plugin_image.go @@ -8,7 +8,6 @@ import ( "github.com/jackc/pgx/v5" itypes "github.com/vultisig/verifier/internal/types" - "github.com/vultisig/verifier/types" ) func (p *PostgresBackend) CreatePluginImage(ctx context.Context, params itypes.PluginImageCreateParams) (*itypes.PluginImageRecord, error) { @@ -49,16 +48,11 @@ func (p *PostgresBackend) CreatePluginImage(ctx context.Context, params itypes.P return &record, nil } -func (p *PostgresBackend) GetPluginImagesByPluginIDs(ctx context.Context, pluginIDs []types.PluginID) ([]itypes.PluginImageRecord, error) { +func (p *PostgresBackend) GetPluginImagesByPluginIDs(ctx context.Context, pluginIDs []string) ([]itypes.PluginImageRecord, error) { if len(pluginIDs) == 0 { return []itypes.PluginImageRecord{}, nil } - ids := make([]string, 0, len(pluginIDs)) - for _, id := range pluginIDs { - ids = append(ids, string(id)) - } - query := ` SELECT id, plugin_id, image_type, s3_path, image_order, uploaded_by_public_key, visible, deleted, content_type, filename, created_at, updated_at FROM plugin_images @@ -66,7 +60,7 @@ func (p *PostgresBackend) GetPluginImagesByPluginIDs(ctx context.Context, plugin ORDER BY plugin_id, image_type, image_order ASC ` - rows, err := p.pool.Query(ctx, query, ids) + rows, err := p.pool.Query(ctx, query, pluginIDs) if err != nil { return nil, fmt.Errorf("failed to query plugin images: %w", err) } @@ -103,7 +97,7 @@ func (p *PostgresBackend) GetPluginImagesByPluginIDs(ctx context.Context, plugin return records, nil } -func (p *PostgresBackend) GetPluginImageByType(ctx context.Context, pluginID types.PluginID, imageType itypes.PluginImageType) (*itypes.PluginImageRecord, error) { +func (p *PostgresBackend) GetPluginImageByType(ctx context.Context, pluginID string, imageType itypes.PluginImageType) (*itypes.PluginImageRecord, error) { query := ` SELECT id, plugin_id, image_type, s3_path, image_order, uploaded_by_public_key, visible, deleted, content_type, filename, created_at, updated_at FROM plugin_images @@ -137,7 +131,7 @@ func (p *PostgresBackend) GetPluginImageByType(ctx context.Context, pluginID typ return &r, nil } -func (p *PostgresBackend) SoftDeletePluginImage(ctx context.Context, pluginID types.PluginID, imageID uuid.UUID) (string, error) { +func (p *PostgresBackend) SoftDeletePluginImage(ctx context.Context, pluginID string, imageID uuid.UUID) (string, error) { query := `UPDATE plugin_images SET deleted = true, visible = false, updated_at = NOW() WHERE plugin_id = $1 AND id = $2 AND deleted = false RETURNING s3_path` var s3Path string err := p.pool.QueryRow(ctx, query, pluginID, imageID).Scan(&s3Path) @@ -150,7 +144,7 @@ func (p *PostgresBackend) SoftDeletePluginImage(ctx context.Context, pluginID ty return s3Path, nil } -func (p *PostgresBackend) SoftDeletePluginImageTx(ctx context.Context, tx pgx.Tx, pluginID types.PluginID, imageID uuid.UUID) (string, error) { +func (p *PostgresBackend) SoftDeletePluginImageTx(ctx context.Context, tx pgx.Tx, pluginID string, imageID uuid.UUID) (string, error) { query := `UPDATE plugin_images SET deleted = true, visible = false, updated_at = NOW() WHERE plugin_id = $1 AND id = $2 AND deleted = false RETURNING s3_path` var s3Path string err := tx.QueryRow(ctx, query, pluginID, imageID).Scan(&s3Path) @@ -163,7 +157,7 @@ func (p *PostgresBackend) SoftDeletePluginImageTx(ctx context.Context, tx pgx.Tx return s3Path, nil } -func (p *PostgresBackend) ReplacePluginImage(ctx context.Context, pluginID types.PluginID, imageType itypes.PluginImageType, s3Path, contentType, filename, uploadedBy string) (*itypes.PluginImageRecord, error) { +func (p *PostgresBackend) ReplacePluginImage(ctx context.Context, pluginID string, imageType itypes.PluginImageType, s3Path, contentType, filename, uploadedBy string) (*itypes.PluginImageRecord, error) { if imageType == itypes.PluginImageTypeMedia { return nil, fmt.Errorf("ReplacePluginImage not valid for media type, use CreatePluginImage instead") } @@ -216,7 +210,7 @@ func (p *PostgresBackend) ReplacePluginImage(ctx context.Context, pluginID types return result, nil } -func (p *PostgresBackend) GetNextMediaOrder(ctx context.Context, pluginID types.PluginID) (int, error) { +func (p *PostgresBackend) GetNextMediaOrder(ctx context.Context, pluginID string) (int, error) { query := ` SELECT COALESCE(MAX(image_order) + 1, 0) FROM plugin_images @@ -232,7 +226,7 @@ func (p *PostgresBackend) GetNextMediaOrder(ctx context.Context, pluginID types. return nextOrder, nil } -func (p *PostgresBackend) GetNextMediaOrderTx(ctx context.Context, tx pgx.Tx, pluginID types.PluginID) (int, error) { +func (p *PostgresBackend) GetNextMediaOrderTx(ctx context.Context, tx pgx.Tx, pluginID string) (int, error) { query := ` SELECT COALESCE(MAX(image_order) + 1, 0) FROM plugin_images @@ -248,7 +242,7 @@ func (p *PostgresBackend) GetNextMediaOrderTx(ctx context.Context, tx pgx.Tx, pl return nextOrder, nil } -func (p *PostgresBackend) LockPluginForUpdate(ctx context.Context, tx pgx.Tx, pluginID types.PluginID) error { +func (p *PostgresBackend) LockPluginForUpdate(ctx context.Context, tx pgx.Tx, pluginID string) error { _, err := tx.Exec(ctx, `SELECT 1 FROM plugins WHERE id = $1 FOR UPDATE`, pluginID) if err != nil { return fmt.Errorf("failed to lock plugin: %w", err) @@ -256,7 +250,7 @@ func (p *PostgresBackend) LockPluginForUpdate(ctx context.Context, tx pgx.Tx, pl return nil } -func (p *PostgresBackend) CountVisibleMediaImages(ctx context.Context, tx pgx.Tx, pluginID types.PluginID) (int, error) { +func (p *PostgresBackend) CountVisibleMediaImages(ctx context.Context, tx pgx.Tx, pluginID string) (int, error) { query := `SELECT COUNT(*) FROM plugin_images WHERE plugin_id = $1 AND image_type = 'media' AND visible = true AND deleted = false` var count int err := tx.QueryRow(ctx, query, pluginID).Scan(&count) @@ -304,7 +298,7 @@ func (p *PostgresBackend) CreatePendingPluginImage(ctx context.Context, tx pgx.T return &record, nil } -func (p *PostgresBackend) GetPluginImageByID(ctx context.Context, pluginID types.PluginID, imageID uuid.UUID) (*itypes.PluginImageRecord, error) { +func (p *PostgresBackend) GetPluginImageByID(ctx context.Context, pluginID string, imageID uuid.UUID) (*itypes.PluginImageRecord, error) { query := ` SELECT id, plugin_id, image_type, s3_path, image_order, uploaded_by_public_key, visible, deleted, content_type, filename, created_at, updated_at FROM plugin_images @@ -337,7 +331,7 @@ func (p *PostgresBackend) GetPluginImageByID(ctx context.Context, pluginID types } type ListPluginImagesParams struct { - PluginID types.PluginID + PluginID string ImageType *itypes.PluginImageType IncludeHidden bool IncludeDeleted bool @@ -401,7 +395,7 @@ func (p *PostgresBackend) ListPluginImages(ctx context.Context, params ListPlugi return records, nil } -func (p *PostgresBackend) ConfirmPluginImage(ctx context.Context, tx pgx.Tx, pluginID types.PluginID, imageID uuid.UUID) (*itypes.PluginImageRecord, error) { +func (p *PostgresBackend) ConfirmPluginImage(ctx context.Context, tx pgx.Tx, pluginID string, imageID uuid.UUID) (*itypes.PluginImageRecord, error) { var imageType string err := tx.QueryRow(ctx, `SELECT image_type FROM plugin_images WHERE id = $1 AND plugin_id = $2 AND visible = false AND deleted = false`, imageID, pluginID).Scan(&imageType) if err != nil { @@ -452,7 +446,7 @@ func (p *PostgresBackend) ConfirmPluginImage(ctx context.Context, tx pgx.Tx, plu return &r, nil } -func (p *PostgresBackend) UpdatePluginImage(ctx context.Context, pluginID types.PluginID, imageID uuid.UUID, visible *bool, imageOrder *int) (*itypes.PluginImageRecord, error) { +func (p *PostgresBackend) UpdatePluginImage(ctx context.Context, pluginID string, imageID uuid.UUID, visible *bool, imageOrder *int) (*itypes.PluginImageRecord, error) { query := ` UPDATE plugin_images SET visible = COALESCE($3, visible), @@ -487,7 +481,7 @@ func (p *PostgresBackend) UpdatePluginImage(ctx context.Context, pluginID types. return &r, nil } -func (p *PostgresBackend) ReorderMediaImages(ctx context.Context, tx pgx.Tx, pluginID types.PluginID, imageIDs []uuid.UUID) error { +func (p *PostgresBackend) ReorderMediaImages(ctx context.Context, tx pgx.Tx, pluginID string, imageIDs []uuid.UUID) error { if len(imageIDs) == 0 { return nil } diff --git a/internal/storage/postgres/plugin_owner.go b/internal/storage/postgres/plugin_owner.go index f3abc28c..53a53610 100644 --- a/internal/storage/postgres/plugin_owner.go +++ b/internal/storage/postgres/plugin_owner.go @@ -5,10 +5,9 @@ import ( "fmt" itypes "github.com/vultisig/verifier/internal/types" - "github.com/vultisig/verifier/types" ) -func (p *PostgresBackend) IsOwner(ctx context.Context, pluginID types.PluginID, publicKey string) (bool, error) { +func (p *PostgresBackend) IsOwner(ctx context.Context, pluginID string, publicKey string) (bool, error) { query := `SELECT EXISTS(SELECT 1 FROM plugin_owners WHERE plugin_id = $1 AND public_key = $2 AND active = TRUE)` var exists bool err := p.pool.QueryRow(ctx, query, pluginID, publicKey).Scan(&exists) @@ -18,7 +17,7 @@ func (p *PostgresBackend) IsOwner(ctx context.Context, pluginID types.PluginID, return exists, nil } -func (p *PostgresBackend) GetPluginsByOwner(ctx context.Context, publicKey string) ([]types.PluginID, error) { +func (p *PostgresBackend) GetPluginsByOwner(ctx context.Context, publicKey string) ([]string, error) { query := `SELECT plugin_id FROM plugin_owners WHERE public_key = $1 AND active = TRUE` rows, err := p.pool.Query(ctx, query, publicKey) if err != nil { @@ -26,9 +25,9 @@ func (p *PostgresBackend) GetPluginsByOwner(ctx context.Context, publicKey strin } defer rows.Close() - var pluginIDs []types.PluginID + var pluginIDs []string for rows.Next() { - var id types.PluginID + var id string err := rows.Scan(&id) if err != nil { return nil, fmt.Errorf("failed to scan plugin id: %w", err) @@ -43,7 +42,7 @@ func (p *PostgresBackend) GetPluginsByOwner(ctx context.Context, publicKey strin return pluginIDs, nil } -func (p *PostgresBackend) AddOwner(ctx context.Context, pluginID types.PluginID, publicKey string, addedVia itypes.PluginOwnerAddedVia, addedBy string) error { +func (p *PostgresBackend) AddOwner(ctx context.Context, pluginID string, publicKey string, addedVia itypes.PluginOwnerAddedVia, addedBy string) error { query := ` INSERT INTO plugin_owners (plugin_id, public_key, active, added_via, added_by_public_key) VALUES ($1, $2, TRUE, $3, $4) @@ -57,7 +56,7 @@ func (p *PostgresBackend) AddOwner(ctx context.Context, pluginID types.PluginID, return nil } -func (p *PostgresBackend) DeactivateOwner(ctx context.Context, pluginID types.PluginID, publicKey string) error { +func (p *PostgresBackend) DeactivateOwner(ctx context.Context, pluginID string, publicKey string) error { query := `UPDATE plugin_owners SET active = FALSE, updated_at = NOW() WHERE plugin_id = $1 AND public_key = $2` _, err := p.pool.Exec(ctx, query, pluginID, publicKey) if err != nil { diff --git a/internal/storage/postgres/policy.go b/internal/storage/postgres/policy.go index 192cc6f2..882dc6f4 100644 --- a/internal/storage/postgres/policy.go +++ b/internal/storage/postgres/policy.go @@ -68,7 +68,7 @@ func (p *PostgresBackend) GetPluginPolicy(ctx context.Context, id uuid.UUID) (*t return &policy, nil } -func (p *PostgresBackend) GetPluginPolicies(ctx context.Context, publicKey string, pluginIds []types.PluginID, includeInactive bool) ([]types.PluginPolicy, error) { +func (p *PostgresBackend) GetPluginPolicies(ctx context.Context, publicKey string, pluginIds []string, includeInactive bool) ([]types.PluginPolicy, error) { var rows pgx.Rows var err error @@ -85,20 +85,16 @@ FROM plugin_policies WHERE public_key = $1 AND deleted = false`, publicKey) } } else { - pids := []string{} - for _, pid := range pluginIds { - pids = append(pids, pid.String()) - } if !includeInactive { rows, err = p.pool.Query(ctx, ` SELECT id, public_key, plugin_id, plugin_version, policy_version, signature, active, recipe, deactivation_reason FROM plugin_policies -WHERE public_key = $1 AND plugin_id = ANY($2) AND active = true AND deleted = false`, publicKey, pids) +WHERE public_key = $1 AND plugin_id = ANY($2) AND active = true AND deleted = false`, publicKey, pluginIds) } else { rows, err = p.pool.Query(ctx, ` SELECT id, public_key, plugin_id, plugin_version, policy_version, signature, active, recipe, deactivation_reason FROM plugin_policies -WHERE public_key = $1 AND plugin_id = ANY($2) AND deleted = false`, publicKey, pids) +WHERE public_key = $1 AND plugin_id = ANY($2) AND deleted = false`, publicKey, pluginIds) } } @@ -134,7 +130,7 @@ WHERE public_key = $1 AND plugin_id = ANY($2) AND deleted = false`, publicKey, p return policies, nil } -func (p *PostgresBackend) GetAllPluginPolicies(ctx context.Context, publicKey string, pluginID types.PluginID, take int, skip int, activeFilter *bool) (*itypes.PluginPolicyPaginatedList, error) { +func (p *PostgresBackend) GetAllPluginPolicies(ctx context.Context, publicKey string, pluginID string, take int, skip int, activeFilter *bool) (*itypes.PluginPolicyPaginatedList, error) { if p.pool == nil { return nil, fmt.Errorf("database pool is nil") } @@ -446,7 +442,7 @@ func (p *PostgresBackend) UpdatePluginPolicySync(ctx context.Context, dbTx pgx.T return nil } -func (p *PostgresBackend) DeleteAllPolicies(ctx context.Context, dbTx pgx.Tx, pluginID types.PluginID, publicKey string) error { +func (p *PostgresBackend) DeleteAllPolicies(ctx context.Context, dbTx pgx.Tx, pluginID string, publicKey string) error { query := `UPDATE plugin_policies SET deleted = true, active = false WHERE plugin_id = $1 AND public_key = $2 AND deleted = false` _, err := dbTx.Exec(ctx, query, pluginID, publicKey) if err != nil { diff --git a/internal/storage/postgres/pricing.go b/internal/storage/postgres/pricing.go index ef3aa104..be857dfb 100644 --- a/internal/storage/postgres/pricing.go +++ b/internal/storage/postgres/pricing.go @@ -6,11 +6,10 @@ import ( "github.com/google/uuid" "github.com/jackc/pgx/v5" - ptypes "github.com/vultisig/verifier/types" - types "github.com/vultisig/verifier/types" + "github.com/vultisig/verifier/types" ) -func (p *PostgresBackend) GetPricingByPluginId(ctx context.Context, pluginId ptypes.PluginID) ([]types.Pricing, error) { +func (p *PostgresBackend) GetPricingByPluginId(ctx context.Context, pluginId string) ([]types.Pricing, error) { query := `SELECT pricings.* FROM pricings WHERE pricings.plugin_id = $1` rows, err := p.pool.Query(ctx, query, pluginId) diff --git a/internal/storage/postgres/reports.go b/internal/storage/postgres/reports.go index 10f9a1dd..4c3d6c24 100644 --- a/internal/storage/postgres/reports.go +++ b/internal/storage/postgres/reports.go @@ -10,7 +10,6 @@ import ( itypes "github.com/vultisig/verifier/internal/types" "github.com/vultisig/verifier/plugin/safety" - "github.com/vultisig/verifier/types" ) const ( @@ -18,7 +17,7 @@ const ( PLUGIN_PAUSE_HISTORY_TABLE = "plugin_pause_history" ) -func (p *PostgresBackend) UpsertReport(ctx context.Context, pluginID types.PluginID, publicKey, reason, details string, cooldown time.Duration) error { +func (p *PostgresBackend) UpsertReport(ctx context.Context, pluginID string, publicKey, reason, details string, cooldown time.Duration) error { if p.pool == nil { return fmt.Errorf("database pool is nil") } @@ -48,7 +47,7 @@ func (p *PostgresBackend) UpsertReport(ctx context.Context, pluginID types.Plugi return nil } -func (p *PostgresBackend) GetReport(ctx context.Context, pluginID types.PluginID, publicKey string) (*itypes.PluginReport, error) { +func (p *PostgresBackend) GetReport(ctx context.Context, pluginID string, publicKey string) (*itypes.PluginReport, error) { if p.pool == nil { return nil, fmt.Errorf("database pool is nil") } @@ -79,7 +78,7 @@ func (p *PostgresBackend) GetReport(ctx context.Context, pluginID types.PluginID return &report, nil } -func (p *PostgresBackend) CountReportsInWindow(ctx context.Context, pluginID types.PluginID, window time.Duration) (int, error) { +func (p *PostgresBackend) CountReportsInWindow(ctx context.Context, pluginID string, window time.Duration) (int, error) { if p.pool == nil { return 0, fmt.Errorf("database pool is nil") } @@ -101,7 +100,7 @@ func (p *PostgresBackend) CountReportsInWindow(ctx context.Context, pluginID typ return count, nil } -func (p *PostgresBackend) HasInstallation(ctx context.Context, pluginID types.PluginID, publicKey string) (bool, error) { +func (p *PostgresBackend) HasInstallation(ctx context.Context, pluginID string, publicKey string) (bool, error) { if p.pool == nil { return false, fmt.Errorf("database pool is nil") } @@ -121,7 +120,7 @@ func (p *PostgresBackend) HasInstallation(ctx context.Context, pluginID types.Pl return exists, nil } -func (p *PostgresBackend) CountInstallations(ctx context.Context, pluginID types.PluginID) (int, error) { +func (p *PostgresBackend) CountInstallations(ctx context.Context, pluginID string) (int, error) { if p.pool == nil { return 0, fmt.Errorf("database pool is nil") } @@ -140,13 +139,13 @@ func (p *PostgresBackend) CountInstallations(ctx context.Context, pluginID types return count, nil } -func (p *PostgresBackend) IsPluginPaused(ctx context.Context, pluginID types.PluginID) (bool, error) { +func (p *PostgresBackend) IsPluginPaused(ctx context.Context, pluginID string) (bool, error) { if p.pool == nil { return false, fmt.Errorf("database pool is nil") } - keysignKey := safety.KeysignFlagKey(string(pluginID)) - keygenKey := safety.KeygenFlagKey(string(pluginID)) + keysignKey := safety.KeysignFlagKey(pluginID) + keygenKey := safety.KeygenFlagKey(pluginID) keys := []string{keysignKey, keygenKey} query := ` @@ -222,10 +221,10 @@ func (p *PostgresBackend) recordPauseHistoryTx(ctx context.Context, tx pgx.Tx, r return nil } -func (p *PostgresBackend) PausePlugin(ctx context.Context, pluginID types.PluginID, record itypes.PauseHistoryRecord) error { +func (p *PostgresBackend) PausePlugin(ctx context.Context, pluginID string, record itypes.PauseHistoryRecord) error { return p.WithTransaction(ctx, func(ctx context.Context, tx pgx.Tx) error { - keysignKey := safety.KeysignFlagKey(string(pluginID)) - keygenKey := safety.KeygenFlagKey(string(pluginID)) + keysignKey := safety.KeysignFlagKey(pluginID) + keygenKey := safety.KeygenFlagKey(pluginID) err := p.setControlFlagTx(ctx, tx, keysignKey, false) if err != nil { diff --git a/internal/syncer/safety.go b/internal/syncer/safety.go index 189a6e13..1025b39d 100644 --- a/internal/syncer/safety.go +++ b/internal/syncer/safety.go @@ -9,12 +9,11 @@ import ( "net/http" "github.com/vultisig/verifier/plugin/safety" - "github.com/vultisig/verifier/types" ) const safetyEndpoint = "/plugin/safety" -func (s *Syncer) SyncSafetyToPlugin(ctx context.Context, pluginID types.PluginID, flags []safety.ControlFlag) error { +func (s *Syncer) SyncSafetyToPlugin(ctx context.Context, pluginID string, flags []safety.ControlFlag) error { flagBytes, err := json.Marshal(flags) if err != nil { return fmt.Errorf("failed to marshal flags: %w", err) diff --git a/internal/syncer/sync.go b/internal/syncer/sync.go index 4e6c7bfb..f119032c 100644 --- a/internal/syncer/sync.go +++ b/internal/syncer/sync.go @@ -18,7 +18,6 @@ import ( "github.com/vultisig/verifier/internal/storage" itypes "github.com/vultisig/verifier/internal/types" "github.com/vultisig/verifier/types" - ptypes "github.com/vultisig/verifier/types" ) const ( @@ -42,7 +41,7 @@ type Syncer struct { storage storage.DatabaseStorage cacheLocker sync.Locker - pluginServerInfoCache map[ptypes.PluginID]*ServerInfo + pluginServerInfoCache map[string]*ServerInfo } type ServerInfo struct { @@ -60,12 +59,12 @@ func NewPolicySyncer(storage storage.DatabaseStorage) *Syncer { logger: logger, client: retryClient, storage: storage, - pluginServerInfoCache: make(map[ptypes.PluginID]*ServerInfo), + pluginServerInfoCache: make(map[string]*ServerInfo), cacheLocker: &sync.Mutex{}, } } -func (s *Syncer) getServerInfo(ctx context.Context, pluginID ptypes.PluginID) (*ServerInfo, error) { +func (s *Syncer) getServerInfo(ctx context.Context, pluginID string) (*ServerInfo, error) { s.cacheLocker.Lock() defer s.cacheLocker.Unlock() @@ -81,16 +80,16 @@ func (s *Syncer) getServerInfo(ctx context.Context, pluginID ptypes.PluginID) (* return addr, nil } -func (s *Syncer) getServerInfoFromStorage(ctx context.Context, pluginID ptypes.PluginID) (*ServerInfo, error) { +func (s *Syncer) getServerInfoFromStorage(ctx context.Context, pluginID string) (*ServerInfo, error) { if err := contexthelper.CheckCancellation(ctx); err != nil { return nil, err } - s.logger.Infof("pluginid: %s", pluginID.String()) + s.logger.Infof("pluginid: %s", pluginID) plugin, err := s.storage.FindPluginById(ctx, nil, pluginID) if err != nil { return nil, fmt.Errorf("failed to find plugin by id: %w", err) } - apiKey, err := s.storage.GetAPIKeyByPluginId(ctx, pluginID.String()) + apiKey, err := s.storage.GetAPIKeyByPluginId(ctx, pluginID) if err != nil { return nil, fmt.Errorf("failed to get api key by id: %w", err) } diff --git a/internal/tx_indexer/indexer.go b/internal/tx_indexer/indexer.go index 5a60c908..bab8e142 100644 --- a/internal/tx_indexer/indexer.go +++ b/internal/tx_indexer/indexer.go @@ -11,6 +11,7 @@ import ( "golang.org/x/sync/errgroup" vstorage "github.com/vultisig/verifier/internal/storage" + itypes "github.com/vultisig/verifier/internal/types" "github.com/vultisig/verifier/plugin/tx_indexer" "github.com/vultisig/verifier/plugin/tx_indexer/pkg/graceful" "github.com/vultisig/verifier/plugin/tx_indexer/pkg/rpc" @@ -73,7 +74,7 @@ func (fi *FeeIndexer) updateTxStatus(ctx context.Context, tx storage.Tx) error { return fmt.Errorf("w.UpdateTxStatus: %w", err) } - if tx.PluginID != types.PluginVultisigFees_feee && newStatus != nil && *newStatus == rpc.TxOnChainSuccess { + if tx.PluginID != itypes.PluginVultisigFees && newStatus != nil && *newStatus == rpc.TxOnChainSuccess { err = fi.db.WithTransaction(ctx, func(ctx context.Context, dbTx pgx.Tx) error { var err error @@ -115,7 +116,7 @@ func (fi *FeeIndexer) updateTxStatus(ctx context.Context, tx storage.Tx) error { return fmt.Errorf("failed to insert fee: %w", err) } } - if tx.PluginID == types.PluginVultisigFees_feee { + if tx.PluginID == itypes.PluginVultisigFees { if tx.TxHash == nil { return fmt.Errorf("nil tx hash") } diff --git a/internal/types/api_key.go b/internal/types/api_key.go index 3182bd71..b703dc1d 100644 --- a/internal/types/api_key.go +++ b/internal/types/api_key.go @@ -2,14 +2,12 @@ package types import ( "time" - - "github.com/vultisig/verifier/types" ) type APIKey struct { ID string `json:"id"` ApiKey string `json:"apiKey"` - PluginID types.PluginID `json:"pluginId"` + PluginID string `json:"pluginId"` Status int64 `json:"status"` ExpiresAt *time.Time `json:"expires_at"` } diff --git a/internal/types/plugin.go b/internal/types/plugin.go index b0499e92..126ccb87 100644 --- a/internal/types/plugin.go +++ b/internal/types/plugin.go @@ -9,7 +9,7 @@ import ( ) type Plugin struct { - ID types.PluginID `json:"id" validate:"required"` + ID string `json:"id" validate:"required"` Title string `json:"title" validate:"required"` Description string `json:"description" validate:"required"` ServerEndpoint string `json:"server_endpoint" validate:"required"` @@ -84,7 +84,7 @@ type PluginPolicyPaginatedList struct { } type PluginTotalCount struct { - ID types.PluginID `json:"id" validate:"required"` + ID string `json:"id" validate:"required"` TotalCount int `json:"total_count" validate:"required"` } diff --git a/internal/types/plugin_image.go b/internal/types/plugin_image.go index 1bb72575..6135b4a1 100644 --- a/internal/types/plugin_image.go +++ b/internal/types/plugin_image.go @@ -4,7 +4,6 @@ import ( "time" "github.com/google/uuid" - "github.com/vultisig/verifier/types" ) type PluginImageType string @@ -18,7 +17,7 @@ const ( type PluginImageRecord struct { ID uuid.UUID `json:"id"` - PluginID types.PluginID `json:"plugin_id"` + PluginID string `json:"plugin_id"` ImageType PluginImageType `json:"image_type"` S3Path string `json:"s3_path"` ImageOrder int `json:"image_order"` @@ -33,7 +32,7 @@ type PluginImageRecord struct { type PluginImageCreateParams struct { ID uuid.UUID - PluginID types.PluginID + PluginID string ImageType PluginImageType S3Path string ImageOrder int diff --git a/internal/types/plugin_owner.go b/internal/types/plugin_owner.go index 0f0996b8..d64b098d 100644 --- a/internal/types/plugin_owner.go +++ b/internal/types/plugin_owner.go @@ -2,8 +2,6 @@ package types import ( "time" - - vtypes "github.com/vultisig/verifier/types" ) type PluginOwnerRole string @@ -21,7 +19,7 @@ const ( ) type PluginOwner struct { - PluginID vtypes.PluginID `json:"plugin_id"` + PluginID string `json:"plugin_id"` PublicKey string `json:"public_key"` Active bool `json:"active"` Role PluginOwnerRole `json:"role"` diff --git a/internal/types/policy_sync.go b/internal/types/policy_sync.go index 45a3b2fb..d02a37a4 100644 --- a/internal/types/policy_sync.go +++ b/internal/types/policy_sync.go @@ -2,7 +2,6 @@ package types import ( "github.com/google/uuid" - ptypes "github.com/vultisig/verifier/types" ) type PolicySyncStatus int @@ -23,7 +22,7 @@ const ( type PluginPolicySync struct { ID uuid.UUID `json:"id" validate:"required"` PolicyID uuid.UUID `json:"policy_id" validate:"required"` - PluginID ptypes.PluginID `json:"plugin_id" validate:"required"` + PluginID string `json:"plugin_id" validate:"required"` Signature string `json:"signature" validate:"required"` SyncType PolicySyncType `json:"sync_type" validate:"required"` Status PolicySyncStatus `json:"status" validate:"required"` diff --git a/internal/types/registry.go b/internal/types/registry.go new file mode 100644 index 00000000..532bf6a5 --- /dev/null +++ b/internal/types/registry.go @@ -0,0 +1,11 @@ +package types + +// Each plugin must reserve a unique ID. +// +// A plugin ID is comprised of a all-lowercase string, ending with 4 random hex digits. +// +// Example: vultisig-dca-00a1 +const ( + PluginVultisigFees = "vultisig-fees-feee" + PluginVultisigRecurringSends = "vultisig-recurring-sends-0000" +) diff --git a/internal/types/report.go b/internal/types/report.go index 3c4d9e03..ce4ffe62 100644 --- a/internal/types/report.go +++ b/internal/types/report.go @@ -5,8 +5,6 @@ import ( "time" "github.com/google/uuid" - - "github.com/vultisig/verifier/types" ) var ( @@ -14,8 +12,8 @@ var ( ) type PluginReport struct { - PluginID types.PluginID `json:"plugin_id"` - ReporterPubKey string `json:"reporter_public_key"` + PluginID string `json:"plugin_id"` + ReporterPubKey string `json:"reporter_public_key"` Reason string `json:"reason"` Details string `json:"details"` CreatedAt time.Time `json:"created_at"` @@ -25,7 +23,7 @@ type PluginReport struct { type PauseHistoryRecord struct { ID uuid.UUID `json:"id"` - PluginID types.PluginID `json:"plugin_id"` + PluginID string `json:"plugin_id"` Action string `json:"action"` ReportCountWindow *int `json:"report_count_window,omitempty"` ActiveUsers *int `json:"active_users,omitempty"` diff --git a/internal/types/transaction.go b/internal/types/transaction.go index eb3f7c2e..b31ed1eb 100644 --- a/internal/types/transaction.go +++ b/internal/types/transaction.go @@ -15,7 +15,7 @@ import ( // It matches the Fee format as closely as possible for frontend consistency. type PluginTransactionResponse struct { ID uuid.UUID `json:"id"` - PluginID vtypes.PluginID `json:"plugin_id"` + PluginID string `json:"plugin_id"` AppName string `json:"app_name"` // Plugin title for display PolicyID uuid.UUID `json:"policy_id"` PublicKey string `json:"public_key"` // Matches Fee format (was from_public_key) @@ -37,7 +37,7 @@ type PluginTransactionResponse struct { func FromStorageTxs(txs []storage.Tx, titleMap map[string]string) []PluginTransactionResponse { result := make([]PluginTransactionResponse, len(txs)) for i, tx := range txs { - appName := titleMap[string(tx.PluginID)] + appName := titleMap[tx.PluginID] result[i] = PluginTransactionResponse{ ID: tx.ID, PluginID: tx.PluginID, @@ -69,7 +69,7 @@ type TransactionHistoryPaginatedList struct { // It matches the transaction history format for frontend consistency. type PluginFeeResponse struct { ID uint64 `json:"id"` - PluginID vtypes.PluginID `json:"plugin_id"` + PluginID string `json:"plugin_id"` AppName string `json:"app_name"` // Plugin title for display PolicyID uuid.UUID `json:"policy_id"` PublicKey string `json:"public_key"` @@ -94,7 +94,7 @@ func FromFeesWithStatus(fees []FeeWithStatus, titleMap map[string]string) []Plug appName := titleMap[fee.PluginID] result[i] = PluginFeeResponse{ ID: fee.ID, - PluginID: vtypes.PluginID(fee.PluginID), + PluginID: fee.PluginID, AppName: appName, PolicyID: fee.PolicyID, PublicKey: fee.PublicKey, @@ -130,7 +130,7 @@ type PricingInfo struct { // PluginBillingSummary is the response DTO for plugin billing info type PluginBillingSummary struct { - PluginID vtypes.PluginID `json:"plugin_id"` + PluginID string `json:"plugin_id"` AppName string `json:"app_name"` Pricing string `json:"pricing"` // Formatted: "0.50 USDC one-time + 0.01 USDC per transaction" StartDate time.Time `json:"start_date"` diff --git a/plugin/policy/policy_pg/repo.go b/plugin/policy/policy_pg/repo.go index ad900391..1a045198 100644 --- a/plugin/policy/policy_pg/repo.go +++ b/plugin/policy/policy_pg/repo.go @@ -53,7 +53,7 @@ func (r *Repo) GetPluginPolicy(ctx context.Context, id uuid.UUID) (*types.Plugin return &policy, nil } -func (r *Repo) GetAllPluginPolicies(ctx context.Context, publicKey string, pluginID types.PluginID, onlyActive bool) ([]types.PluginPolicy, error) { +func (r *Repo) GetAllPluginPolicies(ctx context.Context, publicKey string, pluginID string, onlyActive bool) ([]types.PluginPolicy, error) { query := ` SELECT id, public_key, plugin_id, plugin_version, policy_version, signature, active, recipe, deactivation_reason FROM plugin_policies diff --git a/plugin/policy/service.go b/plugin/policy/service.go index e4898a2b..28c605b1 100644 --- a/plugin/policy/service.go +++ b/plugin/policy/service.go @@ -18,7 +18,7 @@ type Service interface { DeletePolicy(ctx context.Context, policyID uuid.UUID, signature string) error GetPluginPolicies( ctx context.Context, - pluginID types.PluginID, + pluginID string, publicKey string, onlyActive bool, ) ([]types.PluginPolicy, error) @@ -130,7 +130,7 @@ func (p *Policy) DeletePolicy(c context.Context, policyID uuid.UUID, signature s func (p *Policy) GetPluginPolicies( ctx context.Context, - pluginID types.PluginID, + pluginID string, publicKey string, onlyActive bool, ) ([]types.PluginPolicy, error) { diff --git a/plugin/policy/storage.go b/plugin/policy/storage.go index 60a52ad5..c97155c4 100644 --- a/plugin/policy/storage.go +++ b/plugin/policy/storage.go @@ -14,7 +14,7 @@ type Storage interface { GetAllPluginPolicies( ctx context.Context, publicKey string, - pluginID types.PluginID, + pluginID string, onlyActive bool, ) ([]types.PluginPolicy, error) DeletePluginPolicy(ctx context.Context, id uuid.UUID) error diff --git a/plugin/server/server.go b/plugin/server/server.go index 1cc3df33..8f2714db 100644 --- a/plugin/server/server.go +++ b/plugin/server/server.go @@ -477,7 +477,7 @@ func (s *Server) verifyPolicySignature(policy vtypes.PluginPolicy) bool { s.logger.WithError(err).Error("Failed to decode signature bytes") return false } - vault, err := s.getVault(policy.PublicKey, policy.PluginID.String()) + vault, err := s.getVault(policy.PublicKey, policy.PluginID) if err != nil { s.logger.WithError(err).Error("fail to get vault") return false diff --git a/plugin/tx_indexer/pkg/storage/postgres.go b/plugin/tx_indexer/pkg/storage/postgres.go index 691b6c4e..16587285 100644 --- a/plugin/tx_indexer/pkg/storage/postgres.go +++ b/plugin/tx_indexer/pkg/storage/postgres.go @@ -10,7 +10,6 @@ import ( "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" "github.com/vultisig/verifier/plugin/tx_indexer/pkg/rpc" - "github.com/vultisig/verifier/types" ) const maxErrorMessageLength = 2048 @@ -322,7 +321,7 @@ func (p *PostgresTxIndexStore) CountByPolicyID(c context.Context, policyID uuid. func (p *PostgresTxIndexStore) GetByPluginIDAndPublicKey( c context.Context, - pluginID types.PluginID, + pluginID string, publicKey string, skip, take uint32, ) <-chan RowsStream[Tx] { @@ -338,7 +337,7 @@ func (p *PostgresTxIndexStore) GetByPluginIDAndPublicKey( ) } -func (p *PostgresTxIndexStore) CountByPluginIDAndPublicKey(c context.Context, pluginID types.PluginID, publicKey string) (uint32, error) { +func (p *PostgresTxIndexStore) CountByPluginIDAndPublicKey(c context.Context, pluginID string, publicKey string) (uint32, error) { ctx, cancel := context.WithTimeout(c, defaultTimeout) defer cancel() diff --git a/plugin/tx_indexer/pkg/storage/types.go b/plugin/tx_indexer/pkg/storage/types.go index 738e38ff..8582ad25 100644 --- a/plugin/tx_indexer/pkg/storage/types.go +++ b/plugin/tx_indexer/pkg/storage/types.go @@ -9,7 +9,6 @@ import ( "github.com/sirupsen/logrus" "github.com/vultisig/verifier/plugin/tx_indexer/pkg/conv" "github.com/vultisig/verifier/plugin/tx_indexer/pkg/rpc" - "github.com/vultisig/verifier/types" "github.com/vultisig/vultisig-go/common" ) @@ -24,8 +23,8 @@ type TxIndexerRepo interface { GetTxsInTimeRange(ctx context.Context, policyID uuid.UUID, from, to time.Time) <-chan RowsStream[Tx] GetByPolicyID(ctx context.Context, policyID uuid.UUID, skip, take uint32) <-chan RowsStream[Tx] CountByPolicyID(ctx context.Context, policyID uuid.UUID) (uint32, error) - GetByPluginIDAndPublicKey(ctx context.Context, pluginID types.PluginID, publicKey string, skip, take uint32) <-chan RowsStream[Tx] - CountByPluginIDAndPublicKey(ctx context.Context, pluginID types.PluginID, publicKey string) (uint32, error) + GetByPluginIDAndPublicKey(ctx context.Context, pluginID string, publicKey string, skip, take uint32) <-chan RowsStream[Tx] + CountByPluginIDAndPublicKey(ctx context.Context, pluginID string, publicKey string) (uint32, error) GetByPublicKey(ctx context.Context, publicKey string, skip, take uint32) <-chan RowsStream[Tx] CountByPublicKey(ctx context.Context, publicKey string) (uint32, error) } @@ -42,7 +41,7 @@ var ErrNoTx = errors.New("transaction not found") type Tx struct { ID uuid.UUID `json:"id" validate:"required"` - PluginID types.PluginID `json:"plugin_id" validate:"required"` + PluginID string `json:"plugin_id" validate:"required"` TxHash *string `json:"tx_hash"` ChainID int `json:"chain_id" validate:"required"` PolicyID uuid.UUID `json:"policy_id" validate:"required"` @@ -80,7 +79,7 @@ func (t *Tx) Fields() logrus.Fields { } type CreateTxDto struct { - PluginID types.PluginID + PluginID string ChainID common.Chain PolicyID uuid.UUID TokenID string diff --git a/plugin/tx_indexer/service.go b/plugin/tx_indexer/service.go index a36002f7..8cbd9317 100644 --- a/plugin/tx_indexer/service.go +++ b/plugin/tx_indexer/service.go @@ -13,7 +13,6 @@ import ( "github.com/vultisig/mobile-tss-lib/tss" "github.com/vultisig/verifier/plugin/tx_indexer/pkg/rpc" "github.com/vultisig/verifier/plugin/tx_indexer/pkg/storage" - "github.com/vultisig/verifier/types" "github.com/vultisig/vultisig-go/common" "golang.org/x/sync/errgroup" ) @@ -160,7 +159,7 @@ func (t *Service) GetByPolicyID( func (t *Service) GetByPluginIDAndPublicKey( c context.Context, - pluginID types.PluginID, + pluginID string, publicKey string, skip, take uint32, ) ([]storage.Tx, uint32, error) { diff --git a/plugin/tx_indexer/worker_test.go b/plugin/tx_indexer/worker_test.go index bdcdf89e..00f8a156 100644 --- a/plugin/tx_indexer/worker_test.go +++ b/plugin/tx_indexer/worker_test.go @@ -112,7 +112,7 @@ func TestWorker_positive(t *testing.T) { require.Nil(t, err) txBefore, err := db.CreateTx(ctx, storage.CreateTxDto{ - PluginID: "vultisig-payroll-0000", + PluginID: "vultisig-recurring-sends-0000", ChainID: testcase.chain, PolicyID: policyID, FromPublicKey: testcase.fromPublicKey, diff --git a/scripts/migrate-images/main.go b/scripts/migrate-images/main.go index 51ca5e6b..468fc752 100644 --- a/scripts/migrate-images/main.go +++ b/scripts/migrate-images/main.go @@ -19,7 +19,6 @@ import ( "github.com/vultisig/verifier/config" "github.com/vultisig/verifier/internal/storage" itypes "github.com/vultisig/verifier/internal/types" - "github.com/vultisig/verifier/types" ) const ( @@ -34,7 +33,7 @@ var ( ) type pluginData struct { - ID types.PluginID + ID string LogoURL string BannerURL string MediaURLs []string @@ -225,7 +224,7 @@ func getExistingPluginIDs(ctx context.Context, pool *pgxpool.Pool) (map[string]b return result, rows.Err() } -func hasActiveImage(ctx context.Context, pool *pgxpool.Pool, pluginID types.PluginID, imageType itypes.PluginImageType) (bool, error) { +func hasActiveImage(ctx context.Context, pool *pgxpool.Pool, pluginID string, imageType itypes.PluginImageType) (bool, error) { query := `SELECT EXISTS(SELECT 1 FROM plugin_images WHERE plugin_id = $1 AND image_type = $2 AND deleted = false AND visible = true)` var exists bool err := pool.QueryRow(ctx, query, pluginID, string(imageType)).Scan(&exists) @@ -235,7 +234,7 @@ func hasActiveImage(ctx context.Context, pool *pgxpool.Pool, pluginID types.Plug return exists, nil } -func migrateImage(ctx context.Context, logger *logrus.Logger, client *http.Client, pool *pgxpool.Pool, assetStorage storage.PluginAssetStorage, pluginID types.PluginID, source string, imageType itypes.PluginImageType, imageOrder int) error { +func migrateImage(ctx context.Context, logger *logrus.Logger, client *http.Client, pool *pgxpool.Pool, assetStorage storage.PluginAssetStorage, pluginID string, source string, imageType itypes.PluginImageType, imageOrder int) error { if *dryRun { logger.Infof("[DRY-RUN] would migrate %s for plugin %s from %s", imageType, pluginID, source) return nil diff --git a/types/keysign.go b/types/keysign.go index 3baf8d3f..a33f60ef 100644 --- a/types/keysign.go +++ b/types/keysign.go @@ -97,7 +97,7 @@ func NewPluginKeysignRequestEvm(policy PluginPolicy, txToTrack string, chain vgc }, }, PolicyID: policy.ID, - PluginID: policy.PluginID.String(), + PluginID: policy.PluginID, }, Transaction: base64.StdEncoding.EncodeToString(tx), }, nil diff --git a/types/policy.go b/types/policy.go index 57103330..57453d21 100644 --- a/types/policy.go +++ b/types/policy.go @@ -40,7 +40,7 @@ const ( type PluginPolicy struct { ID uuid.UUID `json:"id" validate:"required"` PublicKey string `json:"public_key" validate:"required"` - PluginID PluginID `json:"plugin_id" validate:"required"` + PluginID string `json:"plugin_id" validate:"required"` PluginVersion string `json:"plugin_version" validate:"required"` PolicyVersion int `json:"policy_version" validate:"required"` Signature string `json:"signature" validate:"required"` diff --git a/types/pricing.go b/types/pricing.go index f7a5f745..a7c36654 100644 --- a/types/pricing.go +++ b/types/pricing.go @@ -44,7 +44,7 @@ type Pricing struct { Metric PricingMetric `json:"metric" validate:"required"` CreatedAt time.Time `json:"created_at" validate:"required"` UpdatedAt time.Time `json:"updated_at" validate:"required"` - PluginID PluginID `json:"plugin_id" validate:"required"` + PluginID string `json:"plugin_id" validate:"required"` } type PricingCreateDataDto struct { Type PricingType `json:"type" validate:"required"` @@ -54,5 +54,5 @@ type PricingCreateDataDto struct { } type PricingCreateDto struct { PricingCreateDataDto - PluginID PluginID `json:"plugin_id" validate:"required"` + PluginID string `json:"plugin_id" validate:"required"` } diff --git a/types/registry.go b/types/registry.go index 69771a09..ab1254f4 100644 --- a/types/registry.go +++ b/types/registry.go @@ -1,20 +1 @@ package types - -type PluginID string - -// Each plugin must reserve a unique ID. -// -// A plugin ID is comprised of a all-lowercase string, ending with 4 random hex digits. -// -// Example: vultisig-dca-00a1 -const ( - PluginVultisigDCA_0000 PluginID = "vultisig-dca-0000" - PluginVultisigRecurringSends_0000 PluginID = "vultisig-recurring-sends-0000" - PluginVultisigPayroll_0000 PluginID = "vultisig-payroll-0000" - PluginVultisigFees_feee PluginID = "vultisig-fees-feee" - PluginNBitsLabsMerkle_0000 PluginID = "nbits-labs-merkle-e93d" -) - -func (p PluginID) String() string { - return string(p) -} From 6ec1aee98b54cbcb0119af5dc7cefa92d0d11b81 Mon Sep 17 00:00:00 2001 From: Raghav Sood Date: Sun, 8 Feb 2026 19:54:12 +0800 Subject: [PATCH 2/3] types: remove registry file --- types/registry.go | 1 - 1 file changed, 1 deletion(-) delete mode 100644 types/registry.go diff --git a/types/registry.go b/types/registry.go deleted file mode 100644 index ab1254f4..00000000 --- a/types/registry.go +++ /dev/null @@ -1 +0,0 @@ -package types From 934088ded52f447fb84b703d0672d48c07b38637 Mon Sep 17 00:00:00 2001 From: Raghav Sood Date: Sun, 8 Feb 2026 20:03:11 +0800 Subject: [PATCH 3/3] go: fmt --- internal/api/server.go | 2 +- internal/types/api_key.go | 10 ++++---- internal/types/plugin.go | 4 ++-- internal/types/report.go | 32 +++++++++++++------------- internal/types/transaction.go | 12 +++++----- plugin/tx_indexer/pkg/storage/types.go | 2 +- 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/internal/api/server.go b/internal/api/server.go index ff964a27..6350d664 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -30,9 +30,9 @@ import ( "github.com/vultisig/verifier/internal/service" "github.com/vultisig/verifier/internal/sigutil" "github.com/vultisig/verifier/internal/storage" - itypes "github.com/vultisig/verifier/internal/types" "github.com/vultisig/verifier/internal/storage/postgres" "github.com/vultisig/verifier/internal/syncer" + itypes "github.com/vultisig/verifier/internal/types" "github.com/vultisig/verifier/plugin/tasks" "github.com/vultisig/verifier/plugin/tx_indexer" vtypes "github.com/vultisig/verifier/types" diff --git a/internal/types/api_key.go b/internal/types/api_key.go index b703dc1d..7a07208b 100644 --- a/internal/types/api_key.go +++ b/internal/types/api_key.go @@ -5,9 +5,9 @@ import ( ) type APIKey struct { - ID string `json:"id"` - ApiKey string `json:"apiKey"` - PluginID string `json:"pluginId"` - Status int64 `json:"status"` - ExpiresAt *time.Time `json:"expires_at"` + ID string `json:"id"` + ApiKey string `json:"apiKey"` + PluginID string `json:"pluginId"` + Status int64 `json:"status"` + ExpiresAt *time.Time `json:"expires_at"` } diff --git a/internal/types/plugin.go b/internal/types/plugin.go index 126ccb87..0cfccbcf 100644 --- a/internal/types/plugin.go +++ b/internal/types/plugin.go @@ -84,8 +84,8 @@ type PluginPolicyPaginatedList struct { } type PluginTotalCount struct { - ID string `json:"id" validate:"required"` - TotalCount int `json:"total_count" validate:"required"` + ID string `json:"id" validate:"required"` + TotalCount int `json:"total_count" validate:"required"` } type RecipeFunctions struct { diff --git a/internal/types/report.go b/internal/types/report.go index ce4ffe62..413e790b 100644 --- a/internal/types/report.go +++ b/internal/types/report.go @@ -12,25 +12,25 @@ var ( ) type PluginReport struct { - PluginID string `json:"plugin_id"` - ReporterPubKey string `json:"reporter_public_key"` - Reason string `json:"reason"` - Details string `json:"details"` - CreatedAt time.Time `json:"created_at"` - LastReportedAt time.Time `json:"last_reported_at"` - ReportCount int `json:"report_count"` + PluginID string `json:"plugin_id"` + ReporterPubKey string `json:"reporter_public_key"` + Reason string `json:"reason"` + Details string `json:"details"` + CreatedAt time.Time `json:"created_at"` + LastReportedAt time.Time `json:"last_reported_at"` + ReportCount int `json:"report_count"` } type PauseHistoryRecord struct { - ID uuid.UUID `json:"id"` - PluginID string `json:"plugin_id"` - Action string `json:"action"` - ReportCountWindow *int `json:"report_count_window,omitempty"` - ActiveUsers *int `json:"active_users,omitempty"` - ThresholdRate *float64 `json:"threshold_rate,omitempty"` - Reason *string `json:"reason,omitempty"` - TriggeredBy *string `json:"triggered_by,omitempty"` - CreatedAt time.Time `json:"created_at"` + ID uuid.UUID `json:"id"` + PluginID string `json:"plugin_id"` + Action string `json:"action"` + ReportCountWindow *int `json:"report_count_window,omitempty"` + ActiveUsers *int `json:"active_users,omitempty"` + ThresholdRate *float64 `json:"threshold_rate,omitempty"` + Reason *string `json:"reason,omitempty"` + TriggeredBy *string `json:"triggered_by,omitempty"` + CreatedAt time.Time `json:"created_at"` } type ReportCreateRequest struct { diff --git a/internal/types/transaction.go b/internal/types/transaction.go index b31ed1eb..88efa5ec 100644 --- a/internal/types/transaction.go +++ b/internal/types/transaction.go @@ -130,12 +130,12 @@ type PricingInfo struct { // PluginBillingSummary is the response DTO for plugin billing info type PluginBillingSummary struct { - PluginID string `json:"plugin_id"` - AppName string `json:"app_name"` - Pricing string `json:"pricing"` // Formatted: "0.50 USDC one-time + 0.01 USDC per transaction" - StartDate time.Time `json:"start_date"` - NextPayment *time.Time `json:"next_payment"` // nil for non-recurring - TotalFees string `json:"total_fees"` + PluginID string `json:"plugin_id"` + AppName string `json:"app_name"` + Pricing string `json:"pricing"` // Formatted: "0.50 USDC one-time + 0.01 USDC per transaction" + StartDate time.Time `json:"start_date"` + NextPayment *time.Time `json:"next_payment"` // nil for non-recurring + TotalFees string `json:"total_fees"` } // PluginBillingSummaryList is the response for the billing summary endpoint diff --git a/plugin/tx_indexer/pkg/storage/types.go b/plugin/tx_indexer/pkg/storage/types.go index 8582ad25..6c844801 100644 --- a/plugin/tx_indexer/pkg/storage/types.go +++ b/plugin/tx_indexer/pkg/storage/types.go @@ -41,7 +41,7 @@ var ErrNoTx = errors.New("transaction not found") type Tx struct { ID uuid.UUID `json:"id" validate:"required"` - PluginID string `json:"plugin_id" validate:"required"` + PluginID string `json:"plugin_id" validate:"required"` TxHash *string `json:"tx_hash"` ChainID int `json:"chain_id" validate:"required"` PolicyID uuid.UUID `json:"policy_id" validate:"required"`