{"id":19070817,"url":"https://github.com/mento-protocol/oracle-relayer","last_synced_at":"2026-01-11T02:57:46.506Z","repository":{"id":250317811,"uuid":"833695021","full_name":"mento-protocol/oracle-relayer","owner":"mento-protocol","description":null,"archived":false,"fork":false,"pushed_at":"2025-04-16T10:15:33.000Z","size":211,"stargazers_count":1,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-16T12:24:04.757Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","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}},"created_at":"2024-07-25T14:57:43.000Z","updated_at":"2025-04-16T09:19:35.000Z","dependencies_parsed_at":"2024-10-22T23:22:34.828Z","dependency_job_id":null,"html_url":"https://github.com/mento-protocol/oracle-relayer","commit_stats":null,"previous_names":["mento-protocol/oracle-relayer"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mento-protocol%2Foracle-relayer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mento-protocol%2Foracle-relayer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mento-protocol%2Foracle-relayer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mento-protocol%2Foracle-relayer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mento-protocol","download_url":"https://codeload.github.com/mento-protocol/oracle-relayer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249436751,"owners_count":21271932,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":"2024-11-09T01:20:43.203Z","updated_at":"2026-01-11T02:57:46.496Z","avatar_url":"https://github.com/mento-protocol.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Oracle Relayer Infra\n\n- [Local Setup](#local-setup)\n- [Switching between environments](#switching-between-environments)\n- [Debugging Local Problems](#debugging-local-problems)\n- [Viewing Logs](#viewing-logs)\n- [npm tasks and dev scripts](#npm-tasks-and-dev-scripts)\n- [Updating the Cloud Function](#updating-the-cloud-function)\n- [Deploying a new Oracle Relayer](#deploying-a-new-oracle-relayer)\n- [Aegis Export for Monitoring Relayers](#aegis-export-for-monitoring-relayers)\n\n## Local Setup\n\n1. Install the `gcloud` CLI\n\n   ```sh\n   # For macOS\n   brew install google-cloud-sdk\n\n   # For other systems, see https://cloud.google.com/sdk/docs/install\n   ```\n\n1. Install `trunk` (one linter to rule them all)\n\n   ```sh\n   # For macOS\n   brew install trunk-io\n\n   # For other systems, see https://docs.trunk.io/check/usage\n   ```\n\n   Optionally, you can also install the [Trunk VS Code Extension](https://marketplace.visualstudio.com/items?itemName=Trunk.io)\n\n1. Install `jq` (used in shell scripts)\n\n   ```sh\n   # For macOS\n   brew install jq\n\n   # For other systems, see https://jqlang.github.io/jq/\n   ```\n\n1. Install `terraform`\n\n   ```sh\n   # For macOS\n   brew tap hashicorp/tap\n   brew install hashicorp/tap/terraform\n\n   # For other systems, see https://developer.hashicorp.com/terraform/install\n   ```\n\n1. Run terraform setup script\n\n   ```sh\n   # Checks required permissions, provisions terraform providers, modules, and workspaces\n   ./bin/set-up-terraform.sh\n   ```\n\n1. Set your local `gcloud` project:\n\n   ```sh\n   # Points your local gcloud config to the right project and caches values frequently used in shell scripts\n   ./bin/get-project-vars.sh\n   ```\n\n1. Create a `infra/terraform.tfvars` file. This is like `.env` for Terraform:\n\n   ```sh\n   touch infra/terraform.tfvars\n   # This file is `.gitignore`d to avoid accidentally leaking sensitive data\n   ```\n\n1. Add the following values to your `terraform.tfvars`:\n\n   ```sh\n   # Get it via `gcloud organizations list`\n   org_id          = \"\u003cour-org-id\u003e\"\n\n   # Get it via `gcloud billing accounts list` (pick the GmbH account)\n   billing_account = \"\u003cour-billing-account-id\u003e\"\n\n   # Get it via `gcloud secrets versions access latest --secret relayer-mnemonic-celo-sepolia`\n   # Note that the mnemonic is the same for both the celo-sepolia and celo environments.\n   # To fetch secrets, you'll need the `Secret Manager Secret Accessor` IAM role assigned to your Google Cloud Account\n   relayer_mnemonic      = \"\u003crelayer-mnemonic\u003e\"\n\n   # Get it via `gcloud secrets versions access latest --secret discord-webhook-url-celo-sepolia`\n   # Note that the above secret only exists in the oracle-relayer-celo-sepolia GCP project\n   discord_webhook_url_celo_sepolia      = \"\u003ccelo-sepolia-webhook-url\u003e\"\n\n   # Get it via `gcloud secrets versions access latest --secret discord-webhook-url-celo`\n   # Note that the above secret only exists in the oracle-relayer-celo GCP project\n   discord_webhook_url_celo      = \"\u003ccelo-webhook-url\u003e\"\n\n   # Get it from our VictorOps by going to `Integrations` \u003e `Stackdriver` and copying the URL. The routing key can be found under the settings tab\n   victorops_webhook_url   = \"\u003cvictorops-webhook-url\u003e/\u003cvictorops-routing-key\u003e\"\n\n   ```\n\n1. Verify that everything works\n\n   ```sh\n   # Switch your local gcloud context to Celo\n   npm run celo\n\n   # See if you can fetch celo logs of the relay cloud function\n   npm run logs\n\n   # Switch your local gcloud context to Celo Sepolia\n   npm run celo-sepolia\n\n   # See if you can fetch celo-sepolia logs of the relay cloud function\n   npm run logs\n\n   # Try running the function locally\n   npm install\n   npm run dev\n\n   # Fire a mock request against your local function\n   npm test\n\n   # Optionally accepts a rate feed and relayer contract arg\n   npm test \"GBP/USD\" \"0x215d3ba962597DeFb38Da439ED4dB8E8a63e409a\"\n\n   # See if you can manually trigger a relay on celo for a specific rate feed\n   npm run test:celo \"CELO/ETH\"\n\n   # See if you can manually trigger a relay on celo-sepolia\n   npm run test:celo-sepolia \"EUR/USD\"\n   ```\n\n## Switching between environments\n\n- There is 1 Google Cloud Project per chain where oracle relayers are deployed\n- You can quickly switch between these projects (=chains) via `npm run celo`, `npm run celo-sepolia`\n\n### Why is this necessary?\n\nMost dev scripts under [`./bin`](./bin) are using `gcloud` commands.\nThese `gcloud` commands per default always run against the currently active project.\nAlternatively, you'd always need to explicitly pass a `--project-id` flag to every `gcloud` command which can get annoying quickly.\n\n## Debugging Local Problems\n\nFor most local `terraform` or `gcloud` problems, your first steps should always be to:\n\n- Clear your local shell script cache via `npm run cache:clear`\n- Re-run the Terraform setup script via `./bin/set-up-terraform.sh`\n\n## Viewing Logs\n\nThe Oracle Relayer uses structured logging with Google Cloud Logging. Logs include severity levels, timestamps, rate feed labels, and trace IDs for correlating function invocations.\n\n### Quick Start\n\nFirst, switch to the environment you want to view:\n\n```bash\nnpm run celo              # Switch to celo\nnpm run celo-sepolia      # Switch to celo-sepolia\n```\n\n### Logs in your CLI\n\n**View recent logs (last 50):**\n\n```bash\nnpm run logs                     # All logs\nnpm run logs CELO/USD            # Filter by rate feed\n```\n\n**Stream logs in real-time:**\n\n```bash\nnpm run logs:tail                   # All logs\nnpm run logs:tail CELO/USD          # Filter by rate feed\n```\n\nPress `Ctrl+C` to stop tailing.\n\n### Logs in the Google Cloud Console UI\n\n**Generate Log Explorer URLs:**\n\n```bash\nnpm run logs:url                      # All logs for current environment\nnpm run logs:url CELO/USD             # Filter by rate feed\n```\n\nThis generates URLs for:\n\n- **Logs Explorer** (recommended): Full-featured viewer with filtering and grouping\n- **Cloud Run Logs**: For debugging function startup issues (excludes function execution logs)\n\n### Using gcloud Directly\n\n```bash\n# View recent logs\ngcloud logging read 'resource.labels.service_name=\"relay-function-celo-sepolia\"' --limit 50\n\n# Tail logs in real-time\ngcloud beta logging tail 'resource.labels.service_name=\"relay-function-celo-sepolia\"' \\\n  --format \"table(timestamp, severity, labels.rateFeed, jsonPayload.message)\"\n\n# Filter by rate feed\ngcloud beta logging tail 'resource.labels.service_name=\"relay-function-celo-sepolia\" AND labels.rateFeed=\"CELO/USD\"'\n```\n\n### Best Practices\n\n- Use the logger instance (not `console.log`) for structured logging\n- Use appropriate severity: `logger.info()` for normal operations, `logger.warn()` for non-blocking issues, `logger.error()` for failures\n- Filter by rate feed when debugging specific oracles to reduce noise\n\n## npm tasks and dev scripts\n\n- **Local Function Development**\n  - `dev`: Starts a local server for the cloud function code (with hot-reloading via `nodemon`)\n  - `start`: Starts a local server for the cloud function code (without hot-reloading)\n  - `test`: Triggers a local cloud function server with a mocked PubSub event\n- **Switching Between Environments**\n  - `celo-sepolia`: Switches the terraform workspace and your local `gcloud` project to celo-sepolia\n  - `celo`: Switches the terraform workspace and your local `gcloud` project to celo\n- **Deploying and Destroying**\n  - `deploy:celo-sepolia`: Deploys full project to celo-sepolia (via `terraform apply`)\n  - `deploy:celo`: Deploys full project to celo (via `terraform apply`)\n  - `deploy:function:celo-sepolia`: Deploys only the cloud function for the celo-sepolia chain (via `gcloud functions deploy`)\n  - `deploy:function:celo`: Deploys only cloud function for the celo chain (via `gcloud functions deploy`)\n  - `plan:celo-sepolia`: Shorthand for running `terraform plan` in the `./infra` folder for celo-sepolia\n  - `plan:celo`: Shorthand for running `terraform plan` in the `./infra` folder for celo\n  - `destroy:celo-sepolia`: 🚨 Destroys entire project on celo-sepolia (via `terraform destroy`)\n  - `destroy:celo`: 🚨 Destroys entire project on celo (via `terraform destroy`)\n- **View Logs** (see [Viewing Logs](#viewing-logs) section)\n  - `logs [RATE_FEED]`: View recent logs (last 50 entries)\n  - `logs:tail [RATE_FEED]`: Stream logs in real-time\n  - `logs:url [RATE_FEED]`: Generate log explorer URLs for Google Cloud Console\n- **Manually Triggering a Relay**\n  - `test:celo-sepolia`: Manually trigger a relay on celo-sepolia, e.g. `npm run test:celo-sepolia PHP/USD`\n  - `test:celo`: Manually trigger a relay on celo, e.g. `npm run test:celo PHP/USD`\n- **General Helper \u0026 DX Scripts**\n  - `cache:clear`: Clears local shell script cache and refresh it with current values\n  - `generate:env`: Auto-generates/updates a local `.env` required by a locally running cloud function server\n  - `todo`: Lists all `TODO` and `FIXME` comments\n  - `get:relayer:signer`: Prints the signer address that calls the relay function on the given rate feed's relayer contract.\n  - `refill:celo` or `refill:celo-sepolia`: Refills all relayer signer addresses with a low balance on the given network\n- **Shell Scripts**\n  - `set-up-terraform.sh`: Checks required IAM permissions, provisions terraform providers, modules, and workspaces\n  - `check-gcloud-login.sh`: Checks for Google Cloud login and application-default credentials.\n\n## Refilling relayer signer accounts\n\nThe relayer signer addresses run out of CELO from time to time and need to be refilled. This can be done by adding a `REFILLER_PRIVATE_KEY` to the `.env` file (e.g. the deployer private key) and running the `refill:celo` or `refill:celo-sepolia` script, which will transfer CELO to all signer addresses running low on balance.\n\n## Updating the Cloud Function\n\nYou have two options to deploy the Cloud Function code, `terraform` or `gcloud` cli. Both are perfectly fine to use.\n\n1. Via `terraform` by running `npm run deploy:[celo-sepolia|celo]`\n   - How? The npm task will:\n     - Call `terraform apply` with the correct workspace which re-deploys the function with the latest code from your local machine\n   - Pros\n     - Keeps the terraform state clean\n     - Same command for all changes, regardless of infra or cloud function code\n   - Cons\n     - Less familiar way of deploying cloud functions (if you're used to `gcloud functions deploy`)\n     - Less log output\n     - Slightly slower because `terraform apply` will always fetch the current state from the cloud storage bucket before deploying\n2. Via `gcloud` by running `npm run deploy:function:[celo-sepolia:celo]`\n   - How? The npm task will:\n     - Look up the service account used by the cloud function\n     - Call `gcloud functions deploy` with the correct parameters\n   - Pros\n     - Familiar way of deploying cloud functions\n     - More log output making deployment failures slightly faster to debug\n     - Slightly faster because we're skipping the terraform state lookup\n   - Cons\n     - Will lead to inconsistent terraform state (because terraform is tracking the function source code and its version)\n     - Different commands to remember when updating infra components vs cloud function source code\n     - Will only work for updating a pre-existing cloud function's code, will fail for a first-time deploy\n\n## Deploying a new Oracle Relayer\n\n1. Deploy the new relayer contracts via the [relayer factory](https://github.com/mento-protocol/mento-core/blob/develop/contracts/oracles/ChainlinkRelayerFactory.sol). Exemplary deployment scripts can be found in the [MU07 Deployment Scripts](https://github.com/mento-protocol/mento-deployment/blob/main/script/upgrades/MU07/deploy/MU07-Deploy-ChainlinkRelayers.sol)\n1. Ensure the new relayers have been whitelisted in SortedOracles on both Celo Sepolia and Celo Mainnet (otherwise relay() transactions will fail)\n1. Add the addresses of the deployed relayers to [relayer_addresses.json](./infra/relayer_addresses.json) (celo-sepolia relayers under `celo-sepolia`, celo mainnet relayers under `celo`)\n1. Run `npm run deploy:celo-sepolia` and/or `npm run deploy:celo` to create GCP cloud scheduler jobs for the new relayers\n1. [Add the new relayers to aegis for monitoring](#aegis-export-for-monitoring-relayers)\n\n### Aegis Export for Monitoring Relayers\n\n1. Run `npm run aegis:export` to print out an aegis config template in your local CLI\n1. Copy the relevant sections for the relayers you want to add to aegis\n1. Paste them into [aegis' config.yaml](https://github.com/mento-protocol/aegis/blob/main/config.yaml)\n1. Run aegis in dev mode via `npm run dev`, check that there are no errors in the log outputs\n1. Submit a PR with your changes\n1. After successful code review, deploy your changes via `npm run deploy` in aegis\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmento-protocol%2Foracle-relayer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmento-protocol%2Foracle-relayer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmento-protocol%2Foracle-relayer/lists"}