├── .gitbook
└── assets
│ ├── Abacus Application SDK Diagram v2.png
│ ├── Abacus Application SDK Diagram.png
│ ├── Abacus Application SDK Diagram.svg
│ ├── Hyperlane Message Lifecycle Clear bg.png
│ ├── Hyperlane Message Lifecycle.png
│ ├── ICA Quickstart Polyscan (1).png
│ ├── ICA Quickstart Polyscan.png
│ ├── Screen Shot 2022-08-10 at 4.01.00 PM.png
│ ├── Screen Shot 2022-08-10 at 4.04.40 PM.png
│ ├── Screen Shot 2022-10-04 at 11.39.30 AM.png
│ ├── Screen Shot 2022-10-04 at 4.24.21 PM.png
│ ├── Screen Shot 2022-11-02 at 5.37.06 PM.png
│ ├── Screen Shot 2022-11-02 at 5.45.23 PM.png
│ ├── Screen Shot 2022-11-02 at 5.51.56 PM.png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (1) (1) (1) (2).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (2).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (2).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (2).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1) (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM (1).png
│ ├── Screen Shot 2022-11-02 at 5.52.14 PM.png
│ ├── Screen Shot 2022-11-03 at 1.56.04 PM.png
│ ├── Screen Shot 2023-01-26 at 10.47.06 AM.png
│ ├── Screen Shot 2023-01-30 at 1.15.50 PM.png
│ ├── Screen Shot 2023-01-30 at 1.18.06 PM.png
│ ├── Screen Shot 2023-01-30 at 11.30.56 AM (1).png
│ ├── Screen Shot 2023-01-30 at 11.30.56 AM.png
│ ├── Screen Shot 2023-01-30 at 11.48.02 AM.png
│ ├── Screen Shot 2023-01-30 at 2.05.19 PM.png
│ ├── Screen Shot 2023-01-30 at 2.05.42 PM.png
│ ├── Screen Shot 2023-01-30 at 4.30.00 PM.png
│ ├── Screen Shot 2023-01-31 at 1.55.10 PM (1).png
│ ├── Screen Shot 2023-01-31 at 1.55.10 PM.png
│ ├── Screen Shot 2023-01-31 at 2.14.07 PM.png
│ ├── Screen Shot 2023-01-31 at 2.28.57 PM.png
│ ├── Screen Shot 2023-03-18 at 11.58.57 AM.png
│ ├── Screen Shot 2023-03-18 at 11.59.44 AM.png
│ ├── Screenshot 2023-03-14 at 4.02.17 PM.png
│ ├── Screenshot 2023-03-14 at 4.03.15 PM.png
│ ├── Screenshot 2023-03-14 at 4.08.22 PM.png
│ ├── Screenshot 2023-08-23 at 3.30.04 PM.png
│ ├── Screenshot 2023-08-23 at 3.31.42 PM.png
│ ├── Screenshot 2023-08-23 at 4.05.26 PM.png
│ ├── Screenshot 2023-08-26 at 3.22.01 PM (1).png
│ ├── Screenshot 2023-08-26 at 3.22.01 PM.png
│ ├── Screenshot 2023-08-26 at 3.23.46 PM.png
│ ├── Screenshot 2023-08-28 at 1.35.30 PM.png
│ ├── Screenshot 2023-08-28 at 1.35.45 PM.png
│ ├── Test Message Sent -- Hyperlane Explorer.png
│ ├── Test Message in Hyperlane Explorer.png
│ ├── Token Bridge transaction on Hyperlane Explorer.png
│ ├── Untitled Diagram.drawio (1).svg
│ ├── Untitled Diagram.drawio (2).svg
│ ├── Untitled Diagram.drawio.svg
│ ├── failed tx in explorer.png
│ ├── failed tx screenshot.png
│ ├── image (1) (1).png
│ ├── image (1).png
│ ├── image.png
│ └── pending tx in msg explorer.png
├── .github
├── CODEOWNERS
└── workflows
│ ├── lint.yml
│ └── sync.yml
├── .gitignore
├── README.md
├── SUMMARY.md
├── apis-and-sdks
├── accounts.md
├── building-applications
│ ├── README.md
│ └── nodejs-sdk
│ │ └── README.md
├── hooks
│ ├── README.md
│ └── addresses.md
├── interchain-gas-paymaster-api.md
└── warp-api.md
├── apis
├── messaging-api
│ ├── README.md
│ ├── receive.md
│ └── send.md
└── query.md
├── build-with-hyperlane
├── examples.md
├── explorer
│ ├── README.md
│ ├── configuring-pi-chains.md
│ ├── graphql-api.md
│ ├── observability.md
│ └── rest-api.md
├── guides
│ ├── README.md
│ ├── finding-my-messages.md
│ ├── manually-pay-for-interchain-gas.md
│ ├── paying-for-interchain-gas.md
│ ├── receive-1.md
│ ├── unit-testing.md
│ ├── v2-migration-guide.md
│ └── which-igp-to-use-and-understanding-gas-amounts.md
├── quickstarts
│ ├── README.md
│ ├── accounts.md
│ ├── hyperlane-quickstart.md
│ ├── messaging.md
│ └── queries.md
└── troubleshooting.md
├── deploy
├── celestia-+-hyperlane.md
├── deploy-hyperlane.md
├── deploy-warp-route
│ ├── README.md
│ ├── deploy-a-warp-route.md
│ └── deploy-the-ui-for-your-warp-route.md
└── permissionless-interoperability.md
├── diagrams
├── accounts-implementation.md
├── accounts-simple.md
├── interchain-gas.md
├── liquidity-layer-simple.md
├── messaging-isms.md
├── messaging-simple.md
├── multisig-pos-ism.md
├── queries-implementation.md
├── queries-simple.md
└── router.md
├── introduction
├── getting-started.md
└── why-should-you-use-hyperlane.md
├── operators
├── agent-configuration
│ ├── README.md
│ └── configuration-reference.md
├── agent-keys
│ ├── README.md
│ ├── aws-setup.md
│ └── hexadecimal-key-setup.md
├── relayers
│ ├── README.md
│ ├── message-filtering.md
│ └── setup.md
├── running-with-docker-compose.md
└── validators
│ ├── README.md
│ ├── aws-setup.md
│ ├── monitoring-and-alerting.md
│ └── setup.md
├── package.json
├── protocol
├── agents
│ ├── README.md
│ ├── processor.md
│ ├── relayer.md
│ └── validators.md
├── interchain-gas-payments.md
├── messaging.md
├── permissionless-interoperability.md
├── proof-of-stake.md
├── sovereign-consensus
│ ├── README.md
│ ├── aggregation-ism.md
│ ├── ccip-read-ism.md
│ ├── hook-ism.md
│ ├── interchain-security-modules.md
│ ├── multisig-ism.md
│ ├── optimistic-ism.md
│ ├── routing-ism.md
│ └── wormhole-ism.md
└── spec.md
├── resources
├── addresses.md
├── addresses
│ ├── README.md
│ └── permissionless.md
├── coming-soon-hyperlane-v3.md
├── domains
│ ├── README.md
│ └── permissionless-domain-identifiers.md
├── faq.md
├── glossary.md
├── latencies.md
├── security.md
└── token-sources-and-faucets.md
├── sdks
└── building-applications
│ ├── example-usage
│ ├── README.md
│ ├── erc20-token.md
│ └── helloworld.md
│ ├── nodejs-sdk
│ ├── contract-interaction.md
│ ├── deploying-contracts.md
│ ├── gas.md
│ ├── multiprovider.md
│ └── testing-contracts.md
│ └── writing-contracts
│ ├── README.md
│ ├── abacusconnectionclient.md
│ └── router.md
├── sync-addresses.js
├── sync-config.js
├── sync-partials.js
└── yarn.lock
/.gitbook/assets/Abacus Application SDK Diagram v2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Abacus Application SDK Diagram v2.png
--------------------------------------------------------------------------------
/.gitbook/assets/Abacus Application SDK Diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Abacus Application SDK Diagram.png
--------------------------------------------------------------------------------
/.gitbook/assets/Hyperlane Message Lifecycle Clear bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Hyperlane Message Lifecycle Clear bg.png
--------------------------------------------------------------------------------
/.gitbook/assets/Hyperlane Message Lifecycle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Hyperlane Message Lifecycle.png
--------------------------------------------------------------------------------
/.gitbook/assets/ICA Quickstart Polyscan (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/ICA Quickstart Polyscan (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/ICA Quickstart Polyscan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/ICA Quickstart Polyscan.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-08-10 at 4.01.00 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-08-10 at 4.01.00 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-08-10 at 4.04.40 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-08-10 at 4.04.40 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-10-04 at 11.39.30 AM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-10-04 at 11.39.30 AM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-10-04 at 4.24.21 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-10-04 at 4.24.21 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.37.06 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.37.06 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.45.23 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.45.23 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.51.56 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.51.56 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (1) (1) (1) (2).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (1) (1) (1) (2).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (2).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (2).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (2).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1) (2).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (2).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1) (2).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-02 at 5.52.14 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2022-11-03 at 1.56.04 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2022-11-03 at 1.56.04 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2023-01-26 at 10.47.06 AM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2023-01-26 at 10.47.06 AM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2023-01-30 at 1.15.50 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2023-01-30 at 1.15.50 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2023-01-30 at 1.18.06 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2023-01-30 at 1.18.06 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2023-01-30 at 11.30.56 AM (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2023-01-30 at 11.30.56 AM (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2023-01-30 at 11.30.56 AM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2023-01-30 at 11.30.56 AM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2023-01-30 at 11.48.02 AM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2023-01-30 at 11.48.02 AM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2023-01-30 at 2.05.19 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2023-01-30 at 2.05.19 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2023-01-30 at 2.05.42 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2023-01-30 at 2.05.42 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2023-01-30 at 4.30.00 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2023-01-30 at 4.30.00 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2023-01-31 at 1.55.10 PM (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2023-01-31 at 1.55.10 PM (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2023-01-31 at 1.55.10 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2023-01-31 at 1.55.10 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2023-01-31 at 2.14.07 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2023-01-31 at 2.14.07 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2023-01-31 at 2.28.57 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2023-01-31 at 2.28.57 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2023-03-18 at 11.58.57 AM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2023-03-18 at 11.58.57 AM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screen Shot 2023-03-18 at 11.59.44 AM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screen Shot 2023-03-18 at 11.59.44 AM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screenshot 2023-03-14 at 4.02.17 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screenshot 2023-03-14 at 4.02.17 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screenshot 2023-03-14 at 4.03.15 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screenshot 2023-03-14 at 4.03.15 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screenshot 2023-03-14 at 4.08.22 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screenshot 2023-03-14 at 4.08.22 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screenshot 2023-08-23 at 3.30.04 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screenshot 2023-08-23 at 3.30.04 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screenshot 2023-08-23 at 3.31.42 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screenshot 2023-08-23 at 3.31.42 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screenshot 2023-08-23 at 4.05.26 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screenshot 2023-08-23 at 4.05.26 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screenshot 2023-08-26 at 3.22.01 PM (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screenshot 2023-08-26 at 3.22.01 PM (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/Screenshot 2023-08-26 at 3.22.01 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screenshot 2023-08-26 at 3.22.01 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screenshot 2023-08-26 at 3.23.46 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screenshot 2023-08-26 at 3.23.46 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screenshot 2023-08-28 at 1.35.30 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screenshot 2023-08-28 at 1.35.30 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Screenshot 2023-08-28 at 1.35.45 PM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Screenshot 2023-08-28 at 1.35.45 PM.png
--------------------------------------------------------------------------------
/.gitbook/assets/Test Message Sent -- Hyperlane Explorer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Test Message Sent -- Hyperlane Explorer.png
--------------------------------------------------------------------------------
/.gitbook/assets/Test Message in Hyperlane Explorer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Test Message in Hyperlane Explorer.png
--------------------------------------------------------------------------------
/.gitbook/assets/Token Bridge transaction on Hyperlane Explorer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/Token Bridge transaction on Hyperlane Explorer.png
--------------------------------------------------------------------------------
/.gitbook/assets/failed tx in explorer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/failed tx in explorer.png
--------------------------------------------------------------------------------
/.gitbook/assets/failed tx screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/failed tx screenshot.png
--------------------------------------------------------------------------------
/.gitbook/assets/image (1) (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/image (1) (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/image (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/image (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/image.png
--------------------------------------------------------------------------------
/.gitbook/assets/pending tx in msg explorer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperlane-xyz/v2-docs/d5987d4f134c8ba37511f8242a15f4f975b1e722/.gitbook/assets/pending tx in msg explorer.png
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @yorhodes
2 |
3 | *.md @asaj @nambrot @skunkchain
4 |
--------------------------------------------------------------------------------
/.github/workflows/lint.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
3 |
4 | name: Lint
5 |
6 | on:
7 | pull_request:
8 | branches: [ "v2-gitbook" ]
9 | schedule:
10 | - cron: "0 2 * * 1-5"
11 |
12 | jobs:
13 | lint:
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - uses: actions/checkout@v3
18 |
19 | - name: Use Node.js
20 | uses: actions/setup-node@v3
21 | with:
22 | cache: 'yarn'
23 |
24 | - name: Install dependencies
25 | run: yarn install
26 |
27 | - name: Lint
28 | run: yarn lint
29 |
--------------------------------------------------------------------------------
/.github/workflows/sync.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
3 |
4 | name: Sync generated content
5 |
6 | on:
7 | push:
8 | branches: [ "main" ]
9 |
10 | jobs:
11 | sync:
12 | permissions:
13 | # Give the default GITHUB_TOKEN write permission to commit and push the
14 | # added or changed files to the repository.
15 | contents: write
16 |
17 | runs-on: ubuntu-latest
18 |
19 | steps:
20 | - uses: actions/checkout@v3
21 |
22 | - name: Use Node.js
23 | uses: actions/setup-node@v3
24 | with:
25 | cache: 'yarn'
26 |
27 | - name: Install dependencies
28 | run: yarn install
29 |
30 | - name: Sync generated content
31 | run: yarn sync
32 |
33 | - uses: stefanzweifel/git-auto-commit-action@v4
34 | with:
35 | file_pattern: '**/*.md'
36 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ⚠️ With the [launch of v3](https://github.com/hyperlane-xyz/v3-docs/), this repo is deprecated. ⚠️
2 |
3 | **For the current docs site, visit [docs.hyperlane.xyz](https://docs.hyperlane.xyz/) - for the old v2 docs see [v2](https://v2.hyperlane.xyz/).**
4 |
5 | ## Hyperlane introduction
6 |
7 | Hyperlane is the first universal and permissionless interoperability layer built for the modular blockchain stack.
8 |
9 | Anyone can [deploy-hyperlane.md](deploy/deploy-hyperlane.md "mention") to any blockchain environment, whether it is a layer 1, rollup, or app-chain, allowing that chain to communicate seamlessly with any other chain on which Hyperlane has been deployed.
10 |
11 | Hyperlane is designed with modularity in mind. Notably, its [sovereign-consensus](protocol/sovereign-consensus/ "mention") gives developers control over their security model, allowing them to configure, compose, and customize security according to the needs of their application.
12 |
13 | Using Hyperlane, developers can build _Interchain Applications_ - dapps that span multiple blockchains. Some pre-built examples that can be deployed out of the box include:
14 |
15 | 1. [deploy-warp-route](deploy/deploy-warp-route/ "mention"), which allow native, `ERC20`, and `ERC721` tokens to move seamlessly across chains
16 | 2. Interchain [accounts.md](apis-and-sdks/accounts.md "mention"), which allows an account on one chain (e.g. a DAO) to make smart contract calls on remote chains
17 | 3. Interchain [query.md](apis/query.md "mention"), which allow an account on one chain to make view calls on remote chains
18 |
19 | Keep reading to learn all the things Hyperlane can do for you!
20 |
21 | ### Integrate Hyperlane into your chain, rollup, or app
22 |
23 | Check out the [getting-started.md](introduction/getting-started.md "mention") guide for everything you need to start building with Hyperlane. As a creator of a new Chain or Rollup, a Rollup Framework, or a Rollup Service, you can learn how to [deploy-hyperlane.md](deploy/deploy-hyperlane.md "mention") yourself!\
24 | \
25 | If you run into an issue or have any questions, [join our discord](https://discord.gg/hyperlane) to get support from the community of Hyperlane builders!
26 |
27 | ### Learn more about the Hyperlane protocol
28 |
29 | First, take a look at the [faq.md](resources/faq.md "mention"), which covers some high level questions about what Hyperlane is and how it works.
30 |
31 | {% content-ref url="resources/faq.md" %}
32 | [faq.md](resources/faq.md)
33 | {% endcontent-ref %}
34 |
35 | To dive deeper into the Hyperlane, take a look at the protocol architecture [permissionless-interoperability.md](protocol/permissionless-interoperability.md "mention"), or read more about [sovereign-consensus](protocol/sovereign-consensus/ "mention") to learn more about how Hyperlane interchain messaging is secured.
36 |
37 |
38 |
39 | ###
40 |
--------------------------------------------------------------------------------
/apis-and-sdks/building-applications/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Create interchain applications with the Hyperlane Application SDK
3 | ---
4 |
5 | # Hyperlane App Framework
6 |
7 | Hyperlane provides an optional framework that helps developers create and manage applications built on top of interchain smart contracts. It is designed primarily for applications which leverage the shared state model and symmetric communication patterns such as the [Router](../../sdks/building-applications/writing-contracts/router.md) pattern. Note that this is a more fully feature abstraction that requires a learning curve. If you are just looking to try out Hyperlane, we recommend for you to look at the [getting-started.md](../../introduction/getting-started.md "mention") page with the [quickstarts](../../build-with-hyperlane/quickstarts/ "mention") first.
8 |
9 | ### Solidity SDK
10 |
11 | The classes in the [`@hyperlane-xyz/core`](https://www.npmjs.com/package/@hyperlane-xyz/core) package help you write interchain contracts intended to be deployed on multiple networks.
12 |
13 | ### NodeJS SDK
14 |
15 | The classes in the [`@hyperlane-xyz/sdk`](https://www.npmjs.com/package/@hyperlane-xyz/sdk) package help you manage and interact with Hyperlane applications on multiple networks. The building experience is familiar to smart contract developers, but a [test](../../sdks/building-applications/nodejs-sdk/testing-contracts.md) and [deployment](../../sdks/building-applications/nodejs-sdk/deploying-contracts.md) framework is provided to accelerate the development lifecycle. Furthermore, the [app abstraction](../../sdks/building-applications/nodejs-sdk/contract-interaction.md) helps developers productionize their apps into a seamless browser experience.
16 |
--------------------------------------------------------------------------------
/apis-and-sdks/building-applications/nodejs-sdk/README.md:
--------------------------------------------------------------------------------
1 | # NodeJS SDK
2 |
3 | _Note: Abacus is the former name of the Hyperlane protocol. The repos will soon be renamed._
4 |
5 | The NodeJS SDK ([`@hyperlane-xyz/sdk`](https://www.npmjs.com/package/@hyperlane-xyz/sdk)) contains everything you need to productionize your interchain app on the web, including:
6 |
7 | ### [RPC Provider Management](../../../sdks/building-applications/nodejs-sdk/multiprovider.md)
8 |
9 | App to chain communication is performed via ethers.js compatible [providers](https://docs.ethers.io/v5/api/providers/). To help manage providers for multiple chains, the SDK includes a `MultiProvider` utility.
10 |
11 | ### [Multichain Deployment Tooling](../../../sdks/building-applications/nodejs-sdk/deploying-contracts.md)
12 |
13 | Facilitate deploying your contract(s) to multiple chains. This includes utilities for bytecode verification, contract upgradability patterns, and resumability from partially successful deployments (e.g. k/n chains successfully deployed).
14 |
15 | ### [Interchain Gas Estimation](./#gas-estimation-and-payment)
16 |
17 | Hyperlane allows users to pay for message processing on the destination chain using tokens from the origin chain. Use the `InterchainGasCalculator` utility for gas estimation of interchain messages.
18 |
19 | ### [App Abstraction](../../../sdks/building-applications/nodejs-sdk/contract-interaction.md)
20 |
21 | ## Class Hierarchy
22 |
23 | 
24 |
--------------------------------------------------------------------------------
/apis-and-sdks/hooks/addresses.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Hyperlane hook contract addresses
3 | ---
4 |
5 | # Contract addresses
6 |
7 | {% tabs %}
8 | {% tab title="Testnet" %}
9 | Hooks
10 |
11 |
Hook
Network
Address
Explorer
Optimism
Ethereum
0x0346FE0a1ad1033fFc6B19A8485A3543370F04c5
Optimism
0x3bd7524b82bcbb94ba5Fe4992F493991bb951839
12 | {% endtab %}
13 |
14 | {% tab title="Mainnet" %}
15 |
16 | {% endtab %}
17 | {% endtabs %}
18 |
--------------------------------------------------------------------------------
/apis-and-sdks/interchain-gas-paymaster-api.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Pay for message delivery on the origin chain
3 | ---
4 |
5 | # Interchain gas paymaster API
6 |
7 | Hyperlane provides an on-chain API on the origin chain that allows message senders to pay one or more [relayers](../operators/relayers/ "mention") to deliver a message on the destination chain.
8 |
9 | {% hint style="info" %}
10 | Learn more about [interchain-gas-payments.md](../protocol/interchain-gas-payments.md "mention") protocol [here](../protocol/interchain-gas-payments.md)
11 | {% endhint %}
12 |
13 | ## Interface
14 |
15 | The interchain gas paymaster (IGP) interface exposes two functions that can be used together to quote and pay for interchain gas.
16 |
17 | 1. `quoteGasPayment` is a view function that allows users to get a quote for an amount of gas on the destination chain, denominated in the origin chain's native token.
18 | 2. `payGasFor` is a payable function that pays a relayer to deliver a specific message to the destination chain
19 |
20 | These functions do not necessarily need to be called in the same transaction as the message dispatch.
21 |
22 | You can find deployed IGPs on [addresses](../resources/addresses/ "mention")
23 |
24 | ```solidity
25 | // SPDX-License-Identifier: MIT OR Apache-2.0
26 | pragma solidity >=0.6.11;
27 |
28 | /**
29 | * @title IInterchainGasPaymaster
30 | * @notice Manages payments on a source chain to cover gas costs of relaying
31 | * messages to destination chains.
32 | */
33 | interface IInterchainGasPaymaster {
34 | /**
35 | * @notice Emitted when a payment is made for a message's gas costs.
36 | * @param messageId The ID of the message to pay for.
37 | * @param gasAmount The amount of destination gas paid for.
38 | * @param payment The amount of native tokens paid.
39 | */
40 | event GasPayment(
41 | bytes32 indexed messageId,
42 | uint256 gasAmount,
43 | uint256 payment
44 | );
45 |
46 | /**
47 | * @notice Deposits msg.value as a payment for the relaying of a message
48 | * to its destination chain.
49 | * @dev Overpayment will result in a refund of native tokens to the _refundAddress.
50 | * Callers should be aware that this may present reentrancy issues.
51 | * @param _messageId The ID of the message to pay for.
52 | * @param _destinationDomain The domain of the message's destination chain.
53 | * @param _gasAmount The amount of destination gas to pay for.
54 | * @param _refundAddress The address to refund any overpayment to.
55 | */
56 | function payForGas(
57 | bytes32 _messageId,
58 | uint32 _destinationDomain,
59 | uint256 _gasAmount,
60 | address _refundAddress
61 | ) external payable;
62 |
63 | /**
64 | * @notice Quotes the amount of native tokens to pay for interchain gas.
65 | * @param _destinationDomain The domain of the message's destination chain.
66 | * @param _gasAmount The amount of destination gas to pay for.
67 | * @return The amount of native tokens required to pay for interchain gas.
68 | */
69 | function quoteGasPayment(uint32 _destinationDomain, uint256 _gasAmount)
70 | external
71 | view
72 | returns (uint256);
73 | }
74 | ```
75 |
76 | ## Refunds
77 |
78 | Users may call `payGasFor` with `msg.value` greater than what would be returned by `quoteGasPayment`. In this case, the IGP contract should refund the difference to the `_refundAddress` provided. This allows users to not need to call `quoteGasPayment` explicitly.
79 |
80 | For example, if you are paying for 1M gas and pass 0.1 ETH to the IGP contract, but `quoteGasPayment` quotes a payment of 0.08 ETH, the `_refundAddress` will be refunded `0.02` ETH.
81 |
82 | Note that refunds are only made if what is paid was greater than what was quoted. Refunds are **not** made if delivery of a message on the destination chain winds up requiring less gas than what was paid for.
83 |
84 | #### Reentrancy Risk
85 |
86 | Note that refunding overpayment involves the IGP contract calling the `_refundAddress`, which can present a risk of [reentrancy](https://www.certik.com/resources/blog/3K7ZUAKpOr1GW75J2i0VHh-what-is-a-reentracy-attack) for your application. Special care should be made by callers to ensure they are not vulnerable to reentrancy exploits.
87 |
88 | #### Unsuccessful Refunds
89 |
90 | If a refund is unsuccessful, the `payForGas` call will revert.
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/apis-and-sdks/warp-api.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Move your token between chains
3 | ---
4 |
5 | # Warp Route API
6 |
7 | Developers can use Hyperlane's Warp API to permissionlessly deploy "Warp Routes", contracts that allow ERC20 tokens to move effortlessly between chains.
8 |
9 | Unlike other token wrapping protocols, Warp Routes are secured by Hyperlane's modular [sovereign-consensus](../protocol/sovereign-consensus/ "mention") protocol, allowing developers to specify the security model that governs the minting, burning, and unwrapping of their interchain token.
10 |
11 | ### Overview
12 |
13 | A Hyperlane Warp Route allows a particular token to be moved between chains according to a security model specified by the deployer.
14 |
15 | Each Warp Route consists of one contract deployed on every chain that the token can move between. These contracts use the [messaging-api](../apis/messaging-api/ "mention") to send interchain messages to one another.
16 |
17 | When a user transfers from the _canonical_ origin chain to a _non-canonical_ destination chain, their tokens are locked in a `HypERC20Collateral` contract, which sends a message to the destination chain to mint wrapped tokens.
18 |
19 | When a user transfers between non-canonical chains, their wrapped tokens are burned on the origin chain, which sends a message to the destination chain to mint wrapped tokens.
20 |
21 | Finally, if a user transfers from a non-canonical origin chain back to the canonical destination chain, their wrapped tokens are burned on the origin chain, which sends a message to the destination chain to release the tokens locked in the`HypERC20Collateral` contract.
22 |
23 | ### Interface
24 |
25 | Hyperlane Warp Route exposes the following token interface. Warp Route tokens implement this interface, in addition to the standard `ERC20` interface.
26 |
27 | ```solidity
28 | /// @notice An interchain extension of the ERC20 interface
29 | interface IHypERC20 is IERC20 {
30 | /**
31 | * @notice Transfers tokens to the specified recipient on a remote chain
32 | * @param _destination The domain ID of the destination chain
33 | * @param _recipient The address of the recipient, encoded as bytes32
34 | * @param _amount The amount of tokens to transfer
35 | */
36 | function transferRemote(
37 | uint32 _destination,
38 | bytes32 _recipient,
39 | uint256 _amount
40 | ) external payable;
41 | }
42 | ```
43 |
44 |
45 |
46 | ### Security considerations
47 |
48 | The deployer of a Warp Route can optionally specify the [interchain-security-modules.md](../protocol/sovereign-consensus/interchain-security-modules.md "mention") (ISMs) that are used to verify interchain transfer messages.
49 |
50 | This means that each Warp Route may have a unique security configuration. Users transferring interchain tokens should understand the trust assumptions of a Route before using it.
51 |
52 | Similarly, Warp front-ends should maintain a list of known Routes so as to avoid recommending an insecure Route. The reference UI supports a minor modification to the [TokenList](https://tokenlists.org/) standard so that curators can create lists of "safe" Routes.
53 |
54 |
--------------------------------------------------------------------------------
/apis/messaging-api/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Send and receive interchain messages using Hyperlane
3 | ---
4 |
5 | # Messaging API
6 |
7 | Hyperlane provides an on-chain API for sending and receiving interchain messages.
8 |
9 | Cant wait to get started? Follow the [messaging.md](../../build-with-hyperlane/quickstarts/messaging.md "mention") quickstart to send your first interchain message in less than five minutes. Otherwise, read on—
10 |
11 | #### Interface
12 |
13 | To [send.md](send.md "mention") interchain messages, reference the `Mailbox.dispatch()` API.
14 |
15 | To [receive.md](receive.md "mention") interchain messages, implement the `IMessageRecipient` interface.
16 |
17 | ```mermaid
18 | %%{ init: {
19 | "theme": "neutral",
20 | "themeVariables": {
21 | "mainBkg": "#025AA1",
22 | "textColor": "white",
23 | "clusterBkg": "white"
24 | },
25 | "themeCSS": ".edgeLabel { color: black }"
26 | }}%%
27 |
28 | flowchart LR
29 | subgraph Origin Chain
30 | Sender
31 | M_O[(Mailbox)]
32 | Sender -- "dispatch(destination, recipient, body)" --> M_O
33 | end
34 |
35 | subgraph Destination Chain
36 | Recipient[IMessageRecipient]
37 | M_D[(Mailbox)]
38 |
39 | M_D -- "handle(origin, sender, body)" --> Recipient
40 | end
41 |
42 | M_O -. "relay" .-> M_D
43 |
44 | click M_O https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/Mailbox.sol
45 | click Recipient https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/interfaces/IMessageRecipient.sol
46 | click M_D https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/Mailbox.sol
47 |
48 | style Sender fill:#efab17
49 | style Recipient fill:#efab17
50 | ```
51 |
52 | #### Testing
53 |
54 | See the [unit-testing.md](../../build-with-hyperlane/guides/unit-testing.md "mention") documentation to see how to test your integration with the Hyperlane messaging API using the `MockMailbox` contracts.
55 |
56 | #### Interchain gas
57 |
58 | Delivering an interchain message requires submitting a transaction on the destination chain. Optionally, you can pay for the gas for this transaction on the origin chain, and let Hyperlane [relayers](../../operators/relayers/ "mention") deliver your message for you.
59 |
60 | Learn more about [paying-for-interchain-gas.md](../../build-with-hyperlane/guides/paying-for-interchain-gas.md "mention").
61 |
--------------------------------------------------------------------------------
/apis/messaging-api/receive.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Receive an inbound message from any Hyperlane supported network
3 | ---
4 |
5 | # Receive
6 |
7 | {% hint style="warning" %}
8 | Developers **must** implement the `IMessageRecipient` interface in order to be able to receive interchain messages.
9 | {% endhint %}
10 |
11 | ### Interface
12 |
13 | ```solidity
14 | // SPDX-License-Identifier: MIT OR Apache-2.0
15 | pragma solidity >=0.6.11;
16 |
17 | interface IMessageRecipient {
18 | /**
19 | * @notice Handle an interchain message
20 | * @param _origin Domain ID of the chain from which the message came
21 | * @param _sender Address of the message sender on the origin chain as bytes32
22 | * @param _body Raw bytes content of message body
23 | */
24 | function handle(
25 | uint32 _origin,
26 | bytes32 _sender,
27 | bytes calldata _body
28 | ) external;
29 | }
30 |
31 | ```
32 |
33 | ## Security
34 |
35 | ### Access control
36 |
37 | {% hint style="danger" %}
38 | To ensure only valid interchain messages are accepted, it is important to require that `msg.sender` is a known Hyperlane [messaging.md](../../protocol/messaging.md "mention").
39 | {% endhint %}
40 |
41 | Developers must implement access control on `handle()` in order to ensure the security of interchain messages. Only a Hyperlane [messaging.md](../../protocol/messaging.md "mention") contract should have permission to call this function. An example of this access control is shown below.
42 |
43 | ```solidity
44 | address constant mailbox = 0x0E3239277501d215e17a4d31c487F86a425E110B;
45 | // for access control on handle implementations
46 | modifier onlyMailbox() {
47 | require(msg.sender == mailbox);
48 | _;
49 | }
50 |
51 | function handle(
52 | uint32 _origin,
53 | bytes32 _sender,
54 | bytes calldata _body
55 | ) external onlyMailbox {};
56 | ```
57 |
58 | ### Interchain security modules
59 |
60 | Developers can override Hyperlane's default [multisig-ism.md](../../protocol/sovereign-consensus/multisig-ism.md "mention")-based security model by specifying their own [sovereign-consensus](../../protocol/sovereign-consensus/ "mention").
61 |
62 | See the [sovereign-consensus](../../protocol/sovereign-consensus/ "mention") documentation for more info on how to set the ISM used by your application.
63 |
64 |
65 |
66 | ### Encoding
67 |
68 | {% hint style="info" %}
69 | Hyperlane message senders are left-padded to `bytes32` for compatibility with virtual machines that are addressed differently.
70 | {% endhint %}
71 |
72 | The following utility is provided in the [`TypeCasts` library](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/libs/TypeCasts.sol) for convenience.
73 |
74 | ```solidity
75 | // alignment preserving cast
76 | function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {
77 | return address(uint160(uint256(_buf)));
78 | }
79 | ```
80 |
81 | ### Example usage
82 |
83 | An example `handle()` implementation for receiving messages is provided below.
84 |
85 | ```solidity
86 | event Received(uint32 origin, address sender, bytes body);
87 | function handle(
88 | uint32 _origin,
89 | bytes32 _sender,
90 | bytes memory _body
91 | ) external onlyMailbox() {
92 | address sender = bytes32ToAddress(_sender);
93 | emit Received(_origin, sender, _body);
94 | }
95 | ```
96 |
--------------------------------------------------------------------------------
/apis/messaging-api/send.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Send a message to any Hyperlane supported network
3 | ---
4 |
5 | # Send
6 |
7 | Developers can send interchain messages by calling `Mailbox.dispatch()`.
8 |
9 | ### Interface
10 |
11 | {% hint style="warning" %}
12 | Hyperlane can only deliver messages to smart contracts that implement the `IMessageRecipient` interface. See the [receive.md](receive.md "mention") documentation for more information.
13 | {% endhint %}
14 |
15 | ```solidity
16 | /**
17 | * @notice Dispatches a message to the destination domain & recipient.
18 | * @param _destinationDomain Domain of destination chain
19 | * @param _recipientAddress Address of recipient on destination chain as bytes32
20 | * @param _body Raw bytes content of message body
21 | * @return The message ID inserted into the Mailbox's merkle tree
22 | */
23 | function dispatch(
24 | uint32 _destination,
25 | bytes32 _recipient,
26 | bytes calldata _body
27 | ) external returns (bytes32) {
28 | ```
29 |
30 | See [addresses](../../resources/addresses/ "mention")and [domains](../../resources/domains/ "mention") for `Mailbox` contract addresses, and chain domain IDs, respectively.
31 |
32 | ### Encoding
33 |
34 | {% hint style="info" %}
35 | Recipient addresses are left-padded to `bytes32` for compatibility with virtual machines that are addressed differently.
36 | {% endhint %}
37 |
38 | The following utility is provided in the [`TypeCasts` library](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/libs/TypeCasts.sol) for convenience.
39 |
40 | ```solidity
41 | // alignment preserving cast
42 | function addressToBytes32(address _addr) internal pure returns (bytes32) {
43 | return bytes32(uint256(uint160(_addr)));
44 | }
45 | ```
46 |
47 | ### Paying for Interchain Gas
48 |
49 | Delivering a message to its destination requires submitting a transaction on the destination chain. If you want to have [relayer.md](../../protocol/agents/relayer.md "mention") deliver the message on your behalf, you can pay for the gas for this transaction on the origin chain.
50 |
51 | Learn more about [paying-for-interchain-gas.md](../../build-with-hyperlane/guides/paying-for-interchain-gas.md "mention").
52 |
53 | ### Example Usage
54 |
55 | The code snippet below shows an example of sending a message from Ethereum to Avalanche.
56 |
57 | {% hint style="warning" %}
58 | Note this example does not pay for interchain gas, and therefore would not be delivered automatically by a relayer.
59 | {% endhint %}
60 |
61 | ```solidity
62 | uint32 constant avalancheDomain = 43114;
63 | address constant avalancheRecipient = 0x36FdA966CfffF8a9Cdc814f546db0e6378bFef35;
64 | address constant ethereumMailbox = 0x2f9db5616fa3fad1ab06cb2c906830ba63d135e3;
65 | IMailbox(ethereumMailbox).dispatch(
66 | avalancheDomain,
67 | addressToBytes32(avalancheRecipient),
68 | bytes("hello avalanche from ethereum")
69 | );
70 | ```
71 |
--------------------------------------------------------------------------------
/build-with-hyperlane/explorer/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Using the Hyperlane Explorer to find and track messages
3 | ---
4 |
5 | # Explorer
6 |
7 | The [Hyperlane Explorer](https://explorer.hyperlane.xyz/) can be used to find messages on any network with a Hyperlane deployment. Drill down into messages for more details about their properties and status.
8 |
9 | Messages to/from [core chains](../../resources/domains/) will searchable by transaction hash, message ID, or sender/recipient address. For other chains, the explorer can be configured to search for messages by providing it a chain config.
10 |
11 | ### Searching for messages
12 |
13 | The [Hyperlane Explorer](https://explorer.hyperlane.xyz/) supports searching for messages using any of the following values:
14 |
15 | * Hash of the transaction that initiated the message (origin tx)
16 | * Hash of the transaction that delivered message (destination tx)
17 | * Address of the account that sent the origin transaction
18 | * Address of the account that sent the destination transaction
19 | * Address of the message sender
20 | * Address of the message recipient
21 | * ID of the message
22 |
23 | To search, enter your query into the top search bar. You can use the Origin Chain, Destination Chain, and Time filter options to narrow down your search.
24 |
25 |
Explorer search bar
26 |
27 | {% hint style="info" %}
28 | Note, by default the explorer will only find message on [core Hyperlane chains](../../resources/domains/). To view messages send to and/or from other chains, see [configuring-pi-chains.md](configuring-pi-chains.md "mention") .
29 | {% endhint %}
30 |
31 | ### Permissionless Interoperability
32 |
33 | The explorer UI and REST API can be configured to search for messages on any chain with a Hyperlane deployment. See [configuring-pi-chains.md](configuring-pi-chains.md "mention") for details.
34 |
35 | ### Debugging Messages
36 |
37 | If you're trying to debug a problem with message delivery, the [observability.md](observability.md "mention") page has useful tips.
38 |
39 | ### API Reference
40 |
41 | The explorer's data can be accessed programmatically via the [rest-api.md](rest-api.md "mention") or [graphql-api.md](graphql-api.md "mention"). The REST API is recommended because it exposes a simpler interface for message data.
42 |
43 | ###
44 |
--------------------------------------------------------------------------------
/build-with-hyperlane/explorer/configuring-pi-chains.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Using a Permissionless Interoperability chain in the Explorer
3 | ---
4 |
5 | # Configuring PI Chains
6 |
7 | Hyperlane can be [permissionlessly deployed](../../deploy/permissionless-interoperability.md) to any chain, but messages on PI chains cannot be identified by the default Hyperlane agents. To view details about messages from PI chains, first configure the explorer with metadata about that chain.
8 |
9 | To begin, go to the [explorer's settings page](https://explorer.hyperlane.xyz/settings). From there, click the Add Custom Chain button.
10 |
11 |
12 |
13 | A modal will appear. Input the configuration for your PI Chain. The chain config schema is an extension of the Hyperlane SDK's [ChainMetadata schema](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/typescript/sdk/src/consts/chainMetadata.ts#L21) but with a `contracts` object added. Currently only the `mailbox` contract address is required but more functionality may be enabled in the future if more addresses are provided.
14 |
15 | If a valid Etherscan-based block explorer config is provided, the Hyperlane Explorer will utilize it to find the desired messages. If not, it will use the RPC URL. Note, Explorers with api keys (even just free-tier keys), perform faster and more reliably.
16 |
17 | ### Chain Config Examples
18 |
19 | **A minimal chain config:**
20 |
21 | ```json
22 | {
23 | "chainId": 12345,
24 | "name": "myChain",
25 | "publicRpcUrls": [{ "http": "https://myRpcUrl.com" }],
26 | "contracts": {
27 | "mailbox": "0x12345..."
28 | }
29 | }
30 | ```
31 |
32 | **A chain config with a block explorer and block timings included:**
33 |
34 | ```json
35 | {
36 | "chainId": 12345,
37 | "name": "myChain",
38 | "publicRpcUrls": [{ "http": "https://myRpcUrl.com" }],
39 | "blockExplorers": [ {
40 | "name": "MyScan",
41 | "url": "https://myScanExplorer.com",
42 | "apiUrl": "https://api-myScanExplorer.com/api"
43 | } ],
44 | "blocks": { "confirmations": 1, "estimateBlockTime": 10 },
45 | "contracts": {
46 | "mailbox": "0x12345..."
47 | }
48 | }
49 | ```
50 |
51 | {% hint style="info" %}
52 | If the origin or destination `domainId` of chains in your messages doesn't match their `chainId` then you must include the `domainId` field in your chain config.
53 | {% endhint %}
54 |
--------------------------------------------------------------------------------
/build-with-hyperlane/explorer/observability.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: How to use the Hyperlane Explorer to debug messages
3 | ---
4 |
5 | # Debugging messages
6 |
7 | Visit the Explorer at [https://explorer.hyperlane.xyz](https://explorer.hyperlane.xyz/)
8 |
9 | Then paste a sender/recipient address or a transaction hash into the top search field. All matching messages will be shown in the result list. Click the row for more details.
10 |
11 |
Retrieving a transaction in the Hyperlane Message Explorer
12 |
13 | ### Debugging failed messages
14 |
15 | You'll know that a message failed to process because the bar at the top of the Message Explorer will turn red and the upper right section of the page will feature error reasons indicating why the message wasn't able to process.
16 |
17 |
Failed transaction from Fuji to Goerli
18 |
19 | If your message was not delivered it can be due to several factors:
20 |
21 | #### Invalid destination
22 |
23 | If the destination domain identifier (`uint32`) is not known to relay clients they will have no way to deliver your message. Refer to the [domains](../../resources/domains/ "mention") for known domains and the canonical identifiers to use when sending messages to these destinations.
24 |
25 | #### Invalid recipient
26 |
27 | If the recipient address (`bytes32`) is not a contract address that implements the [`IMessageRecipient` interface](../../apis/messaging-api/receive.md), the relayer will not be able to deliver your message.
28 |
29 | {% hint style="warning" %}
30 | EVM addresses (`address`) must be left-padded with zeroes to be compliant. Refer to the send [#encoding](../../apis/messaging-api/send.md#encoding "mention") section for details and a `pure addressToBytes32` utility function.
31 | {% endhint %}
32 |
33 | #### Unprocessable
34 |
35 | If gas estimation of the message recipient's `IMessageRecipient.handle()` function fails, [relayer.md](../../protocol/agents/relayer.md "mention") will not be able to deliver the message. Relayers will continue to estimate gas for message delivery, as state changes may allow for successful delivery of a previously undeliverable message.
36 |
37 | {% hint style="info" %}
38 | If you have a use case which is not accommodated by this behavior, **please reach out** [on Discord](https://discord.com/invite/KBD3aD78Bb).
39 | {% endhint %}
40 |
41 | #### Underfunded
42 |
43 | An underfunded message implies the [interchain-gas-payments.md](../../protocol/interchain-gas-payments.md "mention") made to deliver this message are insufficient.
44 |
45 | Relayers use the [`eth_estimateGas`](https://ethereum.github.io/execution-apis/api-documentation/)RPC on the destination chain to determine the absolute cost of relaying a message. If this amount exceeds the total amount of gas paid for on the origin chain, relayers will typically refuse to deliver a message.
46 |
47 | You can [manually-pay-for-interchain-gas.md](../guides/manually-pay-for-interchain-gas.md "mention") to resolve this.
48 |
49 | ### Using Etherscan
50 |
51 | You can also look at the Etherscan page of the recipient on the destination chain however be aware that the processing transaction won't show up on list of transactions as you would typically imagine. The reason for that is that relayers actually call the Mailbox contracts which in turn call the `handle` function on the recipient. Thus, you will find evidence of processing on the under the `Internal Txns` tab instead
52 |
--------------------------------------------------------------------------------
/build-with-hyperlane/explorer/rest-api.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Retrieve info about messages using REST Queries
3 | ---
4 |
5 | # REST API
6 |
7 | The Hyperlane agents collect useful information about activity on the system, including all messages. That data can be queried via the APIs.
8 |
9 | The APIs are currently available free of charge and without any required authentication.
10 |
11 | {% hint style="info" %}
12 | Connect your preferred fetch client or library to [Explorer API page](https://explorer.hyperlane.xyz/api-docs) to query data!
13 | {% endhint %}
14 |
15 | ### Example Query
16 |
17 | #### Request
18 |
19 | ```javascript
20 | const baseUrl = 'https://explorer.hyperlane.xyz/api'
21 | const action = 'module=message&action=get-messages'
22 | const messageId = '62d30bde22af368e43f981f65186ff2c2b895a09774a9397f815dcc366793875'
23 | const url =`${baseUrl}?${action}&id=${messageId}`;
24 | const response = await fetch(url, {
25 | method: "GET",
26 | headers: { "Content-Type": "application/json" },
27 | });
28 | const data = await response.json();
29 | ```
30 |
31 | #### Response
32 |
33 | ```json
34 | {
35 | "status": "1",
36 | "message": "OK",
37 | "result": [
38 | {
39 | "id": "62d30bde22af368e43f981f65186ff2c2b895a09774a9397f815dcc366793875",
40 | "status": "delivered",
41 | "sender": "0x854fd51c04408ad84da3838a4ff7282522f7866e",
42 | "recipient": "0x1c847335d123632fc7d662ab87ac7872acd920f2",
43 | "originDomainId": 80001,
44 | "destinationDomainId": 43113,
45 | "nonce": 613,
46 | "body": "0x48656c6c6f21",
47 | "originTransaction": {
48 | "from": "0x06c8798aa665bdbeea6aba6fc1b1d9bbdca8d613",
49 | "transactionHash": "0x8359f6c022a1e164e052f2a106c8f67a222c7e2355ded825c4112486510cdb80",
50 | "blockNumber": 30789012,
51 | "gasUsed": 100813,
52 | "timestamp": 1673373764000
53 | },
54 | "destinationTransaction": {
55 | "from": "0x0a1a869dc7f56c9fd4276b0568fd232a07d88e83",
56 | "transactionHash": "0x439ae6fbbd768404166ef31a08ade52d4659f9843ac490203b90406661b5001b",
57 | "blockNumber": 17884981,
58 | "gasUsed": 153381,
59 | "timestamp": 1673373842000
60 | }
61 | }
62 | ]
63 | }
64 | ```
65 |
66 | ### API Reference
67 |
68 | #### Module: Message
69 |
70 | Action: `get-message`, Parameter (1 required):
71 |
72 | * `id`: message id (string)
73 | * `sender`: address of message sender (string)
74 | * `recipient`: address of message recipient (string)
75 | * `origin-tx-hash`: hash of origin transaction (string)
76 | * `origin-tx-sender`: address of origin tx sender (string)
77 | * `destination-tx-hash`: hash of destination transaction (string)
78 | * `destination-tx-sender`: address of destination tx sender (string)
79 |
80 | Action: `get-status` Parameter (1 required):
81 |
82 | * _Same as get-message above_
83 |
84 | Action: `search-messages`, Parameter (1 required):
85 |
86 | * `query`: address or hash to search (string)
87 |
88 | ### APIs for Permissionless Interoperability chains
89 |
90 | Hyperlane can be [permissionlessly deployed](../../deploy/permissionless-interoperability.md) to any chain, but messages on PI chains cannot be identified by the default Hyperlane agents. To view details about messages from PI chains, query the `search-pi-messages` action. The search requires a chain config in the request body. Note, this same functionality is also available in the [explorer UI](configuring-pi-chains.md).
91 |
92 | ```javascript
93 | const chainConfig = {
94 | "chainId": 1234,
95 | "name": "mychain",
96 | "publicRpcUrls": [{ "http": "https://myRpcUrl.com" }],
97 | "blockExplorers": [ {
98 | "name": "MyChainScan",
99 | "url": "https://myChainExplorer.com",
100 | "apiUrl": "https://myChainExplorer.com/api",
101 | "apiKey": "12345"
102 | } ],
103 | "contracts": {
104 | "mailbox": "0x123..."
105 | }
106 | }
107 |
108 | const baseUrl = 'https://explorer.hyperlane.xyz/api'
109 | const action = 'module=message&action=search-pi-messages'
110 | const query = '62d30bde22af368e43f981f65186ff2c2b895a09774a9397f815dcc366793875'
111 | const url =`${baseUrl}?${action}&query=${query}`;
112 | const response = await fetch(url, {
113 | method: "POST",
114 | body: JSON.stringify(chainConfig),
115 | headers: { "Content-Type": "application/json" },
116 | });
117 | const data = await response.json();
118 | ```
119 |
120 | #### Chain Config Schema
121 |
122 | The chain config schema is an extension of the Hyperlane SDK's [ChainMetadata schema](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/typescript/sdk/src/consts/chainMetadata.ts#L21) but with a `contracts` object added. See [Configuring PI Chains](configuring-pi-chains.md) for more details about this config object.
123 |
--------------------------------------------------------------------------------
/build-with-hyperlane/guides/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Read below for a comprehensive set of guides for common procedures
3 | ---
4 |
5 | # Guides
6 |
7 |
--------------------------------------------------------------------------------
/build-with-hyperlane/guides/finding-my-messages.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Find message details and track status updates
3 | ---
4 |
5 | # Finding my messages
6 |
7 | The Hyperlane Explorer is the recommended way to find information about messages. See the [explorer](../explorer/ "mention") documentation for details.
8 |
9 | {% content-ref url="../explorer/" %}
10 | [explorer](../explorer/)
11 | {% endcontent-ref %}
12 |
--------------------------------------------------------------------------------
/build-with-hyperlane/guides/paying-for-interchain-gas.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Automatically pay a relayer to deliver messages
3 | ---
4 |
5 | # Automatically pay for interchain gas
6 |
7 | {% hint style="info" %}
8 | Read up on [interchain-gas-payments.md](../../protocol/interchain-gas-payments.md "mention") and the [interchain-gas-paymaster-api.md](../../apis-and-sdks/interchain-gas-paymaster-api.md "mention")
9 | {% endhint %}
10 |
11 | This guide will show you how to integrate the [interchain-gas-paymaster-api.md](../../apis-and-sdks/interchain-gas-paymaster-api.md "mention") into your application.
12 |
13 | Doing so ensures your application automatically makes [interchain-gas-payments.md](../../protocol/interchain-gas-payments.md "mention") to a relayer so that they will deliver the messages sent by your application.
14 |
15 | We will cover two different approaches. If you know which approach you would prefer, feel free to jump directly to that section.
16 |
17 | ## Interchain gas payments funded by the user
18 |
19 | A common approach is to pass the interchain gas payment costs through to `msg.sender`. This ensures that users of your application pay the full costs of sending _and_ delivering an interchain message.
20 |
21 | Note since the caller of the function is paying for the message's interchain gas, the function must be payable!
22 |
23 | ```solidity
24 | // The Mailbox (same address on all EVM chains)
25 | IMailbox mailbox = IMailbox(0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70);
26 | // An IGP contract associated with the Abacus Works relayer
27 | // (same address on all mainnet EVM chains)
28 | IInterchainGasPaymaster igp = IInterchainGasPaymaster(
29 | 0x56f52c0A1ddcD557285f7CBc782D3d83096CE1Cc
30 | );
31 | // The amount of gas that the recipient contract consumes on the destination
32 | // chain when handling a message from this origin chain.
33 | uint256 gasAmount = 100000;
34 |
35 | function sendAndPayForMessage() external payable {
36 | bytes32 messageId = mailbox.dispatch(/* ... */);
37 | igp.payForGas{ value: msg.value }(
38 | messageId, // The ID of the message that was just dispatched
39 | destinationDomain, // The destination domain of the message
40 | gasAmount, // 100k gas to use in the recipient's handle function
41 | msg.sender // refunds go to msg.sender, who paid the msg.value
42 | );
43 | }
44 | ```
45 |
46 | ## Interchain gas payments funded by the application
47 |
48 | An alternative approach is for the application to pay the interchain gas payment costs itself.
49 |
50 | This may be desirable if the intent is for the application to subsidize some transaction costs, or if the application is already collecting a fee from the user that can be used to cover the costs of delivering interchain messages.
51 |
52 | ```solidity
53 | // The Mailbox (same address on all EVM chains)
54 | IMailbox mailbox = IMailbox(0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70);
55 | // An IGP contract associated with the Abacus Works relayer
56 | // (same address on all mainnet EVM chains)
57 | IInterchainGasPaymaster igp = IInterchainGasPaymaster(
58 | 0x56f52c0A1ddcD557285f7CBc782D3d83096CE1Cc
59 | );
60 | // The amount of gas that the recipient contract consumes on the destination
61 | // chain when handling a message from this origin chain.
62 | uint256 gasAmount = 100000;
63 |
64 | function sendMessage() external {
65 | bytes32 messageId = mailbox.dispatch(/* ... */);
66 |
67 | // Get the required payment from the IGP.
68 | uint256 quote = igp.quoteGasPayment(
69 | destinationDomain,
70 | gasAmount
71 | );
72 | // Pay from the contract's balance
73 | igp.payForGas{ value: quote }(
74 | messageId, // The ID of the message that was just dispatched
75 | destinationDomain, // The destination domain of the message
76 | gasAmount,
77 | address(this) // refunds are returned to this contract
78 | );
79 | }
80 |
81 | // so that the contract can receive native tokens, including refunds
82 | receive() external payable {}
83 | ```
84 |
--------------------------------------------------------------------------------
/build-with-hyperlane/guides/receive-1.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Customize interchain security using ISMs
3 | ---
4 |
5 | # Specifying an ISM
6 |
7 | Developers can take control of interchain security using [sovereign-consensus](../../protocol/sovereign-consensus/ "mention").
8 |
9 | ### Interchain Security Modules
10 |
11 | An Interchain Security Module (ISM) is a smart contract that is responsible for verifying messages from a remote chain. ISMs must implement the `IInterchainSecurityModule` interface.
12 |
13 | ```solidity
14 | // SPDX-License-Identifier: MIT OR Apache-2.0
15 | pragma solidity >=0.6.11;
16 |
17 | interface IInterchainSecurityModule {
18 | /**
19 | * @notice Returns an enum that represents the type of security model
20 | * encoded by this ISM.
21 | * @dev Relayers infer how to fetch and format metadata.
22 | */
23 | function moduleType() external view returns (uint8);
24 |
25 | /**
26 | * @notice Defines a security model responsible for verifying interchain
27 | * messages based on the provided metadata.
28 | * @param _metadata Off-chain metadata provided by a relayer, specific to
29 | * the security model encoded by the module (e.g. validator signatures)
30 | * @param _message Hyperlane encoded interchain message
31 | * @return True if the message was verified
32 | */
33 | function verify(bytes calldata _metadata, bytes calldata _message)
34 | external
35 | returns (bool);
36 | }
37 |
38 | interface ISpecifiesInterchainSecurityModule {
39 | function interchainSecurityModule()
40 | external
41 | view
42 | returns (IInterchainSecurityModule);
43 | }
44 |
45 | ```
46 |
47 | To specify the ISM they would like to use, developers may implement the `ISpecifiesInterchainSecurityModule` interface in any contract that receives interchain messages.
48 |
49 | If no ISM is specified, or if the specified ISM is the null address, whatever ISM is configured as the default on the destination chain `Mailbox` will be used.
50 |
51 | {% hint style="info" %}
52 | See [`Message.sol`](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/libs/Message.sol)for more details on Hyperlane message encoding.
53 | {% endhint %}
54 |
--------------------------------------------------------------------------------
/build-with-hyperlane/guides/v2-migration-guide.md:
--------------------------------------------------------------------------------
1 | # V2 migration guide
2 |
3 | An **API compatible** V2 of Hyperlane is currently under development. This page outlines some of the changes users can expect in V2 so they can prepare accordingly. More extensive documentation will be available prior to testnet launch.
4 |
5 | The latest code can be found on the is on the main [branch of the monorepo](https://github.com/hyperlane-xyz/hyperlane-monorepo/tree/v2).
6 |
7 | ## Summary of changes
8 |
9 | A high level overview of some of the changes in V2.
10 |
11 | ### Unified mailboxes
12 |
13 | Hyperlane V2 will have one `Mailbox` contract per chain, as opposed to one `Outbox` and several `Inboxes`. This allows applications to specify a single address from which they send and receive messages. ConnectionManager contracts can still be used but are less useful as there are no longer many `Inbox` contracts to aggregate.
14 |
15 | ### Interchain security modules
16 |
17 | Hyperlane V2 adopts [sovereign-consensus](../../protocol/sovereign-consensus/ "mention"), as outlined in the sovereign consensus [HIP](https://github.com/hyperlane-xyz/hips/pull/1). More work is needed in order for the relayer to automatically recognize anything other than the default `InterchainSecurityModule`. Until then, V2 will look similar to V1 from a security perspective.
18 |
19 | ### Changing domain IDs
20 |
21 | User feedback has indicated that the difference between Hyperlane domain IDs, and EIP-155 chain IDs. In V2, Hyperlane domain IDs will be changed to match EIP-155 chain IDs.
22 |
23 | ## Migration guide for apps using V1
24 |
25 | If you're building on Hyperlane V1 using an `AbacusConnectionManager`, you will be able to migrate from V1 to V2 by:\
26 | 1\. Calling `abacusConnectionManager.setOutbox(v2MailboxAddress)`\
27 | 2\. Calling `abacusConnectionManager.enrollInbox(v2DomainId, v2MailboxAddress)`\
28 | 3\. Eventually, calling `abacusConnectionManager.unenrollInbox(v1InboxAddress)` for each V1 `Inbox`\
29 |
30 |
31 | ## Using V2 API on V1
32 |
33 | You can use the `V2CompatibilityRouter`(`0x1d3aAC239538e6F1831C8708803e61A9EA299Eec`) on all chains that v1 is on to be able to use the V2 interface (i.e. function signatures and chain IDs instead of domain IDs) and when v2 launches, you can easily change the mailboxes to the actual v2 maiboxes.
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/build-with-hyperlane/guides/which-igp-to-use-and-understanding-gas-amounts.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Which IGP contract should you use?
3 | ---
4 |
5 | # Choosing an interchain gas paymaster contract
6 |
7 | There may be many interchain gas paymaster (IGP) contracts on a given chain, this guide helps you understand which one you should use to pay for message delivery.
8 |
9 | ## Choosing a relayer
10 |
11 | Each relayer must deploy one or more IGP contracts through which it can accept payment to deliver messages to a remote chain.
12 |
13 | Not all [relayer.md](../../protocol/agents/relayer.md "mention") will be able to deliver all messages. For example, some relayers may only deliver messages between a specific subset of chains, or some relayers may only deliver messages between specific sender and recipient contracts.
14 |
15 | Be sure that you're using an IGP for a relayer that is capable of delivering all of the messages that your application might send.
16 |
17 | In some cases, this may mean using different IGP contracts depending on the destination of the message.
18 |
19 | ## Choosing an IGP contract
20 |
21 | Many relayers will deploy two types of IGP contracts. Read below to understand which one to use and how to use it.
22 |
23 | #### When using the default ISM (for most applications)
24 |
25 | If the message recipient uses the default [sovereign-consensus](../../protocol/sovereign-consensus/ "mention"), your application can make use of the `DefaultIsmInterchainGasPaymaster`.
26 |
27 | {% hint style="info" %}
28 | The default ISM is the security module used if no security model is specified explicitly by the recipient. Learn more about [receive-1.md](receive-1.md "mention").
29 | {% endhint %}
30 |
31 | When using the `DefaultIsmInterchainGasPaymaster`, the `_gasAmount` to use when calling the `payForGas` or `quoteGasPayment` functions only needs to be the amount of gas that your message's recipient `handle` function will use at the destination.
32 |
33 | Behind the scenes, the `DefaultIsmInterchainGasPaymaster` is configured to automatically add to the provided `_gasAmount` all overhead gas amounts that your message will use at its destination-- this includes any gas used by the Mailbox or the default ISM (for example, verifying validator signatures). This allows messages to be fully paid for without requiring any knowledge of the internal gas usage of the destination's Mailbox contract or default ISM when a message is processed.
34 |
35 | Find the deployed [#defaultisminterchaingaspaymaster](../../resources/addresses/#defaultisminterchaingaspaymaster "mention") contract addresses for the Abacus Works relayer.
36 |
37 | #### When using a custom ISM (advanced)
38 |
39 | If the message recipient is [receive-1.md](receive-1.md "mention") other than the default ISM, you should instead use the `InterchainGasPaymaster`.
40 |
41 | This IGP requires that the `_gasAmount` used when calling the `payForGas` or `quoteGasPayment` functions accounts for _all_ gas required by the relayer to process the message on the destination chain.
42 |
43 | The gas amount required to process the message should include:
44 |
45 | * Intrinsic transaction gas costs, including gas for calldata
46 | * The amount of gas used by the `Mailbox.process` function
47 | * The amount of gas used by the ISM to verify the message
48 | * The amount of gas used by the message's recipient `handle` function
49 |
50 | Find the deployed [#interchaingaspaymaster](../../resources/addresses/#interchaingaspaymaster "mention") contract addresses for the Abacus Works relayer.
51 |
52 | #### TL;DR
53 |
54 | | Recipient specifies an ISM | IGP Contract | \_gasAmount |
55 | | -------------------------- | ---------------------------------- | -------------------------------------------------------- |
56 | | No | `DefaultIsmInterchainGasPaymaster` | Only recipient `handle` function gas usage |
57 | | Yes | `InterchainGasPaymaster` | All gas used by a transaction that processes the message |
58 |
--------------------------------------------------------------------------------
/build-with-hyperlane/quickstarts/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: >-
3 | Want to quickly explore how Hyperlane works without writing any code? You're
4 | in the right place.
5 | ---
6 |
7 | # Quickstarts
8 |
9 | Each API has a Quickstart section that can be used with just Metamask or [Cast by Foundry](https://book.getfoundry.sh/cast/).
10 |
11 | ### Messaging
12 |
13 | Hyperlane makes interchain communication straightforward by providing a simple on-chain API for sending and receiving messages.
14 |
15 | Send your first message in under 5 minutes with the [messaging.md](messaging.md "mention") quickstart.
16 |
17 | ### Interchain Accounts
18 |
19 | With Hyperlane, you can make a simple call via Interchain Accounts to a pre-deployed [`TestRecipient`](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/test/TestRecipient.sol) contract on a remote destination chain.
20 |
21 | Try it here with the [accounts.md](accounts.md "mention") quickstart.
22 |
23 | ### Interchain Queries
24 |
25 | Query any contract, not just `IMessageRecipient`s with the `handle()` function (even legacy contracts!).
26 |
27 | Make a view call in moments using `TestQuerySender` and the [queries.md](queries.md "mention") quickstart.
28 |
--------------------------------------------------------------------------------
/build-with-hyperlane/quickstarts/accounts.md:
--------------------------------------------------------------------------------
1 | # Accounts
2 |
3 | This tutorial demonstrates how to make a simple interchain call using the [accounts.md](../../apis-and-sdks/accounts.md "mention") to a pre-deployed [`TestRecipient`](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/test/TestRecipient.sol) contract on a remote chain.
4 |
5 | You can also check out the [`hyperlane-quickstart`](https://github.com/hyperlane-xyz/hyperlane-quickstart) repo for running this out of the box.
6 |
7 | {% hint style="info" %}
8 | Want to learn more about interchain accounts? Take a look at the [accounts.md](../../apis-and-sdks/accounts.md "mention") documentation
9 | {% endhint %}
10 |
11 | ### Inputs
12 |
13 | * `$DESTINATION_DOMAIN`: The domain ID of the destination chain. See [domains](../../resources/domains/ "mention")
14 | * `$RECIPIENT`: The address of the `TestRecipient` contract on the destination chain,`0x36FdA966CfffF8a9Cdc814f546db0e6378bFef35`
15 | * `$CALLDATA`: The calldata of the call to make on `TestRecipient`, which we generate using `cast`: `0xf07c1f4700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001648656c6c6f576f726c642066726f6d20616e2049434100000000000000000000`
16 |
17 | ```
18 | $ cast calldata "fooBar(uint256,string)" 1 "HelloWorld from an ICA"
19 | ```
20 |
21 | ### Make a call
22 |
23 | Sending a message is a simple matter of calling `InterchainAccountRouter.callRemote()`. This function can be called easily using Etherscan+[Metamask](https://metamask.io/) or [cast](https://book.getfoundry.sh/cast/).
24 |
25 | {% tabs %}
26 | {% tab title="Using Metamask" %}
27 | 1. Navigate to the `InterchainAccountRouter` contract page on Etherscan (or whatever chain you want to send from). See [addresses](../../resources/addresses/ "mention") for `InterchainAccountRouter` addresses
28 | 2. Under the `Contract` tab, find the `Write as Proxy` button.
29 | 3. Click on the `Connect to Web3` button to connect your Wallet (i.e. Metamask). Make sure that you are on the correct network.
30 | 4. Expand the `callRemote` box
31 | 5. For destination domain, enter `$DESTINATION_DOMAIN`. You could use `137` to send to mainnet Polygon, or see other [domains](../../resources/domains/ "mention")
32 | 6. For the `_to` argument, enter the `$RECIPIENT`
33 | 7. For the `_value` argument, enter 0
34 | 8. For the `_data` argument, enter the `$CALLDATA`
35 | 9. Submit the transaction via your wallet/Metamask
36 | {% endtab %}
37 |
38 | {% tab title="Using cast" %}
39 | You can call the `InterchainAccountRouter` directly using `cast`. Make sure that you have a valid RPC URL for the origin chain and a private key with which you can pay for gas.
40 |
41 |
46 | {% endtab %}
47 | {% endtabs %}
48 |
49 | If you view the transaction on a block explorer, you should be able to see the `Dispatch` event. You can see an example message sending transaction [here](https://goerli.etherscan.io/tx/0xbb076b17dca5e436f574a4728dd59d25da4fd9d05c48c6ec304ea5a354849edf).
50 |
51 | {% hint style="warning" %}
52 | For your call to be executed on the destination chain, you **must** [manually-pay-for-interchain-gas.md](../guides/manually-pay-for-interchain-gas.md "mention"), using `550000` for the gas amount
53 | {% endhint %}
54 |
55 | {% content-ref url="../guides/manually-pay-for-interchain-gas.md" %}
56 | [manually-pay-for-interchain-gas.md](../guides/manually-pay-for-interchain-gas.md)
57 | {% endcontent-ref %}
58 |
--------------------------------------------------------------------------------
/build-with-hyperlane/quickstarts/messaging.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Send your first interchain message in under 5 minutes
3 | ---
4 |
5 | # Messaging
6 |
7 | This tutorial demonstrates how to:
8 |
9 | * [send.md](../../apis/messaging-api/send.md "mention") a simple interchain message to a pre-deployed [`TestRecipient`](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/test/TestRecipient.sol) contract.
10 | * Make [interchain-gas-payments.md](../../protocol/interchain-gas-payments.md "mention") to have [relayer.md](../../protocol/agents/relayer.md "mention") deliver the message.
11 |
12 | ### Inputs
13 |
14 | * `$MAILBOX_ADDRESS`: The [messaging.md](../../protocol/messaging.md "mention") contract address on the origin chain, see [addresses](../../resources/addresses/ "mention").
15 | * `$DESTINATION_DOMAIN`: The domain ID of the destination chain, see [domains](../../resources/domains/ "mention")
16 | * `$RECIPIENT`: The address of the `TestRecipient` contract on the destination chain, left padded to a `bytes32`. In our case: `0x00000000000000000000000036FdA966CfffF8a9Cdc814f546db0e6378bFef35`
17 |
18 | ### Send a message
19 |
20 | Sending a message is a simple matter of calling `Mailbox.dispatch()`. This function can be called easily using Etherscan+[Metamask](https://metamask.io/) or [cast](https://book.getfoundry.sh/cast/).
21 |
22 | {% tabs %}
23 | {% tab title="Using Metamask" %}
24 | 1. Navigate to the `Mailbox` contract page on [Etherscan](https://etherscan.io/address/0x35231d4c2D8B8ADcB5617A638A0c4548684c7C70) (see [#mailbox](../../resources/addresses/#mailbox "mention") contract addresses for other chains).
25 | 2. Under the `Contract` tab, find the `Write as Proxy` button.
26 | 3. Click on the `Connect to Web3` button to connect your Wallet (i.e. Metamask). Make sure that you are on the correct network.
27 | 4. Expand the `dispatch` box.
28 | 5. For destination domain, enter `$DESTINATION_DOMAIN`. You could use `137` to send to mainnet Polygon, or see other [domains](../../resources/domains/ "mention").
29 | 6. For the recipient address, enter `$RECIPIENT`. Remember to make sure to zero-pad this to a `bytes32` if you are using your own address. Alternatively, you can use `0x00000000000000000000000036FdA966CfffF8a9Cdc814f546db0e6378bFef35` (our test recipient address).
30 | 7. For the message body, enter whatever you like! A [string-to-hex converter website](https://dencode.com/en/string/hex) can help you write your message if you want to send a human-readable message. In the example below, we sent the "Hello World" string as `0x48656c6c6f20576f726c64`
31 | 8. Submit the transaction via your wallet/Metamask
32 |
33 | 
34 | {% endtab %}
35 |
36 | {% tab title="Using Cast" %}
37 | You can call `Mailbox.dispatch()` directly using `cast`. Make sure that you have a valid RPC URL for the origin chain and a private key with which you can pay for gas.
38 |
39 |
42 | {% endtab %}
43 | {% endtabs %}
44 |
45 | {% hint style="warning" %}
46 | For your transfer to be executed on the destination chain, you **must** [manually-pay-for-interchain-gas.md](../guides/manually-pay-for-interchain-gas.md "mention"), using `100000` for the gas amount
47 | {% endhint %}
48 |
49 | {% content-ref url="../guides/manually-pay-for-interchain-gas.md" %}
50 | [manually-pay-for-interchain-gas.md](../guides/manually-pay-for-interchain-gas.md)
51 | {% endcontent-ref %}
52 |
--------------------------------------------------------------------------------
/build-with-hyperlane/troubleshooting.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Having trouble with Hyperlane? Let's help you figure it out!
3 | ---
4 |
5 | # Troubleshooting/Developer FAQ
6 |
7 | As you navigate the interchain space and begin sending your first messages between blockchains, you may run into some issues. This section will help you troubleshoot common issues so you can get right back on the Interchain Highway and onwards to your destination!
8 |
9 | ### Message Delivery
10 |
11 | For a simple approach to debugging messages, try the Hyperlane Explorer. It can diagnose common issues with message delivery. See [Debugging with Explorer](explorer/observability.md) for details.
12 |
13 | Still need more help? Find our team on the [Hyperlane Discord](http://discord.gg/hyperlane) and ask away!
14 |
15 | #### Can I retry my messages?
16 |
17 | Relayers are configured to automatically retry delivering a message with an exponential back-off (assuming that there was sufficient gas paid for on the origin chain).
18 |
19 | #### Etherscan says an Error ocurrred
20 |
21 | More often than not, it is not actually an error. What happens is that the [messaging.md](../protocol/messaging.md "mention") will attempt to make a call to the recipient to query its [sovereign-consensus](../protocol/sovereign-consensus/ "mention"). If a recipient does not specify an ISM by implementing the interface, the Mailbox will default to the default ISM that is configured on it. However, to Etherscan, the transaction trace includes a revert which it calls out, however in this case, it is a false-positive. So if you see a process transaction like [this one](https://goerli-optimism.etherscan.io/tx/0x753843852e95048c21ce7b4e68149e8496beb86174197f8d727467dae1183dae), know that your message has actually been processed.
22 |
23 |
This is actually fine!
24 |
25 |
This is also fine!
26 |
27 | #### I deployed Hyperlane to a new chain but my message/tokens are not getting delivered
28 |
29 | The relayer logs are your best friend. If you are running a validator on your local machine and writing checkpoints to localStorage, make sure that the relayer has access to them. If you use docker, ensure that you mount the path through. Also, enable the `--allowLocalCheckpointSyncers` option on the relayer.
30 |
31 | ### Message cancellation
32 |
33 | Once a message is enqueued on a Mailbox merkle tree, from the system perspective, messages are perpetually processable. If messages are supposed to be of limited validity or cancelable, it is up to the application to encode those semantics into their message bytes.
34 |
35 | ### Off-chain Agents
36 |
37 | #### Missing name field error
38 |
39 | An error about a missing `name` field most likely indicates that you have an environment variable that implies the existence of a chain, but said chain does not exist in the config files. You may have misspelled the ENV name (`HYP_BASE_CHAINS_GOERLI_CONNECTION_URL)`. Or you may have specified a new chain but forgot to load the corresponding config file.
40 |
--------------------------------------------------------------------------------
/deploy/deploy-warp-route/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Interchain ERC20 and ERC721 tokens
3 | ---
4 |
5 | # Warp Routes
6 |
7 | {% content-ref url="deploy-a-warp-route.md" %}
8 | [deploy-a-warp-route.md](deploy-a-warp-route.md)
9 | {% endcontent-ref %}
10 |
11 | ### Overview of Warp Routes
12 |
13 | Warp Routes are Hyperlane's take on the concept of token bridging, allowing you to permissionlessly transfer any ERC20-like asset to any chain via Hyperlane.
14 |
15 | You can combine Warp Routes with a Hyperlane deployment to create economic trade routes between any chain and others already connected through Hyperlane.
16 |
17 | This diagram below illustrates a fairly simplified overview of the flow in creating your Warp Route, and the resulting asset.
18 |
19 | ## Warp Route Architecture
20 |
21 |
22 |
23 | Warp Route contracts transfer value between chains by locking [#collateral-token](../../resources/glossary.md#collateral-token "mention")s on the origin chain (the [#collateral-chain](../../resources/glossary.md#collateral-chain "mention")) and then minting wrapped tokens on the destination chain (the[#synthetic-chain](../../resources/glossary.md#synthetic-chain "mention")).
24 |
25 | Users can redeem their locked tokens at any time by transferring their wrapped tokens back to the collateral chain.
26 |
27 | Like all applications built on top of Hyperlane, Warp Routes have customizable security via [sovereign-consensus](../../protocol/sovereign-consensus/ "mention"). This allows Warp Route deployers to configure and enforce custom rules and constraints that the interchain token must follow.
28 |
29 | Warp Routes can be deployed between any set of chains that have Hyperlane deployments. If you would like to create a Warp Route that includes a chain that Hyperlane is not currently deployed on, feel free to [deploy-hyperlane.md](../deploy-hyperlane.md "mention")yourself!
30 |
31 | {% content-ref url="deploy-a-warp-route.md" %}
32 | [deploy-a-warp-route.md](deploy-a-warp-route.md)
33 | {% endcontent-ref %}
34 |
--------------------------------------------------------------------------------
/deploy/deploy-warp-route/deploy-the-ui-for-your-warp-route.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: A front-end for interchain token transfers
3 | ---
4 |
5 | # Deploy a UI for your Warp Route
6 |
7 | After you [deploy-a-warp-route.md](deploy-a-warp-route.md "mention"), you may want to deploy a UI for it. You can use the [UI template](https://github.com/hyperlane-xyz/hyperlane-warp-ui-template) and customize it to fit your needs.
8 |
9 | ### Configure & Customize the UI
10 |
11 | Follow these [instructions](https://github.com/hyperlane-xyz/hyperlane-warp-ui-template/blob/main/CUSTOMIZE.md) for details on how to configure the UI's tokens and change the default branding assets/theme.
12 |
13 | #### Configure Tokens
14 |
15 | As mentioned in the [customization instructions](https://github.com/hyperlane-xyz/hyperlane-warp-ui-template/blob/main/CUSTOMIZE.md), the UI repo contains a token list (see `./src/consts/tokens.ts)`which must be updated. Here's an example:
16 |
17 | ```typescript
18 | import { WarpTokenConfig } from '../features/tokens/types';
19 |
20 | export const tokenList: WarpTokenConfig = [
21 | {
22 | chainId: 5,
23 | address: '0xb4fbf271143f4fbf7b91a5ded31805e42b2208d6',
24 | hypCollateralAddress: '0x145de8760021c4ac6676376691b78038d3DE9097',
25 | type: 'collateral' // or 'native'
26 | name: 'Weth',
27 | symbol: 'WETH',
28 | decimals: 18,
29 | logoURI: '/logos/weth.png',
30 | },
31 | ];
32 |
33 | ```
34 |
35 | You can replace the `tokens` entry with the output that was written to `hyperlane-deploy/artifacts/warp-ui-token-list.ts` from the [deploy-a-warp-route.md](deploy-a-warp-route.md "mention") instructions.
36 |
37 | #### Configure Chain
38 |
39 | In addition, custom chains also need to be configured, in \`./src/consts/chains.ts\`. This should be the same configuration as the one used in the [#setup](../deploy-hyperlane.md#setup "mention") step when deploying Hyperlane and the [#example-1](deploy-a-warp-route.md#example-1 "mention")when deploying the Warp Route. Here's an example:
40 |
41 |
57 |
58 | ### Deploy the UI
59 |
60 | Since the UI is a Next.js app, you can use your favorite hosting service to host it. We recommend [Vercel](https://vercel.com), which works very well with Next. [Netlify](https://www.netlify.com) and [Fleek](https://fleek.co) are also a good options.
61 |
62 | * Sign up for [Vercel](https://vercel.com/)
63 | * Create a new project
64 | * Connect it to your Git repo
65 | * Hit Deploy!
66 |
67 | And that's it! Now you and your users can use the UI to send tokens from the collateral chain to remote chains, from one remote chain to another, and from any remote chain back to the collateral chain.
68 |
69 | #### Stranded Whale Problem
70 |
71 | A common problem with token bridges like Warp Routes is that a user may transfer a token like USDC to a new chain, but only afterwords realize that they do not have the native gas token to move those tokens anywhere including back. You may consider modifying the UI to warn the users of this situation, or better faucet them some dust of native gas token so improve their experience. You can either do so by modifying the warp route contracts where it holds some balance of the native token and can share that with recipients, or you could build an off-chain service which just observes the[ `ReceivedTransferRemote`](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/11d9d0bf0d5ac9f2f57141e0e7549dd415e0325e/typescript/token/contracts/libs/TokenRouter.sol#L90)transfer the native gas token to the recipient.
72 |
--------------------------------------------------------------------------------
/deploy/permissionless-interoperability.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Deploy Hyperlane - anywhere, anytime
3 | ---
4 |
5 | # Overview
6 |
7 | At present, most interoperability protocols must be permissioned due to their security model. Developers have to request support for their desired networks from interoperability platforms, which is not sustainable as the number of chains increases.
8 |
9 | Hyperlane solves this problem by modularizing security, allowing for permissionless interoperability.
10 |
11 | ## Permissionless interoperability
12 |
13 | Permissionless Interoperability allows you to deploy Hyperlane anywhere, anytime, without needing permission from a Hyperlane team or any external parties. It empowers you to have full control over your project's destiny and brings interoperability features to any blockchain, appchain, or rollup.
14 |
15 | Key features of Hyperlane's permissionless and modular design:
16 |
17 | 1. Expand to any environment without relying on external parties.
18 | 2. Customizable security models with [sovereign-consensus](../protocol/sovereign-consensus/ "mention").
19 | 3. Move value anywhere, permissionlessly.
20 |
21 | Hyperlane believes that permissionless interoperability will drive the adoption of new ecosystems and increase interchain interoperability across all environments. The modular security design minimizes risk, even at the weakest points.
22 |
23 | {% content-ref url="deploy-hyperlane.md" %}
24 | [deploy-hyperlane.md](deploy-hyperlane.md)
25 | {% endcontent-ref %}
26 |
--------------------------------------------------------------------------------
/diagrams/accounts-implementation.md:
--------------------------------------------------------------------------------
1 | ```mermaid
2 | %%{ init: {
3 | "theme": "neutral",
4 | "themeVariables": {
5 | "mainBkg": "#025AA1",
6 | "textColor": "white",
7 | "clusterBkg": "white"
8 | },
9 | "themeCSS": ".edgeLabel { color: black }"
10 | }}%%
11 |
12 | flowchart TB
13 | subgraph Origin Chain
14 | Sender
15 | A_O[InterchainAccountRouter]
16 | M_O[(Mailbox)]
17 | end
18 |
19 | subgraph Destination Chain
20 | M_D[(Mailbox)]
21 | A_D[InterchainAccountRouter]
22 | SenderAccount
23 | Recipient
24 | end
25 |
26 | Sender -- "dispatch(destination, recipient, call)" --> A_O
27 | A_O -- "dispatch(destination, router, \n[sender, recipient, call])" --> M_O
28 | M_O -. "relay" .- M_D
29 | M_D -- "handle(origin, router, \n[sender, recipient, call])" --> A_D
30 | A_D == "interchainAccount(origin, sender)" ==> SenderAccount
31 | SenderAccount -- "call(data)" --> Recipient
32 |
33 | click A_O https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/middleware/InterchainAccountRouter.sol
34 | click A_D https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/middleware/InterchainAccountRouter.sol
35 |
36 | style Sender fill:#efab17
37 | style SenderAccount fill:#efab17
38 | style Recipient fill:#efab17
39 | ```
--------------------------------------------------------------------------------
/diagrams/accounts-simple.md:
--------------------------------------------------------------------------------
1 | ```mermaid
2 | %%{ init: {
3 | "theme": "neutral",
4 | "themeVariables": {
5 | "mainBkg": "#025AA1",
6 | "textColor": "white",
7 | "clusterBkg": "white"
8 | },
9 | "themeCSS": ".edgeLabel { color: black }"
10 | }}%%
11 |
12 | flowchart TB
13 | subgraph Origin Chain
14 | Sender
15 | A_O[API]
16 | end
17 |
18 | subgraph Destination Chain
19 | SenderAccount
20 | Recipient
21 | end
22 |
23 | Sender -- "dispatch(destination, recipient, call)" --> A_O
24 | A_O -. "relay" .- SenderAccount
25 | SenderAccount -- "call(data)" --> Recipient
26 |
27 | click A_O https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/middleware/InterchainAccountRouter.sol
28 | click A_D https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/middleware/InterchainAccountRouter.sol
29 |
30 | style Sender fill:#efab17
31 | style SenderAccount fill:#efab17
32 | style Recipient fill:#efab17
33 | ```
--------------------------------------------------------------------------------
/diagrams/interchain-gas.md:
--------------------------------------------------------------------------------
1 | ```mermaid
2 | %%{ init: {
3 | "theme": "neutral",
4 | "themeVariables": {
5 | "mainBkg": "#025AA1",
6 | "textColor": "white",
7 | "clusterBkg": "white"
8 | },
9 | "themeCSS": ".edgeLabel { color: black }"
10 | }}%%
11 |
12 | flowchart TB
13 | subgraph Origin
14 | Sender
15 | M_O[(Mailbox)]
16 | IGP[InterchainGasPaymaster]
17 | Sender -- "id = dispatch()" --> M_O
18 | Sender -- "payForGas(id)\n{value: payment}" --> IGP
19 | end
20 |
21 | Relayer((Relayer))
22 |
23 | M_O -. "indexing" .-> Relayer
24 | IGP -. "paymaster" .- Relayer
25 |
26 | subgraph Destination
27 | M_D[(Mailbox)]
28 | end
29 |
30 | Relayer -- "process()" --> M_D
31 |
32 | style Sender fill:#efab17
33 |
34 | click IGP https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/igps/InterchainGasPaymaster.sol
35 | ```
36 |
--------------------------------------------------------------------------------
/diagrams/liquidity-layer-simple.md:
--------------------------------------------------------------------------------
1 | ```mermaid
2 | %%{ init: {
3 | "theme": "neutral",
4 | "themeVariables": {
5 | "mainBkg": "#025AA1",
6 | "textColor": "white",
7 | "clusterBkg": "white"
8 | },
9 | "themeCSS": ".edgeLabel { color: black }"
10 | }}%%
11 |
12 | flowchart TB
13 | subgraph origin chain
14 | sender --"dispatchWithTokens()"--> HypO(API)
15 | HypO --> AdapterO(Circle/Portal)
16 |
17 | end
18 |
19 | HypO -."message".-> HypD
20 | AdapterO -."value".-> AdapterD
21 |
22 |
23 | subgraph destination chain
24 | AdapterD(Circle/Portal) --> HypD
25 |
26 |
27 | HypD(API) --"handleWithTokens(Call)"--> recipient(Recipient)
28 | end
29 |
30 | style sender fill:#efab17
31 | style recipient fill:#efab17
32 | style AdapterO fill:green
33 | style AdapterD fill:green
34 | ```
35 |
--------------------------------------------------------------------------------
/diagrams/messaging-isms.md:
--------------------------------------------------------------------------------
1 | ```mermaid
2 | %%{ init: {
3 | "theme": "neutral",
4 | "themeVariables": {
5 | "mainBkg": "#025AA1",
6 | "textColor": "white",
7 | "clusterBkg": "white"
8 | },
9 | "themeCSS": ".edgeLabel { color: black }"
10 | }}%%
11 |
12 | flowchart TB
13 | subgraph Origin Chain
14 | Sender
15 | M_O[(Mailbox)]
16 | Sender -- "dispatch(destination, recipient, body)" --> M_O
17 | end
18 |
19 | subgraph Destination Chain
20 | ISM[InterchainSecurityModule]
21 | Recipient[IMessageRecipient]
22 | M_D[(Mailbox)]
23 |
24 | M_D -- "verify(metadata, [origin, sender, body])" --> ISM
25 | ISM -. "interchainSecurityModule()" .- Recipient
26 | M_D -- "handle(origin, sender, body)" --> Recipient
27 |
28 | end
29 |
30 | M_O -. "relay" .-> M_D
31 |
32 | click M_O https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/Mailbox.sol
33 | click ISM https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/isms/InterchainSecurityModule.sol
34 | click Recipient https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/interfaces/IMessageRecipient.sol
35 | click M_D https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/Mailbox.sol
36 |
37 | style Sender fill:#efab17
38 | style Recipient fill:#efab17
39 | ```
40 |
--------------------------------------------------------------------------------
/diagrams/messaging-simple.md:
--------------------------------------------------------------------------------
1 | ```mermaid
2 | %%{ init: {
3 | "theme": "neutral",
4 | "themeVariables": {
5 | "mainBkg": "#025AA1",
6 | "textColor": "white",
7 | "clusterBkg": "white"
8 | },
9 | "themeCSS": ".edgeLabel { color: black }"
10 | }}%%
11 |
12 | flowchart TB
13 | subgraph Origin Chain
14 | Sender
15 | M_O[(Mailbox)]
16 | Sender -- "dispatch(destination, recipient, body)" --> M_O
17 | end
18 |
19 | subgraph Destination Chain
20 | Recipient[IMessageRecipient]
21 | M_D[(Mailbox)]
22 |
23 | M_D -- "handle(origin, sender, body)" --> Recipient
24 | end
25 |
26 | M_O -. "relay" .-> M_D
27 |
28 | click M_O https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/Mailbox.sol
29 | click Recipient https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/interfaces/IMessageRecipient.sol
30 | click M_D https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/Mailbox.sol
31 |
32 | style Sender fill:#efab17
33 | style Recipient fill:#efab17
34 | ```
35 |
--------------------------------------------------------------------------------
/diagrams/multisig-pos-ism.md:
--------------------------------------------------------------------------------
1 | ```mermaid
2 | %%{ init: {
3 | "theme": "neutral",
4 | "themeVariables": {
5 | "mainBkg": "#025AA1",
6 | "textColor": "white",
7 | "clusterBkg": "white"
8 | },
9 | "themeCSS": ".edgeLabel { color: black }",
10 | "flowchart": {"useMaxWidth": "true" }
11 | }}%%
12 |
13 | flowchart TB
14 | V(("Validator(s)"))
15 | Relayer((Relayer))
16 |
17 | subgraph Origin
18 | Sender
19 | M_O[(Mailbox)]
20 | POS[Proof of Stake]
21 |
22 | Sender -- "dispatch(destination, recipient, body)" --> M_O
23 | end
24 |
25 | subgraph Cloud
26 | aws[(Metadata\nDatabase)]
27 | end
28 |
29 | M_O -. "indexing" .-> Relayer
30 | M_O -. "indexing" .-> V
31 | POS == "staking" === V
32 |
33 | V -- "signatures" --> aws
34 |
35 | subgraph Destination
36 | Recipient
37 | M_D[(Mailbox)]
38 | ISM[MultisigISM]
39 |
40 | M_D -- "verify(metadata, [origin, sender, body])" --> ISM
41 | M_D -- "handle(origin, sender, body)" --> Recipient
42 | ISM -. "interchainSecurityModule()" .- Recipient
43 | end
44 |
45 | Relayer -- "process()" --> M_D
46 |
47 | aws -. "metadata" .-> Relayer
48 | aws -. "moduleType()" .- ISM
49 |
50 | POS -. "validators()" .- ISM
51 |
52 | click ISM https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/isms/MultisigIsm.sol
53 |
54 | style Sender fill:#efab17
55 | style Recipient fill:#efab17
56 | ```
--------------------------------------------------------------------------------
/diagrams/queries-implementation.md:
--------------------------------------------------------------------------------
1 | ```mermaid
2 | %%{ init: {
3 | "theme": "neutral",
4 | "themeVariables": {
5 | "mainBkg": "#025AA1",
6 | "textColor": "white",
7 | "clusterBkg": "white"
8 | },
9 | "themeCSS": ".edgeLabel { color: black }"
10 | }}%%
11 |
12 | flowchart TB
13 | subgraph Origin Chain
14 | Sender
15 | Q_O[InterchainQueryRouter]
16 | M_O[(Mailbox)]
17 | end
18 |
19 | subgraph Destination Chain
20 | M_D[(Mailbox)]
21 | Q_D[InterchainQueryRouter]
22 | Recipient
23 | end
24 |
25 | Sender -- "query(destination, recipient, data, callback)" --> Q_O
26 | Q_O -- "dispatch(destination, router, \n[sender, recipient, data, callback])" --> M_O
27 | M_O -. "relay" .- M_D
28 | M_D -- "handle(origin, router, \n[sender, recipient, data, callback])" --> Q_D
29 | Q_D -- "call(data)" --> Recipient
30 | Recipient -- "result" --> Q_D
31 | M_O -- "handle(destination, router, \n[sender, result, callback])" --> Q_O
32 | Q_D -- "dispatch(origin, router, \n[sender, result, callback])" --> M_D
33 | Q_O -- "callback(result)" --> Sender
34 |
35 | click Q_O https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/middleware/InterchainQueryRouter.sol
36 | click Q_D https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/middleware/InterchainQueryRouter.sol
37 |
38 | style Sender fill:#efab17
39 | style Recipient fill:#efab17
40 | ```
--------------------------------------------------------------------------------
/diagrams/queries-simple.md:
--------------------------------------------------------------------------------
1 | ```mermaid
2 | %%{ init: {
3 | "theme": "neutral",
4 | "themeVariables": {
5 | "mainBkg": "#025AA1",
6 | "textColor": "white",
7 | "clusterBkg": "white"
8 | },
9 | "themeCSS": ".edgeLabel { color: black }"
10 | }}%%
11 |
12 | flowchart BT
13 | subgraph Origin Chain
14 | Sender
15 | Q_O[API]
16 | end
17 |
18 | subgraph Destination Chain
19 | Recipient[Recipient]
20 | end
21 |
22 | Sender -- "query(recipient, data, callback)" --> Q_O
23 | Recipient -- "result" --> Q_O
24 | Q_O -- "call(data)" --> Recipient
25 | Q_O -- "callback(result)" --> Sender
26 |
27 | click Q_O https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/middleware/InterchainQueryRouter.sol
28 | click Q_D https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/middleware/InterchainQueryRouter.sol
29 |
30 | style Sender fill:#efab17
31 | style Recipient fill:#efab17
32 | ```
--------------------------------------------------------------------------------
/diagrams/router.md:
--------------------------------------------------------------------------------
1 | ```mermaid
2 | %%{ init: {
3 | "theme": "neutral",
4 | "themeVariables": {
5 | "mainBkg": "#025AA1",
6 | "textColor": "white",
7 | "clusterBkg": "white"
8 | },
9 | "themeCSS": ".edgeLabel { color: black }"
10 | }}%%
11 |
12 | graph BT
13 | subgraph "Ethereum"
14 | R_E[Router]
15 | Mailbox_E[(Mailbox)]
16 | Mailbox_E -. "mailbox()" .- R_E
17 | end
18 |
19 | subgraph "Polygon"
20 | R_P[Router]
21 | Mailbox_P[(Mailbox)]
22 | Mailbox_P -. "mailbox()" .- R_P
23 | end
24 |
25 | subgraph "Gnosis"
26 | R_G[Router]
27 | Mailbox_G[(Mailbox)]
28 | Mailbox_G -. "mailbox()" .- R_G
29 | end
30 |
31 | R_E -. "routers()" .- R_P -. "routers()" .- R_G
32 | R_G -. "routers()" .- R_E
33 |
34 | style R_E fill:#efab17
35 | style R_P fill:#efab17
36 | style R_G fill:#efab17
37 | ```
38 |
--------------------------------------------------------------------------------
/introduction/getting-started.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: >-
3 | Welcome to Hyperlane! Here are some resources to help you get started building
4 | on the modular interoperability stack.
5 | ---
6 |
7 | # Getting started
8 |
9 | ## For blockchain developers
10 |
11 | #### Permissionless interoperability
12 |
13 | If you have deployed your own chain or rollup and want interoperability for that chain, you can deploy Hyperlane to your chain. Here's how:
14 |
15 | * [deploy-hyperlane.md](../deploy/deploy-hyperlane.md "mention") to the chain of your choice
16 | * [deploy-warp-route](../deploy/deploy-warp-route/ "mention") enable token representations of popular tokens like ETH or USDC on your chain with a working UI out of the box.
17 |
18 | ## For application developers
19 |
20 | Once Hyperlane exists on your desired chains, you can use one of the APIs provided. For each of the APIs, we have [quickstarts](../build-with-hyperlane/quickstarts/ "mention") that folks can use to quickly try out the APIs and see how easy it is to use them. We highly recommend trying the quickstarts first to get a feel for the APIs before diving into the API reference pages.
21 |
22 | **Accounts API**
23 |
24 | You can use the accounts API to have an account make function calls on another chain. For example, a DAO can easily own assets on other chains without needing any remote smart contracts.
25 |
26 | * [accounts.md](../build-with-hyperlane/quickstarts/accounts.md "mention") quickstart
27 | * [accounts.md](../apis-and-sdks/accounts.md "mention") reference
28 |
29 | **Queries API**
30 |
31 | You can use the queries API to read state from a remote chain. For example, you can read a price feed or ENS name on Ethereum from BSC.
32 |
33 | * [queries.md](../build-with-hyperlane/quickstarts/queries.md "mention")quickstart
34 | * [query.md](../apis/query.md "mention") reference
35 |
36 | **Messaging API**
37 |
38 | Anything that doesn't fit in the above, you can use Hyperlane messaging to send and receive arbitrary bytes between your contracts on different chains for maximum flexibility.
39 |
40 | * [messaging.md](../build-with-hyperlane/quickstarts/messaging.md "mention") quickstart
41 | * [messaging-api](../apis/messaging-api/ "mention") reference
42 |
43 | ## Example applications
44 |
45 | Looking for some inspiration? Check out these example applications that have been built on top of Hyperlane
46 |
47 | * [examples.md](../build-with-hyperlane/examples.md "mention")
48 |
49 | ## Hyperlane Explorer
50 |
51 | The [explorer](../build-with-hyperlane/explorer/ "mention") is an excellent tool that allows you to track the status of messages sent over Hyperlane, including messages from/to chains that you deployed Hyperlane on. The [explorer](../build-with-hyperlane/explorer/ "mention")also has an API that you can use to show the status in your user interface.
52 |
53 | ### Help and support
54 |
55 | If you need help using Hyperlane, please reach out on [Discord](https://discord.com/invite/KBD3aD78Bb) or [Twitter](https://twitter.com/hyperlane\_xyz)!
56 |
57 | If you're running into issues once you've begun using Hyperlane, such as messages not getting processed or delivered properly, transaction failures, or other issues check out the [troubleshooting.md](../build-with-hyperlane/troubleshooting.md "mention") pages.
58 |
--------------------------------------------------------------------------------
/operators/agent-configuration/README.md:
--------------------------------------------------------------------------------
1 | # Agent configuration
2 |
3 | All agents use the same method of configuration which is a multi-layered config approach which allows for easy overriding of default configs. Each layer overrides overlapping values in the previous.
4 |
5 | ### Config layers
6 |
7 | 1. Base configuration from "default deployments" are in the [monorepo](https://github.com/hyperlane-xyz/hyperlane-monorepo/tree/main/rust/config) and all of these are loaded automatically.
8 | 2. Config files passed in via the `CONFIG_FILES` env var are loaded next; this env var should be a comma separated list of paths to json files that should be loaded in order from first to last.
9 | 3. `HYP_BASE_` prefixed env vars will be read next.
10 | 4. `HYP__` prefixed env vars are then read and apply ONLY for the current agent. I.e. `RELAYER`, `VALIDATOR`, and `SCRAPER` will only read their respective prefixes.
11 | 5. Command line arguments will be read last
12 |
13 | ### Command line arguments
14 |
15 | Command line arguments are added after the application name, such as`./relayer --originChainNames="test1,test2,test3"`
16 |
17 | The following formats are supported:
18 |
19 | * `--argName argValue`
20 | * `--argName "argValue"`
21 | * `--argName 'argValue'`
22 | * `--argName=argValue`
23 | * `--argName="argValue"`
24 | * `--argName='argValue'`
25 |
26 | Argument names are case-insensitive, so in this guide we may show them in camel-case for easier reading, but `--argName` is equivalent to `--ARGNAME` and `--argname.`
27 |
28 | Examples:
29 |
30 | * `{ "db": "/path/to/dir" }` can be set with `--db "/path/to/dir"`
31 | * `{ "chains": { "ethereum": { "name": "ethereum" } } }` (abbreviated as `chains.ethereum.name` or `chains..name`) can be set with `--chains.ethereum.name ethereum`
32 | * `{ "chains": { "avalanche": { "connection": { "url": "https://some-url.com" } } } }` (abbreviated as `chains.avalanche.connection.url` or `chains..connection.url`) can be set with `--chains.avalanche.connection.url "https://some-url.com"`
33 |
34 | ### Environment variables
35 |
36 | The config file format is the preferred way to set things which are not secret and do not need to change for each run as it is the easiest format to inspect and edit. Every config value in the file can be set as an env var if you use the correct name, however, there are a few env vars that cannot be set in the config such as `CONFIG_FILES`.
37 |
38 | `HYP_BASE_` and `HYP__` are equivalent prefixes with the only difference being which order they are loaded in and can refer to all of the config values in the config files.
39 |
40 | The env name will be one of those two prefixes, and then the underscore-separated path of the uppercased path components to the config value.
41 |
42 | For example:
43 |
44 | * `{ "db": "/path/to/dir" }` can be set with `HYP_BASE_DB="/path/to/dir"` or `HYP_RELAYER_DB="/path/to/dir"`
45 | * `{ "chains": { "ethereum": { "name": "ethereum" } } }` (abbreviated as `chains.ethereum.name` or `chains..name`) can be set with `HYP_BASE_CHAINS_ETHEREUM_NAME="ethereum"` or `HYP_VALIDATOR_CHAINS_ETHEREUM_NAME="ethereum"` or `HYP_RELAYER_CHAINS_ETHEREUM_NAME="ethereum"` ...
46 | * `{ "chains": { "avalanche": { "connection": { "url": "https://some-url.com" } } } }` (abbreviated as `chains.avalanche.connection.url` or `chains..connection.url`) can be set with `HYP_BASE_CHAINS_AVALANCHE_CONNECTION_URL="https://some-url.com"` or `HYP_BASE_VALIDATOR_AVALANCHE_CONNECTION_URL="https://some-url.com"` and so on...
47 |
48 | ### Config files with Docker
49 |
50 | Running with the agent in Docker adds an extra layer of complexity because the config files need to be accessible from within the Docker container. The base configs that can be found in [the repo](https://github.com/hyperlane-xyz/hyperlane-monorepo/tree/main/rust/config) are already part of the provided Docker image and will all be loaded by default.
51 |
52 | Mounting a single config file can be done with the flag `--mount type=bind,source=$LOCAL_CONFIG_PATH,target=/config/$CONFIG_NAME,readonly` and then adding the config file to `CONFIG_FILES` so it is loaded.
53 |
54 | Mounting an entire directory can be done with the flag `--mount source=$LOCAL_CONFIG_DIR_PATH,target=/config,readonly` then adding the individual config files to `CONFIG_FILES` that you want so they are loaded.
55 |
56 | For example, suppose you have a config file at your local machine's path `/home/workspace/ethereum.json` and want to run the validator with it.
57 |
58 | {% code title="Example" overflow="wrap" %}
59 | ```bash
60 | docker run -it --mount type=bind,source=/home/workspace/ethereum.json,target=/config/ethereum.json,readonly -e CONFIG_FILES=/config/ethereum.json $DOCKER_IMAGE ./validator
61 | ```
62 | {% endcode %}
63 |
64 | The `source` path is the path on your local machine, the `target` path is where the source path contents will be made available within the Docker container, and the `CONFIG_FILES` should specify config(s) from the target path.
65 |
--------------------------------------------------------------------------------
/operators/agent-keys/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Generate private keys for running Validators and Relayers
3 | ---
4 |
5 | # Agent keys
6 |
7 | Hyperlane agents must be configured with private keys in order to operate. [validators.md](../../protocol/agents/validators.md "mention") use private keys to sign attestations, and [relayer.md](../../protocol/agents/relayer.md "mention") use private keys to sign transactions that deliver messages.
8 |
9 | Hyperlane agents currently support being configured with private keys in one of two ways.
10 |
11 | ## 1. Hexadecimal keys
12 |
13 | A raw hexadecimal private key used for in-memory signing. This is the recommended setup for testing or development purposes, but not recommended for production. Hexadecimal keys are **especially** discouraged for production validators.
14 |
15 | {% content-ref url="hexadecimal-key-setup.md" %}
16 | [hexadecimal-key-setup.md](hexadecimal-key-setup.md)
17 | {% endcontent-ref %}
18 |
19 | ## 2. AWS KMS
20 |
21 | A key generated by AWS and stored in a CloudHSM. This is the recommended setup for production agents, **especially** for validators.
22 |
23 | {% content-ref url="aws-setup.md" %}
24 | [aws-setup.md](aws-setup.md)
25 | {% endcontent-ref %}
26 |
27 |
--------------------------------------------------------------------------------
/operators/agent-keys/aws-setup.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Generate a key using AWS KMS CloudHSM
3 | ---
4 |
5 | # AWS KMS keys
6 |
7 | Using AWS KMS keys in your agents is recommended for production environments.
8 |
9 | {% hint style="info" %}
10 | For non-production environments, it may be faster to configure your agents with [hexadecimal-key-setup.md](hexadecimal-key-setup.md "mention")
11 | {% endhint %}
12 |
13 | ### 1. Create an IAM user
14 |
15 | This IAM user will be given permission to sign with the KMS key that you will later configure. Your Hyperlane agent will use this identity when signing transactions.
16 |
17 | 1. Go to AWS's Identity and Access Management (IAM) in the [AWS console](https://us-east-1.console.aws.amazon.com/iamv2/home).
18 | 2. On the left, under "Access management", click "Users".
19 | 3. Click the blue button "Add users".
20 | 4. Pick a friendly and informative username, like `hyperlane-validator-${chain_name}` or `hyperlane-relayer-${chain_name}`. This username will be referenced in future steps, so if you choose a different username be sure to use your correct username in the future.
21 | 5. Click "Next", you do not need to assign the user any permissions.
22 | 6. Click "Create user".
23 | 7. Click into the user that you just created
24 | 8. Click the "Security Credentials" tab
25 | 9. Scroll down to "Access Keys" and click "Create Access Key"
26 | 10. Select "Application running outside AWS" and click "Next"
27 | 11. Click "Next", no need to add a description tag
28 | 12. Click "Create access key"
29 | 13. Copy the "Access key ID" and "Secret access key" to a safe place. These will be passed to your Hyperlane relayer as environment variables.
30 |
31 | ### 2. Create a KMS key
32 |
33 | This key will be used by your agent for signing.
34 |
35 | 1. Go to AWS's Key Management Service (KMS) in the AWS console.
36 | 2. Ensure you are in the region you want to create the key in. This can be confirmed by viewing the region at the top right of the console, or by finding the name in the URL's subdomain (e.g. `us-west-2.console.aws.amazon.com` means you're operating in the region `us-west-2`).
37 | 3. On the left, click "Customer managed keys".
38 | 4. Click "Create key".
39 | 5. Select the "Asymmetric" key type.
40 | 6. Select the "Sign and verify" key usage.
41 | 7. Select the `ECC_SECG_P256K1` key spec.
42 | 8. Click "Next".
43 | 9. Set the Alias to something friendly and informative, like `hyperlane-validator-signer-${chain_name}` or `hyperlane-relayer-signer-${chain_name}`
44 | 10. While not necessary, feel free to write a description and add any tags that you think will be useful.
45 | 11. Click "Next".
46 | 12. A key administrator is not required, but if you want, you can select one.
47 | 13. Click "Next".
48 | 14. Give usage permissions to the IAM user you created in section [#1.-create-an-iam-user](aws-setup.md#1.-create-an-iam-user "mention")
49 | 15. Click "Next".
50 | 16. In the Review page, scroll to the "Key policy". The generated key policy is acceptable, but you can make the access even less permissive if you wish by:
51 | 1. Removing the `kms:DescribeKey` and `kms:Verify` actions from the statement whose "Sid" is "Allow use of the key"
52 | 2. Removing the entire statement whose "Sid" is "Allow attachment of persistent resources".
53 | 17. Click "Finish"
54 |
55 | ### 3. Query address
56 |
57 | In some cases you may need to know the address associated with the KMS key you generated.
58 |
59 | The script at the following repo will allow you to query this address: [https://github.com/tkporter/get-aws-kms-address](https://github.com/tkporter/get-aws-kms-address)
60 |
--------------------------------------------------------------------------------
/operators/agent-keys/hexadecimal-key-setup.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Generating a raw hexadecimal key
3 | ---
4 |
5 | # Hexadecimal keys
6 |
7 | Using hexadecimal keys is the easiest and fastest way to configure Hyperlane agents.
8 |
9 | {% hint style="warning" %}
10 | Hexadecimal keys are not recommended for production environments, for which [aws-setup.md](aws-setup.md "mention") are recommended.
11 | {% endhint %}
12 |
13 | ### Generate a hexadecimal key
14 |
15 | Keep track of your address and private key for use with your agent.
16 |
17 | {% tabs %}
18 | {% tab title="Cast CLI" %}
19 | Using [Foundry's cast](https://book.getfoundry.sh/cast/), you can create a new key pair:
20 |
21 | {% code overflow="wrap" %}
22 | ```sh
23 | cast wallet new
24 | ```
25 | {% endcode %}
26 |
27 | The output will look something like this:
28 |
29 | {% code overflow="wrap" %}
30 | ```
31 | Successfully created new keypair.
32 | Address: 0x32e6d32E7b1C8691Ef4ad3841003371214a0eebC
33 | Private Key: 0x2958f0eb2ab71bbfb5ea1422835e20e488778b61e3c107f369572e2b53b578f9
34 | ```
35 | {% endcode %}
36 | {% endtab %}
37 |
38 | {% tab title="Using privatekeys.pw" %}
39 | You can visit [https://privatekeys.pw/keys/ethereum/random](https://privatekeys.pw/keys/ethereum/random), which will automatically display a list of hexadecimal private keys and their addresses.
40 |
41 | {% hint style="warning" %}
42 | Please note that because these are generated by a website, these private keys should be considered insecure and should not be used for anything other than testing purposes!
43 | {% endhint %}
44 | {% endtab %}
45 | {% endtabs %}
46 |
--------------------------------------------------------------------------------
/operators/relayers/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Everything you need to start running a relayer
3 | ---
4 |
5 | # Relayers
6 |
7 | Hyperlane [relayer.md](../../protocol/agents/relayer.md "mention") deliver interchain messages to their recipients.
8 |
9 | Every Hyperlane message requires two transactions to be delivered, one on the origin chain to [send.md](../../apis/messaging-api/send.md "mention") the message, and one on the destination chain to [receive.md](../../apis/messaging-api/receive.md "mention") the messages. Relayers are responsible for sending the second transaction.
10 |
11 | ```mermaid
12 | %%{ init: {
13 | "theme": "neutral",
14 | "themeVariables": {
15 | "mainBkg": "#025AA1",
16 | "textColor": "white",
17 | "clusterBkg": "white"
18 | },
19 | "themeCSS": ".edgeLabel { color: black }"
20 | }}%%
21 |
22 | flowchart TB
23 | subgraph Origin
24 | Sender
25 | M_O[(Mailbox)]
26 | IGP[InterchainGasPaymaster]
27 | Sender -- "id = dispatch()" --> M_O
28 | Sender -- "payForGas(id)\n{value: payment}" --> IGP
29 | end
30 |
31 | Relayer((Relayer))
32 |
33 | M_O -. "indexing" .-> Relayer
34 | IGP -. "paymaster" .- Relayer
35 |
36 | subgraph Destination
37 | M_D[(Mailbox)]
38 | end
39 |
40 | Relayer -- "process()" --> M_D
41 |
42 | style Sender fill:#efab17
43 |
44 | click IGP https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/igps/InterchainGasPaymaster.sol
45 | ```
46 |
47 | Hyperlane relayers are configured to relayer messages between one or more origin chains and destination chains. Relayers have no special permissions in Hyperlane. If relayer keys are compromised, only the tokens held by those keys are at risk.
48 |
49 | Running a relayer requires the following:
50 |
51 | #### RPC nodes
52 |
53 | Relayers use RPC nodes to read the origin chain(s), and deliver messages to the destination chain(s). Relayers must be configured with an RPC node for all origin and destination chains.
54 |
55 | #### One or more signing keys
56 |
57 | In order to deliver messages, relayers must be configured with a signing key for each destination chain.
58 |
59 | The relayer uses this key to sign `Mailbox.process()` transactions. The Hyperlane relayer agent currently supports configuration with AWS KMS keys that are accessed via API keys/secrets or raw hexadecimal private keys.
60 |
61 | #### A machine to run on
62 |
63 | Relayers can compile the Rust binary themselves, or run a Docker image provided by Abacus Works. The binary can be run using your favorite cloud service.
64 |
--------------------------------------------------------------------------------
/operators/relayers/message-filtering.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Configure which messages to relay, and which to ignore
3 | ---
4 |
5 | # Message filtering
6 |
7 | By default, the relayer will attempt to deliver messages sent from its origin chain to any of the configured destination chains.
8 |
9 | Relayers may want to further filter the messages they attempt to deliver. For example, someone building an interchain app may want to run a relayer that only delivers messages sent to that application. Similarly, some relayers may wish to only relay messages to a subset of available chains.
10 |
11 | Relayers may **optionally** filter the messages they deliver by setting the `--whitelist` or `--blacklist` environment variables. See also the configuration reference's[#whitelist](../agent-configuration/configuration-reference.md#whitelist "mention") and[#blacklist](../agent-configuration/configuration-reference.md#blacklist "mention") sections.
12 |
13 | These configs are stringified JSON objects with the following format:
14 |
15 | ```typescript
16 | // A list of matching rules. A message matches if any of the list
17 | // elements matches the message.
18 | type MatchingList = Array;
19 |
20 | // Matches a message if any of the provided values matches.
21 | interface ListElement {
22 | originDomain?: NumericFilter
23 | senderAddress?: HashFilter
24 | destinationDomain?: NumericFilter
25 | recipientAddress?: HashFilter
26 | }
27 |
28 | type NumericFilter = Wildcard | U32 | Array;
29 | type HashFilter = Wildcard | H256 | Array;
30 |
31 | // 32-bit unsigned integer
32 | type U32 = number | string;
33 | // 256-bit hash (can also be less) encoded as hex
34 | type H256 = string;
35 | // Matches anything
36 | type Wildcard = "*";
37 | ```
38 |
39 | Both the whitelist and blacklists have "any" semantics. In other words, the relayer will deliver messages that match _any_ of the whitelist filters, and ignore messages that match _any_ of the blacklist filters.
40 |
41 | For example, the following config used as a whitelist will ensure the relayer will relay any messages sent to Ethereum, any messages sent from address `0xca7f632e91B592178D83A70B404f398c0a51581F` to either Celo or Avalanche, and any messages sent to address `0xca7f632e91B592178D83A70B404f398c0a51581F` on Arbitrum or Optimism.
42 |
43 | ```json
44 | [
45 | {
46 | senderAddress: "*",
47 | destinationDomain: ["1"],
48 | recipientAddress: "*"
49 | },
50 | {
51 | senderAddress: "0xca7f632e91B592178D83A70B404f398c0a51581F",
52 | destinationDomain: ["42220", "43114"],
53 | recipientAddress: "*"
54 | },
55 | {
56 | senderAddress: "*",
57 | destinationDomain: ["42161", "420"],
58 | recipientAddress: "0xca7f632e91B592178D83A70B404f398c0a51581F"
59 | }
60 | ]
61 | ```
62 |
63 | A valid config may look like
64 |
65 | ```bash
66 | --whitelist='[{"senderAddress":"*","destinationDomain":["1"],"recipientAddress":"*"},{"senderAddress":"0xca7f632e91B592178D83A70B404f398c0a51581F","destinationDomain":["42220","43114"],"recipientAddress":"*"},{"senderAddress":"*","destinationDomain":["42161","420"],"recipientAddress":"0xca7f632e91B592178D83A70B404f398c0a51581F"}]'
67 | ```
68 |
69 | The blacklist supersedes the whitelist, i.e. if a message matches both the whitelist _and_ the blacklist, it will not be delivered.
70 |
--------------------------------------------------------------------------------
/operators/running-with-docker-compose.md:
--------------------------------------------------------------------------------
1 | # Running with docker compose
2 |
3 | Sometimes it is nice to not rely on long docker commands. Running with docker compose is very similar to using raw docker and you can find a full specification of the format in the [docker docs](https://docs.docker.com/compose/compose-file/).
4 |
5 | This is an example docker-compose file for running a validator that should get you most of the way.
6 |
7 | {% code title="ethereum_validator.json" %}
8 | ```json
9 | {
10 | "chains": {
11 | "ethereum": {
12 | "connection": {
13 | "type": "httpQuorum",
14 | "urls": "https://node1.com,https://node2.com,https://node3.com"
15 | }
16 | }
17 | },
18 | "originchainname": "ethereum",
19 | "validator": {
20 | "id": "alias/validator-signer-ethereum",
21 | "type": "aws",
22 | "region": "us-east-1"
23 | },
24 | "checkpointsyncer": {
25 | "bucket": "signatures-ethereum",
26 | "region": "us-east-1",
27 | "type": "s3"
28 | },
29 | "reorgperiod": 1,
30 | "interval": 30,
31 | "metrics": "9090"
32 | }
33 | ```
34 | {% endcode %}
35 |
36 | {% code title="compose.yml" %}
37 | ```yaml
38 | services:
39 | ethereum-validator:
40 | image: gcr.io/abacus-labs-dev/hyperlane-agent:1fff74e-20230614-005705
41 | command: ./validator
42 | ports:
43 | - "9090:9090/tcp"
44 | environment:
45 | CONFIG_FILES: /ethereum_validator.json
46 | AWS_ACCESS_KEY_ID: somesecretkey
47 | AWS_SECRET_ACCESS_KEY: somesecretkey
48 | configs:
49 | - ethereum_validator.json
50 | configs:
51 | ethereum_validator.json:
52 | file: ./ethereum_validator.json
53 | ```
54 | {% endcode %}
55 |
56 | The above has a lot of filler values, you will of course need to update those with real ones.
57 |
58 | You can also specify multiple services, so if you are running several validators, you can specify each one under `services`.
59 |
60 | To run the compose configuration use `docker compose up` and `docker compose down` to clean up after. Full documentation on the command line can be found on the [docker website](https://docs.docker.com/engine/reference/commandline/compose/).
61 |
--------------------------------------------------------------------------------
/operators/validators/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Everything you need to start running a validator
3 | ---
4 |
5 | # Validators
6 |
7 | Hyperlane [validators.md](../../protocol/agents/validators.md "mention") are not networked with other validators and do not regularly submit transactions. Hyperlane validators are run on a per-origin-chain basis, and these instructions are written for a single chain.
8 |
9 | ```mermaid
10 | %%{ init: {
11 | "theme": "neutral",
12 | "themeVariables": {
13 | "mainBkg": "#025AA1",
14 | "textColor": "white",
15 | "clusterBkg": "white"
16 | },
17 | "themeCSS": ".edgeLabel { color: black }",
18 | "flowchart": {"useMaxWidth": "true" }
19 | }}%%
20 |
21 | flowchart TB
22 | V(("Validator(s)"))
23 | Relayer((Relayer))
24 |
25 | subgraph Origin
26 | Sender
27 | M_O[(Mailbox)]
28 | POS[Proof of Stake]
29 |
30 | Sender -- "dispatch(destination, recipient, body)" --> M_O
31 | end
32 |
33 | subgraph Cloud
34 | aws[(Metadata\nDatabase)]
35 | end
36 |
37 | M_O -. "indexing" .-> Relayer
38 | M_O -. "indexing" .-> V
39 | POS == "staking" === V
40 |
41 | V -- "signatures" --> aws
42 |
43 | subgraph Destination
44 | Recipient
45 | M_D[(Mailbox)]
46 | ISM[MultisigISM]
47 |
48 | M_D -- "verify(metadata, [origin, sender, body])" --> ISM
49 | M_D -- "handle(origin, sender, body)" --> Recipient
50 | ISM -. "interchainSecurityModule()" .- Recipient
51 | end
52 |
53 | Relayer -- "process()" --> M_D
54 |
55 | aws -. "metadata" .-> Relayer
56 | aws -. "moduleType()" .- ISM
57 |
58 | POS -. "validators()" .- ISM
59 |
60 | click ISM https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/isms/MultisigIsm.sol
61 |
62 | style Sender fill:#efab17
63 | style Recipient fill:#efab17
64 | ```
65 |
66 | Running a validator simply requires the following:
67 |
68 | #### An RPC node
69 |
70 | Validators make simple view calls to read merkle roots from the [`Mailbox`](../../protocol/messaging.md) contract on the chain they are validating for.
71 |
72 | {% hint style="warning" %}
73 | Operating a validator for Polygon mainnet requires access to an archive node. This is because validators should only sign roots once they've been finalized, and Polygon requires 256 block confirmations to achieve finality.
74 | {% endhint %}
75 |
76 | #### A secure signing key
77 |
78 | Validators use this key to sign the `Mailbox's` latest merkle root. Securing this key is important. If it is compromised, attackers can attempt to falsify messages, causing the validator to be slashed.
79 |
80 | The Hyperlane validator agent currently supports signing with AWS KMS keys that are accessed via API keys/secrets as well as hexadecimal plaintext keys for testing. See more under [agent-keys](../agent-keys/ "mention").
81 |
82 | #### Publicly readable storage
83 |
84 | Validators write their signatures off-chain to publicly accessible, highly available, storage, so that they can be aggregated by [relayer.md](../../protocol/agents/relayer.md "mention").
85 |
86 | The Hyperlane validator agent currently supports storing signatures on AWS S3 using the same AWS API key above, as well as storing signatures in the local filesystem for testing.
87 |
88 | #### A machine to run on
89 |
90 | Validators can compile the Rust binary themselves or run a Docker image provided by Abacus Works. The binary can be run using your favorite cloud service. You can even run multiple instances of them in different regions for high availability, as Hyperlane has no notion of "double signing".
91 |
--------------------------------------------------------------------------------
/operators/validators/aws-setup.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Configure your signing key and S3 bucket
3 | ---
4 |
5 | # AWS setup
6 |
7 | {% hint style="info" %}
8 | These instructions are for a production environment where validator keys exist in AWS's Key Management Service and validator signatures are posted publicly in an S3 bucket.
9 |
10 | If you're only intending to run a validator for testing or development purposes, consider the [#local-setup](setup.md#local-setup "mention") instead.
11 | {% endhint %}
12 |
13 | ### 1. Create an AWS IAM user and KMS key
14 |
15 | Follow the instructions for [aws-setup.md](../agent-keys/aws-setup.md "mention") to generate an AWS IAM user and KMS key. You will use this user and key in the following steps.
16 |
17 | {% content-ref url="../agent-keys/aws-setup.md" %}
18 | [aws-setup.md](../agent-keys/aws-setup.md)
19 | {% endcontent-ref %}
20 |
21 | ### 2. Create an S3 bucket
22 |
23 | Your validator will post their signatures to this bucket.
24 |
25 | 1. Go to AWS's S3 in the AWS console.
26 | 2. On the right, click the orange "Create Bucket" button
27 | 3. Pick an informative bucket name, such as `hyperlane-validator-signatures-${validator_name}-${chain_name}`
28 | 4. Consider choosing the same region as the KMS key you created in the previous step.
29 | 5. Keep the recommended "ACLs disabled" setting for object ownership.
30 | 6. Configure public access settings so that relayers can read your signatures
31 | 1. Uncheck "Block all public access"
32 | 2. Check the first two options that block access via access control lists
33 | 3. Leave the last two options unchecked, we will be granting public read access via a bucket policy
34 | 4. Acknowledge that these settings may result in public access to your bucket
35 | 7. The remaining default settings are fine, click the orange "Create bucket" button on the bottom
36 |
37 | ### 3. Configure S3 bucket permissions
38 |
39 | Your validator IAM user will need write permissions, and it should be publicly readable by relayers.
40 |
41 | 1. Navigate back to "Identity and Access Management (IAM)" in the AWS console
42 | 2. Under "IAM resources" you should see at least one "User", click into that
43 | 3. Click on the name of the user that you provisioned earlier (e.g. `hyperlane-validator-${chain_name}`)
44 | 4. Copy the "User ARN" to your clipboard, it should look something like `arn:aws:iam::791444913613:user/hyperlane-validator-${chain_name}`
45 | 5. Navigate back to "S3" in the AWS console
46 | 6. Click on the name of the bucket you just created
47 | 7. Just under the name of the bucket, click "Permissions"
48 | 8. Scroll down to "Bucket policy" and click "Edit"
49 | 9. Enter the following contents. The Bucket ARN is shown just above where you enter the policy
50 |
51 | ```json
52 | {
53 | "Version": "2012-10-17",
54 | "Statement": [
55 | {
56 | "Effect": "Allow",
57 | "Principal": "*",
58 | "Action": [
59 | "s3:GetObject",
60 | "s3:ListBucket"
61 | ],
62 | "Resource": [
63 | "${BUCKET_ARN}",
64 | "${BUCKET_ARN}/*"
65 | ]
66 | },
67 | {
68 | "Effect": "Allow",
69 | "Principal": {
70 | "AWS": "${USER_ARN}"
71 | },
72 | "Action": [
73 | "s3:DeleteObject",
74 | "s3:PutObject"
75 | ],
76 | "Resource": "${BUCKET_ARN}/*"
77 | }
78 | ]
79 | }
80 | ```
81 |
--------------------------------------------------------------------------------
/operators/validators/monitoring-and-alerting.md:
--------------------------------------------------------------------------------
1 | # Monitoring and alerting
2 |
3 | Validators expose metrics on the port number specified by the argument `--metrics`. Port `9090` is the default, though any valid port can be chosen.
4 |
5 | {% hint style="info" %}
6 | If running as a Docker image, make sure to port-forward the metrics endpoint port. For, instance, to forward port 9090 on the local port 80, add the following flag to your `docker run` command: `-p 9090:80`
7 | {% endhint %}
8 |
9 | We also provide a mostly-ready-to-go Grafana dashboard to get you started, you can find the source and instructions for importing it under [tools/grafana](https://github.com/hyperlane-xyz/hyperlane-monorepo/tree/main/tools/grafana). If you want to use your own, the `hyperlane_latest_checkpoint` is the most critical metric in both the `phase="validator_observed"` and `phase="validator_processed"` dimension. It should gradually increase and the two should never really be out of sync.
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@hyperlane-xyz/docs",
3 | "description": "Private docs package",
4 | "version": "0.0.0",
5 | "devDependencies": {
6 | "@hyperlane-xyz/core": "^1.4.2",
7 | "@hyperlane-xyz/sdk": "^1.4.2",
8 | "@hyperlane-xyz/hyperlane-token": "^1.4.2",
9 | "@hyperlane-xyz/helloworld": "^1.4.2",
10 | "@types/node": "^18.11.18",
11 | "glob": "^8.1.0",
12 | "markdown-table": "^3.0.3",
13 | "remark-cli": "^11.0.0",
14 | "remark-lint-no-dead-urls": "^1.1.0",
15 | "remark-mdx": "^2.3.0",
16 | "remark-validate-links": "^12.1.0"
17 | },
18 | "packageManager": "yarn@3.2.0",
19 | "private": true,
20 | "type": "module",
21 | "scripts": {
22 | "sync": "node sync-addresses.js | grep -v 'duplicate definition' > ./resources/addresses.md && node sync-partials.js && node sync-config.js > resources/security.md",
23 | "lint": "remark . --quiet --frail"
24 | },
25 | "remarkConfig": {
26 | "plugins": [
27 | "remark-validate-links",
28 | "remark-lint-no-dead-urls"
29 | ]
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/protocol/agents/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: The off-chain actors that power the Hyperlane protocol
3 | ---
4 |
5 | # Agents
6 |
7 | Like most intricate protocols, the Hyperlane protocol is operated by a set of off-chain agents. These agents are critical for the overall function of the network. In its quest for maximal decentralization, Hyperlane seeks to keep these roles permissionless, so that anyone willing and able can take an active role in operating the protocol.
8 |
9 | For convenience, Hyperlane implements these agents as a set of Rust binaries.
10 |
11 | 1. [validators.md](validators.md "mention") sign [messaging.md](../messaging.md "mention")merkle roots, and make their signatures available to relayers.
12 | 2. [relayer.md](relayer.md "mention") aggregate off-chain metadata for [interchain-security-modules.md](../sovereign-consensus/interchain-security-modules.md "mention") and deliver messages to their recipients
13 | 3. [processor.md](processor.md "mention") observe the network for fraud by [validators.md](validators.md "mention"). If detected, watchtowers submit evidence to the origin chain, slashing the fraudulent validator(s).
14 |
--------------------------------------------------------------------------------
/protocol/agents/processor.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Watchtowers observe the network for validator fraud
3 | ---
4 |
5 | # Watchtowers
6 |
7 | {% hint style="warning" %}
8 | `Watchtowers` are coming soon and is not yet implemented. This page is shown for informational purposes only. Details may change as the design matures.
9 | {% endhint %}
10 |
11 | [validators.md](validators.md "mention") are responsible for signing attestations of [messaging.md](../messaging.md "mention") state on the origin chain. These attestations can be consumed by [interchain-security-modules.md](../sovereign-consensus/interchain-security-modules.md "mention") to prove the validity of interchain messages on the destination chain.
12 |
13 | But who watches them? Who makes sure they perform their role dutifully, without fault? The Watchtowers!
14 |
15 | Watchtowers are responsible for observing a [messaging.md](../messaging.md "mention") and validator signatures to detect if validators are attempting to censor or falsify messages. They are a permissionless agent by which the network protects against fraud.
16 |
17 | If fraud is detected, the watchtower submits evidence to the origin chain, slashing the validator. Watchtowers earn a reward for successfully submitting evidence of fraud.
18 |
19 | The presence of one or more watchtowers acts to deter misbehavior by validators.
20 |
21 | For convenience, Abacus Works will run an open source and configurable watchtower agent, implemented as a rust binary. Watchtowers will remain an open source and permissionless role. Applications could run watchtowers, but so could validators, relayers, and any other stakeholder in the Hyperlane ecosystem.
22 |
23 |
--------------------------------------------------------------------------------
/protocol/agents/relayer.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Relayers deliver interchain messages to their recipients
3 | ---
4 |
5 | # Relayers
6 |
7 | Relayers are responsible for ensuring messages are delivered to their recipients. Relayers are a permissionless but integral part of the Hyperlane protocol. Anyone can run a relayer.
8 |
9 | {% hint style="info" %}
10 | Want to run a relayer? Follow the instructions at [relayers](../../operators/relayers/ "mention")
11 | {% endhint %}
12 |
13 | Relayers are configured to relay messages from one or more origin chains to one or more destination chains. A relayer observes the [messaging.md](../messaging.md "mention") on the origin chain, watching for new messages. When a new message is detected, the relayer queries the destination chain to determine the message recipient's [interchain-security-modules.md](../sovereign-consensus/interchain-security-modules.md "mention").
14 |
15 | The relayer is then responsible for aggregating the metadata needed by that ISM. This will vary by ISM, and may include signatures from one or more [validators.md](validators.md "mention"), merkle proofs, zero knowledge proofs, and more!
16 |
17 | Finally, relayers deliver the message to its recipient by calling `Mailbox.process()` on the destination chain with the aforementioned metadata.
18 |
19 | Relayers do not receive direct token incentives from the protocol, but relayers can configure their fee structure for the messages they process, enabling them to earn revenue streams for providing their critical service.
20 |
21 | Relayers can easily configure the messages that they wish to process. Currently, the relayer will support:
22 |
23 | 1. A sender/recipient whitelist
24 | 2. A sender/recipient blacklist
25 | 3. The ability to accept [payments on the origin chain](../../sdks/building-applications/nodejs-sdk/gas.md) as for processing a message on the destination chain.
26 |
27 | For convenience, Abacus Works will run an open source and configurable relayer agent, implemented as a rust binary. If you'd like to run your own relayer, we've open sourced the [binary here](https://github.com/hyperlane-xyz/hyperlane-monorepo/tree/main/rust/agents/relayer).
28 |
29 | Eventually, we envision a robust marketplace of relayers, each providing unique transaction processing services with different fee structures. Additionally, it is possible that relayers will eventually receive token incentives from the protocol for the services they provide.
30 |
31 | #### Error handling
32 |
33 | The relayer may be configured to retry messages when processing fails. Messages that fail to process on the first attempt will cause the relayer to retry with exponential backoff. After a maximum amount of retries, the relayer will no longer attempt to process the message.
34 |
--------------------------------------------------------------------------------
/protocol/agents/validators.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Validators help secure the Hyperlane protocol
3 | ---
4 |
5 | # Validators
6 |
7 | Validators are responsible for observing the [messaging.md](../messaging.md "mention") contract and signing its merkle root, facilitating message transmission to remote chains.
8 |
9 | Unlike many other protocols, Hyperlane does **not** have an enshrined validator set. Anyone is free to run a validator and help contribute to securing interchain messages.
10 |
11 | {% hint style="info" %}
12 | Want to run a validator? Follow the instructions at [validators](../../operators/validators/ "mention")
13 | {% endhint %}
14 |
15 | Validators read the current merkle root by calling `Mailbox.latestCheckpoint()`. Once a root has achieved sufficient [finality](https://medium.com/mechanism-labs/finality-in-blockchain-consensus-d1f83c120a9a), validators are expected to sign it and post their signature to highly available storage so that it can be aggregated by [relayer.md](relayer.md "mention").
16 |
17 | ```solidity
18 | /**
19 | * @notice Returns the latest checkpoint for validators to sign.
20 | * @return root Latest checkpointed root
21 | * @return index Latest checkpointed index
22 | */
23 | function latestCheckpoint()
24 | external
25 | view
26 | returns (bytes32 root, uint256 index);
27 | ```
28 |
29 | Validators that sign anything other than a finalized checkpoint risk compromising the safety of the protocol. If they are participating in [proof-of-stake.md](../proof-of-stake.md "mention"), this may result in their stake being slashed.
30 |
31 | Abacus Works is developing the validator as a Rust binary that can be easily run by anyone. Operationally, validators need to run this binary and a node for the chain that they are validating for. We hope that the majority of Hyperlane validators will come from each chain's existing node operator community.
32 |
33 |
--------------------------------------------------------------------------------
/protocol/interchain-gas-payments.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Pay for message delivery on the origin chain
3 | ---
4 |
5 | # Interchain gas payments
6 |
7 | Successful interchain messages require two transactions; one on the origin chain to send the message, and one on the destination chain to deliver the message.
8 |
9 | For convenience, Hyperlane provides an on-chain API on the origin chain that allows message senders to pay one or more [relayers](../operators/relayers/ "mention") to deliver a message on the destination chain. This payment is called an interchain gas payment.
10 |
11 | ```mermaid
12 | %%{ init: {
13 | "theme": "neutral",
14 | "themeVariables": {
15 | "mainBkg": "#025AA1",
16 | "textColor": "white",
17 | "clusterBkg": "white"
18 | },
19 | "themeCSS": ".edgeLabel { color: black }"
20 | }}%%
21 |
22 | flowchart LR
23 | subgraph Origin
24 | Sender
25 | M_O[(Mailbox)]
26 | IGP[InterchainGasPaymaster]
27 | Sender -- "id = dispatch(message)" --> M_O
28 | Sender -- "payForGas(id)\n{value: payment}" --> IGP
29 | end
30 |
31 | Relayer((Relayer))
32 |
33 | M_O -. "emit Dispatch(message)" .-> Relayer
34 | IGP -.- Relayer
35 |
36 | subgraph Destination
37 | M_D[(Mailbox)]
38 | end
39 |
40 | Relayer -- "process(message)" --> M_D
41 |
42 | style Sender fill:#efab17
43 |
44 | click IGP https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/igps/InterchainGasPaymaster.sol
45 | ```
46 |
47 | ## InterchainGasPaymasters
48 |
49 | Interchain gas payments are facilitated by `InterchainGasPaymaster` (IGP) smart contract contracts.
50 |
51 | These contracts expose the [interchain-gas-paymaster-api.md](../apis-and-sdks/interchain-gas-paymaster-api.md "mention"), which allows users to pay [relayer.md](agents/relayer.md "mention") with native tokens on the origin chain to cover the costs of delivering a message on the destination chain.
52 |
53 | Each `InterchainGasPaymaster` contract corresponds to exactly one relayer. You can find addresses of the Abacus Works' relayer under [addresses](../resources/addresses/ "mention")
54 |
55 | ### Gas oracles
56 |
57 | In order to support the [interchain-gas-paymaster-api.md](../apis-and-sdks/interchain-gas-paymaster-api.md "mention"), IGP contracts may be configured with gas oracles, which are responsible for tracking remote token gas prices and exchange rates.
58 |
59 | This allows the `quoteGasPayment` function to provide an accurate quote for the price of gas on a remote chain, denominated in the local chain's native token.
60 |
61 | Eventually, relayers will be able to automatically update their gas oracles in order to ensure that their IGP always quotes a fair price for remote gas.
62 |
63 | ## Trust assumptions
64 |
65 | Interchain gas payments are based on a social contract between the message sender and relayer.
66 |
67 | In other words, a relayer may receive interchain gas payments without delivering the corresponding messages.
68 |
69 | Therefore, when making interchain gas payments, it is recommended to use an IGP contract that is associated with a known and reputable relayer.
70 |
71 | An honest relayer implementation will honor any successful gas payments made to its IGP, no matter how many tokens were actually paid. By keeping [#gas-oracles](interchain-gas-payments.md#gas-oracles "mention") up to date, the relayer can ensure that gas payments succeed if and only if a "fair" price was paid.
72 |
73 | There are no trust assumptions with respect to relayers in the Hyperlane protocol, and under no circumstances will a malicious relayer be able to censor or falsify messages. The worst thing that a relayer can do is accept payments without delivering a message.
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/protocol/messaging.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Send and receive interchain messages
3 | ---
4 |
5 | # Mailbox
6 |
7 | The Hyperlane`Mailbox` smart contracts expose an on-chain API for sending and receiving interchain messages. There is a `Mailbox` contract deployed on every chain Hyperlane supports.
8 |
9 | The network of `Mailboxes` facilitates the connective tissue between blockchains that developers leverage to create interchain applications, and add interchain functionality to their existing applications.
10 |
11 | ## Interface
12 |
13 | The `IMailbox` interface exposes two state-mutating functions; `dispatch()` and `process()`, which are used to send and receive messages, respectively.
14 |
15 | ```solidity
16 | // SPDX-License-Identifier: MIT OR Apache-2.0
17 | pragma solidity >=0.8.0;
18 |
19 | interface IMailbox {
20 | function dispatch(
21 | uint32 _destinationDomain,
22 | bytes32 _recipientAddress,
23 | bytes calldata _messageBody
24 | ) external returns (bytes32);
25 |
26 | function process(bytes calldata _metadata, bytes calldata _message)
27 | external;
28 | }
29 | ```
30 |
31 | ### Dispatch
32 |
33 | To send interchain messages, developers call `Mailbox.dispatch()`.
34 |
35 | This function takes as parameters the message contents, the destination chain ID, and the recipient address. Each message get inserted as a leaf into an [incremental merkle tree](https://medium.com/@josephdelong/ethereum-2-0-deposit-merkle-tree-13ec8404ca4f) stored by the `Mailbox`.
36 |
37 | Hyperlane's [proof-of-stake.md](proof-of-stake.md "mention") protocol uses this merkle tree to verify fraud proofs.
38 |
39 | ### Process
40 |
41 | To deliver interchain messages, [relayer.md](agents/relayer.md "mention") call `Mailbox.process()`.
42 |
43 | This function takes as parameters the message to deliver as well as arbitrary metadata that can be specified by the relayer.
44 |
45 | The `Mailbox` will pass the message and metadata to the recipient's interchain security module for verification. If the ISM successfully verifies the message, the `Mailbox` delivers the message to the recipient by calling `recipient.handle()`.
46 |
47 | {% hint style="info" %}
48 | See [`Message.sol`](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/libs/Message.sol)for more details on Hyperlane message encoding
49 | {% endhint %}
50 |
--------------------------------------------------------------------------------
/protocol/permissionless-interoperability.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: The Permissionless Interoperability Layer
3 | ---
4 |
5 | # Overview
6 |
7 | Hyperlane is the first [#permissionless-interoperability](../deploy/permissionless-interoperability.md#permissionless-interoperability "mention") layer that allows smart contract developers to send arbitrary data between blockchains.
8 |
9 | Developers can use Hyperlane to move tokens, execute function calls, and many other things that allow for the creation of interchain applications, apps that can be accessed by users on any blockchain.
10 |
11 | Users interface with the Hyperlane protocol via [messaging.md](messaging.md "mention") smart contracts, which provide an on-chain [messaging-api](../apis/messaging-api/ "mention") to send and receive interchain messages.
12 |
13 | Hyperlane takes a modular approach to security, allowing applications to configure and choose from a selection of [sovereign-consensus](sovereign-consensus/ "mention") (ISMs). Applications may specify an ISM to customize the security model that secures their integration with the Hyperlane messaging API.
14 |
15 | ```mermaid
16 | %%{ init: {
17 | "theme": "neutral",
18 | "themeVariables": {
19 | "mainBkg": "#025AA1",
20 | "textColor": "white",
21 | "clusterBkg": "white"
22 | },
23 | "themeCSS": ".edgeLabel { color: black }",
24 | "flowchart": {"useMaxWidth": "true" }
25 | }}%%
26 |
27 | flowchart TB
28 | Relayer((Relayer))
29 |
30 | subgraph Origin
31 | Sender
32 | M_O[(Mailbox)]
33 |
34 | Sender -- "1. dispatch(destination, recipient, body)" --> M_O
35 | end
36 |
37 | M_O -. "2. emit Message(origin, sender, destination, recipient, body)" .-> Relayer
38 |
39 | subgraph Destination
40 | Recipient
41 | M_D[(Mailbox)]
42 | ISM[InterchainSecurityModule]
43 |
44 | M_D -. "4. interchainSecurityModule()" .-> Recipient
45 | M_D -- "5. verify(metadata, message)" --> ISM
46 | M_D -- "6. handle(origin, sender, body)" --> Recipient
47 | end
48 |
49 | Relayer -- "3. process(metadata, message)" --> M_D
50 |
51 | style Sender fill:#efab17
52 | style Recipient fill:#efab17
53 | ```
54 |
--------------------------------------------------------------------------------
/protocol/proof-of-stake.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Making fraud costly
3 | ---
4 |
5 | # Staking and slashing
6 |
7 | {% hint style="warning" %}
8 | Staking and slashing are coming soon and are not yet implemented. This page is shown for informational purposes only. Details may change as the design matures.
9 | {% endhint %}
10 |
11 | Staking and slashing allow economic security to be added to ISMs that rely on validator signatures, including [multisig-ism.md](sovereign-consensus/multisig-ism.md "mention")and [optimistic-ism.md](sovereign-consensus/optimistic-ism.md "mention").
12 |
13 | Hyperlane validators can optionally participate in Hyperlane's staking protocol. Later, if these validators attempt to falsify or censor interchain messages, their stake, and any stake delegated to them, can be slashed.
14 |
15 | [interchain-security-modules.md](sovereign-consensus/interchain-security-modules.md "mention") that depend on signatures from these validators benefit from the additional economic security provided by staking and slashing.
16 |
17 | ### Verifiable fraud proofs
18 |
19 | Unlike many other interchain communication protocols, Hyperlane's slashing protocol uses **verifiable fraud proofs**.
20 |
21 | This means that the Hyperlane protocol is able to verify whether or not a validator signed a fraudulent checkpoint without any participation from trusted parties.
22 |
23 | This is possible because the stake put up by validators lives on the **same chain** as the state (i.e. the [messaging.md](messaging.md "mention") merkle root) that they're attesting to. The slashing smart contract can compare the validator signature with the latest root of the [messaging.md](messaging.md "mention"), and do some complicated merkle tree manipulation to confirm whether or not the checkpoint signed by the validator was fraudulent.
24 |
25 | In many other interchain communication protocols, it is common for a validator's stake to live on a **different chain** than the chain from which an interchain message originated.
26 |
27 | What this means is that in order for a fraudulent validator to have their stake slashed, the same message passing protocol must relay a message to the chain where the stake lives. You can see the problem with this right? The same validator set where fraud occurred is the mechanism by which evidence of that fraud is delivered, what could go wrong?
28 |
29 | Hyperlane doesn't want to allow for that possibility, thus in Hyperlane validators must keep their bonded stake on the origin chain for which they are validating. This means fraud proofs are trustlessly verifiable. The record of fraud that is examined for slashing exists in the same environment as the stake to be slashed, leaving no room for error with the process of fraud proofs.
30 |
31 |
--------------------------------------------------------------------------------
/protocol/sovereign-consensus/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Modular interchain security
3 | ---
4 |
5 | # Interchain security modules
6 |
7 | Hyperlane is secured by **Interchain Security Modules** (ISMs). ISMs are smart contracts that are responsible for verifying that interchain messages being delivered on the destination chain were _actually sent_ on the origin chain.
8 |
9 | Hyperlane developers can **optionally** **override** the [messaging.md](../messaging.md "mention")'s default ISM by specifying an application-specific ISM, which they can configure, compose, and customize according to the needs of their application.
10 |
11 | ### Configure
12 |
13 | Hyperlane defines a set of pre-built ISMs. Developers can deploy any of these contracts "off-the-shelf" and configure them with their own parameters.
14 |
15 | For example, application developers that want increased sovereignty over interchain security could deploy a [multisig-ism.md](multisig-ism.md "mention") configured with validators sourced from their community.
16 |
17 | ### Compose
18 |
19 | ISMs act as "security [legos](https://en.wikipedia.org/wiki/Lego)". Developers can mix and match different ISMs together to encode a security model that best fits their needs.
20 |
21 | For example, application developers that want additional security could deploy an [aggregation-ism.md](aggregation-ism.md "mention") that requires verification by both a [multisig-ism.md](multisig-ism.md "mention") configured with validators from the Hyperlane community, **and** a [wormhole-ism.md](wormhole-ism.md "mention") that verifies that a quorum of the [Wormhole](https://wormhole.com/) validator set verified the message.
22 |
23 | ### Customize
24 |
25 | ISMs are fully customizable. Developers can write their own ISMs, tailoring them to the needs of their application.
26 |
27 | For example, application developers can build ISMs that adjust security models based on message content. High value and infrequent messages (e.g. governance) could be verified by a security model that prioritizes safety over latency and gas costs. Lower value and more frequent messages could be verified by a security model that prioritizes latency and gas costs over safety.
28 |
29 | ## Overriding the default ISM
30 |
31 | Application developers can override the default ISM by implementing the `ISpecifiesInterchainSecurityModule` interface in their application.
32 |
33 | Specifically, this interface must be implemented in the same smart contract that implements `handle()`.
34 |
35 | ```solidity
36 | // SPDX-License-Identifier: MIT OR Apache-2.0
37 | pragma solidity >=0.6.11;
38 |
39 | interface ISpecifiesInterchainSecurityModule {
40 | function interchainSecurityModule()
41 | external
42 | view
43 | returns (IInterchainSecurityModule);
44 | }
45 | ```
46 |
--------------------------------------------------------------------------------
/protocol/sovereign-consensus/aggregation-ism.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Aggregate security from multiple ISMs
3 | ---
4 |
5 | # Aggregation ISM
6 |
7 | Developers can use an `AggregationISM` to combine security from multiple ISMs. Simply put, an `AggregationISM` requires that `m` of `n` ISMs verify a particular interchain message.
8 |
9 | ## Interface
10 |
11 | `AggregationISMs` must implement the `IAggregationIsm` interface.
12 |
13 | ```solidity
14 | // SPDX-License-Identifier: MIT OR Apache-2.0
15 | pragma solidity >=0.6.11;
16 |
17 | import {IInterchainSecurityModule} from "../IInterchainSecurityModule.sol";
18 |
19 | interface IAggregationIsm is IInterchainSecurityModule {
20 | /**
21 | * @notice Returns the set of modules responsible for verifying _message
22 | * and the number of modules that must verify
23 | * @dev Can change based on the content of _message
24 | * @param _message Hyperlane formatted interchain message
25 | * @return modules The array of ISM addresses
26 | * @return threshold The number of modules needed to verify
27 | */
28 | function modulesAndThreshold(bytes calldata _message)
29 | external
30 | view
31 | returns (address[] memory modules, uint8 threshold);
32 | }
33 |
34 | ```
35 |
36 | ## Configure
37 |
38 | The hyperlane-monorepo contains an `AggregationISM` implementation that application developers can deploy off-the-shelf, specifying their desired configuration.
39 |
40 | Developers can configure, for each origin chain, a set of `n` ISMs, and the number of ISMs needed to verify a message.
41 |
42 | `AggregationISMs` can aggregate the security of any ISMs. For example, users can deploy a [multisig-ism.md](multisig-ism.md "mention") with their own validator set, and deploy an `AggregationISM` that aggregates that ISM with the Hyperlane default ISM.
43 |
44 | The [hyperlane-deploy repo](https://github.com/hyperlane-xyz/hyperlane-deploy) contains the tooling and instructions needed to deploy and configure an `AggregationISM`.
45 |
46 | ## Customize
47 |
48 | The hyperlane-monorepo contains an abstract `AggregationISM` implementation that application developers can fork.
49 |
50 | Developers simply need to implement the `modulesAndThreshold()` function.
51 |
52 | By creating a custom implementation, application developers can tailor the security provided by a `AggregationISM` to the needs of their application.
53 |
54 | For example, a custom implementation could require that low value messages be verified by a [multisig-ism.md](multisig-ism.md "mention"), and require that high value messages _also_ be verified by a [wormhole-ism.md](wormhole-ism.md "mention").
55 |
--------------------------------------------------------------------------------
/protocol/sovereign-consensus/hook-ism.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Use external hook for security
3 | ---
4 |
5 | # Hook ISM
6 |
7 | [hooks](../../apis-and-sdks/hooks/ "mention")
8 |
--------------------------------------------------------------------------------
/protocol/sovereign-consensus/interchain-security-modules.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: The security interface for Hyperlane
3 | ---
4 |
5 | # Interface
6 |
7 | ISMs must implement the `IInterchainSecurityModel()` interface. This interface consists of two functions.
8 |
9 | ```solidity
10 | // SPDX-License-Identifier: MIT OR Apache-2.0
11 | pragma solidity >=0.6.11;
12 |
13 | interface IInterchainSecurityModule {
14 | /**
15 | * @notice Returns an enum that represents the type of security model
16 | * encoded by this ISM.
17 | * @dev Relayers infer how to fetch and format metadata.
18 | */
19 | function moduleType() external view returns (uint8);
20 |
21 | /**
22 | * @notice Defines a security model responsible for verifying interchain
23 | * messages based on the provided metadata.
24 | * @param _metadata Off-chain metadata provided by a relayer, specific to
25 | * the security model encoded by the module (e.g. validator signatures)
26 | * @param _message Hyperlane encoded interchain message
27 | * @return True if the message was verified
28 | */
29 | function verify(bytes calldata _metadata, bytes calldata _message)
30 | external
31 | returns (bool);
32 | }
33 | ```
34 |
35 | ### Verify
36 |
37 | The primary function that ISMs must implement is `verify()`. The [messaging.md](../messaging.md "mention") will call `IInterchainSecurityModule.verify()` before delivering a message to its recipient. If `verify()` reverts or returns `false`, the message will not be delivered.
38 |
39 | The `verify()` function takes two parameters.
40 |
41 | The first, `_metadata`, consists of arbitrary bytes provided by [relayer.md](../agents/relayer.md "mention"). Typically, these bytes are specific to the ISM. For example, for a [multisig-ism.md](multisig-ism.md "mention"), `_metadata` must include validator signatures.
42 |
43 | The second, `_message`, consists of the Hyperlane message being verified. ISMs can use this to inspect details about the message being verified. For example, a [multisig-ism.md](multisig-ism.md "mention") could change validator sets based on the origin chain of the message.
44 |
45 | {% hint style="warning" %}
46 | See the [`Message.sol`](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/libs/Message.sol) library for more information on the format of the Hyperlane message passed to `verify()`
47 | {% endhint %}
48 |
49 | ### Module type
50 |
51 | The secondary function that ISMs must implement is `moduleType()`. This is used to signal to [relayer.md](../agents/relayer.md "mention")what to include in `_metadata`. ISMs **must** return one of the supported module types.
52 |
53 | ## Sequence diagram
54 |
55 | The following shows a simplified sequence diagram of an interchain message being verified and delivered on the destination chain.
56 |
57 | {% hint style="info" %}
58 | If the recipient does not implement `ISpecifiesInterchainSecurityModule` or `recipient.interchainSecurityModule()` returns `address(0)`, the default ISM configured on the [messaging.md](../messaging.md "mention") will be used to verify the message.
59 |
60 | This is omitted from the sequence diagram for clarity.
61 | {% endhint %}
62 |
63 | ```mermaid
64 | sequenceDiagram
65 |
66 |
67 | participant Relayer
68 | participant Mailbox
69 | participant ISM
70 | participant Recipient
71 |
72 | Relayer-->>ISM: moduleType()
73 | ISM-->>Relayer: ISM type
74 | Relayer->>Mailbox: process(metadata, message)
75 | Mailbox-->>Recipient: interchainSecurityModule()
76 | Recipient-->>Mailbox: ISM address
77 | Mailbox->>ISM: verify(metadata, message)
78 | ISM-->>Mailbox: true
79 | Mailbox->>Recipient: handle(origin, sender, body)
80 |
81 | ```
82 |
--------------------------------------------------------------------------------
/protocol/sovereign-consensus/multisig-ism.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Verify messages using validator signatures
3 | ---
4 |
5 | # Multisig ISM
6 |
7 | The `MultisigISM` is one of the most commonly used ISM types. These ISMs verify that `m` of `n` [validators.md](../agents/validators.md "mention") have attested to the validity of a particular interchain message.
8 |
9 | ## Interface
10 |
11 | `MultisigISMs` must implement the `IMultisigIsm` interface.
12 |
13 | ```solidity
14 | // SPDX-License-Identifier: MIT OR Apache-2.0
15 | pragma solidity >=0.6.0;
16 |
17 | import {IInterchainSecurityModule} from "./IInterchainSecurityModule.sol";
18 |
19 | interface IMultisigIsm is IInterchainSecurityModule {
20 | /**
21 | * @notice Returns the set of validators responsible for verifying _message
22 | * and the number of signatures required
23 | * @dev Can change based on the content of _message
24 | * @param _message Hyperlane formatted interchain message
25 | * @return validators The array of validator addresses
26 | * @return threshold The number of validator signatures needed
27 | */
28 | function validatorsAndThreshold(bytes calldata _message)
29 | external
30 | view
31 | returns (address[] memory validators, uint8 threshold);
32 | }
33 | ```
34 |
35 | ## Configure
36 |
37 | The hyperlane-monorepo contains [`MultisigISM` implementations](https://github.com/hyperlane-xyz/hyperlane-monorepo/tree/main/solidity/contracts/isms/multisig) (including a [legacy](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/isms/multisig/LegacyMultisigIsm.sol) version and more gas-efficient [versions](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/isms/multisig/StaticMultisigIsm.sol) deployable via factories) that application developers can deploy off-the-shelf, specifying their desired configuration.
38 |
39 | Developers can configure, for each origin chain, a set of `n` [validators.md](../agents/validators.md "mention"), and the number of validator signatures (`m`) needed to verify a message.
40 |
41 | Validator signatures are **not** specific to an ISM. In other words, developers can configure their `MultisigISM` to use **any** validator that's running on Hyperlane and it will "just work".
42 |
43 | The [hyperlane-deploy repo](https://github.com/hyperlane-xyz/hyperlane-deploy) contains the tooling and instructions needed to deploy and configure a `MultisigISM`.
44 |
45 | ## Customize
46 |
47 | The hyperlane-monorepo contains an abstract `MultisigISM` implementation that application developers can fork.
48 |
49 | Developers simply need to implement the `validatorsAndThreshold()` function.
50 |
51 | By creating a custom implementation, application developers can tailor the security provided by a `MultisigISM` to the needs of their application.
52 |
53 | For example, a custom implementation could vary the number of signatures required, based on the content of the message being verified.
54 |
--------------------------------------------------------------------------------
/protocol/sovereign-consensus/optimistic-ism.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Prioritizing safety over liveness
3 | ---
4 |
5 | # Optimistic ISM
6 |
7 | {% hint style="warning" %}
8 | `OptimisticISM` is coming soon and is not yet implemented. This page is shown for informational purposes only. Details may change as the design matures.
9 | {% endhint %}
10 |
11 | The `OptimisticISM` encodes the optimistic verification security model pioneered by [Optics](https://docs.celo.org/protocol/bridge/optics) and adopted by [Synapse](https://docs.synapseprotocol.com/protocol/optimistic-verification), [Nomad](https://docs.nomad.xyz/the-nomad-protocol/verification-mechanisms/optimistic-verification), and [Connext](https://blog.connext.network/optimistic-bridges-fb800dc7b0e0).
12 |
13 | `OptimisticISMs` rely on a fraud window after message verification, during which `m` of `n` **watchers** configured on the `OptimisticISM` have an opportunity to flag messages as fraudulent, preventing them from being delivered to their recipient.
14 |
15 | **This security model prioritizes safety over liveness;** the increased message latency allows for the addition of a second layer of security, the watchers, without significant increases in gas costs.
16 |
--------------------------------------------------------------------------------
/protocol/sovereign-consensus/routing-ism.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Smarter interchain security models
3 | ---
4 |
5 | # Routing ISM
6 |
7 | Developers can use a `RoutingISM` to delegate message verification to a different ISM. This allows developers to change security models based on message content or application context.
8 |
9 | ## Interface
10 |
11 | `RoutingISMs` must implement the `IRoutingIsm` interface.
12 |
13 | ```solidity
14 | interface IRoutingIsm is IInterchainSecurityModule {
15 | /**
16 | * @notice Returns the ISM responsible for verifying _message
17 | * @dev Can change based on the content of _message
18 | * @param _message Formatted Hyperlane message (see Message.sol).
19 | * @return module The ISM to use to verify _message
20 | */
21 | function route(bytes calldata _message)
22 | external
23 | view
24 | returns (IInterchainSecurityModule);
25 | }
26 | ```
27 |
28 | ## Configure
29 |
30 | The hyperlane-monorepo contains a `RoutingISM` implementation, `DomainRoutingIsm`, that application developers can deploy off-the-shelf, specifying their desired configuration.
31 |
32 | This ISM simply switches security models depending on the origin chain of the message. A simple use case for this is to use different [multisig-ism.md](multisig-ism.md "mention") validator sets for each chain.
33 |
34 | Eventually, you could imagine a `DomainRoutingIsm` routing to different light-client-based ISMs, depending on the type of consensus protocol used on the origin chain.
35 |
36 | The [hyperlane-deploy repo](https://github.com/hyperlane-xyz/hyperlane-deploy) contains the tooling and instructions needed to deploy and configure a `DomainRoutingIsm`.
37 |
38 | ## Customize
39 |
40 | The hyperlane-monorepo contains an abstract `RoutingISM` implementation that application developers can fork.
41 |
42 | Developers simply need to implement the `route()` function.
43 |
44 | By creating a custom implementation, application developers can tailor the security provided by a `RoutingISM` to the needs of their application.
45 |
46 | For example, a custom implementation could change security models based on the contents of the message or the state of the application receiving the message.
47 |
--------------------------------------------------------------------------------
/protocol/sovereign-consensus/wormhole-ism.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Leverage security from the Wormhole guardians
3 | ---
4 |
5 | # Wormhole ISM
6 |
7 | {% hint style="warning" %}
8 | `WormholeISM` is coming soon and is not yet implemented. This page is shown for informational purposes only. Details may change as the design matures.
9 | {% endhint %}
10 |
11 | The `WormholeISM` encodes the security model used by [Wormhole's](https://wormhole.com/) interchain communication protocol.
12 |
13 | This ISM requires that 13 of the 19 [Wormhole guardians](https://wormhole.com/network/#guardians) attest to the validity of a Hyperlane message.
14 |
15 | ## Compose
16 |
17 | Developers can compose a Wormhole ISM with a [multisig-ism.md](multisig-ism.md "mention")using an [aggregation-ism.md](aggregation-ism.md "mention") to require that m of n Hyperlane validators **and** 13-of-19 Wormhole guardians verify a message.
18 |
--------------------------------------------------------------------------------
/resources/domains/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Unique IDs for each Hyperlane-supported chain
3 | ---
4 |
5 | # Domain identifiers
6 |
7 | {% hint style="warning" %}
8 | Note that Hyperlane domain IDs are not guaranteed to be the same as EVM chain IDs, as Hyperlane will eventually support non-EVM chains.
9 | {% endhint %}
10 |
11 | Hyperlane uses proprietary domain IDs to reference each Hyperlane-supported chain.
12 |
13 | When [sending a message](../../apis/messaging-api/send.md), users must provide the domain ID of the destination chain. When [receiving a message](../../apis/messaging-api/receive.md), the recipient will be passed the domain ID of the origin chain.
14 |
15 | {% hint style="info" %}
16 | This list includes only the deployments on chains that are managed by Abacus Works (our legal entity). Anybody can deploy Hyperlane on any chain using [Permissionless ](../broken-reference/)[Interoperability ](../broken-reference/)and thus this list may not be exhaustive.
17 | {% endhint %}
18 |
19 | ### Mainnet
20 |
21 | | Network | Domain Identifier (uint32) |
22 | | --------- | -------------------------- |
23 | | Arbitrum | `42161` |
24 | | Avalanche | `43114` |
25 | | BSC | `56` |
26 | | Celo | `42220` |
27 | | Ethereum | `1` |
28 | | Optimism | `10` |
29 | | Polygon | `137` |
30 | | Moonbeam | `1284` |
31 | | Gnosis | `100` |
32 |
33 | ### Testnet
34 |
35 | | Network | Domain Identifier (uint32) |
36 | | --------------- | -------------------------- |
37 | | Alfajores | `44787` |
38 | | BSC Testnet | `97` |
39 | | Fuji | `43113` |
40 | | Goerli | `5` |
41 | | Sepolia | `11155111` |
42 | | Mumbai | `80001` |
43 | | Moonbase Alpha | `1287` |
44 | | Optimism Goerli | `420` |
45 | | Arbitrum Goerli | `421613` |
46 |
--------------------------------------------------------------------------------
/resources/domains/permissionless-domain-identifiers.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Unique IDs for each Hyperlane-supported chain
3 | ---
4 |
5 | # Permissionless Domain Identifiers
6 |
7 | {% hint style="warning" %}
8 | Note that Hyperlane domain IDs are not guaranteed to be the same as EVM chain IDs, as Hyperlane will eventually support non-EVM chains.
9 | {% endhint %}
10 |
11 | Hyperlane uses proprietary domain IDs to reference each Hyperlane-supported chain.
12 |
13 | When [sending a message](../../apis/messaging-api/send.md), users must provide the domain ID of the destination chain. When [receiving a message](../../apis/messaging-api/receive.md), the recipient will be passed the domain ID of the origin chain.
14 |
15 | {% hint style="info" %}
16 | This list includes only the deployments on chains that are managed by Abacus Works (our legal entity). Anybody can deploy Hyperlane on any chain using [Permissionless ](../broken-reference/)[Interoperability ](../broken-reference/)and thus this list may not be exhaustive.
17 | {% endhint %}
18 |
19 | ### Testnet
20 |
21 | | Network | Domain Identifier (uint32) | Deployer |
22 | | --------------------- | -------------------------- | ----------------------------------------------------- |
23 | | Polygon zkEVM Testnet | `1442` | [Hyperlane India](https://twitter.com/HyperlaneIndia) |
24 | | Chiado | `10200` | [Hyperlane India](https://twitter.com/HyperlaneIndia) |
25 | | Scroll Alpha | `534353` | [Hyperlane India](https://twitter.com/HyperlaneIndia) |
26 | | Linea Goerli | `59140` | [Hyperlane India](https://twitter.com/HyperlaneIndia) |
27 | | Mantle Testnet | `5001` | [Hyperlane India](https://twitter.com/HyperlaneIndia) |
28 |
--------------------------------------------------------------------------------
/resources/latencies.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Hyperlane block finality latency configuration.
3 | ---
4 |
5 | # Latencies
6 |
7 | Validators must wait a certain number of blocks to be mined before they are considered valid and [reorg-safe](https://www.alchemy.com/overviews/what-is-a-reorg). Without this, validators could be slashed since they may have signed a checkpoint that is no longer valid.
8 |
9 | Refer to the following sections for block finality configuration used by the Hyperlane validators.
10 |
11 | ### Mainnet
12 |
13 | | Network | Reorg Period | Validator Polling Interval |
14 | | --------- | ------------------- | -------------------------- |
15 | | Arbitrum | 1 block | 1s |
16 | | Avalanche | 3 blocks (6s) | 2s |
17 | | BSC | 15 blocks (45s) | 3s |
18 | | Celo | 0 blocks (5s) | 5s |
19 | | Ethereum | 20 blocks (260s) | 15s |
20 | | Gnosis | 14 blocks (74s) | 5s |
21 | | Moonbeam | 2 blocks (20s) | 5s |
22 | | Optimism | 0 blocks | 15s |
23 | | Polygon | 256 blocks (\~540s) | 2s |
24 |
25 | ### Testnet
26 |
27 | | Network | Reorg Period | Validator Polling Interval |
28 | | --------------------- | ---------------- | -------------------------- |
29 | | Alfajores | 1 block (5s) | 5s |
30 | | Arbitrum Goerli | 1 block | 5s |
31 | | BSC Testnet | 9 blocks (27s) | 5s |
32 | | Fuji | 3 blocks (\~6s) | 5s |
33 | | Goerli | 2 blocks (30s) | 5s |
34 | | Moonbase Alpha | 2 blocks (20s) | 5s |
35 | | Mumbai | 32 blocks (160s) | 5s |
36 | | Optimism Goerli | 1 block | 5s |
37 | | Sepolia | 7 blocks (90s) | 5s |
38 | | Anvil (local network) | 0 blocks | 5s |
39 |
--------------------------------------------------------------------------------
/resources/token-sources-and-faucets.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Where to acquire tokens for development
3 | ---
4 |
5 | # Token sources & faucets
6 |
7 |
8 |
9 | | **Mainnets** | **Did you really need to ask?** | |
10 | | --------------- | ------------------------------------------------------------------------------- | ---------------------------- |
11 | | Avalanche | Most major exchanges | |
12 | | BSC | Binance, FTX, Kucoin | |
13 | | Polygon | Most major exchanges | |
14 | | Celo | Binance, Coinbase, Kucoin | |
15 | | Arbitrum | Most major exchanges or canonical bridge | |
16 | | Optimism | Most major exchanges or canonical bridge | |
17 | | Ethereum | Most major exchanges | |
18 | | Moonbeam | Binance, Coinbase, Kucoin | |
19 | | | | |
20 | | | | |
21 | | **Testnets** | **Faucet Link** | **Amounts** |
22 | | Alfajores | [Alfrajores Token Faucet](https://faucet.celo.org/) | 5 CELO |
23 | | Mumbai | [Polygon Faucet](https://faucet.polygon.technology/) | 2 MATIC with alchemy account |
24 | | Fuji | [Avalanche Faucet](https://faucet.avax.network/) | 2 AVAX |
25 | | BSC Testnet | [BNB Smart Chain Faucet](https://testnet.bnbchain.org/faucet-smart) | 0.5 BNB |
26 | | Arbitrum Goerli | [Triangle Faucet](https://faucet.triangleplatform.com/arbitrum/goerli) | 0.1 ETH |
27 | | Optimism Goerli | [Swap Goerli ETH for Optimism Goerli](https://app.optimism.io/bridge/deposit) | 0.1 ETH |
28 | | Moonbase Alpha | [Moonbase Alpha Faucet](https://apps.moonbeam.network/moonbase-alpha/faucet/) | 1 DEV |
29 | | Hyperspace | [Filecoin Faucet](https://hyperspace.yoga/#faucet) | 5 tFIL |
30 | | Sepolia | [Sepolia Faucet](https://sepoliafaucet.com/) | 0.5 ETH |
31 |
--------------------------------------------------------------------------------
/sdks/building-applications/example-usage/README.md:
--------------------------------------------------------------------------------
1 | # Example usage
2 |
3 | For examples of integrating contracts with Hyperlane app framework, see the following examples
4 |
5 | [helloworld.md](helloworld.md "mention") - A skeleton for building with the App Framework
6 |
7 | [erc20-token.md](erc20-token.md "mention") - A skeloton for building an interchain token with the App Framework
8 |
--------------------------------------------------------------------------------
/sdks/building-applications/example-usage/erc20-token.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: An interchain ERC20 token contract
3 | ---
4 |
5 | # Interchain Token
6 |
7 | \*\*\*\*[**ERC20 Token**](erc20-token.md) \*\*\*\* app is an interchain ERC20 token contract using the [App framework.](../../../apis-and-sdks/building-applications/)
8 |
9 | The [hyperlane-token repo](https://github.com/hyperlane-xyz/hyperlane-token) shows an example Interchain Token, an ERC20 that can travel between any Hyperlane chain, also called a `HypERC20`.
10 |
11 | The changes to the vanilla OpenZeppelin ERC20 contract are minimal. It has a `transferRemote()` function that burns the specified amount of tokens on the sending chain and mints the equivalent amount on the receiving chain.
12 |
13 | #### Contract
14 |
15 | Its [contract](https://github.com/hyperlane-xyz/hyperlane-token/blob/main/contracts/HypERC20.sol) implements a `transferRemote` method which burns tokens and dispatches corresponding messages.
16 |
17 | ```solidity
18 | /**
19 | * @notice Transfers `_amount` of tokens from `msg.sender` to `_recipient` on the `_destination` chain.
20 | * @dev Burns `_amount` of tokens from `msg.sender` on the origin chain and dispatches
21 | * message to the `destination` chain to mint `_amount` of tokens to `recipient`.
22 | * @param _destination The identifier of the destination chain.
23 | * @param _recipient The address of the recipient on the destination chain.
24 | * @param _amount The amount of tokens to be sent to the remote recipient.
25 | */
26 | function transferRemote(
27 | uint32 _destination,
28 | address _recipient,
29 | uint256 _amount
30 | ) external payable {
31 | _burn(msg.sender, _amount);
32 | _dispatchWithGas(
33 | _destination,
34 | Message.format(_recipient, _amount),
35 | gasAmount,
36 | msg.value,
37 | msg.sender
38 | );
39 | }
40 | ```
41 |
42 | It also requires a `_handle` method which mints tokens upon receiving messages.
43 |
44 | ```solidity
45 | /**
46 | * @dev Mints tokens to recipient when router receives transfer message.
47 | * @param _origin The identifier of the origin chain.
48 | * @param _message The encoded remote transfer message containing the recipient address and amount.
49 | */
50 | function _handle(
51 | uint32 _origin,
52 | bytes32,
53 | bytes memory _message
54 | ) internal override {
55 | (address recipient, uint256 amount) = abi.decode(
56 | _message,
57 | (address, uint256)
58 | );
59 | _mint(recipient, amount);
60 | }
61 | ```
62 |
--------------------------------------------------------------------------------
/sdks/building-applications/example-usage/helloworld.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: The skeleton of an Hyperlane-connected contract and app
3 | ---
4 |
5 | # HelloWorld
6 |
7 | \*\*\*\*[**HelloWorld**](helloworld.md) \*\*\*\* app \*\*\*\* is the skeleton of an Hyperlane-connected contract and app using the [App framework](../../../apis-and-sdks/building-applications/).
8 |
9 | The [hyperlane-app-template repo](https://github.com/hyperlane-xyz/hyperlane-app-template) shows the basic skeleton of an Hyperlane app.
10 |
11 | ### Contract
12 |
13 | Its [contract](https://github.com/hyperlane-xyz/hyperlane-app-template/blob/main/contracts/HelloWorld.sol) sends a user-specified string to another chain which handles the message by increasing counters and emitting events.
14 |
15 | To conveniently implement the router pattern, the contract extends `@hyperlane-xyz/core/contracts/Router.sol`
16 |
17 | To send the message, it calls the `_dispatchWithGas` method.
18 |
19 | ### Deployer
20 |
21 | The [deployer](https://github.com/hyperlane-xyz/hyperlane-app-template/blob/main/src/deploy/deploy.ts) is configured to deploy to local hardhat-based test networks.
22 |
23 | The main purpose of defining a deployer is to provide the custom types and implementation of the `deployContracts` method. See [Deploying contracts](../nodejs-sdk/deploying-contracts.md) for more details.
24 |
25 | ```typescript
26 | export class HelloWorldDeployer<
27 | Chain extends ChainName,
28 | > extends HyperlaneRouterDeployer<
29 | Chain,
30 | HelloWorldConfig,
31 | HelloWorldContracts,
32 | HelloWorldFactories,
33 | >
34 | ```
35 |
36 | ### Application
37 |
38 | The [application](https://github.com/hyperlane-xyz/hyperlane-app-template/blob/main/src/app/app.ts) fetches some basic statistics and returns them.
39 |
40 | The `sendHelloWorld` method shows an example of triggering the remote message dispatch:
41 |
42 | ```typescript
43 | const tx = await sender.sendHelloWorld(toDomain, message, {
44 | ...chainConnection.overrides,
45 | gasLimit,
46 | value,
47 | });
48 | ```
49 |
--------------------------------------------------------------------------------
/sdks/building-applications/nodejs-sdk/contract-interaction.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Interact with your application on multiple chains
3 | ---
4 |
5 | # App Abstraction
6 |
7 | The Hyperlane SDK simplifies the interface for smart contract applications deployed across multiple chains. It provides utilties for invoking a contract's methods on a target chain and a [`MultiProvider`](multiprovider.md) for managing chain connections.
8 |
9 | ### Implement
10 |
11 | The `HyperlaneApp` abstraction is a mapping that resolves a chain to a collection of [ethers Contracts](https://docs.ethers.io/v5/api/contract/contract/#Contract). Developers should extend `HyperlaneApp` and can add methods for different kinds of contract calls/transactions they would like to initiate.
12 |
13 | A simple `HyperlaneApp` extension could look like this:
14 |
15 | ```typescript
16 | export class MyHyperlaneApp
17 | extends HyperlaneApp
18 | {
19 | async myMethod(from: Chain, to: Chain, message: string) {
20 | const myContract = this.getContracts(from).router;
21 | const toDomain = ChainNameToDomainId[to];
22 | const tx = await helloWorldContract.myMethod(toDomain, message);
23 | return tx.wait();
24 | }
25 | }
26 | ```
27 |
28 | {% hint style="info" %}
29 | See the [Hyperlane Hello World](https://github.com/hyperlane-xyz/hyperlane-app-template/blob/main/src/app/app.ts) app for an example of how to extend `HyperlaneApp`.
30 | {% endhint %}
31 |
32 | ### Interact
33 |
34 | Once a `HyperlaneApp` implementation is defined, it can be instantiated using the output generated from the `HyperlaneAppDeployer` and an instance of the [`MultiProvider`](multiprovider.md).
35 |
36 | ```typescript
37 | const chainToContracts = await myDeployer.deploy();
38 | const app = new mydApp(chainToContracts, multiProvider);
39 | ```
40 |
41 | To interact with contracts on a particular network, simply provide the namespace to the app.
42 |
43 | ```typescript
44 | const ethereumContracts = myApp.getContracts('ethereum');
45 | ```
46 |
--------------------------------------------------------------------------------
/sdks/building-applications/nodejs-sdk/deploying-contracts.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Managing multi-chain contract deployments
3 | ---
4 |
5 | # Deployment
6 |
7 | `HyperlaneDeployer` helps manage the deployment of contracts across multiple chains. Hyperlane apps should extend a deployer to specify the needed types and implement any needed logic for deployment of their contracts.
8 |
9 | ### Implement
10 |
11 | Developers must provide an implementation for `deployContracts` which describes the logic for deploying the application on a single chain. Developers building with the [Router](../writing-contracts/router.md) pattern can extend `HyperlaneRouterDeployer`, which handles some Router-specific boilerplate.
12 |
13 | Deployers will also need contract [Factories](https://docs.ethers.io/v5/api/contract/contract-factory/), which be defined manually or generated automatically by tooling like TypeChain (recommended).
14 |
15 | ```typescript
16 | import { HyperlaneRouterDeployer, ChainName } from '@hyperlane-xyz/sdk';
17 |
18 | class MyDeployer
19 | extends HyperlaneRouterDeployer {
20 | function deployContracts(network: Networks, config: MyConfig) {
21 | // Custom contract deployment logic to goes here
22 | // This method is called once for each target chain
23 | }
24 | }
25 | ```
26 |
27 | For a simple, single contract app that extends the `Router` contract, it is sufficient to call the `deployContract` method in the `deployContracts` implementation:
28 |
29 | ```typescript
30 | async deployContracts(chain: Chain, config: HelloWorldConfig) {
31 | const router = await this.deployContract(chain, 'router', [
32 | config.mailbox,
33 | config.interchainGasPaymaster,
34 | ]);
35 | return {
36 | router,
37 | };
38 | }
39 | ```
40 |
41 | {% hint style="info" %}
42 | For an example deployer implementation see the [Hyperlane Hello World](https://github.com/hyperlane-xyz/hyperlane-app-template/blob/main/src/deploy/deploy.ts) app.
43 | {% endhint %}
44 |
45 | ### Interact
46 |
47 | Once a`HyperlaneDeployer` class has been defined, the deployer can be instantiated with a [Multiprovider](multiprovider.md) and a map of chains to configurations. These configs will be provided to your `deployContracts` methods and can include any values needed there. The initialization of Invoking `deploy()` will deploy contracts for all specified chains.
48 |
49 | ```typescript
50 | const ethereum: MyConfig = {...};
51 | const polygon: MyConfig = {...};
52 | const myDeployer = new MyDeployer(multiProvider, { ethereum, polygon });
53 | const contracts = await myDeployer.deploy();
54 | ```
55 |
56 | In scripts that calls `deploy`, consider persisting deployment artifacts as they will be important for future use of your application. This includes addresses, compiler options, and contract constructor arguments.
57 |
58 | {% hint style="info" %}
59 | For an example deployment script, see the [Hyperlane Hello World](https://github.com/hyperlane-xyz/hyperlane-app-template/blob/main/src/deploy/deploy.ts) app. This script is the same as the one provided above.
60 | {% endhint %}
61 |
--------------------------------------------------------------------------------
/sdks/building-applications/nodejs-sdk/gas.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Pay for message delivery on the origin chain
3 | ---
4 |
5 | # Quoting gas payments
6 |
7 | Applications can use the `HyperlaneIgp` in the Hyperlane SDK to quote [Broken link](broken-reference "mention") when dispatching a message. See the example below illustrating how to estimate and pay interchain gas payments.
8 |
9 | ### Getting a quote Using the SDK
10 |
11 | An interchain gas payment quote will call the `quoteGasPayment` function on an Interchain Gas Paymaster contract.
12 |
13 | In this example, we'll get an interchain gas payment quote for a message from Avalanche to Polygon.
14 |
15 | First, let's create the `HyperlaneIgp` instance. See [multiprovider.md](multiprovider.md "mention") for creating a `MultiProvider` with your own RPC providers.
16 |
17 | ```typescript
18 | import {
19 | chainConnectionConfigs,
20 | InterchainGasCalculator,
21 | MultiProvider
22 | } from "@hyperlane-xyz/sdk";
23 | import { ethers } from "ethers";
24 |
25 | // Set up a MultiProvider with the default providers.
26 | const multiProvider = new MultiProvider({
27 | avalanche: chainConnectionConfigs.avalanche,
28 | polygon: chainConnectionConfigs.polygon,
29 | });
30 |
31 | // Create the HyperlaneIgp instance.
32 | const igp = HyperlaneIgp.fromEnvironment(
33 | 'mainnet',
34 | multiProvider,
35 | );
36 | ```
37 |
38 | There are two functions that can be used to quote interchain gas payment. See [which-igp-to-use-and-understanding-gas-amounts.md](../../../build-with-hyperlane/guides/which-igp-to-use-and-understanding-gas-amounts.md "mention") to understand which IGP contract you should be using and to get more information on gas amounts.
39 |
40 | | Function | IGP contract | Gas amount |
41 | | --------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
42 | | `quoteGasPaymentForDefaultIsmIgp` | The provided `DefaultIsmInterchainGasPayaster` for use with the default ISM | The gas amount used by the message's recipient `handle` function |
43 | | `quoteGasPayment` | The provided `InterchainGasPaymaster` | All gas required to process the message, which includes the cost of ISM verification |
44 |
45 | Now, we can use the `HyperlaneIgp` to find how much AVAX should be paid for our message from Avalanche to Polygon that we expect to consume 200,000 gas in the recipient contract's `handle` function.
46 |
47 | ```typescript
48 | // Calculate the AVAX payment to send from Avalanche to Polygon,
49 | // with the recipient's `handle` function consuming 200,000 gas.
50 | const avaxPayment = await igp.quoteGasPaymentForDefaultIsmIgp(
51 | 'avalanche',
52 | 'polygon',
53 | ethers.BigNumber.from(200_000),
54 | );
55 |
56 | console.log('Avalanche -> Polygon payment for 200k handle gas on destination:');
57 | console.log(`${ethers.utils.formatEther(avaxPayment)} AVAX`);
58 |
59 | // At the time of writing, this outputs:
60 |
61 | // Avalanche -> Polygon payment for 200k handle gas on destination:
62 | // 0.00071510955746088 AVAX
63 | ```
64 |
--------------------------------------------------------------------------------
/sdks/building-applications/nodejs-sdk/multiprovider.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Manage RPC providers for Hyperlane supported chains in one place
3 | ---
4 |
5 | # RPC Providers
6 |
7 | `MultiProvider` is a utility used throughout the Hyperlane Application SDK. In essence, it is a mapping that resolves a chain namespace to a configured node (JSON RPC) provider.
8 |
9 | ### Configure
10 |
11 | To configure and create your `MultiProvider`, create ethers.js-compatible providers and optionally specify a block confirmation threshold:
12 |
13 | ```typescript
14 | import {chainConnectionConfigs} from '@hyperlane-xyz/sdk';
15 | // You can use a custom defined provider, say for a local node:
16 | const ethereum = {
17 | provider: new ethers.providers.UrlJsonRpcProvider('http://localhost:8545/')
18 | };
19 | const polygon = {
20 | provider: new ethers.providers.UrlJsonRpcProvider('https://rpc-mainnet.matic.network'),
21 | confirmations: 10, // wait 10 blocks for finality
22 | };
23 | // Or you can use the SDK's default configs and providers:
24 | const celo = chainConnectionConfigs.celo
25 | const multiProvider = new MultiProvider({ ethereum, polygon, celo });
26 | ```
27 |
28 | ### Interact
29 |
30 | `MultiProvider` allows, for example, an application to have static node provisioning per target chain and register a user's signer for the duration of a session.
31 |
32 | ```typescript
33 | const userSigner = await getSessionSigner();
34 | serverMultiProvider.getDomainConnection('ethereum').registerSigner(userSigner);
35 | ```
36 |
37 | ### Test
38 |
39 | For use in tests, the Hardhat `signer` can be used to emulate a multichain system locally. The chains shown (`test1`, `test2`, `test3`) are included for convenience.
40 |
41 | ```typescript
42 | import { ethers } from 'hardhat';
43 |
44 | const [signer] = await ethers.getSigners();
45 | const testMultiProvider = new MultiProvider({
46 | test1: { signer },
47 | test2: { signer },
48 | test3: { signer },
49 | });
50 | ```
51 |
52 |
--------------------------------------------------------------------------------
/sdks/building-applications/nodejs-sdk/testing-contracts.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Testing contracts locally using SDK test utilities
3 | ---
4 |
5 | # Interchain Testing
6 |
7 | Once you're done writing your contracts, it's time to test them! You can use the Hyperlane `TestCoreApp` and `TestCoreDeployer` to create an instance of Hyperlane for testing purposes and simulate interchain messaging.
8 |
9 | ### Example Usage
10 |
11 | In the example below, we simulate message passing between two chains. For more in depth examples see the tests in the [Hyperlane template application](https://github.com/hyperlane-xyz/hyperlane-app-template/tree/main/src/test).
12 |
13 | ```typescript
14 | import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers';
15 | import { expect } from 'chai';
16 | import { ethers } from 'hardhat';
17 |
18 | import {
19 | ChainMap,
20 | ChainNameToDomainId,
21 | MultiProvider,
22 | TestChainNames,
23 | TestCoreApp,
24 | TestCoreDeployer,
25 | getChainToOwnerMap,
26 | getTestMultiProvider,
27 | testChainConnectionConfigs,
28 | } from '@hyperlane-xyz/sdk';
29 |
30 | import { HelloWorldConfig } from '../deploy/config';
31 | import { HelloWorldDeployer } from '../deploy/deploy';
32 | import { HelloWorld } from '../types';
33 |
34 | describe('HelloWorld', async () => {
35 | const localChain = 'test1';
36 | const remoteChain = 'test2';
37 | const localDomain = ChainNameToDomainId[localChain];
38 | const remoteDomain = ChainNameToDomainId[remoteChain];
39 |
40 | let signer: SignerWithAddress;
41 | let local: HelloWorld;
42 | let remote: HelloWorld;
43 | let multiProvider: MultiProvider;
44 | let coreApp: TestCoreApp;
45 | let config: ChainMap;
46 |
47 | before(async () => {
48 | [signer] = await ethers.getSigners();
49 |
50 | multiProvider = getTestMultiProvider(signer);
51 |
52 | const coreDeployer = new TestCoreDeployer(multiProvider);
53 | const coreContractsMaps = await coreDeployer.deploy();
54 | coreApp = new TestCoreApp(coreContractsMaps, multiProvider);
55 | config = coreApp.extendWithConnectionClientConfig(
56 | getChainToOwnerMap(testChainConnectionConfigs, signer.address),
57 | );
58 | });
59 |
60 | beforeEach(async () => {
61 | const helloWorld = new HelloWorldDeployer(multiProvider, config, coreApp);
62 | const contracts = await helloWorld.deploy();
63 |
64 | local = contracts[localChain].router;
65 | remote = contracts[remoteChain].router;
66 |
67 | // The all counts start empty
68 | expect(await local.sent()).to.equal(0);
69 | expect(await local.received()).to.equal(0);
70 | expect(await remote.sent()).to.equal(0);
71 | expect(await remote.received()).to.equal(0);
72 | });
73 |
74 | it('sends a message', async () => {
75 | await expect(local.sendHelloWorld(remoteDomain, 'Hello')).to.emit(
76 | local,
77 | 'SentHelloWorld',
78 | );
79 | // The sent counts are correct
80 | expect(await local.sent()).to.equal(1);
81 | expect(await local.sentTo(remoteDomain)).to.equal(1);
82 | // The received counts are correct
83 | expect(await local.received()).to.equal(0);
84 | });
85 |
86 | it('handles a message', async () => {
87 | await local.sendHelloWorld(remoteDomain, 'World');
88 | // Mock processing of the message by Hyperlane
89 | await coreApp.processOutboundMessages(localChain);
90 | // The initial message has been dispatched.
91 | expect(await local.sent()).to.equal(1);
92 | // The initial message has been processed.
93 | expect(await remote.received()).to.equal(1);
94 | expect(await remote.receivedFrom(localDomain)).to.equal(1);
95 | });
96 | ```
97 |
--------------------------------------------------------------------------------
/sdks/building-applications/writing-contracts/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Build interchain smart contracts
3 | ---
4 |
5 | # Solidity SDK
6 |
7 | The solidity SDK ([`@hyperlane-xyz/core`](https://www.npmjs.com/package/@hyperlane-xyz/core)) contains smart contract libraries for helping you write your interchain apps, including:
8 |
9 | ### [`HyperlaneConnectionClient`](abacusconnectionclient.md)
10 |
11 | A mix-in that your contract can inherit from when integrating with Hyperlane.
12 |
13 | ### [`Router`](router.md)
14 |
15 | A mix-in contract, which implements a recommended pattern for interchain applications. Contracts can be written once and then deployed across many chains.
16 |
--------------------------------------------------------------------------------
/sdks/building-applications/writing-contracts/abacusconnectionclient.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: The easiest way to integrate with Hyperlane
3 | ---
4 |
5 | # HyperlaneConnectionClient
6 |
7 | Inheriting from [`HyperlaneConnectionClient`](https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/solidity/contracts/HyperlaneConnectionClient.sol) is a simple way to ensure your contract knows where to send or receive interchain messages to or from.
8 |
9 | This mix-in contract maintains a pointers to the three contracts Hyperlane developers may need to interact with:
10 |
11 | 1. [`Mailbox`](../../../protocol/messaging.md) (required)
12 | 2. [`InterchainGasPaymaster`](broken-reference) (optional)
13 | 3. [`InterchainSecurityModule`](../../../protocol/sovereign-consensus/) (optional)
14 |
15 | `HyperlaneConnectionClient` exposes functions that allow subclasses to easily send messages to the `Mailbox` via the `mailbox` storage variable, and permission message delivery via the `onlyMailbox` modifier.
16 |
17 | ```solidity
18 | import {HyperlaneConnectionClient} from "@hyperlane-xyz/core/contracts/HyperlaneConnectionClient.sol";
19 |
20 | contract HelloWorld is HyperlaneConnectionClient {
21 |
22 | /**
23 | * @notice Sends a "hello world" message to an address on a remote chain.
24 | * @param _destination The ID of the chain we're sending the message to.
25 | * @param _recipient The address of the recipient we're sending the message to.
26 | */
27 | function sendHelloWorld(uint32 _destination, address _recipient) external {
28 | // The message that we're sending.
29 | bytes memory _message = "hello world";
30 | // Send the message!
31 | mailbox.dispatch(_destination, _recipient, _message);
32 | }
33 |
34 | /**
35 | * @notice Emits a HelloWorld event upon receipt of an interchain message
36 | * @param _origin The chain ID from which the message was sent
37 | * @param _sender The address that sent the message
38 | * @param _message The contents of the message
39 | */
40 | function handle(
41 | uint32 _origin,
42 | bytes32 _sender,
43 | bytes memory _message
44 | ) external override onlyMailbox {
45 | emit HelloWorld(_origin, _sender, _message);
46 | }
47 | }
48 | ```
49 |
50 | \_\_
51 |
--------------------------------------------------------------------------------
/sync-addresses.js:
--------------------------------------------------------------------------------
1 | import { hyperlaneEnvironments, chainMetadata } from "@hyperlane-xyz/sdk";
2 |
3 | import { markdownTable } from "markdown-table";
4 |
5 | function capitalize(str) {
6 | return str.charAt(0).toUpperCase() + str.slice(1);
7 | }
8 |
9 | function generateTable(contract, addresses) {
10 | const entries = Object.entries(addresses).map(([network, contracts]) => {
11 | const explorer = chainMetadata[network].blockExplorers[0].url;
12 | const url = new URL(explorer);
13 | const entries = Object.entries(contracts)
14 | .filter(([candidate]) => candidate === contract)
15 | .map(([_, addressObject]) => {
16 | const address = addressObject.proxy ?? addressObject;
17 | return [
18 | capitalize(network),
19 | `\`${address}\``,
20 | `[View on ${url.hostname}](${explorer}/address/${address})`,
21 | ];
22 | })[0];
23 | return entries;
24 | });
25 |
26 | return markdownTable([
27 | ["Network", "Address", "Explorer"],
28 | ...entries.filter((x) => x),
29 | ]);
30 | }
31 |
32 | const enviroments = ["mainnet", "testnet"];
33 | const contracts = [
34 | { name: "mailbox" },
35 | {
36 | name: "defaultIsmInterchainGasPaymaster",
37 | subtitle:
38 | "Read about this [here](../build-with-hyperlane/guides/developers/paying-for-interchain-gas/which-igp-to-use-and-understanding-gas-amounts.md#when-using-the-default-ism-for-most-applications)",
39 | },
40 | {
41 | name: "interchainGasPaymaster",
42 | subtitle:
43 | "Advanced use - [read here](../build-with-hyperlane/guides/developers/paying-for-interchain-gas/which-igp-to-use-and-understanding-gas-amounts.md#when-using-a-custom-ism-advanced)",
44 | },
45 | { name: "multisigIsm" },
46 | { name: "interchainQueryRouter" },
47 | { name: "interchainAccountRouter" },
48 | { name: "validatorAnnounce" },
49 | ];
50 |
51 | console.log(`---
52 | description: Hyperlane core contract addresses
53 | ---
54 |
55 | # Contract addresses
56 |
57 | {% tabs %}
58 | `);
59 |
60 | // Liquidity layer is not yet in the SDK
61 | const extraContracts = ["liquidityLayer"];
62 | const extraAddresses = {
63 | mainnet: {
64 | ethereum: {
65 | liquidityLayer: "0x9954A0d5C9ac7e4a3687f9B08c0FF272f9d0dc71",
66 | },
67 | avalanche: {
68 | liquidityLayer: "0xEff8C988b9F9f606059c436F5C1Cc431571C8B03",
69 | },
70 | },
71 | testnet: {
72 | goerli: {
73 | liquidityLayer: "0x2abe0860D81FB4242C748132bD69D125D88eaE26",
74 | },
75 | fuji: {
76 | liquidityLayer: "0x2abe0860D81FB4242C748132bD69D125D88eaE26",
77 | },
78 | mumbai: {
79 | liquidityLayer: "0x2abe0860D81FB4242C748132bD69D125D88eaE26",
80 | },
81 | bsctestnet: {
82 | liquidityLayer: "0x2abe0860D81FB4242C748132bD69D125D88eaE26",
83 | },
84 | alfajores: {
85 | liquidityLayer: "0x2abe0860D81FB4242C748132bD69D125D88eaE26",
86 | },
87 | },
88 | };
89 |
90 | for (const env of enviroments) {
91 | console.log(`{% tab title="${capitalize(env)}" %}`);
92 | for (const contract of contracts) {
93 | console.log(`### ${capitalize(contract.name)}\n`);
94 | if (contract.subtitle) {
95 | console.log(`${contract.subtitle}`);
96 | }
97 | console.log(generateTable(contract.name, hyperlaneEnvironments[env]));
98 | console.log("\n");
99 | }
100 |
101 | for (const contract of extraContracts) {
102 | console.log(`### ${capitalize(contract)}\n`);
103 | console.log(generateTable(contract, extraAddresses[env]));
104 | console.log("\n");
105 | }
106 |
107 | console.log("{% endtab %}");
108 | }
109 | console.log("{% endtabs %}");
110 |
--------------------------------------------------------------------------------
/sync-config.js:
--------------------------------------------------------------------------------
1 | import {
2 | MultiProvider,
3 | defaultMultisigIsmConfigs,
4 | hyperlaneEnvironments,
5 | chainMetadata,
6 | } from "@hyperlane-xyz/sdk";
7 |
8 | import {
9 | Mailbox__factory,
10 | ValidatorAnnounce__factory,
11 | } from "@hyperlane-xyz/core";
12 |
13 | import { markdownTable } from "markdown-table";
14 |
15 | const homepages = {
16 | dsrv: "https://www.dsrvlabs.com/",
17 | abacus: "https://www.hyperlane.xyz/crew",
18 | everstake: "https://everstake.one/",
19 | "zee prime": "https://zeeprime.capital/",
20 | staked: "https://staked.us/",
21 | zkv: "https://zkvalidator.com/",
22 | };
23 |
24 | // TODO: add to storage modality
25 | export const multisigConfigNames = {
26 | celo: {
27 | names: ["abacus", "dsrv", "everstake", "zee prime", "staked", "zkv"],
28 | },
29 | ethereum: {
30 | names: ["abacus", "dsrv", "everstake", "zee prime", "staked", "zkv"],
31 | },
32 | avalanche: {
33 | names: ["abacus", "dsrv", "everstake", "zee prime", "staked", "zkv"],
34 | },
35 | polygon: {
36 | names: ["abacus", "dsrv", "everstake", "zee prime", "staked", "zkv"],
37 | },
38 | bsc: {
39 | names: ["abacus", "dsrv", "everstake", "zee prime", "staked", "zkv"],
40 | },
41 | arbitrum: {
42 | names: ["abacus", "dsrv", "everstake", "zee prime", "staked", "ZKV"],
43 | },
44 | optimism: {
45 | names: ["abacus", "dsrv", "everstake", "zee prime", "staked", "ZKV"],
46 | },
47 | moonbeam: {
48 | names: ["abacus", "dsrv", "everstake", "staked"],
49 | },
50 | gnosis: {
51 | names: ["abacus", "dsrv", "everstake", "staked"],
52 | },
53 | };
54 |
55 | function capitalize(str) {
56 | return str.charAt(0).toUpperCase() + str.slice(1);
57 | }
58 |
59 | console.log(`---
60 | description: Mailbox default security settings
61 | ---
62 |
63 | # Mailbox default security settings
64 | `);
65 |
66 | const multiProvider = new MultiProvider();
67 |
68 | const environments = ["mainnet"];
69 | for (const env of environments) {
70 | const addresses = hyperlaneEnvironments[env];
71 |
72 | const networks = Object.keys(addresses);
73 |
74 | for (const network of networks) {
75 | const config = defaultMultisigIsmConfigs[network];
76 |
77 | console.log(`## ${capitalize(network)}\n`);
78 |
79 | const contracts = addresses[network];
80 | const provider = multiProvider.getProvider(network);
81 |
82 | const validatorAnnounce = ValidatorAnnounce__factory.connect(
83 | contracts.validatorAnnounce,
84 | provider
85 | );
86 |
87 | const names = multisigConfigNames[network].names;
88 |
89 | const storageLocations =
90 | await validatorAnnounce.getAnnouncedStorageLocations(config.validators);
91 |
92 | const storageUrls = storageLocations.map((sl) => {
93 | const [modality, , bucket, region] = sl[0].split("/");
94 | if (!modality.includes("s3")) {
95 | throw new Error("Unknown modality");
96 | }
97 | const url = `https://${bucket}.s3.${region}.amazonaws.com`;
98 | return url;
99 | });
100 |
101 | const validatorEntries = [
102 | ["Validator", "Address", "Storage Location"],
103 | ...config.validators.map((address, i) => {
104 | const name = names[i];
105 | const homepage = homepages[name];
106 | return [`[${name}](${homepage})`, `\`${address}\``, `[View on S3](${storageUrls[i]})`];
107 | }),
108 | ];
109 |
110 | console.log(`### Validators\n`);
111 | console.log(markdownTable(validatorEntries));
112 | console.log();
113 |
114 | let ismEntries = [
115 | ["Destination", "Threshold", "Address", "View on Explorer"],
116 | ];
117 | for (const remote of networks.filter((n) => n !== network)) {
118 | const remoteProvider = multiProvider.getProvider(remote);
119 |
120 | const mailbox = Mailbox__factory.connect(
121 | addresses[remote].mailbox,
122 | remoteProvider
123 | );
124 | const ism = await mailbox.defaultIsm();
125 |
126 | const explorer = chainMetadata[remote].blockExplorers[0].url;
127 | const url = new URL(explorer);
128 |
129 | ismEntries.push([
130 | capitalize(remote),
131 | `${config.threshold} / ${config.validators.length}`,
132 | `\`${ism}\``,
133 | `[View on ${url.hostname}](${explorer}/address/${ism})`,
134 | ]);
135 | }
136 |
137 | console.log(`### Multisig ISM\n`);
138 | console.log(markdownTable(ismEntries));
139 | console.log();
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/sync-partials.js:
--------------------------------------------------------------------------------
1 | import glob from "glob";
2 | import fs from "fs";
3 |
4 | // use this comment syntax to include markdown partials between the include and end tags
5 | //
6 | //
7 |
8 | const includeRegex = /(\<\!\-\- INCLUDE (.*) -->)(.|\n)*?()/g;
9 | const warning =
10 | "";
11 |
12 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_function_as_the_replacement
13 | function replacer(path) {
14 | return (_, includeTag, file, __, endTag) => {
15 | console.log(`${path} << ${file}`)
16 | const body = fs.readFileSync(file, "utf8");
17 | let content;
18 | if (file.endsWith(".md")) {
19 | content = body;
20 | } else if (file.endsWith(".sol")) {
21 | content = `\`\`\`solidity\n${body}\n\`\`\``;
22 | }
23 | return [includeTag, warning, content, warning, endTag].join("\n");
24 | };
25 | }
26 |
27 | function modifyFile(path) {
28 | let file = fs.readFileSync(path, "utf8");
29 | file = file.replace(includeRegex, replacer(path));
30 | fs.writeFileSync(path, file);
31 | }
32 |
33 | glob("**/*.md", {}, (_, paths) =>
34 | paths
35 | .filter((path) => !path.startsWith("node_modules"))
36 | .forEach((path) => modifyFile(path))
37 | );
38 |
--------------------------------------------------------------------------------