Skip to content

synapsecns/sanguine

Repository files navigation


Synapse logo


GitHub GitHub commit activity (branch) GitHub pull requests Codecov Code Climate maintainability Codacy Badge

Gitbook Discord Telegram X (formerly Twitter) Follow

Synapse is a interchain messaging protocol & bridge that allows for the creation of decentralized applications that can be deployed across multiple chains. This repo contains a variety of tools, interfaces and services that form the basis of, or are built on top of Synapse.

This repo serves as (or will serve) as the monrepo for all synapse code. Currently, only the liquidity/bridge contracts still need to be migrated.

Contributing

Read through CONTRIBUTING.md for a general overview of our contribution process. Then check out our list of good first issues to find something fun to work on!

Projects

There are a variety of different packages in this repo, covered comprehensively in the Directory Structure section of this document. However, for ease of use to new contributors, a comprehensive list of user-facing components are listed below, along with their source code components.

  • Synapse Interchain Network: An optimistic proof-of-stake interchain messaging network. Please see docs here
  • Synapse Bridge: A cross-chain liquidity + canonical token bridge. Please see docs here
    • Contracts: The contracts used to power the synapse bridge.
    • Frontend: The frontend used to interact with the bridge.
    • SDK: The SDK used to interact with the bridge.
  • Explorer: A bridge explorer that allows users to view on-chain data state about the bridge.
    • Backend: The backend used to power the explorer.
    • Frontend: The frontend used to interact with the explorer.

Directory Structure

root
├── agents: agents contain all the agents used in optimistic messaging
├── committe: sin synapsemodule committee.
├── charts: The helm charts used for deploying sanguine related services
├── contrib: Devops related tools
│   ├── git-changes-action: Github action for identifying changes in dependent modules in a go workspace
│   ├── promexporter: Multi-service prometheus exporter
│   ├── screener-api: Optional address screening api
│   ├── release-copier-action: Github action for copying releases from one repo to another
│   ├── terraform-provider-iap: Terraform provider used for bastion proxy tunneling
│   ├── terraform-provider-helmproxy: Terraform provider that allows helm to be proxied through an iap bastion proxy
│   ├── terraform-provider-kubeproxy: Terraform provider that allows kube to be proxied through an iap bastion proxy
│   ├── tfcore: Terraform core utilities + iap utilities
├── core: The Go core library with common utilities for use across the monorepo
├── ethergo: Go-based ethereum testing + common library
├── packages
│   ├── contracts-core: Core contracts used for synapse, powered by Foundry
│   ├── contracts-communication: SIN contracts.
│   ├── rfq: RFQ contracts
│   ├── coverage-aggregator: Javascript coverage aggregator based on nyc
│   ├── docs: Docasaurus documentation. Note: this is not yet in use, and docs are still maintained on gitbook
│   ├── explorer-ui: Explorer UI
│   ├── rest-api: Rest API
│   ├── sdk-router: SDK router
│   ├── solidity-devops: provides a set of tools and scripts to help with the development of Solidity smart contracts
│   ├── synapse constants: Constants used across synapse
│   ├── synapse-interface: Synapse frontend code
│   ├── widget: Bridge Widget
├── services
│   ├── CCTP Relayer: CCTP message relayer
│   ├── explorer: Bridge/messaging explorer ba
│   ├── stiprelayer: STIP relayer for rewards.
│   ├── rfq: RFQ contracts
│   ├── scribe: Generalized ethereum event logger
│   ├── omnirpc: Latency aware RPC Client used across multiple-chains at once
├── sin-executor: synapse interchain execturo.
├── tools
│   ├── abigen: Used to generate abigen bindings for go
│   ├── bundle: Modified version of  go bundler  with improved shadowing support
│   ├── module copier: Used to copy internal modules and export methods for testing
│   ├── revertresolver: Converts hexified solidity errors into their underlying errors.

Setup

Clone the repository, open it, and install nodejs packages with yarn:

git clone https://github.com/synapsecns/sanguine --recurse-submodules -j10
cd sanguine
yarn install

Install the Correct Version of NodeJS

Using nvm, install the correct version of NodeJS.

nvm use

Building the TypeScript packages

To build all of the TypeScript packages, run:

yarn clean
yarn build

Packages compiled when on one branch may not be compatible with packages on a different branch. You should recompile all packages whenever you move from one branch to another. Use the above commands to recompile the packages.

Dealing with submodules

This repo make use of multiple submodules. To avoid issues when checking out different branches, you can use git submodule update --init --recursive after switching to a branch or git checkout feat/branch-name --recurse-submodules when switching branches.

Contribution workflow

We use a two-branch strategy for development:

  • master: This is the primary development branch where all development happens. All regular pull requests (new features, bug fixes, etc) should be opened against this branch.
  • fe-release: This branch is used for production front-end releases and is the one that gets deployed to production. The production front-end build always uses the latest commit from this branch.

master should never be behind fe-release! The only exception is when a hotfix is needed on the production front-end. Refer to Hotfixing the Production Front-end for more details.

We use the following merge strategies:

  • Squash merge: All pull requests are squash merged into master. This keeps the commit history clean and makes it easier to revert changes if necessary.

    On a very few occasions, we may use a regular merge when master needs to be updated with a few commits from fe-release. In this case, we will use a regular merge so that there are no merge conflicts when later merging into fe-release.

  • Regular merge: Latest changes from master are regularly merged into fe-release. This ensures that the production front-end always uses the latest changes from master, and prevents merge conflicts when merging into fe-release.

    master branch should never be the source branch when merging into fe-release. This is because the source branch is always deleted after merging, and we don't want to delete master.

Scenario 1: Implementing a New Feature

In this scenario you are implementing a new feature that doesn't automatically trigger a front-end release.

  1. Create a new branch: From the master branch, create a new branch for your feature. The branch name should be descriptive of the feature you're implementing.
git checkout master && git pull
# pkg stands for the package you're working on
git checkout -b pkg/feature-name
  1. Implement your feature: Make your changes in this branch.
  2. Commit your changes: Regularly commit your changes with clear, concise commit messages.
  3. Push your branch: When you're ready to open a pull request, push your branch to the remote repository and open a pull request on GitHub. Add an overview of your changes and a link to the relevant issue (if applicable).
git push -u origin pkg/feature-name
  1. Sync with master: If you need to use the latest changes from master, you can merge them into your branch. This is especially useful if you're working on a long-running feature branch (or if some tests are failing on your branch, which have been fixed on master).
git checkout master & git pull
git checkout pkg/feature-name
git merge master
  1. Alternatively, you can rebase your branch on top of master. However, this will rewrite your commit history, which can be problematic if other contributors have already pulled your branch or started reviewing your code. The rule of thumb here is:
  • If your branch hasn't been pushed yet, always rebase.
  • If your branch has been pushed, but it is a draft that no one has reviewed yet, you could rebase.
  • Otherwise, you should merge.
git checkout master & git pull
git checkout pkg/feature-name
# You might need to drop some of your commits here, if they are already in master
# Edit the rebase-todo file to squash, drop, reorder, etc your commits
git rebase -i master
  1. CI checks: Once you've pushed your branch, the CI checks will run automatically. If any of the checks fail, you can fix the issues in your feature branch and push again. The CI checks will run again automatically.
  2. Review and merge: The PR will be reviewed. If any changes are requested, make them in your feature branch and the PR will automatically update. Once the PR is approved by at least one maintainer, it can be squash merged into master and your feature branch will be deleted.

Scenario 2: Releasing a Front-end Update

In this scenario you are releasing a front-end update using the latest changes from master.

  1. Create a new branch: From the fe-release branch, create a new branch for the FE release.
git checkout fe-release && git pull
# Date format is YYYY-MM-DD (sorry my American friends)
git checkout -b release/date
  1. Merge master into your branch: This ensures that the production front-end always uses the latest changes from master, and prevents merge conflicts when merging into fe-release.
git checkout master && git pull
git checkout release/date
# No merge conflicts should occur here
git merge master
  1. Push your branch: Push your branch to the remote repository and open a pull request on GitHub. No overview is necessary, but you can add links to the PRs that are being released.
git push -u origin release/date
  1. CI checks: Once you've pushed your branch, the CI checks will run automatically. Assuming that master is passing all checks, your branch should pass all checks as well.
  2. Review and merge: The PR will be reviewed. Once the PR is approved by at least two maintainers, it can be regularly merged into fe-release and your release branch will be deleted.

Scenario 3: Hotfixing the Production Front-end

Sometimes, a bug is discovered in the production front-end that needs to be fixed immediately. In this scenario, you are hotfixing the production front-end without using the latest changes from master.

  1. Create a new branch: From the fe-release branch, create a new branch for the hotfix.
git checkout fe-release && git pull
# Date format is YYYY-MM-DD (sorry my American friends)
git checkout -b hotfix/date
  1. Implement your hotfix: Make your changes in this branch.

  2. Push your branch: Push your branch to the remote repository and open a pull request on GitHub.

git push -u origin hotfix/date
  1. CI checks: Once you've pushed your branch, the CI checks will run automatically. Depending on the severity of the hotfix, you might want to merge the PR as soon or before it passes all checks. However, you should wait for the linting checks to pass, as these are the fastest and easiest to fix.

  2. Review and merge: The PR will be reviewed. Once the PR is approved by at least two maintainers, it can be squash merged into fe-release and your hotfix branch will be deleted.

  3. Take a deep breath and relax. You've just saved the day. 🦸‍♂️

  4. Catch up master: now that the hotfix is released, you should catch up master with the latest changes from fe-release. This ensures that master branch is never behind fe-release.

git checkout fe-release && git pull
git checkout master && git pull
git checkout -b catchup/date
git merge fe-release
  1. Push your branch: Push your catchup/date branch to the remote repository and open a pull request on GitHub.
git push -u origin catchup/date
  1. CI checks: Once you've pushed your branch, the CI checks will run automatically. Assuming that fe-release is passing all checks, your branch should pass all checks as well.

  2. Review and merge: The PR will be reviewed. Once the PR is approved by at least one maintainer, it can be regularly merged into master and your catchup branch will be deleted.

Building Agents Locally

In order to minimize risks coming from extraneous dependencies or supply chain attacks in a production like environment, all distributed images are built as scratch or distroless images. Builder containers are also not used to restrict the build environment to the goreleaser container. All production images are kept in the docker/ file as [dir].Dockerfile. Local