- Local Setup
- Switching between environments
- Debugging Local Problems
- Viewing Logs
- npm tasks and dev scripts
- Updating the Cloud Function
- Deploying a new Oracle Relayer
- Aegis Export for Monitoring Relayers
-
Install the
gcloudCLI# For macOS brew install google-cloud-sdk # For other systems, see https://cloud.google.com/sdk/docs/install
-
Install
trunk(one linter to rule them all)# For macOS brew install trunk-io # For other systems, see https://docs.trunk.io/check/usage
Optionally, you can also install the Trunk VS Code Extension
-
Install
jq(used in shell scripts)# For macOS brew install jq # For other systems, see https://jqlang.github.io/jq/
-
Install
terraform# For macOS brew tap hashicorp/tap brew install hashicorp/tap/terraform # For other systems, see https://developer.hashicorp.com/terraform/install
-
Run terraform setup script
# Checks required permissions, provisions terraform providers, modules, and workspaces ./bin/set-up-terraform.sh -
Set your local
gcloudproject:# Points your local gcloud config to the right project and caches values frequently used in shell scripts ./bin/get-project-vars.sh -
Create a
infra/terraform.tfvarsfile. This is like.envfor Terraform:touch infra/terraform.tfvars # This file is `.gitignore`d to avoid accidentally leaking sensitive data -
Add the following values to your
terraform.tfvars:# Get it via `gcloud organizations list` org_id = "<our-org-id>" # Get it via `gcloud billing accounts list` (pick the GmbH account) billing_account = "<our-billing-account-id>" # Get it via `gcloud secrets versions access latest --secret relayer-mnemonic-celo-sepolia` # Note that the mnemonic is the same for both the celo-sepolia and celo environments. # To fetch secrets, you'll need the `Secret Manager Secret Accessor` IAM role assigned to your Google Cloud Account relayer_mnemonic = "<relayer-mnemonic>" # Get it via `gcloud secrets versions access latest --secret discord-webhook-url-celo-sepolia` # Note that the above secret only exists in the oracle-relayer-celo-sepolia GCP project discord_webhook_url_celo_sepolia = "<celo-sepolia-webhook-url>" # Get it via `gcloud secrets versions access latest --secret discord-webhook-url-celo` # Note that the above secret only exists in the oracle-relayer-celo GCP project discord_webhook_url_celo = "<celo-webhook-url>" # Get it from our VictorOps by going to `Integrations` > `Stackdriver` and copying the URL. The routing key can be found under the settings tab victorops_webhook_url = "<victorops-webhook-url>/<victorops-routing-key>"
-
Verify that everything works
# Switch your local gcloud context to Celo npm run celo # See if you can fetch celo logs of the relay cloud function npm run logs # Switch your local gcloud context to Celo Sepolia npm run celo-sepolia # See if you can fetch celo-sepolia logs of the relay cloud function npm run logs # Try running the function locally npm install npm run dev # Fire a mock request against your local function npm test # Optionally accepts a rate feed and relayer contract arg npm test "GBP/USD" "0x215d3ba962597DeFb38Da439ED4dB8E8a63e409a" # See if you can manually trigger a relay on celo for a specific rate feed npm run test:celo "CELO/ETH" # See if you can manually trigger a relay on celo-sepolia npm run test:celo-sepolia "EUR/USD"
- There is 1 Google Cloud Project per chain where oracle relayers are deployed
- You can quickly switch between these projects (=chains) via
npm run celo,npm run celo-sepolia
Most dev scripts under ./bin are using gcloud commands.
These gcloud commands per default always run against the currently active project.
Alternatively, you'd always need to explicitly pass a --project-id flag to every gcloud command which can get annoying quickly.
For most local terraform or gcloud problems, your first steps should always be to:
- Clear your local shell script cache via
npm run cache:clear - Re-run the Terraform setup script via
./bin/set-up-terraform.sh
The Oracle Relayer uses structured logging with Google Cloud Logging. Logs include severity levels, timestamps, rate feed labels, and trace IDs for correlating function invocations.
First, switch to the environment you want to view:
npm run celo # Switch to celo
npm run celo-sepolia # Switch to celo-sepoliaView recent logs (last 50):
npm run logs # All logs
npm run logs CELO/USD # Filter by rate feedStream logs in real-time:
npm run logs:tail # All logs
npm run logs:tail CELO/USD # Filter by rate feedPress Ctrl+C to stop tailing.
Generate Log Explorer URLs:
npm run logs:url # All logs for current environment
npm run logs:url CELO/USD # Filter by rate feedThis generates URLs for:
- Logs Explorer (recommended): Full-featured viewer with filtering and grouping
- Cloud Run Logs: For debugging function startup issues (excludes function execution logs)
# View recent logs
gcloud logging read 'resource.labels.service_name="relay-function-celo-sepolia"' --limit 50
# Tail logs in real-time
gcloud beta logging tail 'resource.labels.service_name="relay-function-celo-sepolia"' \
--format "table(timestamp, severity, labels.rateFeed, jsonPayload.message)"
# Filter by rate feed
gcloud beta logging tail 'resource.labels.service_name="relay-function-celo-sepolia" AND labels.rateFeed="CELO/USD"'- Use the logger instance (not
console.log) for structured logging - Use appropriate severity:
logger.info()for normal operations,logger.warn()for non-blocking issues,logger.error()for failures - Filter by rate feed when debugging specific oracles to reduce noise
- Local Function Development
dev: Starts a local server for the cloud function code (with hot-reloading vianodemon)start: Starts a local server for the cloud function code (without hot-reloading)test: Triggers a local cloud function server with a mocked PubSub event
- Switching Between Environments
celo-sepolia: Switches the terraform workspace and your localgcloudproject to celo-sepoliacelo: Switches the terraform workspace and your localgcloudproject to celo
- Deploying and Destroying
deploy:celo-sepolia: Deploys full project to celo-sepolia (viaterraform apply)deploy:celo: Deploys full project to celo (viaterraform apply)deploy:function:celo-sepolia: Deploys only the cloud function for the celo-sepolia chain (viagcloud functions deploy)deploy:function:celo: Deploys only cloud function for the celo chain (viagcloud functions deploy)plan:celo-sepolia: Shorthand for runningterraform planin the./infrafolder for celo-sepoliaplan:celo: Shorthand for runningterraform planin the./infrafolder for celodestroy:celo-sepolia: 🚨 Destroys entire project on celo-sepolia (viaterraform destroy)destroy:celo: 🚨 Destroys entire project on celo (viaterraform destroy)
- View Logs (see Viewing Logs section)
logs [RATE_FEED]: View recent logs (last 50 entries)logs:tail [RATE_FEED]: Stream logs in real-timelogs:url [RATE_FEED]: Generate log explorer URLs for Google Cloud Console
- Manually Triggering a Relay
test:celo-sepolia: Manually trigger a relay on celo-sepolia, e.g.npm run test:celo-sepolia PHP/USDtest:celo: Manually trigger a relay on celo, e.g.npm run test:celo PHP/USD
- General Helper & DX Scripts
cache:clear: Clears local shell script cache and refresh it with current valuesgenerate:env: Auto-generates/updates a local.envrequired by a locally running cloud function servertodo: Lists allTODOandFIXMEcommentsget:relayer:signer: Prints the signer address that calls the relay function on the given rate feed's relayer contract.refill:celoorrefill:celo-sepolia: Refills all relayer signer addresses with a low balance on the given network
- Shell Scripts
set-up-terraform.sh: Checks required IAM permissions, provisions terraform providers, modules, and workspacescheck-gcloud-login.sh: Checks for Google Cloud login and application-default credentials.
The 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.
You have two options to deploy the Cloud Function code, terraform or gcloud cli. Both are perfectly fine to use.
- Via
terraformby runningnpm run deploy:[celo-sepolia|celo]- How? The npm task will:
- Call
terraform applywith the correct workspace which re-deploys the function with the latest code from your local machine
- Call
- Pros
- Keeps the terraform state clean
- Same command for all changes, regardless of infra or cloud function code
- Cons
- Less familiar way of deploying cloud functions (if you're used to
gcloud functions deploy) - Less log output
- Slightly slower because
terraform applywill always fetch the current state from the cloud storage bucket before deploying
- Less familiar way of deploying cloud functions (if you're used to
- How? The npm task will:
- Via
gcloudby runningnpm run deploy:function:[celo-sepolia:celo]- How? The npm task will:
- Look up the service account used by the cloud function
- Call
gcloud functions deploywith the correct parameters
- Pros
- Familiar way of deploying cloud functions
- More log output making deployment failures slightly faster to debug
- Slightly faster because we're skipping the terraform state lookup
- Cons
- Will lead to inconsistent terraform state (because terraform is tracking the function source code and its version)
- Different commands to remember when updating infra components vs cloud function source code
- Will only work for updating a pre-existing cloud function's code, will fail for a first-time deploy
- How? The npm task will:
- Deploy the new relayer contracts via the relayer factory. Exemplary deployment scripts can be found in the MU07 Deployment Scripts
- Ensure the new relayers have been whitelisted in SortedOracles on both Celo Sepolia and Celo Mainnet (otherwise relay() transactions will fail)
- Add the addresses of the deployed relayers to relayer_addresses.json (celo-sepolia relayers under
celo-sepolia, celo mainnet relayers undercelo) - Run
npm run deploy:celo-sepoliaand/ornpm run deploy:celoto create GCP cloud scheduler jobs for the new relayers - Add the new relayers to aegis for monitoring
- Run
npm run aegis:exportto print out an aegis config template in your local CLI - Copy the relevant sections for the relayers you want to add to aegis
- Paste them into aegis' config.yaml
- Run aegis in dev mode via
npm run dev, check that there are no errors in the log outputs - Submit a PR with your changes
- After successful code review, deploy your changes via
npm run deployin aegis