{"id":29168344,"url":"https://github.com/mento-protocol/alerts","last_synced_at":"2026-02-04T17:32:28.106Z","repository":{"id":299595531,"uuid":"920670798","full_name":"mento-protocol/alerts","owner":"mento-protocol","description":"Manage our alert rules across various platforms and services","archived":false,"fork":false,"pushed_at":"2025-12-02T12:51:25.000Z","size":434,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-12-05T09:38:28.509Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mento-protocol.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-22T15:14:49.000Z","updated_at":"2025-12-02T12:51:27.000Z","dependencies_parsed_at":"2025-06-17T10:44:59.233Z","dependency_job_id":"a98e6812-e564-4b0f-b403-7cfe4bf3921f","html_url":"https://github.com/mento-protocol/alerts","commit_stats":null,"previous_names":["mento-protocol/alerts"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mento-protocol/alerts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mento-protocol%2Falerts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mento-protocol%2Falerts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mento-protocol%2Falerts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mento-protocol%2Falerts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mento-protocol","download_url":"https://codeload.github.com/mento-protocol/alerts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mento-protocol%2Falerts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29091843,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-04T03:31:03.593Z","status":"ssl_error","status_checked_at":"2026-02-04T03:29:50.742Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-01T10:07:07.761Z","updated_at":"2026-02-04T17:32:28.099Z","avatar_url":"https://github.com/mento-protocol.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mento Alerts\n\nTerraform-managed alert infrastructure for monitoring Mento's infrastructure across multiple blockchain networks.\n\n## 📦 Module Structure\n\n```plain\n.\n├── main.tf                 # Root configuration and module orchestration\n├── variables.tf            # Shared variable definitions\n├── outputs.tf              # Aggregated outputs\n│\n├── sentry-alerts/          # Sentry JS error monitoring\n├── onchain-event-listeners/ # QuickNode webhook management for on-chain events\n├── onchain-event-handler/   # Cloud Function for processing webhooks\n└── discord-channel-manager/ # Discord channels and webhooks\n```\n\n## 🏗️ Architecture\n\n### Data Flow\n\n```mermaid\ngraph LR\n    A[Blockchain\u003cbr/\u003eCelo/Ethereum] --\u003e|Events emitted| B[QuickNode\u003cbr/\u003eWebhooks]\n    B --\u003e|HTTP POST\u003cbr/\u003esigned| C[Cloud Function\u003cbr/\u003eonchain-event-handler]\n    C --\u003e|1. Verify signature| C\n    C --\u003e|2. Validate payload| C\n    C --\u003e|3. Process events| C\n    C --\u003e|4. Format messages| C\n    C --\u003e|HTTP POST| D[Discord\u003cbr/\u003eWebhooks]\n    D --\u003e|Messages| E[Discord Channels\u003cbr/\u003ealerts/events]\n```\n\n### Component Overview\n\n1. **QuickNode Webhooks**: Monitor blockchain events for configured multisig addresses\n2. **Cloud Function**: Processes webhooks, verifies signatures, formats messages\n3. **Discord Channels**: Receives formatted alerts and event notifications\n4. **Terraform**: Manages all infrastructure as code\n\n### Security\n\n- **Signature Verification**: All QuickNode webhooks are verified using HMAC-SHA256\n- **Timestamp Validation**: Prevents replay attacks (5-minute window)\n- **Payload Size Limits**: Maximum 10MB payload size\n- **Secret Management**: Secrets stored in GCP Secret Manager\n\n## Prerequisites\n\n- **Terraform** \u003e= 1.10.0\n- **GCP account** with billing enabled\n- **Discord bot** with admin permissions\n- **Sentry account** (for JS error monitoring)\n- **QuickNode account** (for blockchain monitoring)\n\n## 🚀 Quick Start\n\n### 1. Configure Variables\n\n```bash\ncp terraform.tfvars.example terraform.tfvars\n```\n\nEdit `terraform.tfvars`:\n\n```hcl\n# Discord Configuration\ndiscord_bot_token      = \"\u003cyour-discord-bot-token\u003e\"\ndiscord_server_id      = \"\u003cdiscord-server-id\u003e\"\ndiscord_category_id    = \"\u003calert-category-id\u003e\"\ndiscord_sentry_role_id = \"\u003csentry-role-id\u003e\"\ndiscord_server_name    = \"\u003cdiscord-server-name\u003e\"\n\n# Sentry Configuration\nsentry_auth_token      = \"your-sentry-auth-token\"\nsentry_organization_slug = \"my-org\"  # Optional, defaults to \"mento-labs\"\nsentry_team_slug       = \"my-team\"    # Optional, defaults to \"mento-labs\"\n\n# GCP Configuration\nproject_name     = \"alerts\"              # Optional, defaults to \"alerts\"\norg_id           = \"123456789012\"        # Optional, omit if not using organization\nbilling_account  = \"XXXXXX-XXXXXX-XXXXXX\"  # Required\nregion           = \"europe-west1\"        # Optional, defaults to \"europe-west1\"\n\n# QuickNode Configuration\nquicknode_api_key        = \"your-quicknode-api-key\"\nquicknode_signing_secret = \"your-signing-secret-at-least-32-chars\"  # Generate: openssl rand -hex 32\n\n# Multisig Configuration\nmultisigs = {\n  \"mento-labs-celo\" = {\n    name                   = \"Mento Labs Multisig\"\n    address                = \"0x655133d8E90F8190ed5c1F0f3710F602800C0150\"\n    chain                  = \"celo\"\n    quicknode_network_name = \"celo-mainnet\"\n  }\n}\n\n# Optional: Additional Labels\nadditional_labels = {\n  environment = \"production\"\n  team        = \"platform\"\n  cost-center = \"infrastructure\"\n}\n```\n\n### 2. Initialize \u0026 Deploy\n\n```bash\nterraform init\nterraform plan\nterraform apply\n```\n\n**Expected deployment time:** 5-10 minutes\n\n### 3. Verify Deployment\n\n```bash\nterraform output\nterraform state list\ncurl -X POST $(terraform output -raw cloud_function_url)  # Should return 401\n```\n\n## 📖 Usage Examples\n\n### Single-Chain Setup\n\n```hcl\nmultisigs = {\n  \"my-multisig\" = {\n    name                   = \"My Multisig\"\n    address                = \"0x1234567890123456789012345678901234567890\"\n    chain                  = \"celo\"\n    quicknode_network_name = \"celo-mainnet\"\n  }\n}\n```\n\n### Multi-Chain Setup\n\nThe module automatically groups multisigs by chain and creates one QuickNode webhook per chain. A single Cloud Function handles webhooks from all chains.\n\n```hcl\nmultisigs = {\n  \"mento-labs-celo\" = {\n    name                   = \"Mento Labs Multisig\"\n    address                = \"0x655133d8E90F8190ed5c1F0f3710F602800C0150\"\n    chain                  = \"celo\"\n    quicknode_network_name = \"celo-mainnet\"\n  }\n  \"mento-labs-ethereum\" = {\n    name                   = \"Mento Labs Multisig\"\n    address                = \"0x1234567890123456789012345678901234567890\"\n    chain                  = \"ethereum\"\n    quicknode_network_name = \"ethereum-mainnet\"\n  }\n}\n```\n\n### Supported Chains\n\n- **Celo**: `chain = \"celo\"`, `quicknode_network_name = \"celo-mainnet\"`\n- **Ethereum**: `chain = \"ethereum\"`, `quicknode_network_name = \"ethereum-mainnet\"`\n\n**Note:** `quicknode_network_name` must be a valid QuickNode network identifier. See QuickNode API documentation for the full list of supported networks.\n\n## 📊 What Gets Created\n\n### Sentry Module\n\n- Discord channels: `#sentry-{project-name}` for each Sentry project\n- Alert rules forwarding errors to Discord\n- Proper permissions for Sentry integration\n\n### Discord Monitoring Infrastructure\n\n**Shared channels for all multisigs:**\n\n- `#🚨︱multisig-alerts` - Critical security events (owner/threshold/module changes)\n- `#🔔︱multisig-events` - Normal transaction events (executions, approvals, funds)\n- Discord webhooks (automated creation)\n\n### Cloud Function\n\n- Processes QuickNode webhooks from all chains\n- Routes security events to alerts channel, operational events to events channel\n- Validates webhook signatures\n- All multisigs share the same two Discord channels\n\n### QuickNode Webhooks\n\n- One webhook per chain\n- Filters events by multisig addresses and event signatures\n- Sends filtered events to Cloud Function\n\n## 🔧 Common Operations\n\n### Add New Multisig\n\nEdit `terraform.tfvars`:\n\n```hcl\nmultisigs = {\n  \"existing-name\" = { ... },\n  \"new-multisig\" = {\n    name                   = \"New Multisig Name\"\n    address                = \"0xYourAddress...\"\n    chain                  = \"celo\"\n    quicknode_network_name = \"celo-mainnet\"\n  }\n}\n```\n\nThen run `terraform apply`.\n\n### View Logs\n\n```bash\ncd onchain-event-handler\n./scripts/get-logs.sh\n```\n\n### Destroy Resources\n\n```bash\nterraform destroy -target=module.sentry_alerts  # Specific module\nterraform destroy  # Everything\n```\n\n## 🐛 Troubleshooting\n\n### Discord Permission Errors\n\nUse the permission checker script:\n\n```bash\ncd scripts \u0026\u0026 npm install\nnpx tsx scripts/check-discord-permissions.ts\n```\n\n**Common errors:**\n\n- `HTTP 403 Forbidden, code 50013` - Missing `MANAGE_CHANNELS` or `MANAGE_WEBHOOKS` permissions\n- `HTTP 403 Forbidden, code 50001` - Bot needs proper role permissions\n\n**Quick fix:** Grant bot `Administrator` permission in Discord Server Settings → Roles.\n\n### Invalid Address Format\n\nAddresses must:\n\n- Start with `0x`\n- Followed by exactly 40 hexadecimal characters\n- Example: `0x655133d8E90F8190ed5c1F0f3710F602800C0150`\n\n### Enable Debug Mode\n\nAdd to `terraform.tfvars`:\n\n```hcl\ndebug_mode = true\n```\n\nThis shows REST API requests/responses for troubleshooting.\n\n## 📚 Documentation\n\n### Module Documentation\n\n- [`sentry-alerts/README.md`](sentry-alerts/README.md) - Sentry module details\n- [`discord-channel-manager/README.md`](discord-channel-manager/README.md) - Discord infrastructure module\n- [`onchain-event-listeners/README.md`](onchain-event-listeners/README.md) - QuickNode webhook module for on-chain events\n- [`onchain-event-handler/README.md`](onchain-event-handler/README.md) - Cloud Function module\n\n### Code Quality\n\nFollows [AWS Terraform best practices](https://docs.aws.amazon.com/prescriptive-guidance/latest/terraform-aws-provider-best-practices/structure.html) (adapted for GCP):\n\n- Standard structure with data sources in dedicated `data.tf` files\n- Consistent formatting (output descriptions, variable descriptions, naming conventions)\n- Comprehensive labeling pattern using `merge()` for extensibility (GCP equivalent of AWS tags)\n- Comprehensive README files for all modules with inline usage examples\n\n### External Documentation\n\n- [Terraform Documentation](https://developer.hashicorp.com/terraform/docs)\n- [Sentry API Docs](https://docs.sentry.io/api/)\n- [Discord Developer Docs](https://discord.com/developers/docs)\n- [QuickNode Documentation](https://www.quicknode.com/docs)\n\n## 🔒 Security\n\n- API keys stored in `terraform.tfvars` (gitignored)\n- Sensitive outputs marked appropriately\n- State file contains secrets - handle carefully\n- Webhook signatures validated for QuickNode requests\n\n## 💰 Cost Estimate\n\n~$5-20/month per chain (Cloud Function + Storage)\n\n---\n\n**Quick Commands Reference:**\n\n```bash\n# Initialization\nterraform init\nterraform plan\nterraform apply\n\n# Management\nterraform output\nterraform state list\n\n# Updates\nterraform plan\nterraform apply\n\n# Destruction\nterraform destroy\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmento-protocol%2Falerts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmento-protocol%2Falerts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmento-protocol%2Falerts/lists"}