Skip to content
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
5 changes: 1 addition & 4 deletions config/aggregator.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@
environment: development

## Aggregator Server Configs
# Migration backups are written to <db_path>_backup automatically.
db_path: /tmp/ap-avs/db

# Backup directory for manual backups (via REPL) and database migrations
# Periodic automated backups are not currently implemented
backup_dir: /tmp/ap-avs-backup

## Aggregator Address: Replace with your aggregator's address
ecdsa_private_key:

Expand Down
28 changes: 1 addition & 27 deletions core/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ type Config struct {
// Account abstraction config
SmartWallet *SmartWalletConfig

BackupConfig BackupConfig

SocketPath string
Environment sdklogging.LogLevel

Expand Down Expand Up @@ -166,12 +164,6 @@ type SmartWalletConfig struct {
MaxWalletsPerOwner int
}

type BackupConfig struct {
Enabled bool // Whether periodic backups are enabled
IntervalMinutes int // Interval between backups in minutes
BackupDir string // Directory to store backups
}

// These are read from configPath
type ConfigRaw struct {
EcdsaPrivateKey string `yaml:"ecdsa_private_key"`
Expand All @@ -188,7 +180,6 @@ type ConfigRaw struct {
AVSRegistryCoordinatorAddr string `yaml:"avs_registry_coordinator_address"`

DbPath string `yaml:"db_path"`
BackupDir string `yaml:"backup_dir"`
JwtSecret string `yaml:"jwt_secret"`

SmartWallet struct {
Expand All @@ -203,12 +194,6 @@ type ConfigRaw struct {
MaxWalletsPerOwner int `yaml:"max_wallets_per_owner"`
} `yaml:"smart_wallet"`

Backup struct {
Enabled bool `yaml:"enabled"`
IntervalMinutes int `yaml:"interval_minutes"`
BackupDir string `yaml:"backup_dir"`
} `yaml:"backup"`

SocketPath string `yaml:"socket_path"`

// List of approved operator addresses that can process tasks
Expand Down Expand Up @@ -381,11 +366,6 @@ func NewConfig(configFilePath string) (*Config, error) {
configRaw.SmartWallet.MaxWalletsPerOwner = HardMaxWalletsPerOwner
}

if configRaw.BackupDir == "" {
// If backup dir is not set, use the default path, usually this path will be mount from our docker compose host
configRaw.BackupDir = "/tmp/ap-avs-backup"
}

config := &Config{
EcdsaPrivateKey: ecdsaPrivateKey,
Logger: logger,
Expand All @@ -406,7 +386,7 @@ func NewConfig(configFilePath string) (*Config, error) {
AggregatorAddress: aggregatorAddr,

DbPath: configRaw.DbPath,
BackupDir: configRaw.BackupDir,
BackupDir: configRaw.DbPath + "_backup",
JwtSecret: []byte(configRaw.JwtSecret),
Comment on lines 388 to 390

SmartWallet: &SmartWalletConfig{
Expand All @@ -423,12 +403,6 @@ func NewConfig(configFilePath string) (*Config, error) {
// PaymasterOwnerAddress will be populated below by calling owner() on the paymaster contract
},

BackupConfig: BackupConfig{
Enabled: configRaw.Backup.Enabled,
IntervalMinutes: configRaw.Backup.IntervalMinutes,
BackupDir: configRaw.Backup.BackupDir,
},

SocketPath: configRaw.SocketPath,
MacroVars: configRaw.Macros["vars"],
MacroSecrets: configRaw.Macros["secrets"],
Expand Down
7 changes: 4 additions & 3 deletions core/taskengine/summarizer_format_telegram.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ func getStatusEmoji(s Summary) string {
}
}

// formatSubjectWithBoldName formats the subject with <code> tags only around the workflow name
// formatSubjectWithBoldName formats the subject with <code> tags around the
// prefix + workflow name (everything except the trailing status suffix).
// Subject patterns:
// - "Simulation: {name} successfully completed"
// - "Run Node: {name} succeeded"
Expand Down Expand Up @@ -206,13 +207,13 @@ func formatSubjectWithBoldName(subject string) string {
// Extract the workflow name
name := subject[nameStart:nameEnd]

// Build the formatted string: prefix + <code>name</code> + suffix
// Build the formatted string: <code>prefix + name</code> + suffix
// Using <code> prevents Telegram from auto-linking names that contain dots
var sb strings.Builder
sb.WriteString("<code>")
if prefix != "" {
sb.WriteString(html.EscapeString(prefix))
}
sb.WriteString("<code>")
sb.WriteString(html.EscapeString(name))
sb.WriteString("</code>")
sb.WriteString(html.EscapeString(suffix))
Expand Down
30 changes: 15 additions & 15 deletions core/taskengine/summarizer_format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ func TestFormatTelegramFromStructured_PRDFormat(t *testing.T) {
},
},
expectedContain: []string{
"✅ Simulation: <code>Recurring Payment</code> successfully completed", // Only workflow name is code-wrapped
"✅ <code>Simulation: Recurring Payment</code> successfully completed", // Prefix + name code-wrapped
"<b>Network:</b> Sepolia",
"<b>Time:</b> Jan 22, 2026 at 4:51 AM UTC",
"<b>Trigger:</b> (Simulated) Your scheduled task (every 3 days at 11:00 PM) triggered on Sepolia.",
Expand All @@ -803,7 +803,7 @@ func TestFormatTelegramFromStructured_PRDFormat(t *testing.T) {
},
},
expectedContain: []string{
"✅ Run #3: <code>Recurring Payment</code> successfully completed", // Only workflow name is code-wrapped
"✅ <code>Run #3: Recurring Payment</code> successfully completed", // Prefix + name code-wrapped
"<b>Network:</b> Sepolia",
"<b>Time:</b> Jan 22, 2026 at 4:51 AM UTC",
"<b>Executed:</b>",
Expand All @@ -823,7 +823,7 @@ func TestFormatTelegramFromStructured_PRDFormat(t *testing.T) {
Errors: []string{"transfer1: Insufficient balance for transfer"},
},
expectedContain: []string{
"❌ Run #5: <code>Recurring Payment</code> failed to execute", // Only workflow name is code-wrapped
"❌ <code>Run #5: Recurring Payment</code> failed to execute", // Prefix + name code-wrapped
"<b>Network:</b> Sepolia",
"<b>What Went Wrong:</b>",
"• transfer1: Insufficient balance for transfer",
Expand All @@ -846,7 +846,7 @@ func TestFormatTelegramFromStructured_PRDFormat(t *testing.T) {
},
},
expectedContain: []string{
"⚠️ Run #2: <code>My Workflow</code> successfully completed",
"⚠️ <code>Run #2: My Workflow</code> successfully completed",
"<i>1 node was skipped by Branch condition.</i>",
"<b>Network:</b> Ethereum",
"<b>Executed:</b>",
Expand All @@ -867,7 +867,7 @@ func TestFormatTelegramFromStructured_PRDFormat(t *testing.T) {
Errors: []string{"loop1 - skipped due to condition not met: `code1.data.balance >= code1.data.totalNeeded` evaluated to false"},
},
expectedContain: []string{
"⚠️ Simulation: <code>Copy of Test Recurring Batch Send</code> successfully completed",
"⚠️ <code>Simulation: Copy of Test Recurring Batch Send</code> successfully completed",
"<i>1 node was skipped by Branch condition.</i>",
"<b>Network:</b> Sepolia",
"<b>What Went Wrong:</b>",
Expand Down Expand Up @@ -943,7 +943,7 @@ func TestFormatTelegramFromStructured_PRDFormat(t *testing.T) {
Executions: []ExecutionEntry{{Description: "(Simulated) On-chain transaction successfully completed"}},
},
expectedContain: []string{
"✅ Simulation: <code>My Workflow</code> successfully completed",
"✅ <code>Simulation: My Workflow</code> successfully completed",
"<b>Network:</b> Sepolia",
"<b>Trigger:</b> (Simulated) Scheduled task ran on Sepolia",
"<b>Executed:</b>",
Expand Down Expand Up @@ -1160,27 +1160,27 @@ func TestFormatSubjectWithBoldName(t *testing.T) {
{
name: "simulation success",
subject: "Simulation: My Workflow successfully completed",
expected: "Simulation: <code>My Workflow</code> successfully completed",
expected: "<code>Simulation: My Workflow</code> successfully completed",
},
{
name: "simulation failure",
subject: "Simulation: Test Workflow failed to execute",
expected: "Simulation: <code>Test Workflow</code> failed to execute",
expected: "<code>Simulation: Test Workflow</code> failed to execute",
},
{
name: "simulation partial",
subject: "Simulation: Another Workflow partially executed",
expected: "Simulation: <code>Another Workflow</code> partially executed",
expected: "<code>Simulation: Another Workflow</code> partially executed",
},
{
name: "run number success",
subject: "Run #3: Payment Flow successfully completed",
expected: "Run #3: <code>Payment Flow</code> successfully completed",
expected: "<code>Run #3: Payment Flow</code> successfully completed",
},
{
name: "run number failure",
subject: "Run #15: Swap Workflow failed to execute",
expected: "Run #15: <code>Swap Workflow</code> failed to execute",
expected: "<code>Run #15: Swap Workflow</code> failed to execute",
},
{
name: "no prefix success",
Expand All @@ -1195,17 +1195,17 @@ func TestFormatSubjectWithBoldName(t *testing.T) {
{
name: "workflow name with special chars",
subject: "Simulation: Copy of Recurring Payment & Report successfully completed",
expected: "Simulation: <code>Copy of Recurring Payment &amp; Report</code> successfully completed",
expected: "<code>Simulation: Copy of Recurring Payment &amp; Report</code> successfully completed",
},
{
name: "run node success",
subject: "Run Node: My Transfer succeeded",
expected: "Run Node: <code>My Transfer</code> succeeded",
expected: "<code>Run Node: My Transfer</code> succeeded",
},
{
name: "run node failure",
subject: "Run Node: My Transfer failed at transfer1",
expected: "Run Node: <code>My Transfer</code> failed at transfer1",
expected: "<code>Run Node: My Transfer</code> failed at transfer1",
},
{
name: "deployed workflow success",
Expand Down Expand Up @@ -1391,7 +1391,7 @@ func TestComposeSummary_SimulateTaskFromClientPayload(t *testing.T) {
telegram := FormatForMessageChannels(summary, "telegram", nil)

expectedTelegramContents := []string{
"✅ Simulation: <code>Test settings.name</code> successfully completed",
"✅ <code>Simulation: Test settings.name</code> successfully completed",
"<b>Network:</b> Sepolia",
"<b>Time:</b>",
"<b>Trigger:</b> (Simulated) Scheduled task ran on Sepolia",
Expand Down
11 changes: 11 additions & 0 deletions docs/changes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# EigenLayer-AVS change log

Long-form notes for changes worth remembering after the PR merges. Format and editorial guidance live in the `create-change-doc` Claude command (`~/.claude/commands/create-change-doc.md` locally) — this README only carries project-specific notes.

Filename: `YYYYMMDD-kebab-case-title.md`. Each entry opens with a header block (Date, Status, Branch, Related) and a body adapted to the change (typically Problem / Decision / Alternatives / Verification). See existing entries for examples.

Earlier entries (`0001-…`, `0002-…`) used a sequential four-digit prefix; those filenames are referenced from merged commits and stay as-is. New entries use the date prefix.

## Project-specific notes

_None yet. Add things here that only apply to this repo: dashboards we cross-link to, tags or prefixes we use, runbooks worth pointing at._
Loading