Documentation
¶
Index ¶
- Constants
- Variables
- func DelegatePayloadToSignRequest(ctx context.Context, payload interface{}, _ string) (*types.SignRequest, *types.ParsedPayload, error)
- func TestCaseInputToSignRequest(input map[string]interface{}) (*types.SignRequest, *types.ParsedPayload, error)
- type AddressListConfig
- type AddressListEvaluator
- type BatchValidationResult
- type CompositePasswordProvider
- type ContractMethodConfig
- type ContractMethodEvaluator
- type EVMAdapter
- func (a *EVMAdapter) HasSigner(ctx context.Context, address string) bool
- func (a *EVMAdapter) ListSigners(ctx context.Context) ([]types.SignerInfo, error)
- func (a *EVMAdapter) ParsePayload(ctx context.Context, signType string, payload []byte) (*types.ParsedPayload, error)
- func (a *EVMAdapter) Sign(ctx context.Context, signerAddress string, signType string, chainID string, ...) (*types.SignResult, error)
- func (a *EVMAdapter) Type() types.ChainType
- func (a *EVMAdapter) ValidateBasicRequest(chainID, signerAddress, signType string, payload []byte) error
- func (a *EVMAdapter) ValidatePayload(ctx context.Context, signType string, payload []byte) error
- type EVMSignPayload
- type EnvPasswordProvider
- type HDWalletConfig
- type HDWalletInfo
- type HDWalletManager
- type HDWalletProvider
- func (p *HDWalletProvider) Close() error
- func (p *HDWalletProvider) CreateHDWallet(ctx context.Context, params types.CreateHDWalletParams) (*HDWalletInfo, error)
- func (p *HDWalletProvider) CreateSigner(ctx context.Context, params interface{}) (*types.SignerInfo, error)
- func (p *HDWalletProvider) DeriveAddress(ctx context.Context, primaryAddr string, index uint32) (*types.SignerInfo, error)
- func (p *HDWalletProvider) DeriveAddresses(ctx context.Context, primaryAddr string, start, count uint32) ([]types.SignerInfo, error)
- func (p *HDWalletProvider) DiscoverLockedSigners() ([]types.SignerInfo, error)
- func (p *HDWalletProvider) ImportHDWallet(ctx context.Context, params types.ImportHDWalletParams) (*HDWalletInfo, error)
- func (p *HDWalletProvider) ListDerivedAddresses(primaryAddr string) ([]types.SignerInfo, error)
- func (p *HDWalletProvider) ListHDWallets() []HDWalletInfo
- func (p *HDWalletProvider) LockSigner(ctx context.Context, address string) error
- func (p *HDWalletProvider) Type() types.SignerType
- func (p *HDWalletProvider) UnlockSigner(ctx context.Context, address string, password string) (*ethsig.Signer, error)
- type JSRuleConfig
- type JSRuleEvaluator
- func (e *JSRuleEvaluator) AppliesToSignType(r *types.Rule, signType string) bool
- func (e *JSRuleEvaluator) Evaluate(ctx context.Context, r *types.Rule, req *types.SignRequest, ...) (bool, string, error)
- func (e *JSRuleEvaluator) EvaluateWithDelegation(ctx context.Context, r *types.Rule, req *types.SignRequest, ...) (bool, string, *rule.DelegationRequest, error)
- func (e *JSRuleEvaluator) Type() types.RuleType
- func (e *JSRuleEvaluator) ValidateWithInput(script string, input *RuleInput, config map[string]interface{}) JSRuleValidateResult
- type JSRuleValidateResult
- type JSRuleValidator
- type JSTestCase
- type KeystoreConfig
- type KeystoreProvider
- func (p *KeystoreProvider) Close() error
- func (p *KeystoreProvider) CreateSigner(ctx context.Context, params interface{}) (*types.SignerInfo, error)
- func (p *KeystoreProvider) DiscoverLockedSigners() ([]types.SignerInfo, error)
- func (p *KeystoreProvider) LockSigner(ctx context.Context, address string) error
- func (p *KeystoreProvider) Type() types.SignerType
- func (p *KeystoreProvider) UnlockSigner(ctx context.Context, address string, password string) (*ethsig.Signer, error)
- type MessagePatternConfig
- type MessagePatternEvaluator
- type MessagePatternRuleValidator
- type MessagePatternTestCase
- type MessagePatternTestInput
- type PasswordProvider
- type PrivateKeyConfig
- type PrivateKeyProvider
- type RuleInput
- type RuleInputPersonalSign
- type RuleInputTransaction
- type RuleInputTypedData
- type SecurityError
- type SignTypeRestrictionConfig
- type SignTypeRestrictionEvaluator
- type SignerConfig
- type SignerCreator
- type SignerDiscoverer
- type SignerLocker
- type SignerManager
- type SignerManagerImpl
- func (m *SignerManagerImpl) CreateSigner(ctx context.Context, req types.CreateSignerRequest) (*types.SignerInfo, error)
- func (m *SignerManagerImpl) DiscoverLockedSigners(ctx context.Context) error
- func (m *SignerManagerImpl) HDWalletManager() (HDWalletManager, error)
- func (m *SignerManagerImpl) ListSigners(ctx context.Context, filter types.SignerFilter) (types.SignerListResult, error)
- func (m *SignerManagerImpl) LockSigner(ctx context.Context, address string) (*types.SignerInfo, error)
- func (m *SignerManagerImpl) UnlockSigner(ctx context.Context, address string, password string) (*types.SignerInfo, error)
- type SignerProvider
- type SignerRegistry
- func (r *SignerRegistry) Close() error
- func (r *SignerRegistry) GetSigner(address string) (*ethsig.Signer, error)
- func (r *SignerRegistry) GetSignerInfo(address string) (types.SignerInfo, bool)
- func (r *SignerRegistry) HasSigner(address string) bool
- func (r *SignerRegistry) IsLocked(address string) bool
- func (r *SignerRegistry) ListSigners() []types.SignerInfo
- func (r *SignerRegistry) ListSignersWithFilter(filter types.SignerFilter) types.SignerListResult
- func (r *SignerRegistry) LockSigner(address string) error
- func (r *SignerRegistry) Provider(t types.SignerType) (SignerProvider, bool)
- func (r *SignerRegistry) RegisterKeystore(address string, keystorePath string, password []byte) error
- func (r *SignerRegistry) RegisterLockedSigner(address string, info types.SignerInfo) error
- func (r *SignerRegistry) RegisterProvider(p SignerProvider)
- func (r *SignerRegistry) RegisterSigner(address string, signer *ethsig.Signer, info types.SignerInfo) error
- func (r *SignerRegistry) SignerCount() int
- func (r *SignerRegistry) TotalCount() int
- func (r *SignerRegistry) UnlockSigner(address string, signer *ethsig.Signer) error
- type SignerRestrictionConfig
- type SignerRestrictionEvaluator
- type SignerUnlocker
- type SolidityEvaluatorConfig
- type SolidityExpressionConfig
- type SolidityRuleEvaluator
- func (e *SolidityRuleEvaluator) AppliesToSignType(rule *types.Rule, signType string) bool
- func (e *SolidityRuleEvaluator) CanBatchEvaluate(rules []*types.Rule) bool
- func (e *SolidityRuleEvaluator) Evaluate(ctx context.Context, rule *types.Rule, req *types.SignRequest, ...) (bool, string, error)
- func (e *SolidityRuleEvaluator) EvaluateBatch(ctx context.Context, rules []*types.Rule, req *types.SignRequest, ...) ([]rule.BatchEvaluationResult, error)
- func (e *SolidityRuleEvaluator) GenerateFunctionSyntaxCheckScript(functions string, inMappingArrays ...map[string][]string) string
- func (e *SolidityRuleEvaluator) GenerateSyntaxCheckScript(expression string, inMappingArrays ...map[string][]string) string
- func (e *SolidityRuleEvaluator) GenerateTypedDataExpressionSyntaxCheckScript(expression string, inMappingArrays ...map[string][]string) string
- func (e *SolidityRuleEvaluator) GenerateTypedDataExpressionSyntaxCheckScriptWithStruct(expression string, structDef *StructDefinition, ...) string
- func (e *SolidityRuleEvaluator) GenerateTypedDataFunctionsSyntaxCheckScript(functions string, inMappingArrays ...map[string][]string) string
- func (e *SolidityRuleEvaluator) GetCacheDir() string
- func (e *SolidityRuleEvaluator) GetFoundryPath() string
- func (e *SolidityRuleEvaluator) GetTempDir() string
- func (e *SolidityRuleEvaluator) GetTimeout() time.Duration
- func (e *SolidityRuleEvaluator) Type() types.RuleType
- type SolidityRuleValidator
- func (v *SolidityRuleValidator) Evaluator() *SolidityRuleEvaluator
- func (v *SolidityRuleValidator) ValidateRule(ctx context.Context, rule *types.Rule) (*ValidationResult, error)
- func (v *SolidityRuleValidator) ValidateRulesBatch(ctx context.Context, rules []*types.Rule) (*BatchValidationResult, error)
- type SolidityTestCase
- type SolidityTestInput
- type StdinPasswordProvider
- type StructDefinition
- type SyntaxError
- type TestCaseResult
- type TransactionPayload
- type TransactionType
- type TypedDataDomain
- type TypedDataDomainInput
- type TypedDataField
- type TypedDataPayload
- type TypedDataTestInput
- type ValidationMode
- type ValidationResult
- type ValueLimitConfig
- type ValueLimitEvaluator
Constants ¶
const ( SignTypeHash = "hash" SignTypeRawMessage = "raw_message" SignTypeEIP191 = "eip191" SignTypePersonal = "personal" SignTypeTypedData = "typed_data" SignTypeTransaction = "transaction" )
EVM sign types (match ethsig interfaces)
Variables ¶
var ErrFromNotDerivable = fmt.Errorf("from address not derivable")
ErrFromNotDerivable is returned when transaction.from cannot be set (e.g. missing signer).
Functions ¶
func DelegatePayloadToSignRequest ¶ added in v0.1.0
func DelegatePayloadToSignRequest(ctx context.Context, payload interface{}, _ string) (*types.SignRequest, *types.ParsedPayload, error)
DelegatePayloadToSignRequest converts a delegation payload (RuleInput-shaped map or *RuleInput) into SignRequest and ParsedPayload for evaluating the target rule. Used by the rule engine when resolving evm_js delegation. Implements the signature expected by rule.WithDelegationPayloadConverter. mode is "single" or "per_item"; for "single" payload is one RuleInput; for "per_item" this is called per element.
func TestCaseInputToSignRequest ¶ added in v0.1.0
func TestCaseInputToSignRequest(input map[string]interface{}) (*types.SignRequest, *types.ParsedPayload, error)
TestCaseInputToSignRequest converts a test case input map (from YAML/JSON test_cases) to a SignRequest and ParsedPayload suitable for engine evaluation. The input map uses the same shape as RuleInput: sign_type, chain_id, signer, transaction (to/value/data), typed_data, personal_sign.
Types ¶
type AddressListConfig ¶
type AddressListConfig struct {
Addresses []string `json:"addresses"` // 0x prefixed
}
AddressListConfig defines addresses for whitelist/blocklist rules When mode=whitelist: transactions TO these addresses are allowed When mode=blocklist: transactions TO these addresses are blocked
type AddressListEvaluator ¶
type AddressListEvaluator struct{}
AddressListEvaluator checks if tx.To is in the address list Behavior depends on rule mode: - Whitelist mode: returns true if address IS in list (allow) - Blocklist mode: returns true if address IS in list (block)
func NewAddressListEvaluator ¶
func NewAddressListEvaluator() (*AddressListEvaluator, error)
NewAddressListEvaluator creates a new address list evaluator
func (*AddressListEvaluator) Evaluate ¶
func (e *AddressListEvaluator) Evaluate(ctx context.Context, r *types.Rule, req *types.SignRequest, parsed *types.ParsedPayload) (bool, string, error)
Evaluate checks if the recipient address is in the list For whitelist mode: returns true if address IS in list (allow transaction) For blocklist mode: returns true if address IS in list (block transaction)
func (*AddressListEvaluator) Type ¶
func (e *AddressListEvaluator) Type() types.RuleType
Type returns the rule type this evaluator handles
type BatchValidationResult ¶
type BatchValidationResult struct {
Results []ValidationResult
Valid bool
}
BatchValidationResult contains results for batch validation
type CompositePasswordProvider ¶
type CompositePasswordProvider struct {
// contains filtered or unexported fields
}
CompositePasswordProvider uses stdin for password_stdin=true, env otherwise
func NewCompositePasswordProvider ¶
func NewCompositePasswordProvider(hasStdinKeystores bool) (*CompositePasswordProvider, error)
NewCompositePasswordProvider creates a composite password provider that uses stdin for keystores with password_stdin=true, otherwise uses env vars
func (*CompositePasswordProvider) GetPassword ¶
func (p *CompositePasswordProvider) GetPassword(address string, config KeystoreConfig) ([]byte, error)
GetPassword returns the password using the appropriate provider based on config
type ContractMethodConfig ¶
type ContractMethodConfig struct {
Contract string `json:"contract"` // 0x prefixed
MethodSigs []string `json:"method_sigs"` // 4-byte hex, 0x prefixed
}
ContractMethodConfig defines allowed contract methods
type ContractMethodEvaluator ¶
type ContractMethodEvaluator struct{}
ContractMethodEvaluator checks if the method selector matches allowed methods for a contract
func NewContractMethodEvaluator ¶
func NewContractMethodEvaluator() (*ContractMethodEvaluator, error)
NewContractMethodEvaluator creates a new contract method evaluator
func (*ContractMethodEvaluator) Evaluate ¶
func (e *ContractMethodEvaluator) Evaluate(ctx context.Context, r *types.Rule, req *types.SignRequest, parsed *types.ParsedPayload) (bool, string, error)
Evaluate checks if the contract and method selector are allowed
func (*ContractMethodEvaluator) Type ¶
func (e *ContractMethodEvaluator) Type() types.RuleType
Type returns the rule type this evaluator handles
type EVMAdapter ¶
type EVMAdapter struct {
// contains filtered or unexported fields
}
EVMAdapter implements types.ChainAdapter for EVM chains
func NewEVMAdapter ¶
func NewEVMAdapter(registry *SignerRegistry) (*EVMAdapter, error)
NewEVMAdapter creates a new EVM chain adapter
func (*EVMAdapter) HasSigner ¶
func (a *EVMAdapter) HasSigner(ctx context.Context, address string) bool
HasSigner checks if a signer exists
func (*EVMAdapter) ListSigners ¶
func (a *EVMAdapter) ListSigners(ctx context.Context) ([]types.SignerInfo, error)
ListSigners returns available signers for this chain
func (*EVMAdapter) ParsePayload ¶
func (a *EVMAdapter) ParsePayload(ctx context.Context, signType string, payload []byte) (*types.ParsedPayload, error)
ParsePayload parses the payload for rule evaluation
func (*EVMAdapter) Sign ¶
func (a *EVMAdapter) Sign(ctx context.Context, signerAddress string, signType string, chainID string, payload []byte) (*types.SignResult, error)
Sign performs the actual signing operation
func (*EVMAdapter) Type ¶
func (a *EVMAdapter) Type() types.ChainType
Type returns the chain type this adapter handles
func (*EVMAdapter) ValidateBasicRequest ¶ added in v0.0.2
func (a *EVMAdapter) ValidateBasicRequest(chainID, signerAddress, signType string, payload []byte) error
ValidateBasicRequest validates request format and size only (chain_id, signer_address, sign_type, payload size). Does not check signer existence or payload semantics. Used so that only well-formed requests are persisted for audit.
func (*EVMAdapter) ValidatePayload ¶
ValidatePayload validates the EVM-specific payload
type EVMSignPayload ¶
type EVMSignPayload struct {
// For hash signing
Hash string `json:"hash,omitempty"` // 0x prefixed, 32 bytes
// For raw message signing
RawMessage []byte `json:"raw_message,omitempty"`
// For EIP-191/Personal signing
Message string `json:"message,omitempty"`
// For EIP-712 typed data signing
TypedData *TypedDataPayload `json:"typed_data,omitempty"`
// For transaction signing
Transaction *TransactionPayload `json:"transaction,omitempty"`
}
EVMSignPayload is the payload for EVM sign requests
type EnvPasswordProvider ¶
type EnvPasswordProvider struct{}
EnvPasswordProvider reads passwords from environment variables
func NewEnvPasswordProvider ¶
func NewEnvPasswordProvider() (*EnvPasswordProvider, error)
NewEnvPasswordProvider creates a new environment variable based password provider
func (*EnvPasswordProvider) GetPassword ¶
func (p *EnvPasswordProvider) GetPassword(address string, config KeystoreConfig) ([]byte, error)
GetPassword reads the password from the environment variable specified in config
type HDWalletConfig ¶ added in v0.1.0
type HDWalletConfig struct {
Path string `yaml:"path"` // Path to encrypted HD wallet file
PasswordEnv string `yaml:"password_env"` // Environment variable containing password
PasswordStdin bool `yaml:"password_stdin"` // If true, read password from stdin
DeriveIndices []uint32 `yaml:"derive_indices"` // Indices to derive at startup
Enabled bool `yaml:"enabled"` // Whether this HD wallet is enabled
}
HDWalletConfig defines an HD wallet signer configuration
type HDWalletInfo ¶ added in v0.1.0
type HDWalletInfo struct {
PrimaryAddress string `json:"primary_address"`
BasePath string `json:"base_path"`
DerivedCount int `json:"derived_count"`
Derived []types.SignerInfo `json:"derived,omitempty"`
}
HDWalletInfo contains information about an HD wallet.
type HDWalletManager ¶ added in v0.1.0
type HDWalletManager interface {
CreateHDWallet(ctx context.Context, params types.CreateHDWalletParams) (*HDWalletInfo, error)
ImportHDWallet(ctx context.Context, params types.ImportHDWalletParams) (*HDWalletInfo, error)
DeriveAddress(ctx context.Context, primaryAddr string, index uint32) (*types.SignerInfo, error)
DeriveAddresses(ctx context.Context, primaryAddr string, start, count uint32) ([]types.SignerInfo, error)
ListHDWallets() []HDWalletInfo
ListDerivedAddresses(primaryAddr string) ([]types.SignerInfo, error)
}
HDWalletManager defines HD wallet-specific operations. The API handler type-asserts a SignerProvider to this interface.
type HDWalletProvider ¶ added in v0.1.0
type HDWalletProvider struct {
// contains filtered or unexported fields
}
HDWalletProvider manages HD wallet signers.
func NewHDWalletProvider ¶ added in v0.1.0
func NewHDWalletProvider( registry *SignerRegistry, configs []HDWalletConfig, walletDir string, pwProvider PasswordProvider, logger *slog.Logger, ) (*HDWalletProvider, error)
NewHDWalletProvider creates an HDWalletProvider and loads all configured HD wallets.
func (*HDWalletProvider) Close ¶ added in v0.1.0
func (p *HDWalletProvider) Close() error
func (*HDWalletProvider) CreateHDWallet ¶ added in v0.1.0
func (p *HDWalletProvider) CreateHDWallet(ctx context.Context, params types.CreateHDWalletParams) (*HDWalletInfo, error)
CreateHDWallet creates a new HD wallet and registers the primary address.
func (*HDWalletProvider) CreateSigner ¶ added in v0.1.0
func (p *HDWalletProvider) CreateSigner(ctx context.Context, params interface{}) (*types.SignerInfo, error)
CreateSigner creates a new HD wallet. Implements SignerCreator.
func (*HDWalletProvider) DeriveAddress ¶ added in v0.1.0
func (p *HDWalletProvider) DeriveAddress(ctx context.Context, primaryAddr string, index uint32) (*types.SignerInfo, error)
DeriveAddress derives a single address at the given index from an HD wallet.
func (*HDWalletProvider) DeriveAddresses ¶ added in v0.1.0
func (p *HDWalletProvider) DeriveAddresses(ctx context.Context, primaryAddr string, start, count uint32) ([]types.SignerInfo, error)
DeriveAddresses derives multiple addresses from an HD wallet.
func (*HDWalletProvider) DiscoverLockedSigners ¶ added in v0.1.0
func (p *HDWalletProvider) DiscoverLockedSigners() ([]types.SignerInfo, error)
DiscoverLockedSigners scans walletDir for HD wallet files not already loaded.
func (*HDWalletProvider) ImportHDWallet ¶ added in v0.1.0
func (p *HDWalletProvider) ImportHDWallet(ctx context.Context, params types.ImportHDWalletParams) (*HDWalletInfo, error)
ImportHDWallet imports an HD wallet from a mnemonic and registers the primary address.
func (*HDWalletProvider) ListDerivedAddresses ¶ added in v0.1.0
func (p *HDWalletProvider) ListDerivedAddresses(primaryAddr string) ([]types.SignerInfo, error)
ListDerivedAddresses returns all derived addresses for an HD wallet.
func (*HDWalletProvider) ListHDWallets ¶ added in v0.1.0
func (p *HDWalletProvider) ListHDWallets() []HDWalletInfo
ListHDWallets returns information about all loaded HD wallets.
func (*HDWalletProvider) LockSigner ¶ added in v0.1.0
func (p *HDWalletProvider) LockSigner(ctx context.Context, address string) error
LockSigner locks an unlocked HD wallet signer (closes wallet, stores path for later unlock).
func (*HDWalletProvider) Type ¶ added in v0.1.0
func (p *HDWalletProvider) Type() types.SignerType
func (*HDWalletProvider) UnlockSigner ¶ added in v0.1.0
func (p *HDWalletProvider) UnlockSigner(ctx context.Context, address string, password string) (*ethsig.Signer, error)
UnlockSigner unlocks a locked HD wallet signer with the given password.
type JSRuleConfig ¶ added in v0.1.0
type JSRuleConfig struct {
// Script is the JS source; must define validate(input) returning { valid, reason?, payload? }.
Script string `json:"script"`
// SignTypeFilter restricts to sign types. For evm_js only: may be comma-separated
// (e.g. "typed_data,transaction"); other rule types support a single value only.
SignTypeFilter string `json:"sign_type_filter,omitempty"`
// Delegation (optional)
DelegateTo string `json:"delegate_to,omitempty"` // target rule ID
DelegateMode string `json:"delegate_mode,omitempty"` // "single" | "per_item" (default "single")
ItemsKey string `json:"items_key,omitempty"` // required for per_item; default "items"
PayloadKey string `json:"payload_key,omitempty"` // optional for single
}
JSRuleConfig holds per-rule config for evm_js (script + optional delegation). Variables are injected exclusively as config object; no string substitution.
type JSRuleEvaluator ¶ added in v0.1.0
type JSRuleEvaluator struct {
// contains filtered or unexported fields
}
JSRuleEvaluator evaluates evm_js rules in-process via Sobek.
func NewJSRuleEvaluator ¶ added in v0.1.0
func NewJSRuleEvaluator(logger *slog.Logger) (*JSRuleEvaluator, error)
NewJSRuleEvaluator creates a new JS rule evaluator.
func (*JSRuleEvaluator) AppliesToSignType ¶ added in v0.1.0
func (e *JSRuleEvaluator) AppliesToSignType(r *types.Rule, signType string) bool
AppliesToSignType returns true if the rule applies to the given sign type. Uses optional sign_type_filter from config; if empty, applies to all.
Only evm_js rules support comma-separated sign_type_filter (e.g. "typed_data,transaction"). Other rule types (evm_solidity_expression, message_pattern, etc.) use a single value only.
func (*JSRuleEvaluator) Evaluate ¶ added in v0.1.0
func (e *JSRuleEvaluator) Evaluate(ctx context.Context, r *types.Rule, req *types.SignRequest, parsed *types.ParsedPayload) (bool, string, error)
Evaluate runs the rule's JS validate(input) and maps result to (matched, reason, error). Supports both whitelist and blocklist modes: whitelist returns (true, reason, nil) when script passes (allow); blocklist returns (true, reason, nil) when script fails (violation → block).
func (*JSRuleEvaluator) EvaluateWithDelegation ¶ added in v0.1.0
func (e *JSRuleEvaluator) EvaluateWithDelegation(ctx context.Context, r *types.Rule, req *types.SignRequest, parsed *types.ParsedPayload) (bool, string, *rule.DelegationRequest, error)
EvaluateWithDelegation implements EvaluatorWithDelegation. Runs the script once; when valid and delegate_to is set and payload is present, returns a DelegationRequest for the engine to resolve.
func (*JSRuleEvaluator) Type ¶ added in v0.1.0
func (e *JSRuleEvaluator) Type() types.RuleType
Type returns the rule type this evaluator handles.
func (*JSRuleEvaluator) ValidateWithInput ¶ added in v0.1.0
func (e *JSRuleEvaluator) ValidateWithInput(script string, input *RuleInput, config map[string]interface{}) JSRuleValidateResult
ValidateWithInput runs the rule script with the given input and config, returns the sanitized result. Used by JSRuleValidator to run test cases.
type JSRuleValidateResult ¶ added in v0.1.0
type JSRuleValidateResult struct {
Valid bool `json:"valid"`
Reason string `json:"reason,omitempty"`
Payload interface{} `json:"payload,omitempty"`
DelegateTo string `json:"delegate_to,omitempty"` // optional; overrides config.delegate_to when delegating
}
JSRuleValidateResult is the return shape of JS validate(input). Invalid return / throw / timeout → wrapper converts to { valid: false, reason: "..." }. Script may optionally return delegate_to to route delegation by payload (e.g. by inner to-address).
type JSRuleValidator ¶ added in v0.1.0
type JSRuleValidator struct {
// contains filtered or unexported fields
}
JSRuleValidator validates evm_js rules by running their test_cases.
func NewJSRuleValidator ¶ added in v0.1.0
func NewJSRuleValidator(evaluator *JSRuleEvaluator, logger *slog.Logger) (*JSRuleValidator, error)
NewJSRuleValidator creates a validator that runs test cases via the JS evaluator.
func (*JSRuleValidator) ValidateRule ¶ added in v0.1.0
func (v *JSRuleValidator) ValidateRule(ctx context.Context, script string, testCases []JSTestCase, testVariables map[string]string) (*ValidationResult, error)
ValidateRule runs script with each test case (input + config from testVariables), compares result to expect_pass/expect_reason. script and testCases are from the rule; testVariables is the config object (e.g. template test_variables).
type JSTestCase ¶ added in v0.1.0
type JSTestCase struct {
Name string `json:"name" yaml:"name"`
Input map[string]interface{} `json:"input" yaml:"input"`
ExpectPass bool `json:"expect_pass" yaml:"expect_pass"`
ExpectReason string `json:"expect_reason,omitempty" yaml:"expect_reason,omitempty"`
}
JSTestCase defines a test case for evm_js rule validation (from YAML test_cases).
type KeystoreConfig ¶
type KeystoreConfig struct {
Address string `yaml:"address"` // Expected address (for verification)
Path string `yaml:"path"` // Path to keystore file
PasswordEnv string `yaml:"password_env"` // Environment variable containing password (used when password_stdin is false)
PasswordStdin bool `yaml:"password_stdin"` // If true, read password from stdin at startup (more secure)
Enabled bool `yaml:"enabled"` // Whether this signer is enabled
}
KeystoreConfig defines a keystore signer configuration
type KeystoreProvider ¶ added in v0.1.0
type KeystoreProvider struct {
// contains filtered or unexported fields
}
KeystoreProvider loads signers from encrypted keystore files and supports dynamic creation.
func NewKeystoreProvider ¶ added in v0.1.0
func NewKeystoreProvider( registry *SignerRegistry, configs []KeystoreConfig, keystoreDir string, pwProvider PasswordProvider, logger *slog.Logger, ) (*KeystoreProvider, error)
NewKeystoreProvider creates a KeystoreProvider and loads all configured keystores into the registry.
func (*KeystoreProvider) Close ¶ added in v0.1.0
func (p *KeystoreProvider) Close() error
func (*KeystoreProvider) CreateSigner ¶ added in v0.1.0
func (p *KeystoreProvider) CreateSigner(ctx context.Context, params interface{}) (*types.SignerInfo, error)
CreateSigner creates a new keystore signer dynamically via API.
func (*KeystoreProvider) DiscoverLockedSigners ¶ added in v0.1.0
func (p *KeystoreProvider) DiscoverLockedSigners() ([]types.SignerInfo, error)
DiscoverLockedSigners scans keystoreDir for keystore files not already loaded.
func (*KeystoreProvider) LockSigner ¶ added in v0.1.0
func (p *KeystoreProvider) LockSigner(ctx context.Context, address string) error
LockSigner locks an unlocked keystore signer (stores path for later unlock).
func (*KeystoreProvider) Type ¶ added in v0.1.0
func (p *KeystoreProvider) Type() types.SignerType
func (*KeystoreProvider) UnlockSigner ¶ added in v0.1.0
func (p *KeystoreProvider) UnlockSigner(ctx context.Context, address string, password string) (*ethsig.Signer, error)
UnlockSigner unlocks a locked keystore signer with the given password.
type MessagePatternConfig ¶
type MessagePatternConfig struct {
// Pattern is a regex pattern that the message must match (whitelist) or must not match (blocklist)
Pattern string `json:"pattern"`
// Patterns is a list of regex patterns (any match = rule fires)
// If both Pattern and Patterns are specified, Pattern is added to Patterns
Patterns []string `json:"patterns,omitempty"`
// SignTypes restricts which sign types this rule applies to
// If empty, applies to "personal" and "eip191" by default
SignTypes []string `json:"sign_types,omitempty"`
// Description provides human-readable explanation of what the pattern validates
Description string `json:"description,omitempty"`
// TestCases defines validation cases to verify rule correctness
TestCases []MessagePatternTestCase `json:"test_cases,omitempty"`
}
MessagePatternConfig defines the configuration for message pattern matching
type MessagePatternEvaluator ¶
type MessagePatternEvaluator struct{}
MessagePatternEvaluator validates personal sign messages against regex patterns Behavior depends on rule mode: - Whitelist mode: returns true if message matches ANY pattern (allow) - Blocklist mode: returns true if message matches ANY pattern (block)
func NewMessagePatternEvaluator ¶
func NewMessagePatternEvaluator() (*MessagePatternEvaluator, error)
NewMessagePatternEvaluator creates a new message pattern evaluator
func (*MessagePatternEvaluator) AppliesToSignType ¶
func (e *MessagePatternEvaluator) AppliesToSignType(rule *types.Rule, signType string) bool
AppliesToSignType implements rule.SignTypeApplicable: returns false if the rule's sign_types do not include signType.
func (*MessagePatternEvaluator) Evaluate ¶
func (e *MessagePatternEvaluator) Evaluate(ctx context.Context, r *types.Rule, req *types.SignRequest, parsed *types.ParsedPayload) (bool, string, error)
Evaluate checks if the message matches the configured patterns For whitelist mode: returns true if message matches ANY pattern (allow signing) For blocklist mode: returns true if message matches ANY pattern (block signing)
func (*MessagePatternEvaluator) Type ¶
func (e *MessagePatternEvaluator) Type() types.RuleType
Type returns the rule type this evaluator handles
type MessagePatternRuleValidator ¶
type MessagePatternRuleValidator struct {
// contains filtered or unexported fields
}
MessagePatternRuleValidator validates message_pattern rules
func NewMessagePatternRuleValidator ¶
func NewMessagePatternRuleValidator(logger *slog.Logger) (*MessagePatternRuleValidator, error)
NewMessagePatternRuleValidator creates a new message pattern rule validator
func (*MessagePatternRuleValidator) ValidateRule ¶
func (v *MessagePatternRuleValidator) ValidateRule(ctx context.Context, rule *types.Rule) (*ValidationResult, error)
ValidateRule validates a single message_pattern rule
type MessagePatternTestCase ¶
type MessagePatternTestCase struct {
Name string `json:"name"`
Input MessagePatternTestInput `json:"input"`
ExpectPass bool `json:"expect_pass"`
ExpectReason string `json:"expect_reason,omitempty"`
}
MessagePatternTestCase defines a test case for validating a message_pattern rule
type MessagePatternTestInput ¶
type MessagePatternTestInput struct {
RawMessage string `json:"raw_message"`
SignType string `json:"sign_type,omitempty"` // default: "personal"
}
MessagePatternTestInput defines the input for a message pattern test case
type PasswordProvider ¶
type PasswordProvider interface {
// GetPassword returns the password for the given keystore configuration
GetPassword(address string, config KeystoreConfig) ([]byte, error)
}
PasswordProvider provides passwords for keystore signers
type PrivateKeyConfig ¶
type PrivateKeyConfig struct {
Address string `yaml:"address"` // Expected address (for verification)
KeyEnvVar string `yaml:"key_env"` // Environment variable containing hex private key
Enabled bool `yaml:"enabled"` // Whether this signer is enabled
}
PrivateKeyConfig defines a private key signer configuration
type PrivateKeyProvider ¶ added in v0.1.0
type PrivateKeyProvider struct {
// contains filtered or unexported fields
}
PrivateKeyProvider loads signers from hex private keys (env vars or direct values).
func NewPrivateKeyProvider ¶ added in v0.1.0
func NewPrivateKeyProvider(registry *SignerRegistry, configs []PrivateKeyConfig) (*PrivateKeyProvider, error)
NewPrivateKeyProvider creates a PrivateKeyProvider and loads all configured keys into the registry.
func (*PrivateKeyProvider) Close ¶ added in v0.1.0
func (p *PrivateKeyProvider) Close() error
func (*PrivateKeyProvider) Type ¶ added in v0.1.0
func (p *PrivateKeyProvider) Type() types.SignerType
type RuleInput ¶ added in v0.1.0
type RuleInput struct {
SignType string `json:"sign_type"` // "transaction" | "typed_data" | "personal_sign"
ChainID int64 `json:"chain_id"`
Signer string `json:"signer"` // checksum address
Transaction *RuleInputTransaction `json:"transaction,omitempty"`
TypedData *RuleInputTypedData `json:"typed_data,omitempty"`
PersonalSign *RuleInputPersonalSign `json:"personal_sign,omitempty"`
}
RuleInput is the normalized input passed to JS rules (evm_js). Matches docs/architecture/js-rules-v5.md §5. Hashes/digests are computed in Go; rules receive this shape only.
func BuildRuleInput ¶ added in v0.1.0
func BuildRuleInput(req *types.SignRequest, parsed *types.ParsedPayload) (*RuleInput, error)
BuildRuleInput builds a normalized RuleInput from a sign request and parsed payload. For transaction sign_type, from is set from req.SignerAddress (checksum). Returns ErrFromNotDerivable if from is required but cannot be derived.
type RuleInputPersonalSign ¶ added in v0.1.0
type RuleInputPersonalSign struct {
Message string `json:"message"`
}
RuleInputPersonalSign is the EIP-191 personal sign subset.
type RuleInputTransaction ¶ added in v0.1.0
type RuleInputTransaction struct {
From string `json:"from"` // REQUIRED, checksum
To string `json:"to"` // empty for contract creation
Value string `json:"value"` // hex
Data string `json:"data"` // hex
Gas string `json:"gas,omitempty"` // decimal string
MethodID string `json:"methodId,omitempty"` // 4-byte hex selector
}
RuleInputTransaction is the transaction subset of RuleInput. From is REQUIRED; engine must populate when derivable.
type RuleInputTypedData ¶ added in v0.1.0
type RuleInputTypedData struct {
Types map[string][]TypedDataField `json:"types"`
PrimaryType string `json:"primaryType"`
Domain TypedDataDomain `json:"domain"`
Message map[string]interface{} `json:"message"`
}
RuleInputTypedData is the EIP-712 subset (standard shape).
type SecurityError ¶
SecurityError represents a security validation error
func ValidateJSCodeSecurity ¶ added in v0.1.0
func ValidateJSCodeSecurity(code string) *SecurityError
ValidateJSCodeSecurity checks JavaScript code for dangerous patterns. Returns nil if code is safe, or SecurityError if dangerous patterns are found.
func ValidateSolidityCodeSecurity ¶
func ValidateSolidityCodeSecurity(code string) *SecurityError
ValidateSolidityCodeSecurity checks code for dangerous patterns Returns nil if code is safe, or SecurityError if dangerous patterns are found
type SignTypeRestrictionConfig ¶
type SignTypeRestrictionConfig struct {
AllowedSignTypes []string `json:"allowed_sign_types"` // List of allowed sign types
}
SignTypeRestrictionConfig defines the configuration for sign type restrictions
type SignTypeRestrictionEvaluator ¶
type SignTypeRestrictionEvaluator struct{}
SignTypeRestrictionEvaluator checks if the sign type is allowed
func NewSignTypeRestrictionEvaluator ¶
func NewSignTypeRestrictionEvaluator() (*SignTypeRestrictionEvaluator, error)
NewSignTypeRestrictionEvaluator creates a new sign type restriction evaluator
func (*SignTypeRestrictionEvaluator) Evaluate ¶
func (e *SignTypeRestrictionEvaluator) Evaluate(ctx context.Context, r *types.Rule, req *types.SignRequest, parsed *types.ParsedPayload) (bool, string, error)
Evaluate checks if the sign type is in the allowed list
func (*SignTypeRestrictionEvaluator) Type ¶
func (e *SignTypeRestrictionEvaluator) Type() types.RuleType
Type returns the rule type this evaluator handles
type SignerConfig ¶
type SignerConfig struct {
PrivateKeys []PrivateKeyConfig `yaml:"private_keys"`
Keystores []KeystoreConfig `yaml:"keystores"`
HDWallets []HDWalletConfig `yaml:"hd_wallets"`
}
SignerConfig defines configuration for EVM signers
type SignerCreator ¶ added in v0.1.0
type SignerCreator interface {
SignerProvider
CreateSigner(ctx context.Context, params interface{}) (*types.SignerInfo, error)
}
SignerCreator can dynamically create new signers at runtime (via API).
type SignerDiscoverer ¶ added in v0.1.0
type SignerDiscoverer interface {
SignerProvider
DiscoverLockedSigners() ([]types.SignerInfo, error)
}
SignerDiscoverer can discover locked signers on startup (scan disk, probe HSM, etc.).
type SignerLocker ¶ added in v0.1.0
type SignerLocker interface {
SignerProvider
LockSigner(ctx context.Context, address string) error
}
SignerLocker can lock an unlocked signer at runtime (zeroize key, remove from memory).
type SignerManager ¶
type SignerManager interface {
// CreateSigner creates a new signer based on the request type
CreateSigner(ctx context.Context, req types.CreateSignerRequest) (*types.SignerInfo, error)
// ListSigners returns signers matching the filter with pagination
ListSigners(ctx context.Context, filter types.SignerFilter) (types.SignerListResult, error)
// HDWalletManager returns the HD wallet provider, or error if not configured.
HDWalletManager() (HDWalletManager, error)
// DiscoverLockedSigners scans all providers for locked signers and registers them.
DiscoverLockedSigners(ctx context.Context) error
// UnlockSigner unlocks a locked signer with the given password.
UnlockSigner(ctx context.Context, address string, password string) (*types.SignerInfo, error)
// LockSigner locks an unlocked signer (remove key from memory).
LockSigner(ctx context.Context, address string) (*types.SignerInfo, error)
}
SignerManager manages signer lifecycle operations
type SignerManagerImpl ¶
type SignerManagerImpl struct {
// contains filtered or unexported fields
}
SignerManagerImpl implements SignerManager
func NewSignerManager ¶
func NewSignerManager(registry *SignerRegistry, logger *slog.Logger) (*SignerManagerImpl, error)
NewSignerManager creates a new SignerManager
func (*SignerManagerImpl) CreateSigner ¶
func (m *SignerManagerImpl) CreateSigner(ctx context.Context, req types.CreateSignerRequest) (*types.SignerInfo, error)
CreateSigner dispatches to the appropriate provider via type assertion.
func (*SignerManagerImpl) DiscoverLockedSigners ¶ added in v0.1.0
func (m *SignerManagerImpl) DiscoverLockedSigners(ctx context.Context) error
DiscoverLockedSigners scans all providers for locked signers and registers them.
func (*SignerManagerImpl) HDWalletManager ¶ added in v0.1.0
func (m *SignerManagerImpl) HDWalletManager() (HDWalletManager, error)
HDWalletManager returns the HD wallet provider if configured.
func (*SignerManagerImpl) ListSigners ¶
func (m *SignerManagerImpl) ListSigners(ctx context.Context, filter types.SignerFilter) (types.SignerListResult, error)
ListSigners returns signers matching the filter with pagination
func (*SignerManagerImpl) LockSigner ¶ added in v0.1.0
func (m *SignerManagerImpl) LockSigner(ctx context.Context, address string) (*types.SignerInfo, error)
LockSigner locks an unlocked signer (remove key from memory).
func (*SignerManagerImpl) UnlockSigner ¶ added in v0.1.0
func (m *SignerManagerImpl) UnlockSigner(ctx context.Context, address string, password string) (*types.SignerInfo, error)
UnlockSigner unlocks a locked signer with the given password.
type SignerProvider ¶ added in v0.1.0
type SignerProvider interface {
// Type returns the signer type this provider manages.
Type() types.SignerType
// Close releases resources (zeroize keys, close HD wallet sessions, etc.)
Close() error
}
SignerProvider is the abstraction for pluggable signing backends. Each backend (private_key, keystore, hd_wallet, future HSM) implements this. All providers produce *ethsig.Signer instances registered in the shared registry.
type SignerRegistry ¶
type SignerRegistry struct {
// contains filtered or unexported fields
}
SignerRegistry manages EVM signers
func NewEmptySignerRegistry ¶ added in v0.1.0
func NewEmptySignerRegistry() *SignerRegistry
NewEmptySignerRegistry creates an empty registry for provider-based initialization.
func NewSignerRegistry ¶
func NewSignerRegistry(cfg SignerConfig) (*SignerRegistry, error)
NewSignerRegistry creates a new signer registry from configuration For keystores with password_stdin=true, passwords will be read from stdin interactively
func NewSignerRegistryWithProvider ¶
func NewSignerRegistryWithProvider(cfg SignerConfig, provider PasswordProvider) (*SignerRegistry, error)
NewSignerRegistryWithProvider creates a new signer registry with a custom password provider
func (*SignerRegistry) Close ¶ added in v0.1.0
func (r *SignerRegistry) Close() error
Close closes all registered providers (zeroize keys, cleanup).
func (*SignerRegistry) GetSigner ¶
func (r *SignerRegistry) GetSigner(address string) (*ethsig.Signer, error)
GetSigner returns the signer for the given address
func (*SignerRegistry) GetSignerInfo ¶ added in v0.1.0
func (r *SignerRegistry) GetSignerInfo(address string) (types.SignerInfo, bool)
GetSignerInfo returns the SignerInfo for a given address.
func (*SignerRegistry) HasSigner ¶
func (r *SignerRegistry) HasSigner(address string) bool
HasSigner checks if a signer exists for the given address (including locked signers).
func (*SignerRegistry) IsLocked ¶ added in v0.1.0
func (r *SignerRegistry) IsLocked(address string) bool
IsLocked returns true if signer exists but is locked.
func (*SignerRegistry) ListSigners ¶
func (r *SignerRegistry) ListSigners() []types.SignerInfo
ListSigners returns information about all registered signers
func (*SignerRegistry) ListSignersWithFilter ¶
func (r *SignerRegistry) ListSignersWithFilter(filter types.SignerFilter) types.SignerListResult
ListSignersWithFilter returns signers matching the filter with pagination
func (*SignerRegistry) LockSigner ¶ added in v0.1.0
func (r *SignerRegistry) LockSigner(address string) error
LockSigner sets an unlocked signer to locked state (nil signer, Locked=true, Enabled=false).
func (*SignerRegistry) Provider ¶ added in v0.1.0
func (r *SignerRegistry) Provider(t types.SignerType) (SignerProvider, bool)
Provider returns the provider for a given signer type.
func (*SignerRegistry) RegisterKeystore ¶
func (r *SignerRegistry) RegisterKeystore(address string, keystorePath string, password []byte) error
RegisterKeystore dynamically registers a keystore signer
func (*SignerRegistry) RegisterLockedSigner ¶ added in v0.1.0
func (r *SignerRegistry) RegisterLockedSigner(address string, info types.SignerInfo) error
RegisterLockedSigner registers a signer as locked (nil signer pointer).
func (*SignerRegistry) RegisterProvider ¶ added in v0.1.0
func (r *SignerRegistry) RegisterProvider(p SignerProvider)
RegisterProvider registers a provider for a given signer type.
func (*SignerRegistry) RegisterSigner ¶ added in v0.1.0
func (r *SignerRegistry) RegisterSigner(address string, signer *ethsig.Signer, info types.SignerInfo) error
RegisterSigner adds a signer to the registry. Called by providers during init/derive.
func (*SignerRegistry) SignerCount ¶ added in v0.1.0
func (r *SignerRegistry) SignerCount() int
SignerCount returns the number of unlocked (usable) signers.
func (*SignerRegistry) TotalCount ¶ added in v0.1.0
func (r *SignerRegistry) TotalCount() int
TotalCount returns total signer count (locked + unlocked).
func (*SignerRegistry) UnlockSigner ¶ added in v0.1.0
func (r *SignerRegistry) UnlockSigner(address string, signer *ethsig.Signer) error
UnlockSigner replaces nil signer with real signer, sets Locked=false, Enabled=true.
type SignerRestrictionConfig ¶
type SignerRestrictionConfig struct {
AllowedSigners []string `json:"allowed_signers"` // List of allowed signer addresses
}
SignerRestrictionConfig defines the configuration for signer restrictions
type SignerRestrictionEvaluator ¶
type SignerRestrictionEvaluator struct{}
SignerRestrictionEvaluator checks if the signer is allowed for the API key
func NewSignerRestrictionEvaluator ¶
func NewSignerRestrictionEvaluator() (*SignerRestrictionEvaluator, error)
NewSignerRestrictionEvaluator creates a new signer restriction evaluator
func (*SignerRestrictionEvaluator) Evaluate ¶
func (e *SignerRestrictionEvaluator) Evaluate(ctx context.Context, r *types.Rule, req *types.SignRequest, parsed *types.ParsedPayload) (bool, string, error)
Evaluate checks if the signer is in the allowed list
func (*SignerRestrictionEvaluator) Type ¶
func (e *SignerRestrictionEvaluator) Type() types.RuleType
Type returns the rule type this evaluator handles
type SignerUnlocker ¶ added in v0.1.0
type SignerUnlocker interface {
SignerProvider
UnlockSigner(ctx context.Context, address string, password string) (*ethsig.Signer, error)
}
SignerUnlocker can unlock a locked signer at runtime.
type SolidityEvaluatorConfig ¶
type SolidityEvaluatorConfig struct {
ForgePath string // path to forge binary, empty = auto-detect from PATH
CacheDir string // cache directory for compiled scripts
TempDir string // workspace dir (foundry.toml + lib/forge-std + rule scripts); empty = os.TempDir()/remote-signer-rules. When set to a dir with pre-installed lib/forge-std (e.g. Docker mount), ensureForgeStd is skipped.
Timeout time.Duration // max execution time per rule
CacheTTL time.Duration // TTL for execution result cache entries, 0 = no expiration
}
SolidityEvaluatorConfig holds configuration for the evaluator
type SolidityExpressionConfig ¶
type SolidityExpressionConfig struct {
// Expression is the Solidity code containing require() statements (Mode 1)
// Available variables:
// - address to (transaction recipient)
// - uint256 value (transaction value in wei)
// - bytes4 selector (method selector, first 4 bytes of data)
// - bytes data (full calldata)
// - uint256 chainId (chain ID)
// - address signer (signing address)
// Example: require(value <= 1 ether, "exceeds limit");
Expression string `json:"expression,omitempty"`
// Functions contains user-defined Solidity functions (Mode 2)
// When the transaction selector matches a function, it's called automatically
// with decoded parameters. Context variables available as txTo, txValue, etc.
// Example:
// function transfer(address to, uint256 amount) external {
// require(amount <= 10000e6, "exceeds 10k limit");
// }
Functions string `json:"functions,omitempty"`
// TypedDataExpression is Solidity code for EIP-712 typed data validation (Mode 3)
// Available variables:
// - string eip712_primaryType (primary type name, e.g., "Permit")
// - string eip712_domainName (domain name)
// - string eip712_domainVersion (domain version)
// - uint256 eip712_domainChainId (domain chain ID)
// - address eip712_domainContract (verifying contract address)
// - Plus message fields as defined by TypedDataTypes (or inferred from request)
// Example: require(value <= 1000000e6, "permit value exceeds 1M limit");
TypedDataExpression string `json:"typed_data_expression,omitempty"`
// TypedDataStruct defines the expected EIP-712 message structure using Solidity struct syntax
// When specified, the rule will:
// 1. Only match requests where primaryType matches the struct name (or TypedDataPrimaryType if set)
// 2. Generate a struct instance variable with lowercase name (e.g., Order -> order)
// 3. Access fields using struct.field syntax (e.g., order.taker, order.feeRateBps)
// Example:
// typed_data_struct: |
// struct Order {
// uint256 salt;
// address maker;
// address taker;
// uint256 feeRateBps;
// }
// typed_data_expression: |
// require(order.taker == address(0), "taker must be zero address");
// require(order.feeRateBps <= 1000, "fee exceeds 10%");
TypedDataStruct string `json:"typed_data_struct,omitempty"`
// TypedDataPrimaryType specifies the expected EIP-712 primaryType to match
// If not set but TypedDataStruct is defined, uses the struct name as primaryType
// The lowercase form of this name is used as the struct instance variable name
// Example: "Order" -> instance variable "order" accessible in expressions
TypedDataPrimaryType string `json:"typed_data_primary_type,omitempty"`
// TypedDataFunctions contains struct definitions and validation functions (Mode 4)
// Define structs matching EIP-712 types and functions to validate them
// Example:
// struct Permit { address owner; address spender; uint256 value; ... }
// function validatePermit(Permit memory permit) external { ... }
TypedDataFunctions string `json:"typed_data_functions,omitempty"`
// SignTypeFilter restricts this rule to specific sign types
// If empty, applies to all sign types (default behavior for transaction rules)
// Common values: "transaction", "typed_data", "personal", "eip191"
SignTypeFilter string `json:"sign_type_filter,omitempty"`
// InMappingArrays supplies address lists for in(expr, varName): varName -> []address.
// When rule body contains in(txTo, allowed_safe_addresses), generate allowed_safe_addresses_mapping
// and set InMappingArrays["allowed_safe_addresses"] to the list. O(1) lookup instead of expanded OR chain.
InMappingArrays map[string][]string `json:"in_mapping_arrays,omitempty"`
// Description explains what the rule validates
Description string `json:"description,omitempty"`
// ABISignature defines custom ABI decoding (optional, only for Expression mode)
// Format: "functionName(type1,type2,...)"
ABISignature string `json:"abi_signature,omitempty"`
// TestCases defines validation cases to verify rule correctness
// Each test case is executed during rule creation/update to ensure validity
TestCases []SolidityTestCase `json:"test_cases"`
}
SolidityExpressionConfig holds the Solidity code for rule evaluation Supports multiple modes:
- Expression mode: require() statements with context variables (for transactions)
- Function mode: define functions that auto-match transaction selectors
- TypedDataExpression mode: require() statements for EIP-712 typed data validation
- TypedDataFunctions mode: struct-based functions for EIP-712 validation
type SolidityRuleEvaluator ¶
type SolidityRuleEvaluator struct {
// contains filtered or unexported fields
}
SolidityRuleEvaluator evaluates rules using Foundry's forge script
func NewSolidityRuleEvaluator ¶
func NewSolidityRuleEvaluator(cfg SolidityEvaluatorConfig, logger *slog.Logger) (*SolidityRuleEvaluator, error)
NewSolidityRuleEvaluator creates a new evaluator
func (*SolidityRuleEvaluator) AppliesToSignType ¶
func (e *SolidityRuleEvaluator) AppliesToSignType(rule *types.Rule, signType string) bool
AppliesToSignType implements rule.SignTypeApplicable: returns false if the rule's sign_type_filter does not match.
func (*SolidityRuleEvaluator) CanBatchEvaluate ¶
func (e *SolidityRuleEvaluator) CanBatchEvaluate(rules []*types.Rule) bool
CanBatchEvaluate returns true if the given rules can be evaluated together Rules can be batched if they all use compatible validation modes
func (*SolidityRuleEvaluator) Evaluate ¶
func (e *SolidityRuleEvaluator) Evaluate( ctx context.Context, rule *types.Rule, req *types.SignRequest, parsed *types.ParsedPayload, ) (bool, string, error)
Evaluate evaluates the rule against the request
func (*SolidityRuleEvaluator) EvaluateBatch ¶
func (e *SolidityRuleEvaluator) EvaluateBatch( ctx context.Context, rules []*types.Rule, req *types.SignRequest, parsed *types.ParsedPayload, ) ([]rule.BatchEvaluationResult, error)
EvaluateBatch evaluates multiple rules against the same request in a single forge execution
func (*SolidityRuleEvaluator) GenerateFunctionSyntaxCheckScript ¶
func (e *SolidityRuleEvaluator) GenerateFunctionSyntaxCheckScript(functions string, inMappingArrays ...map[string][]string) string
GenerateFunctionSyntaxCheckScript generates a script for compilation checking (Functions mode) Uses the same two-contract structure as solidityFunctionTemplate for consistency
func (*SolidityRuleEvaluator) GenerateSyntaxCheckScript ¶
func (e *SolidityRuleEvaluator) GenerateSyntaxCheckScript(expression string, inMappingArrays ...map[string][]string) string
GenerateSyntaxCheckScript generates a script for compilation checking (Expression mode)
func (*SolidityRuleEvaluator) GenerateTypedDataExpressionSyntaxCheckScript ¶
func (e *SolidityRuleEvaluator) GenerateTypedDataExpressionSyntaxCheckScript(expression string, inMappingArrays ...map[string][]string) string
GenerateTypedDataExpressionSyntaxCheckScript generates a syntax check script for TypedDataExpression mode. Callers must pass the rule's typed_data_struct via GenerateTypedDataExpressionSyntaxCheckScriptWithStruct; rules are the single source of truth.
func (*SolidityRuleEvaluator) GenerateTypedDataExpressionSyntaxCheckScriptWithStruct ¶
func (e *SolidityRuleEvaluator) GenerateTypedDataExpressionSyntaxCheckScriptWithStruct(expression string, structDef *StructDefinition, inMappingArrays ...map[string][]string) string
GenerateTypedDataExpressionSyntaxCheckScriptWithStruct generates a syntax check script from the rule's struct definition only. structDef must come from the rule config (typed_data_struct); no hardcoded structs. When structDef is nil, generates only EIP-712/ctx vars so expressions that reference structs fail at compile (caller should require typed_data_struct for typed_data_expression rules).
func (*SolidityRuleEvaluator) GenerateTypedDataFunctionsSyntaxCheckScript ¶
func (e *SolidityRuleEvaluator) GenerateTypedDataFunctionsSyntaxCheckScript(functions string, inMappingArrays ...map[string][]string) string
GenerateTypedDataFunctionsSyntaxCheckScript generates a syntax check script for TypedDataFunctions mode
func (*SolidityRuleEvaluator) GetCacheDir ¶
func (e *SolidityRuleEvaluator) GetCacheDir() string
GetCacheDir returns the cache directory path
func (*SolidityRuleEvaluator) GetFoundryPath ¶
func (e *SolidityRuleEvaluator) GetFoundryPath() string
GetFoundryPath returns the forge binary path
func (*SolidityRuleEvaluator) GetTempDir ¶
func (e *SolidityRuleEvaluator) GetTempDir() string
GetTempDir returns the temp directory path
func (*SolidityRuleEvaluator) GetTimeout ¶ added in v0.0.2
func (e *SolidityRuleEvaluator) GetTimeout() time.Duration
GetTimeout returns the configured execution timeout (for validator to align forge build/test timeouts)
func (*SolidityRuleEvaluator) Type ¶
func (e *SolidityRuleEvaluator) Type() types.RuleType
Type returns the rule type this evaluator handles
type SolidityRuleValidator ¶
type SolidityRuleValidator struct {
// contains filtered or unexported fields
}
SolidityRuleValidator validates Solidity expression rules before storage
func NewSolidityRuleValidator ¶
func NewSolidityRuleValidator(evaluator *SolidityRuleEvaluator, logger *slog.Logger) (*SolidityRuleValidator, error)
NewSolidityRuleValidator creates a new validator
func (*SolidityRuleValidator) Evaluator ¶ added in v0.1.0
func (v *SolidityRuleValidator) Evaluator() *SolidityRuleEvaluator
Evaluator returns the underlying SolidityRuleEvaluator, or nil if not set. Used by validate-rules to register the evaluator with the rule engine.
func (*SolidityRuleValidator) ValidateRule ¶
func (v *SolidityRuleValidator) ValidateRule(ctx context.Context, rule *types.Rule) (*ValidationResult, error)
ValidateRule performs full validation of a Solidity expression rule
func (*SolidityRuleValidator) ValidateRulesBatch ¶
func (v *SolidityRuleValidator) ValidateRulesBatch(ctx context.Context, rules []*types.Rule) (*BatchValidationResult, error)
ValidateRulesBatch validates multiple rules in a single compilation This significantly improves performance by reducing the number of forge compilations. Rules are automatically grouped by validation mode and each group is batched separately.
type SolidityTestCase ¶
type SolidityTestCase struct {
// Name describes what this test case validates
Name string `json:"name"`
// Input defines the transaction context for this test
Input SolidityTestInput `json:"input"`
// ExpectPass indicates whether the rule should pass (true) or revert (false)
ExpectPass bool `json:"expect_pass"`
// ExpectReason is the expected revert reason (only used when ExpectPass is false)
// If empty, any revert is accepted; if set, must match the revert message
ExpectReason string `json:"expect_reason,omitempty"`
}
SolidityTestCase defines a test case for validating a Solidity rule
type SolidityTestInput ¶
type SolidityTestInput struct {
// Transaction context fields (for transaction rules)
To string `json:"to,omitempty"` // recipient address, 0x-prefixed
Value string `json:"value,omitempty"` // value in wei (decimal string)
Selector string `json:"selector,omitempty"` // method selector, 0x-prefixed 4 bytes
Data string `json:"data,omitempty"` // full calldata, 0x-prefixed hex
ChainID string `json:"chain_id,omitempty"` // chain ID (decimal string)
Signer string `json:"signer,omitempty"` // signer address, 0x-prefixed
// EIP-712 typed data fields (for typed_data rules)
TypedData *TypedDataTestInput `json:"typed_data,omitempty"`
}
SolidityTestInput defines the transaction context for a test case
type StdinPasswordProvider ¶
type StdinPasswordProvider struct{}
StdinPasswordProvider reads passwords from stdin interactively
func NewStdinPasswordProvider ¶
func NewStdinPasswordProvider() (*StdinPasswordProvider, error)
NewStdinPasswordProvider creates a new stdin-based password provider
func (*StdinPasswordProvider) GetPassword ¶
func (p *StdinPasswordProvider) GetPassword(address string, config KeystoreConfig) ([]byte, error)
GetPassword reads the password from stdin interactively
type StructDefinition ¶
type StructDefinition struct {
Name string // struct name (e.g., "Order")
Fields []TypedDataField // ordered list of fields
}
StructDefinition represents a parsed Solidity struct
type SyntaxError ¶
type SyntaxError struct {
Message string `json:"message"`
Line int `json:"line,omitempty"`
Column int `json:"column,omitempty"`
Severity string `json:"severity"` // "error" or "warning"
}
SyntaxError contains details about a Solidity compilation error
type TestCaseResult ¶
type TestCaseResult struct {
Name string `json:"name"`
Passed bool `json:"passed"`
ExpectedPass bool `json:"expected_pass"`
ActualPass bool `json:"actual_pass"`
ExpectedReason string `json:"expected_reason,omitempty"`
ActualReason string `json:"actual_reason,omitempty"`
Error string `json:"error,omitempty"`
}
TestCaseResult contains the result of a single test case execution
type TransactionPayload ¶
type TransactionPayload struct {
To *string `json:"to,omitempty"` // nil for contract creation
Value string `json:"value"` // wei as decimal string
Data string `json:"data,omitempty"` // 0x-prefixed hex string
Nonce *uint64 `json:"nonce,omitempty"`
Gas uint64 `json:"gas"`
GasPrice string `json:"gasPrice,omitempty"` // for legacy tx
GasTipCap string `json:"gasTipCap,omitempty"` // for EIP-1559
GasFeeCap string `json:"gasFeeCap,omitempty"` // for EIP-1559
TxType string `json:"txType"` // "legacy", "eip2930", "eip1559"
}
TransactionPayload represents an Ethereum transaction
type TransactionType ¶
type TransactionType string
TransactionType represents the Ethereum transaction type
const ( TransactionTypeLegacy TransactionType = "legacy" TransactionTypeEIP2930 TransactionType = "eip2930" TransactionTypeEIP1559 TransactionType = "eip1559" )
type TypedDataDomain ¶
type TypedDataDomain struct {
Name string `json:"name,omitempty"`
Version string `json:"version,omitempty"`
ChainId string `json:"chainId,omitempty"` // decimal string
VerifyingContract string `json:"verifyingContract,omitempty"`
Salt string `json:"salt,omitempty"`
}
TypedDataDomain represents the domain of EIP-712 typed data
type TypedDataDomainInput ¶
type TypedDataDomainInput struct {
Name string `json:"name,omitempty"`
Version string `json:"version,omitempty"`
ChainID string `json:"chainId,omitempty"`
VerifyingContract string `json:"verifyingContract,omitempty"`
Salt string `json:"salt,omitempty"`
}
TypedDataDomainInput defines the EIP-712 domain for test cases
type TypedDataField ¶
TypedDataField represents a field in EIP-712 typed data
type TypedDataPayload ¶
type TypedDataPayload struct {
Types map[string][]TypedDataField `json:"types"`
PrimaryType string `json:"primaryType"`
Domain TypedDataDomain `json:"domain"`
Message map[string]interface{} `json:"message"`
}
TypedDataPayload represents EIP-712 typed data
type TypedDataTestInput ¶
type TypedDataTestInput struct {
// PrimaryType is the primary type name (e.g., "Permit")
PrimaryType string `json:"primaryType,omitempty"`
// Domain contains the EIP-712 domain parameters
Domain *TypedDataDomainInput `json:"domain,omitempty"`
// Message contains the typed data message fields
// Keys are field names, values are field values (as strings)
Message map[string]interface{} `json:"message,omitempty"`
}
TypedDataTestInput defines EIP-712 typed data for test cases
type ValidationMode ¶
type ValidationMode int
ValidationMode represents the validation mode for a Solidity rule
const ( ValidationModeExpression ValidationMode = iota ValidationModeFunctions ValidationModeTypedDataExpression ValidationModeTypedDataFunctions )
type ValidationResult ¶
type ValidationResult struct {
Valid bool `json:"valid"`
SyntaxError *SyntaxError `json:"syntax_error,omitempty"`
TestCaseResults []TestCaseResult `json:"test_case_results,omitempty"`
FailedTestCases int `json:"failed_test_cases"`
}
ValidationResult contains the result of rule validation
type ValueLimitConfig ¶
type ValueLimitConfig struct {
MaxValue string `json:"max_value"` // wei as decimal string
}
ValueLimitConfig defines value limits
type ValueLimitEvaluator ¶
type ValueLimitEvaluator struct{}
ValueLimitEvaluator checks if the transaction value is within/exceeds the limit Behavior depends on rule mode: - Whitelist mode: returns true if value <= limit (allow small transactions) - Blocklist mode: returns true if value > limit (block large transactions)
func NewValueLimitEvaluator ¶
func NewValueLimitEvaluator() (*ValueLimitEvaluator, error)
NewValueLimitEvaluator creates a new value limit evaluator
func (*ValueLimitEvaluator) Evaluate ¶
func (e *ValueLimitEvaluator) Evaluate(ctx context.Context, r *types.Rule, req *types.SignRequest, parsed *types.ParsedPayload) (bool, string, error)
Evaluate checks the transaction value against the limit For blocklist mode: returns true if value EXCEEDS limit (violation) For whitelist mode: returns true if value is WITHIN limit (allowed)
func (*ValueLimitEvaluator) Type ¶
func (e *ValueLimitEvaluator) Type() types.RuleType
Type returns the rule type this evaluator handles
Source Files
¶
- adapter.go
- delegation_convert.go
- js_abi_tuple.go
- js_evaluator.go
- js_helpers.go
- js_rule_input_map.go
- js_rule_types.go
- js_validator.go
- message_pattern_evaluator.go
- message_pattern_validator.go
- password_provider.go
- provider.go
- provider_hdwallet.go
- provider_keystore.go
- provider_privatekey.go
- rule_evaluator.go
- rule_input.go
- signer.go
- signer_manager.go
- solidity_evaluator.go
- solidity_validator.go
- struct_parser.go
- test_case_input.go
- types.go