├── .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 | ![](<../../../.gitbook/assets/Abacus Application SDK Diagram v2.png>) 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 |
HookNetworkAddressExplorer
OptimismEthereum 0x0346FE0a1ad1033fFc6B19A8485A3543370F04c5
Optimism0x3bd7524b82bcbb94ba5Fe4992F493991bb951839
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 |
cast send 0xE0Be420779cAd6E2bEA1E4F7C02F996D9ED1fCB5 \
42 |   'callRemote(uint32,address,uint256,bytes)' \
43 |   $DESTINATION_DOMAIN $RECIPIENT 0 $CALLDATA \
44 |   --rpc-url $RPC_URL --private-key $PRIVATE_KEY
45 | 
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 | ![How to send an interchain message using Etherscan + Metamask](<../../.gitbook/assets/Screen Shot 2022-08-10 at 4.01.00 PM.png>) 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 |
cast send $MAILBOX_ADDRESS "dispatch(uint32,bytes32,bytes)" $DESTINATION_DOMAIN $RECIPIENT $(cast --from-utf8 "your message") --rpc-url $RPC_URL
40 | --private-key $PRIVATE_KEY
41 | 
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 |
  anvil1: {
42 |     chainId: 31337,
43 |     name: 'anvil1',
44 |     displayName: 'Anvil 1 Local',
45 |     nativeToken: { name: 'Ether', symbol: 'ETH', decimals: 18 },
46 |     publicRpcUrls: [{ http: 'http://127.0.0.1:8545' }],
47 |     blocks: {
48 |       confirmations: 1,
49 |       reorgPeriod: 0,
50 |       estimateBlockTime: 10,
51 |     },
52 |     logoURI: '/logo.svg',
53 |   },
54 | };
55 | 
56 | 
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 | --------------------------------------------------------------------------------