Skip to content
This repository was archived by the owner on Feb 8, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions api/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (s *Server) SignPluginMessages(c echo.Context) error {
return fmt.Errorf("policy plugin ID mismatch")
}

if err := s.plugin.ValidateProposedTransactions(policy.ToPluginPolicyCreateUpdate(), []vtypes.PluginKeysignRequest{req}); err != nil {
if err := s.plugin.ValidateProposedTransactions(policy, []vtypes.PluginKeysignRequest{req}); err != nil {
return fmt.Errorf("failed to validate transaction proposal: %w", err)
}

Expand Down Expand Up @@ -192,7 +192,7 @@ func (s *Server) GetAllPluginPolicies(c echo.Context) error {
}

func (s *Server) CreatePluginPolicy(c echo.Context) error {
var policy vtypes.PluginPolicyCreateUpdate
var policy vtypes.PluginPolicy
if err := c.Bind(&policy); err != nil {
return fmt.Errorf("fail to parse request, err: %w", err)
}
Expand All @@ -208,12 +208,12 @@ func (s *Server) CreatePluginPolicy(c echo.Context) error {
policy.ID = uuid.New()
}

if !s.verifyPolicySignature(policy.ToPluginPolicy()) {
if !s.verifyPolicySignature(policy) {
s.logger.Error("invalid policy signature")
return c.JSON(http.StatusForbidden, NewErrorResponse("Invalid policy signature"))
}

newPolicy, err := s.policyService.CreatePolicy(c.Request().Context(), policy.ToPluginPolicy())
newPolicy, err := s.policyService.CreatePolicy(c.Request().Context(), policy)
if err != nil {
s.logger.WithError(err).Error("Failed to create plugin policy")
return c.JSON(http.StatusInternalServerError, NewErrorResponse("failed to create policy"))
Expand All @@ -223,7 +223,7 @@ func (s *Server) CreatePluginPolicy(c echo.Context) error {
}

func (s *Server) UpdatePluginPolicyById(c echo.Context) error {
var policy vtypes.PluginPolicyCreateUpdate
var policy vtypes.PluginPolicy
if err := c.Bind(&policy); err != nil {
return fmt.Errorf("fail to parse request, err: %w", err)
}
Expand All @@ -236,12 +236,12 @@ func (s *Server) UpdatePluginPolicyById(c echo.Context) error {
return c.JSON(http.StatusBadRequest, NewErrorResponse("failed to validate policy"))
}

if !s.verifyPolicySignature(policy.ToPluginPolicy()) {
if !s.verifyPolicySignature(policy) {
s.logger.Error("invalid policy signature")
return c.JSON(http.StatusForbidden, NewErrorResponse("Invalid policy signature"))
}

updatedPolicy, err := s.policyService.UpdatePolicy(c.Request().Context(), policy.ToPluginPolicy())
updatedPolicy, err := s.policyService.UpdatePolicy(c.Request().Context(), policy)
if err != nil {
s.logger.WithError(err).Error("Failed to update plugin policy")
return c.JSON(http.StatusInternalServerError, NewErrorResponse("failed to update policy"))
Expand Down Expand Up @@ -394,7 +394,7 @@ func policyToMessageHex(policy vtypes.PluginPolicy) ([]byte, error) {
fields := []string{
policy.Recipe,
policy.PublicKey,
policy.PolicyVersion,
fmt.Sprintf("%d", policy.PolicyVersion),
policy.PluginVersion}
for _, item := range fields {
if strings.Contains(item, delimiter) {
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ require (
github.com/spf13/viper v1.20.1
github.com/vultisig/commondata v0.0.0-20250430024109-a2492623ef05
github.com/vultisig/mobile-tss-lib v0.0.0-20250316003201-2e7e570a4a74
github.com/vultisig/recipes v0.0.0-20250606100120-0ee16a73412d
github.com/vultisig/verifier v0.0.0-20250611063307-6e5e760de529
github.com/vultisig/recipes v0.0.0-20250609134859-0655e0445c1b
github.com/vultisig/verifier v0.0.0-20250612165949-9db8a6828606
github.com/vultisig/vultiserver v0.0.0-20250515110921-82d56d3d9cc9
)

Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -745,10 +745,10 @@ github.com/vultisig/go-wrappers v0.0.0-20250403041248-86911e8aa33f h1:124Xlloih1
github.com/vultisig/go-wrappers v0.0.0-20250403041248-86911e8aa33f/go.mod h1:UfGCxUQW08kiwxyNBiHwXe+ePPuBmHVVS+BS51aU/Jg=
github.com/vultisig/mobile-tss-lib v0.0.0-20250316003201-2e7e570a4a74 h1:goqwk4nQ/NEVIb3OPP9SUx7/u9ZfsUIcd5fIN/e4DVU=
github.com/vultisig/mobile-tss-lib v0.0.0-20250316003201-2e7e570a4a74/go.mod h1:nOykk4nOy1L3yXtLSlYvVsgizBnCQ3tR2N5uwGPdvaM=
github.com/vultisig/recipes v0.0.0-20250606100120-0ee16a73412d h1:BVc4OL0BNY/cCmptU3EeqAoxcX8vS13Pr13gWpd5Xi0=
github.com/vultisig/recipes v0.0.0-20250606100120-0ee16a73412d/go.mod h1:JT1FTsiJ8tY5W065vSsrxvrCSl1amp5o6SsBc1VVcCQ=
github.com/vultisig/verifier v0.0.0-20250611063307-6e5e760de529 h1:owEyLmbtlN1yL0xG7EhzXgvXbBZYHSHITh4P8lvPhyQ=
github.com/vultisig/verifier v0.0.0-20250611063307-6e5e760de529/go.mod h1:YpvZN2mbn6Z/34FDfnMS/TdE+B5Y8jghu5FvqOfRmB0=
github.com/vultisig/recipes v0.0.0-20250609134859-0655e0445c1b h1:rXhRaf40re1FdUYlYbCTEIO6JqIx8FfLlksksu8LiGE=
github.com/vultisig/recipes v0.0.0-20250609134859-0655e0445c1b/go.mod h1:JT1FTsiJ8tY5W065vSsrxvrCSl1amp5o6SsBc1VVcCQ=
github.com/vultisig/verifier v0.0.0-20250612165949-9db8a6828606 h1:DGia8ZQM3izAm+Oo/LM+5yWzENc9MIWtEfFCsCZOgO0=
github.com/vultisig/verifier v0.0.0-20250612165949-9db8a6828606/go.mod h1:35VQIKhChb6/H+3J/XkbGhPkVF6lyLuxsUG/WXHS4+A=
github.com/vultisig/vultiserver v0.0.0-20250515110921-82d56d3d9cc9 h1:pZhGN8q8+gPB1JJjVDC1hDg8qn6Tbj0XBJymgTQ8qQg=
github.com/vultisig/vultiserver v0.0.0-20250515110921-82d56d3d9cc9/go.mod h1:HwP2IgW6Mcu/gX8paFuKvfibrGE9UmPgkOFTub6dskM=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
Expand Down
16 changes: 8 additions & 8 deletions plugin/dca/dca.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (p *DCAPlugin) SigningComplete(
ctx context.Context,
signature tss.KeysignResponse,
signRequest vtypes.PluginKeysignRequest,
policy vtypes.PluginPolicyCreateUpdate,
policy vtypes.PluginPolicy,
) error {
var dcaPolicy DCAPolicy
// TODO: convert recipe to DCAPolicy
Expand Down Expand Up @@ -135,7 +135,7 @@ func (p *DCAPlugin) SigningComplete(
return nil
}

func (p *DCAPlugin) ValidatePluginPolicy(policyDoc vtypes.PluginPolicyCreateUpdate) error {
func (p *DCAPlugin) ValidatePluginPolicy(policyDoc vtypes.PluginPolicy) error {
if policyDoc.PluginID != vtypes.PluginVultisigDCA_0000 {
return fmt.Errorf("policy does not match plugin type, expected: %s, got: %s", pluginType, policyDoc.PluginID)
}
Expand All @@ -144,8 +144,8 @@ func (p *DCAPlugin) ValidatePluginPolicy(policyDoc vtypes.PluginPolicyCreateUpda
return fmt.Errorf("policy does not match plugin version, expected: %s, got: %s", pluginVersion, policyDoc.PluginVersion)
}

if policyDoc.PolicyVersion != policyVersion {
return fmt.Errorf("policy does not match policy version, expected: %s, got: %s", policyVersion, policyDoc.PolicyVersion)
if fmt.Sprintf("%d", policyDoc.PolicyVersion) != policyVersion { //TODO policy version will essentially be a nonce that is incremented by 1, not, like plugin versions that will follow traditional engineering versioning e.g. v2.12.3. For now we can compare string types
return fmt.Errorf("policy does not match policy version, expected: %s, got: %d", policyVersion, policyDoc.PolicyVersion)
}

if policyDoc.PublicKey == "" {
Expand Down Expand Up @@ -270,7 +270,7 @@ func validateInterval(intervalStr string, frequency string) error {
return nil
}

func (p *DCAPlugin) ProposeTransactions(policy vtypes.PluginPolicyCreateUpdate) ([]vtypes.PluginKeysignRequest, error) {
func (p *DCAPlugin) ProposeTransactions(policy vtypes.PluginPolicy) ([]vtypes.PluginKeysignRequest, error) {
p.logger.Info("DCA: PROPOSE TRANSACTIONS")

var txs []vtypes.PluginKeysignRequest
Expand Down Expand Up @@ -301,7 +301,7 @@ func (p *DCAPlugin) ProposeTransactions(policy vtypes.PluginPolicyCreateUpdate)
}

if completedSwaps >= totalOrders.Int64() {
if err := p.completePolicy(context.Background(), policy.ToPluginPolicy()); err != nil {
if err := p.completePolicy(context.Background(), policy); err != nil {
return txs, fmt.Errorf("fail to complete policy: %w", err)
}
return txs, ErrCompletedPolicy
Expand Down Expand Up @@ -358,7 +358,7 @@ func (p *DCAPlugin) ProposeTransactions(policy vtypes.PluginPolicyCreateUpdate)
return txs, nil
}

func (p *DCAPlugin) ValidateProposedTransactions(policy vtypes.PluginPolicyCreateUpdate, txs []vtypes.PluginKeysignRequest) error {
func (p *DCAPlugin) ValidateProposedTransactions(policy vtypes.PluginPolicy, txs []vtypes.PluginKeysignRequest) error {
p.logger.Info("DCA: VALIDATE TRANSACTION PROPOSAL")

if len(txs) == 0 {
Expand Down Expand Up @@ -407,7 +407,7 @@ func (p *DCAPlugin) ValidateProposedTransactions(policy vtypes.PluginPolicyCreat
}
// TODO: Change this to make the policy to status COMPLETED if: completed swaps == total orders.
if completedSwaps >= totalOrders.Int64() {
if err := p.completePolicy(context.Background(), policy.ToPluginPolicy()); err != nil {
if err := p.completePolicy(context.Background(), policy); err != nil {
return fmt.Errorf("fail to complete policy: %w", err)
}
p.logger.Info("DCA: COMPLETED SWAPS: ", totalOrders.Int64())
Expand Down
63 changes: 63 additions & 0 deletions plugin/fees/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package fees

import (
"errors"
"fmt"
"strings"

"github.com/spf13/viper"
)

type PluginConfig struct {
Type string `mapstructure:"type"`
Version string `mapstructure:"version"`
RpcURL string `mapstructure:"rpc_url"` // URL for the RPC endpoint to interact with the ethereum/evm blockchain
USDCAddress string `mapstructure:"usdc_address"` // If a non-ethereum chain is used, this is the address of the USDC token contract on that chain
Gas struct {
LimitMultiplier int `mapstructure:"limit_multiplier"`
PriceMultiplier int `mapstructure:"price_multiplier"`
} `mapstructure:"gas"`
Monitoring struct {
TimeoutMinutes int `mapstructure:"timeout_minutes"`
CheckIntervalSeconds int `mapstructure:"check_interval_seconds"`
} `mapstructure:"monitoring"`
}

func loadPluginConfig(basePath string) (*PluginConfig, error) {
v := viper.New()
v.SetConfigName("fees")

// Add config paths in order of precedence
if basePath != "" {
v.AddConfigPath(basePath)
}
v.AddConfigPath(".")
v.AddConfigPath("/etc/vultisig")

// Enable environment variable overrides
v.AutomaticEnv()
v.SetEnvPrefix("FEES")
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))

if err := v.ReadInConfig(); err != nil {
return nil, fmt.Errorf("failed to read config: %w", err)
}
Comment on lines +42 to +44

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Differentiate between “file not found” and real config parse errors

v.ReadInConfig() returns an error when the config file is missing.
Right now any error aborts startup, even when users intend to rely solely on environment variables. Handle viper.ConfigFileNotFoundError explicitly so env-only setups still work.

-if err := v.ReadInConfig(); err != nil {
-    return nil, fmt.Errorf("failed to read config: %w", err)
+if err := v.ReadInConfig(); err != nil {
+    // allow env-only configuration
+    if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
+        return nil, fmt.Errorf("failed to read config: %w", err)
+    }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if err := v.ReadInConfig(); err != nil {
return nil, fmt.Errorf("failed to read config: %w", err)
}
if err := v.ReadInConfig(); err != nil {
// allow env-only configuration
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
return nil, fmt.Errorf("failed to read config: %w", err)
}
}
🤖 Prompt for AI Agents
In plugin/fees/config.go around lines 42 to 44, the current code treats all
errors from v.ReadInConfig() as fatal, including when the config file is
missing. Modify the error handling to explicitly check if the error is a
viper.ConfigFileNotFoundError and ignore it in that case, allowing the program
to continue when users rely only on environment variables. For other errors,
keep returning the wrapped error as before.


var config PluginConfig
if err := v.Unmarshal(&config); err != nil {
return nil, fmt.Errorf("failed to unmarshal config: %w", err)
}

// Validate configuration
if config.Type != PLUGIN_TYPE {
return nil, fmt.Errorf("invalid plugin type: %s", config.Type)
}
if config.RpcURL == "" {
return nil, errors.New("rpc_url is required")
}
if config.Gas.LimitMultiplier <= 0 {
return nil, errors.New("gas limit multiplier must be positive")
}
Comment on lines +58 to +60

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Validate Gas.PriceMultiplier as well

PriceMultiplier can silently be zero or negative, leading to an under-priced transaction and inevitable on-chain failure.

-if config.Gas.LimitMultiplier <= 0 {
-    return nil, errors.New("gas limit multiplier must be positive")
+if config.Gas.LimitMultiplier <= 0 {
+    return nil, errors.New("gas limit multiplier must be positive")
+}
+if config.Gas.PriceMultiplier <= 0 {
+    return nil, errors.New("gas price multiplier must be positive")
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if config.Gas.LimitMultiplier <= 0 {
return nil, errors.New("gas limit multiplier must be positive")
}
if config.Gas.LimitMultiplier <= 0 {
return nil, errors.New("gas limit multiplier must be positive")
}
if config.Gas.PriceMultiplier <= 0 {
return nil, errors.New("gas price multiplier must be positive")
}
🤖 Prompt for AI Agents
In plugin/fees/config.go around lines 58 to 60, add a validation check for
config.Gas.PriceMultiplier similar to the existing check for LimitMultiplier.
Ensure that PriceMultiplier is greater than zero, and if not, return an error
indicating that the gas price multiplier must be positive to prevent
under-priced transactions and on-chain failures.


return &config, nil
}
12 changes: 12 additions & 0 deletions plugin/fees/constraints.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package fees

const PLUGIN_TYPE = "fees"
const erc20ABI = `[{
"name": "transfer",
"type": "function",
"inputs": [
{"name": "recipient", "type": "address"},
{"name": "amount", "type": "uint256"}
],
"outputs": [{"name": "", "type": "bool"}]
}]`
68 changes: 68 additions & 0 deletions plugin/fees/fees.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package fees

import (
"context"
"fmt"

"github.com/ethereum/go-ethereum/ethclient"
"github.com/sirupsen/logrus"
"github.com/vultisig/mobile-tss-lib/tss"
"github.com/vultisig/verifier/plugin"
"github.com/vultisig/verifier/types"

"github.com/vultisig/plugin/storage"
rtypes "github.com/vultisig/recipes/types"
)

var _ plugin.Plugin = (*FeePlugin)(nil)

type FeePlugin struct {
db storage.DatabaseStorage
rpcClient *ethclient.Client
logger logrus.FieldLogger
config *PluginConfig
}

func NewFeePlugin(db storage.DatabaseStorage, baseConfigPath string) (*FeePlugin, error) {
if db == nil {
return nil, fmt.Errorf("database storage cannot be nil")
}
cfg, err := loadPluginConfig(baseConfigPath)
if err != nil {
return nil, fmt.Errorf("failed to load plugin config: %w", err)
}

rpcClient, err := ethclient.Dial(cfg.RpcURL)
if err != nil {
return nil, err
}

return &FeePlugin{
db: db,
rpcClient: rpcClient,
logger: logrus.WithField("plugin", "payroll"),
config: cfg,
}, nil
Comment on lines +40 to +45

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remember to close the ethclient.Client

ethclient.Client holds open connections; without a Close() the process leaks file descriptors.
Expose a Close() on FeePlugin (implement io.Closer) or close it in caller.

🤖 Prompt for AI Agents
In plugin/fees/fees.go around lines 40 to 45, the ethclient.Client instance
assigned to FeePlugin is not closed, causing resource leaks. Implement a Close()
method on FeePlugin that calls Close() on the ethclient.Client to release
resources properly. Ensure FeePlugin implements io.Closer and update callers to
invoke this Close() method when done using the plugin.

}

func (fp *FeePlugin) GetRecipeSpecification() rtypes.RecipeSchema {
fp.logger.Debug("Getting recipe specification")
//TODO garry
return rtypes.RecipeSchema{
PluginId: "vultisig-fees-0000",
Version: 1,
}
}

func (fp *FeePlugin) ValidatePluginPolicy(policyDoc types.PluginPolicy) error {
return nil
}
func (fp *FeePlugin) ProposeTransactions(policy types.PluginPolicy) ([]types.PluginKeysignRequest, error) {
return []types.PluginKeysignRequest{}, nil
}
func (fp *FeePlugin) ValidateProposedTransactions(policy types.PluginPolicy, txs []types.PluginKeysignRequest) error {
return nil
}
func (fp *FeePlugin) SigningComplete(ctx context.Context, signature tss.KeysignResponse, signRequest types.PluginKeysignRequest, policy types.PluginPolicy) error {
return nil
}
4 changes: 2 additions & 2 deletions plugin/payroll/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type Schedule struct {
EndTime string `json:"end_time,omitempty"`
}

func (p *PayrollPlugin) ValidateProposedTransactions(policy vtypes.PluginPolicyCreateUpdate, txs []vtypes.PluginKeysignRequest) error {
func (p *PayrollPlugin) ValidateProposedTransactions(policy vtypes.PluginPolicy, txs []vtypes.PluginKeysignRequest) error {
err := p.ValidatePluginPolicy(policy)
if err != nil {
return fmt.Errorf("failed to validate plugin policy: %v", err)
Expand Down Expand Up @@ -196,7 +196,7 @@ func (p *PayrollPlugin) checkRule(rule *rtypes.Rule) error {
}
return nil
}
func (p *PayrollPlugin) ValidatePluginPolicy(policyDoc vtypes.PluginPolicyCreateUpdate) error {
func (p *PayrollPlugin) ValidatePluginPolicy(policyDoc vtypes.PluginPolicy) error {
if policyDoc.PluginID != vtypes.PluginVultisigPayroll_0000 {
return fmt.Errorf("policy does not match plugin type, expected: %s, got: %s", vtypes.PluginVultisigPayroll_0000, policyDoc.PluginID)
}
Expand Down
6 changes: 3 additions & 3 deletions plugin/payroll/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (p *PayrollPlugin) HandleSchedulerTrigger(ctx context.Context, t *asynq.Tas
_ = pluginPolicy
return nil
}
func (p *PayrollPlugin) ProposeTransactions(policy vtypes.PluginPolicyCreateUpdate) ([]vtypes.PluginKeysignRequest, error) {
func (p *PayrollPlugin) ProposeTransactions(policy vtypes.PluginPolicy) ([]vtypes.PluginKeysignRequest, error) {
var txs []vtypes.PluginKeysignRequest
err := p.ValidatePluginPolicy(policy)
if err != nil {
Expand Down Expand Up @@ -232,8 +232,8 @@ func (p *PayrollPlugin) generatePayrollTransaction(amountString, recipientString
return txHash, rawTx, nil
}

func (p *PayrollPlugin) SigningComplete(ctx context.Context, signature tss.KeysignResponse, signRequest vtypes.PluginKeysignRequest, policy vtypes.PluginPolicyCreateUpdate) error {
R, S, V, originalTx, chainID, _, err := p.convertData(signature, signRequest, policy.ToPluginPolicy())
func (p *PayrollPlugin) SigningComplete(ctx context.Context, signature tss.KeysignResponse, signRequest vtypes.PluginKeysignRequest, policy vtypes.PluginPolicy) error {
R, S, V, originalTx, chainID, _, err := p.convertData(signature, signRequest, policy)
if err != nil {
return fmt.Errorf("failed to convert R and S: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion scripts/dev/create_dca_policy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func main() {
PublicKey: key,
PluginID: vtypes.PluginVultisigDCA_0000,
PluginVersion: "1.0.0",
PolicyVersion: "1.0.0",
PolicyVersion: 1,
Active: true,
Signature: "0x0000000000000000000000000000000000000000000000000000000000000000",
}
Expand Down
2 changes: 1 addition & 1 deletion scripts/dev/create_payroll_policy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func main() {
PublicKey: key,
PluginID: vtypes.PluginVultisigPayroll_0000,
PluginVersion: "1.0.0",
PolicyVersion: "1.0.0",
PolicyVersion: 1,
Active: true,
Signature: "0x0000000000000000000000000000000000000000000000000000000000000000",
}
Expand Down
2 changes: 1 addition & 1 deletion storage/postgres/time_trigger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestTimeTrigger(t *testing.T) {
PublicKey: "4a7b9c2f8e1d3a5b6c4f9e2d7a1b3c5f8d4e6a2b9c1f7e3d5a6b4c2f8e1d3a5b",
PluginID: "vultisig-payroll-0000",
PluginVersion: "1",
PolicyVersion: "1",
PolicyVersion: 1,
Signature: "whatever",
Recipe: "k3uaL47TpWtsT54tfhO7K6Gbyxf4H71jWma0zC2e3kQ=",
Active: true,
Expand Down