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
13 changes: 7 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ require (
github.com/eager7/dogd v0.0.0-20200427085516-2caf59f59dbb
github.com/ethereum/go-ethereum v1.15.11
github.com/go-playground/validator/v10 v10.26.0
github.com/golang/protobuf v1.5.4
github.com/google/uuid v1.6.0
github.com/hibiken/asynq v0.25.1
github.com/jackc/pgx/v5 v5.7.4
Expand All @@ -17,11 +16,14 @@ require (
github.com/redis/go-redis/v9 v9.8.0
github.com/sirupsen/logrus v1.9.3
github.com/spf13/viper v1.20.1
github.com/stretchr/testify v1.10.0
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-20250627044941-5f6e07d5d22f
github.com/vultisig/verifier v0.0.0-20250701180729-848563b4ed33
github.com/vultisig/recipes v0.0.0-20250710152947-d15b238437ae
github.com/vultisig/verifier v0.0.0-20250710201755-2a994bd24c91
github.com/vultisig/vultiserver v0.0.0-20250515110921-82d56d3d9cc9
golang.org/x/sync v0.12.0
google.golang.org/protobuf v1.36.6
)

require (
Expand Down Expand Up @@ -85,6 +87,7 @@ require (
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/golang/glog v1.2.4 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/go-cmp v0.7.0 // indirect
Expand Down Expand Up @@ -127,7 +130,7 @@ require (
github.com/sethvargo/go-retry v0.3.0 // indirect
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
github.com/spf13/cobra v1.8.1 // indirect
github.com/stretchr/testify v1.10.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/supranational/blst v0.3.14 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
github.com/tendermint/go-amino v0.16.0 // indirect
Expand All @@ -136,11 +139,9 @@ require (
github.com/vultisig/go-wrappers v0.0.0-20250403041248-86911e8aa33f // indirect
go.etcd.io/bbolt v1.3.8 // indirect
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
golang.org/x/sync v0.12.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect
google.golang.org/grpc v1.71.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
lukechampine.com/blake3 v1.2.1 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
Expand Down
28 changes: 4 additions & 24 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -745,32 +745,12 @@ 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-20250609134859-0655e0445c1b h1:rXhRaf40re1FdUYlYbCTEIO6JqIx8FfLlksksu8LiGE=
github.com/vultisig/recipes v0.0.0-20250609134859-0655e0445c1b/go.mod h1:JT1FTsiJ8tY5W065vSsrxvrCSl1amp5o6SsBc1VVcCQ=
github.com/vultisig/recipes v0.0.0-20250627044941-5f6e07d5d22f h1:1OaeEJ1zER9pJ8IFh674C1dpZwWhIiTV5nd729dHMzU=
github.com/vultisig/recipes v0.0.0-20250627044941-5f6e07d5d22f/go.mod h1:9ucuiGHbjFTekXNwUc9M+OQSm38P56Gr0yGNdMdE+i0=
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/verifier v0.0.0-20250614014346-e5348c16754b h1:8DFobGSwdD01Zzr8lCWW1UWGHqbd/EpwyrfhEy81xTI=
github.com/vultisig/verifier v0.0.0-20250614014346-e5348c16754b/go.mod h1:35VQIKhChb6/H+3J/XkbGhPkVF6lyLuxsUG/WXHS4+A=
github.com/vultisig/verifier v0.0.0-20250616174756-6ca7c9fac2d8 h1:MZBy2ame3ipaH/0V4TczTqIfW0s+gwtOsX1VSOB/5m4=
github.com/vultisig/verifier v0.0.0-20250616174756-6ca7c9fac2d8/go.mod h1:35VQIKhChb6/H+3J/XkbGhPkVF6lyLuxsUG/WXHS4+A=
github.com/vultisig/verifier v0.0.0-20250616181219-f7ba9f0dfa97 h1:uoeWKNKeTqEFDbqBrD9qeVKYWvzPy8kN/sA4VSNv80k=
github.com/vultisig/verifier v0.0.0-20250616181219-f7ba9f0dfa97/go.mod h1:35VQIKhChb6/H+3J/XkbGhPkVF6lyLuxsUG/WXHS4+A=
github.com/vultisig/verifier v0.0.0-20250616191510-cc66448469ef h1:VNDOwFI4eGJn76dP/lx3x+hoyPc/vzcZ2+fB6Ap8h1M=
github.com/vultisig/verifier v0.0.0-20250616191510-cc66448469ef/go.mod h1:35VQIKhChb6/H+3J/XkbGhPkVF6lyLuxsUG/WXHS4+A=
github.com/vultisig/verifier v0.0.0-20250617153835-9a8d53c93da1 h1:iTB/XLdeidd5v0QmQJp+oLjPP1OHmK1yiT/Ps6QB7hA=
github.com/vultisig/verifier v0.0.0-20250617153835-9a8d53c93da1/go.mod h1:35VQIKhChb6/H+3J/XkbGhPkVF6lyLuxsUG/WXHS4+A=
github.com/vultisig/verifier v0.0.0-20250617205725-01cd5bd5b68b h1:y02mtgV2eNRrxFBXj/8yzaLK1/j8FNNoTXxbjC4Dec4=
github.com/vultisig/verifier v0.0.0-20250617205725-01cd5bd5b68b/go.mod h1:35VQIKhChb6/H+3J/XkbGhPkVF6lyLuxsUG/WXHS4+A=
github.com/vultisig/verifier v0.0.0-20250620085341-b935ecc82e40 h1:SXFcpcq7HGCmveEg2fV+lXSrfVnyc/qxGrE1dwaEInU=
github.com/vultisig/verifier v0.0.0-20250620085341-b935ecc82e40/go.mod h1:jAepDQtls7VT2r4lb6J6Asl5xCSwt6mg/b8XBO3uzsA=
github.com/vultisig/verifier v0.0.0-20250626093402-fa1ecf8bd816 h1:hCTbtaqIKBsnRarJxccgcoi+DrpuNFyHspWb3PSWp40=
github.com/vultisig/verifier v0.0.0-20250626093402-fa1ecf8bd816/go.mod h1:dLmQBnF5F0auFkGtCMHOCqkUwdTRL6fWm3H4yfHfsVU=
github.com/vultisig/verifier v0.0.0-20250627125920-a555ee8da0cb h1:x2h4ud358pS5jQ5ZEVAu6Jazc2OzDrLa1E8rtdFUEFg=
github.com/vultisig/verifier v0.0.0-20250627125920-a555ee8da0cb/go.mod h1:dLmQBnF5F0auFkGtCMHOCqkUwdTRL6fWm3H4yfHfsVU=
github.com/vultisig/recipes v0.0.0-20250710152947-d15b238437ae h1:Per1QtZamO2PiQLxzTJP5SNjg6INtn83IG0c0585/s8=
github.com/vultisig/recipes v0.0.0-20250710152947-d15b238437ae/go.mod h1:Ci29kT+x5vPxLCRvIrbVNzM+JIMjDbVvvaLTzli5kYQ=
github.com/vultisig/verifier v0.0.0-20250701180729-848563b4ed33 h1:PUeuOyOphzJq/NhCOwMJjqm8YC2U5v55jQtg7Fuf5t4=
github.com/vultisig/verifier v0.0.0-20250701180729-848563b4ed33/go.mod h1:dLmQBnF5F0auFkGtCMHOCqkUwdTRL6fWm3H4yfHfsVU=
github.com/vultisig/verifier v0.0.0-20250710201755-2a994bd24c91 h1:P9er37oz5iGogJOB5SoWAFVoLajR7rCl/kKvqU8Hkf4=
github.com/vultisig/verifier v0.0.0-20250710201755-2a994bd24c91/go.mod h1:Qjt7mLLM992hDnjOYSrSuykAULeJUFMbD6o071EExRU=
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
30 changes: 30 additions & 0 deletions internal/plugin/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package plugin

import (
"encoding/base64"
"fmt"

"github.com/vultisig/recipes/engine"
rtypes "github.com/vultisig/recipes/types"
vtypes "github.com/vultisig/verifier/types"
"google.golang.org/protobuf/proto"
)

func ValidatePluginPolicy(policyDoc vtypes.PluginPolicy, spec *rtypes.RecipeSchema) error {
policyBytes, err := base64.StdEncoding.DecodeString(policyDoc.Recipe)
if err != nil {
return fmt.Errorf("failed to decode policy recipe: %w", err)
}

var rPolicy rtypes.Policy
err = proto.Unmarshal(policyBytes, &rPolicy)
if err != nil {
return fmt.Errorf("failed to unmarshal policy: %w", err)
}

err = engine.NewEngine().ValidatePolicyWithSchema(&rPolicy, spec)
if err != nil {
return fmt.Errorf("failed to validate policy: %w", err)
}
return nil
}
4 changes: 2 additions & 2 deletions plugin/dca/dca.go
Original file line number Diff line number Diff line change
Expand Up @@ -774,8 +774,8 @@ func (p *DCAPlugin) completePolicy(ctx context.Context, policy vtypes.PluginPoli
return nil
}

func (p *DCAPlugin) GetRecipeSpecification() rtypes.RecipeSchema {
return rtypes.RecipeSchema{
func (p *DCAPlugin) GetRecipeSpecification() *rtypes.RecipeSchema {
return &rtypes.RecipeSchema{
Version: 1, // Schema version
ScheduleVersion: 1, // Schedule specification version
PluginId: string(vtypes.PluginVultisigDCA_0000),
Expand Down
63 changes: 5 additions & 58 deletions plugin/fees/policy.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
package fees

import (
"encoding/base64"
"fmt"
"slices"

"github.com/vultisig/plugin/internal/plugin"
rtypes "github.com/vultisig/recipes/types"
vtypes "github.com/vultisig/verifier/types"
"google.golang.org/protobuf/proto"
)

/*
Expand All @@ -20,63 +16,14 @@ import (
*/

func (fp *FeePlugin) ValidatePluginPolicy(policyDoc vtypes.PluginPolicy) error {
if policyDoc.PluginID != vtypes.PluginVultisigFees_feee {
return fmt.Errorf("policy does not match plugin type, expected: %s, got: %s", vtypes.PluginVultisigFees_feee, policyDoc.PluginID)
}
var rPolicy rtypes.Policy
policyBytes, err := base64.StdEncoding.DecodeString(policyDoc.Recipe)
if err != nil {
return fmt.Errorf("failed to decode policy recipe: %w", err)
}
if err := proto.Unmarshal(policyBytes, &rPolicy); err != nil {
return fmt.Errorf("failed to unmarshal policy: %w", err)
}

if len(rPolicy.Rules) == 0 {
return fmt.Errorf("no rules")
}
if len(rPolicy.Rules) > 1 {
return fmt.Errorf("only one rule is allowed for the fee plugin")
}

rule := rPolicy.Rules[0]
if rule.Id != "allow-usdc-transfer-to-collector" {
return fmt.Errorf("rule id must be allow-usdc-transfer-to-collector")
}
if rule.Resource != "ethereum.usdc.transfer" {
return fmt.Errorf("rule resource must be ethereum.usdc.transfer")
}

// Validate that recipient address is in the whitelist
var recipient string
for _, constraint := range rule.ParameterConstraints {
if constraint.ParameterName == "recipient" {
if constraint.Constraint.Type != rtypes.ConstraintType_CONSTRAINT_TYPE_FIXED {
return fmt.Errorf("recipient constraint must be a fixed value")
}
fixedValue := constraint.Constraint.GetValue().(*rtypes.Constraint_FixedValue)
recipient = fixedValue.FixedValue
break
}
}

if recipient == "" {
return fmt.Errorf("recipient parameter constraint is required")
}

// Check if recipient is in the whitelist
if !slices.Contains(fp.config.CollectorWhitelistAddresses, recipient) {
return fmt.Errorf("recipient address %s is not in the whitelist: %v", recipient, fp.config.CollectorWhitelistAddresses)
}

return nil
return plugin.ValidatePluginPolicy(policyDoc, fp.GetRecipeSpecification())
}

func (fp FeePlugin) GetRecipeSpecification() rtypes.RecipeSchema {
return rtypes.RecipeSchema{
func (fp *FeePlugin) GetRecipeSpecification() *rtypes.RecipeSchema {
return &rtypes.RecipeSchema{
Version: 1, // Schema version
ScheduleVersion: 1, // Schedule specification version
PluginId: string(vtypes.PluginVultisigFees_feee.String()),
PluginId: vtypes.PluginVultisigFees_feee.String(),
Comment thread
webpiratt marked this conversation as resolved.
PluginName: "Fee Plugin",
PluginVersion: 1,
SupportedResources: []*rtypes.ResourcePattern{
Expand Down
9 changes: 0 additions & 9 deletions plugin/payroll/constants.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
package payroll

const PLUGIN_TYPE = "payroll"
const erc20ABI = `[{
"name": "transfer",
"type": "function",
"inputs": [
{"name": "recipient", "type": "address"},
{"name": "amount", "type": "uint256"}
],
"outputs": [{"name": "", "type": "bool"}]
}]`
37 changes: 0 additions & 37 deletions plugin/payroll/nonce.go

This file was deleted.

Loading