├── .gitignore ├── README.md ├── babel.config.js ├── docs ├── concepts │ ├── _category_.json │ ├── background │ │ ├── _category_.json │ │ ├── modular-bridges.md │ │ ├── verification.md │ │ └── what-is-a-bridge.md │ ├── faq.md │ ├── how-it-works │ │ ├── _category_.json │ │ ├── architecture.md │ │ └── flow.md │ └── what-is-connext.md ├── developers │ ├── _category_.json │ ├── examples │ │ ├── _category_.json │ │ ├── authenticated-hello.md │ │ ├── ping-pong.md │ │ └── simple-bridge.md │ ├── guides │ │ ├── _category_.json │ │ ├── authentication.md │ │ ├── chain-abstraction.md │ │ ├── estimating-fees.md │ │ ├── handling-failures.md │ │ ├── nested-xcalls.md │ │ ├── sdk-frontend-integration.md │ │ ├── sdk-guides.md │ │ └── xcall-status.md │ ├── intro.md │ ├── quickstart.mdx │ └── reference │ │ ├── SDK │ │ ├── SdkBase.mdx │ │ ├── SdkPool.mdx │ │ ├── SdkRouter.mdx │ │ ├── SdkShared.mdx │ │ ├── SdkUtils.mdx │ │ ├── Types.mdx │ │ └── _category_.json │ │ ├── _category_.json │ │ ├── contracts │ │ ├── _category_.json │ │ ├── calls.md │ │ ├── routers.md │ │ ├── stableswap.md │ │ └── types.md │ │ ├── integration │ │ ├── _category_.json │ │ ├── adapters.md │ │ └── receivers.md │ │ └── subgraph │ │ ├── Entities.md │ │ ├── Queries.md │ │ ├── Resources.md │ │ └── _category_.json ├── resources │ ├── _category_.json │ ├── deployed.json │ ├── deployments.md │ └── supported-chains.md └── routers │ ├── Guides │ ├── _category_.json │ ├── community-guides.md │ ├── liquidity.md │ ├── management.md │ └── security.md │ ├── Reference │ └── configuration.md │ ├── _category_.json │ ├── images │ ├── addRouterLiquidity.png │ ├── flow.png │ ├── manageRouter.png │ ├── nat.png │ ├── receiveNextAsset.png │ ├── removeRouterLiquidity.png │ ├── routerAddresses.png │ ├── themis.png │ └── wallet.png │ ├── intro.md │ └── spinning-up.md ├── docusaurus.config.js ├── package.json ├── sidebars.js ├── src ├── components │ ├── CardLink.jsx │ └── CardLink.module.css ├── css │ └── custom.css ├── pages │ ├── index.jsx │ ├── index.module.css │ └── styles.module.css └── remark │ └── CardLink.js ├── static ├── .nojekyll └── img │ ├── background │ ├── Architecture.png │ └── HighLevelFlow.png │ ├── basics │ └── diagram.png │ ├── connextLogoBig.png │ ├── connext_Logo.png │ ├── connext_Logo.svg │ ├── core-concepts │ ├── Connext_quick_overview.png │ ├── clusters.png │ ├── external.png │ ├── interoperability_trilemma.png │ ├── local.png │ ├── native.png │ └── optimistic.png │ ├── developers │ ├── AMB_Architecture.png │ ├── chain_abstraction.png │ ├── connext_flow.png │ └── examples │ │ └── etherscan_xTransferEth.png │ ├── discord_logo.svg │ ├── faq │ ├── assets.png │ └── read_tokenId.png │ ├── github_logo.svg │ ├── guides │ ├── connextscan_complete.png │ └── connextscan_search.png │ ├── logo.svg │ ├── logomark.ico │ ├── logomark.png │ ├── quickstart │ ├── TEST_Etherscan_approve.png │ ├── greeting_updated.png │ ├── write_contract_etherscan.png │ └── xUpdateGreeting.png │ ├── routers │ ├── LPs.png │ └── modular_architecture.png │ ├── tutorial │ ├── docsVersionDropdown.png │ └── localeDropdown.png │ ├── undraw_docusaurus_mountain.svg │ ├── undraw_docusaurus_react.svg │ ├── undraw_docusaurus_tree.svg │ └── xcall_snippet.png ├── versions.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 4 | 5 | ## Installation 6 | 7 | ```console 8 | yarn install 9 | ``` 10 | 11 | 12 | 13 | ## Local Development 14 | 15 | ```console 16 | yarn start 17 | ``` 18 | 19 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 20 | 21 | ## Build 22 | 23 | ```console 24 | yarn build 25 | ``` 26 | 27 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 28 | 29 | ## Deployment 30 | 31 | ```console 32 | GIT_USER= USE_SSH=true yarn deploy 33 | ``` 34 | 35 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 36 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/concepts/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Concepts", 3 | "position": 1 4 | } 5 | -------------------------------------------------------------------------------- /docs/concepts/background/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Bridge Background", 3 | "position": 2 4 | } 5 | -------------------------------------------------------------------------------- /docs/concepts/background/modular-bridges.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | id: "modular-bridges" 4 | --- 5 | 6 | # Modular Bridges 7 | 8 | The vast majority of generalized bridges out there today are *monolithic*. This means that they are tied to a specific verification mechanism that is implemented as a core part of the bridge construction. 9 | 10 | Connext is the first example of a generalized crosschain messaging mechanism that is *modular*, plugging into the best available verification method for a given ecosystem. 11 | 12 | ## Clusters 13 | 14 | To understand why Connext is designed the way that it is, let us first explore the concept of [Clusters](https://blog.celestia.org/clusters/). 15 | 16 | A cluster is a sovereign set of domains that share security and can communicate with one another using trust-minimized methods. For example, Ethereum and its rollups form a cluster. Cosmos chains are another cluster. Singular "monolithic" chains, such as Solana are also their own cluster. 17 | 18 | ![image](../../../static/img/core-concepts/clusters.png) 19 | 20 | In the [Message Verification](./verification.md) section, we broke down the different methods that exist to secure a message that travels between two domains. As we noted, the **best available mechanism** for verifying messages is different based on the specific pair of domains we want to communicate between. Another way to say this is that there is a *heterogenous* topology for message verification mechanisms across all networks. 21 | 22 | For example, between a rollup and its L1, the most secure verification mechanism is to use the rollup bridge itself. 23 | 24 | :::caution 25 | The security of a domain is always the security of its weakest link. This means that *any* method of passing messages to a rollup that isn't the rollup bridge introduces at least *some* trust assumptions and security overhead, which in turn weakens the benefit of using a rollup (vs a less secure domain such as a sidechain) in the first place. 26 | ::: 27 | 28 | On the other hand, the most secure way to verify a message that passes between two discrete chains is a light client (zk or otherwise). Light client implementations exist in some places, but not everywhere yet - and it's highly unlikely that a single light client protocol will "win" every single pathway between sovereign chains. 29 | 30 | ## Pluggable Verification 31 | 32 | Modular bridges make the verification layer (and potentially other parts!) of the [bridging stack](./what-is-a-bridge.md) pluggable. By doing this, they can leverage *existing* methods of message verification wherever possible. This gives the best possible security for applications that may want to interact with multiple (heterogenous) domains simultaneously. -------------------------------------------------------------------------------- /docs/concepts/background/verification.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | id: "verification-mechanisms" 4 | --- 5 | 6 | # Message Verification 7 | 8 | :::note 9 | We recommend checking out the [What is a Bridge?](./what-is-a-bridge.md) section if you haven't already! 10 | ::: 11 | 12 | The most important component of any crosschain messaging system is how messages are *verified* across domains. There are a number of different verification methods, [each with their own tradeoffs](https://blog.connext.network/the-interoperability-trilemma-657c2cf69f17). 13 | 14 | ## Summary Table 15 | 16 | | | **External** | **Optimistic** | **Local** | **Native** | **Rollups** | 17 | |-------------------|---------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------| 18 | | Mechanism | External actors attest message correctness. | Messages incur 30 min delay and are disputable by Watchers. | Messages are verified by the parties who they affect. E.g. a swap is verified by both counterparties. | Messages are verified directly by chain validator set, typically using a light client + using ZKPs for scalability. | Special case: L1 runs a "full node" directly verifying state transitions (not just consensus!) of rollup. | 19 | | Trust assumptions | Fully assumes honesty of verifier set. PoS systems have better security than MPC or Oracle/Relay ones. | Assumes that at least 1 Watcher is online, honest, and able to send a transaction to chain. | Assumes liveness of all parties within a certain period to verify message. | Light clients verify *consensus* but not state - assume honest relayer can give them the correct block to verify. | Reasonable/minimal assumptions around L1 censorability and ZK proof schema. | 20 | | Tradeoffs | Most trusted option compared to underlying chains. | (1) Message latency - can be combined with local verification to cut latency in many cases. (2) Censorship risk of Watchers - can be mitigated with economic incentives. | Doesn't really scale beyond 2 parties. This means only *some* types of messages are supported - see Authentication for details. | Difficult to build + needs custom work for each chain. Doesn't really work for rollups. | Proving state transitions only works for rollups, not between two separate chains. | 21 | | Examples | LayerZero, Celer, Multichain, Axelar | Nomad, Hyperlane, Hop (also local), Across (also local) | Connext v0, Hop (also optimistic), Across (also optimistic) | IBC, Succinct Labs, zkBridge, zkIBC | Optimism, Arbitrum, ZkSync, Starkware | | 22 | 23 | ## External 24 | 25 | ![Externally Verified](/img/core-concepts/external.png) 26 | 27 | Externaly verified bridges rely on an 3rd-party set of actors to attest the correctness of data that is transported between chains. This is typically represented as an multisig, MPC system, PoS validator set, or oracle/relay. 28 | 29 | External verification is easy to extend to any chain, and can support generalized messages at low latency. However, the security of a message passed between chains *fully* relies on the verifier set - this means that security scales with the size of the set. In most cases, externally verified bridges have far less security than the underlying chains, implying that they are not trust-minimized. 30 | 31 | :::tip 32 | External bridges with large validator sets and staked incentives (e.g. PoS systems) are more secure than their smaller counterparts. 33 | ::: 34 | 35 | ## Optimistic 36 | 37 | ![Optimistic Bridges](/img/core-concepts/optimistic.png) 38 | 39 | [Optimistic bridges](https://blog.connext.network/optimistic-bridges-fb800dc7b0e0) use **fraud proofs** to ensure the validity of data relayed across chains. Every message that passes through an optimistic bridge remains in a “pending” state during the dispute window until it is considered valid. During this time, **watchers** can dispute the message if the data is incorrect. 40 | 41 | Optimistic bridges assume that there is at least one Watcher online somewhere (1-of-n assumption) that can send a transaction to chain. They also assume that Watchers will not abuse their position to censor the system. Censorship risk can be minimized using economic (dis)incentives. 42 | 43 | ## Native 44 | 45 | ![Natively Verified](/img/core-concepts/native.png) 46 | 47 | In a natively verified bridge, a chain's own validator set verifies information coming in from another chain. This happens by implementing a [light client](https://geth.ethereum.org/docs/fundamentals/les) of one chain within the VM of another, typically within a zk-snark to keep expensive computation offchain. 48 | 49 | Because light clients verify *consensus* but not the state transitions of the block itself (the latter requires [Data Availability](https://ethereum.org/en/developers/docs/data-availability/)), they assume the existence of an **honest relayer** who can [give them the "correct" block from a connected chain](https://blog.connext.network/validity-proofs-are-not-effective-for-bridging-blockchains-85b5e3b22a35). This makes them vulnerable to attacks where the validators of one chain produce an invalid block (for example, through a 51% attack) to spoof a message through the bridge. 50 | 51 | :::tip 52 | This honest relayer assumption of light client based bridges is the key point behind Vitalik's often-discussed [Multichain not Crosschain](https://twitter.com/VitalikButerin/status/1479501366192132099?s=20) post. 53 | ::: 54 | 55 | Natively verified bridges have an additional tradeoff in that they require custom work for each chain with a new consensus mechanism. For some domains, for example with rollups, there may not be a light-client based strategy for bridging that works without additional trust tradeoffs. 56 | 57 | Despite the above, natively verified bridges (regardless of whether they use ZKPs) are the best mechanism for moving data between two discrete blockchains. 58 | 59 | ## Special Case: Local 60 | 61 | ![Locally Verified](/img/core-concepts/local.png) 62 | 63 | Locally verified bridges are a special case of bridging where only the parties involved in a given cross-domain interaction verify the interaction. This is typically done through schemes like atomic swaps. 64 | 65 | The challenge of locally verified bridges is that they require the liveness of all parties involved in a transaction, degrading UX and making it impractical to execute transactions that involve more than 2 parties. This further means that only some types of transactions are supported. For example, a peer-to-peer transfer is possible because there are only two parties involved, but many types of peer-to-contract interactions would not be possible as *every* chain user would be involved. 66 | 67 | Local verification techniques are typically used in conjunction with other mechanisms such as optimistic bridges to improve latency. You can learn more about what types of messages can be executed immediately through local verification in our Authentication section. 68 | 69 | ## Special Case: Rollups 70 | 71 | Rollups are another special case. Rollups exist specifically to solve for the "honest relayer" assumption that exists with light client based bridges. They do this by creating a strict heirarchy between the parent chain (the L1) and the rollup, with all rollup data being available on the L1. This allows the L1 to run a "full client", directly verifying the state transitions of the rollup itself. 72 | 73 | Rollup bridges are **the most secure** mechanism to communicate between any two domains. Period. 74 | 75 | However, they can only exist between a rollup and its L1. See our section on Intercluster vs Intracluster communication for details. 76 | -------------------------------------------------------------------------------- /docs/concepts/background/what-is-a-bridge.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | id: "what-is-a-bridge" 4 | --- 5 | 6 | # What is a Bridge? 7 | 8 | A bridge (AKA crosschain messaging protocol or interoperability network) is a system that relays information between blockchains. 9 | 10 | While there are many bridges out there today, every bridge has the same core structure and components. 11 | 12 | | **Layer** | **Function** | 13 | |--------------|-------------------------------------------------------------------------------------------------------------------| 14 | | Transport | Read root or hash of data on origin chain and post to destination. | 15 | | Verification | Ensure that the above data is correct. | 16 | | Execution | Generate merkle roots or hashes on origin. Prove against the root and execute the target function on destination. | 17 | | Application | Handle specific usecases such as token transfers, NFTs, governance, and more! | 18 | 19 | ## Messaging Layers 20 | 21 | ### Transport 22 | 23 | Transport is how a payload of data gets read from one domain and posted to another, making no assumptions about the correctness of the data. 24 | 25 | This is typically done by one or many offchain actors that watch an *outbox* of data on the origin chain, and then post the corresponding data to an *inbox* on a connected destination domain. To keep this process scalable, protocols will typically relay merkle roots rather than data in raw form. 26 | 27 | ### Verification 28 | 29 | Verification is how crosschain communication is *secured*. After a payload is transported across chains, a bridge will verify the data prior to it becoming usable on the destination domain. 30 | 31 | There are many different ways to verify messages across domains, each with their own tradeoffs on trust, cost, and latency. See Message Verification for a longer discussion about this step. 32 | 33 | ### Execution 34 | 35 | Once a verified payload is available on the destination, some offchain infrastructure is needed to "push" that payload into a target function. 36 | 37 | Bridge execution layers are the interface that developers will typically interact with when integrating with a bridge. Execution layers collect gas fees (in Connext, this is collected as additional gas paid on the origin chain) and use those fees to execute a transaction on the destination chain against the target function the developer intends to interact with. 38 | 39 | Execution layers may additionally be responsible for generating merkle roots on each origin domain, and then generating a merkle proof against that root on a destination domain. 40 | 41 | ## Application Layers 42 | 43 | In addition to the above messaging layers, bridges may implement one or many **application layers** that define how specific usecases are enabled across domains. 44 | 45 | -------------------------------------------------------------------------------- /docs/concepts/faq.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 7 3 | id: faq 4 | --- 5 | 6 | # FAQ 7 | 8 | This is a list of Frequently Asked Questions for the Amarok public testnet. 9 | 10 | ## What chains are supported? 11 | 12 | An updated list can be found at [Supported Chains](../resources/supported-chains.md). 13 | 14 | ## What assets are supported? 15 | 16 | See the deployed addresses for assets at [Deployed Contract Addresses](../resources/deployments.md). 17 | 18 | ## What are token "flavors"? 19 | 20 | drawing 21 | 22 | ## How do I find the canonical details of a token? 23 | 24 | The canonical domainId and tokenId of a token can be found by calling the [`getTokenId`](https://github.com/connext/monorepo/blob/3d0af2251b2d8d244d2617be6fb738c09a571022/packages/deployments/contracts/contracts/core/connext/helpers/TokenRegistry.sol#L176) function of `TokenRegistry`. 25 | 26 | Example: 27 | - The token of interest is TestERC20 (`0x7ea6eA49B0b0Ae9c5db7907d139D9Cd3439862a1`) on Goerli. We want to figure out its canonical domainId and tokenId. 28 | - Find the Connext contract address on Goerli from [here](../resources/deployments), click its link to open up the Diamond Inspector on Louper. 29 | - Find the `TokenFacet` and click the "Read" button. 30 | - Select the `getTokenId` method and input the TestERC20 address to obtain its canonical details. 31 | 32 | drawing 33 | 34 | - Alternatively, you can call `getTokenId` using a tool like Foundry's `cast` to read from the contract. 35 | 36 | ```bash 37 | cast call --chain goerli 0x99A784d082476E551E5fc918ce3d849f2b8e89B6 "getTokenId(address)(uint32,bytes32)" "0x7ea6eA49B0b0Ae9c5db7907d139D9Cd3439862a1" --rpc-url 38 | ``` 39 | 40 | Returns: 41 | 42 | ```bash 43 | 1735353714 # the canonical domainId is Goerli 44 | 0x0000000000000000000000007ea6ea49b0b0ae9c5db7907d139d9cd3439862a1 # the canonical bytes32 tokenId 45 | ``` 46 | 47 | ## What if I just want to test the destination-side target function? 48 | 49 | If there’s no token transfer involved then just set `transactingAssetId: address(0)` and `amount: 0`. 50 | 51 | ## Do I need to do anything with the AMB contracts? 52 | 53 | No, you do not need to deploy or even interact with AMB contracts directly. 54 | 55 | ## How do I find the different domainIds? 56 | 57 | See [Domain IDs](../resources/supported-chains). 58 | 59 | ## Where are the Connext contracts? 60 | 61 | See [Deployed Contract Addresses](../resources/deployments). 62 | 63 | ## How do I take my token crosschain? 64 | 65 | There are a few steps to take, so please reach out to us for assistance: 66 | 67 | - The Connext team whitelists your asset (for now, this is required). 68 | - You transfer some of the assets across the bridge. 69 | - If the destination asset has the amb flavored asset as the adopted asset (there's no existing pool, no representative asset exists yet), then the Token Registry will deploy a new token and set it as canonical. 70 | 71 | ## Are there size limits to calldata? 72 | 73 | Yes and the details will be posted soon. 74 | -------------------------------------------------------------------------------- /docs/concepts/how-it-works/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "How Connext Works", 3 | "position": 3 4 | } 5 | -------------------------------------------------------------------------------- /docs/concepts/how-it-works/architecture.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | id: "architecture" 4 | --- 5 | 6 | # Architecture 7 | 8 | The Connext protocol is composed of a set of smart contracts and offchain agents. 9 | 10 | ## Smart Contracts 11 | 12 | Connext's smart contracts are the interfaces between the protocol and the wide gamut of different users in the ecosystem. There are contracts for handling `xcall`, managing asset registration, and provisioning liquidity for routers and stableswap LPs. 13 | 14 | The full contract stack consists of the following components. 15 | 16 | ### Connext 17 | 18 | Dispatches and handles messages related to sending funds across chains. Custodies funds for canonical assets, fast liquidity, and stable swaps. 19 | 20 | The Connext contract uses the [Diamond](https://eips.ethereum.org/EIPS/eip-2535) pattern so it comprises a set of Facets that act as logical boundaries for groups of functions. Facets share contract storage and can be upgraded separately. 21 | 22 |
23 | 24 | Diamond Facets 25 | 26 | ### TokenFacet 27 | Manages asset enrollment, stores mappings of adopted <-> local assets, exposes liquidity caps functions, and specifies stableswaps for assets. 28 | 29 | ### BridgeFacet 30 | 31 | Implements `xcall` and enables destination-side calldata execution. 32 | 33 | ### InboxFacet 34 | 35 | Holds all the functionality needed for Connext's messaging layer to reconcile cross-chain transfers. 36 | 37 | ### ProposedOwnableFacet 38 | 39 | Provides a basic access control mechanism. 40 | ### RelayerFacet 41 | 42 | Manages whitelisting of relayers. 43 | ### RoutersFacet 44 | 45 | Manages whitelisting of routers and keeps track of router owners/recipients. 46 | ### StableSwapFacet 47 | 48 | A StableSwap implementation that custodies closely pegged assets (eg. group of stablecoins). 49 | 50 | ### SwapAdminFacet 51 | 52 | Manages only-admin controls for the StableSwapFacet. 53 | 54 | ### DiamondCutFacet 55 | 56 | Functions for adding, removing, and replacing facets. 57 | 58 | ### DiamondLoupeFacet 59 | 60 | Required by the Diamond standard. Implements the DiamondLoupe interface which allows for inspection of a Diamond contract's various facets and their functions. 61 | 62 |
63 | 64 | ### Messaging 65 | 66 | The various contracts required to manage merkle roots containing hashed transfer data and send them through a hub-and-spoke architecture. The messaging architecture includes: 67 | 68 | - **Connector.** A connector is an abstraction around an underlying transport layer. The `IConnector` interface requires a `processMessage` method implemented for handling incoming messages. `Connector` is an abstract contract that is inherited by the following contracts: 69 | 70 | - **SpokeConnector.** The `SpokeConnector` is deployed on spoke domains and implements a `send` method to send the Merkle root of all the messages that originate from the spoke domain to the hub domain. For example, `ArbitrumSpokeConnector` is deployed on the Arbitrum L2. 71 | 72 | - **HubConnector.** The `HubConnector` is deployed on hub domains for each spoke and implements a `sendMessage` method to send the aggregated Merkle root of all the received spoke Merkle roots to the configured destination domain. For example `ArbitrumHubConnector` is deployed on Ethereum L1. 73 | 74 | :::info 75 | 💡 Each AMB implementation requires us to create and deploy `HubConnector` and `SpokeConnector` contracts for that flavor of AMB, calling into the internal bridge infrastructure. 76 | ::: 77 | 78 | ## Offchain Agents 79 | 80 | ### Routers 81 | 82 | Routers are liquidity providers that enable instant liquidity for the user on the destination chain in return for a fee. Anybody can participate in the protocol as a router and there is no minimum liquidity required! Routers provide a crucial service to the Connext protocol. 83 | 84 | Learn how to run one in the [Routers Section](../../routers/intro.md). 85 | 86 | ### Sequencer 87 | 88 | The sequencer collects bids from all chains and randomly selects router(s) to fulfill them. Any number of routers can fulfill a single transaction, which is especially useful for large transfers. The sequencer will post batches of these bids to a relayer network to submit them to chain. 89 | 90 | ### Relayers 91 | 92 | Relayers are a decentralized network of infrastructure operators that can execute smart contract transactions on behalf of a user in exchange for a small fee. Because the last leg of a cross-chain transaction requires execution on the destination domain, relayers play an important role in completing the full flow. 93 | 94 | We are currently using [Gelato](https://www.gelato.network/) as our relayer service. 95 | -------------------------------------------------------------------------------- /docs/concepts/how-it-works/flow.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | id: transaction-flow 4 | --- 5 | 6 | # Transaction Lifecycle 7 | 8 | ![Connext Diagram](/img/core-concepts/Connext_quick_overview.png "Title") 9 | 10 | In this diagram we observe two domains, "origin" and "destination", representing the chains that a cross-chain message will originate from and travel to. 11 | 12 | We also see a differentiation between "fast path" and "slow path". 13 | 14 | --- 15 | ## Fast Path 16 | 17 | ### Requirements 18 | 19 | For a cross-chain message to travel through the fast path, it must abide by **BOTH** of these requirements: 20 | 21 | 1. The transaction is bridging tokens *only* (no calldata) OR the calldata included is unauthenticated (anyone is allowed to call the function on the target contract). 22 | 23 | *AND* 24 | 25 | 2. Routers are providing sufficient liquidity of the bridged token on the destination domain. We sometimes refer to this as the availability of "fast liquidity". If fast liquidity is *not* available, then the message will go through the slow path. 26 | 27 | ### Examples 28 | 29 | - A simple token bridge (like the [Connext Bridge](https://bridge.connext.network/)) 30 | - Send funds from origin to destination and then execute a Uniswap `swap()` on destination 31 | 32 | ### How it works 33 | 34 | Connext is able to shortcut the normal AMB messaging delay (sometimes hours or days of latency!) by allowing its network of routers to **front the capital to the user** on the destination domain. Routers wait out the AMB latency in the user's stead, allowing the user to receive funds almost immediately. In exchange for taking on the risk of this temporary liquidity lockup, routers are compensated with a small fee. Note that at the end of the waiting window, routers always get reimbursed. 35 | 36 | --- 37 | 38 | ## Slow Path 39 | 40 | ### Requirements 41 | 42 | Essentially the inverse of fast path; if **ANY** of these apply to the cross-chain message, it will travel through the slow path: 43 | 44 | 1. The transaction includes authenticated calldata (the destination function checks the originating caller from the origin domain). 45 | 46 | *OR* 47 | 48 | 2. There is insufficient router liquidity of the bridged token on the destination domain. 49 | 50 | ### Examples 51 | 52 | - Execute DAO votes across chains 53 | - Change protocol settings from any chain 54 | - Generally, do anything that has an `onlyOwner` modifier or equivalently must validate the origin caller 55 | 56 | ### How it works 57 | 58 | The message takes on the full AMB delay, allowing the AMB verification process to complete. This is why slow path messages can trust that the origin caller is correct since data integrity is maintained. 59 | 60 | --- 61 | 62 | ## Detailed Flow Summary 63 | 64 | connext full flow summary 65 | 66 | A transaction flowing through Connext will have the following lifecycle: 67 | 68 | - User will initiate the transaction by calling an `xcall` function on the Connext contract, passing in funds, gas details, arbitrary data, and a target address object (includes chain info). 69 | - *Note: `xcall` is meant to mimic solidity's lower level call as best as possible.* 70 | 71 | - The Connext contracts will: 72 | - If needed, swap the passed in token to the AMB version of the same asset. 73 | - Call the AMB contracts with a hash of the transaction details to initiate the 60 minute message latency across chains. 74 | - Emit an event with the transaction details. 75 | 76 | - Routers observing the origin chain with funds on the destination chain will: 77 | - Simulate the transaction (if this fails, the assumption is that this is a more "expressive" crosschain message that requires authentication and so must go through the AMB: the slow path). 78 | - Prepare a signed transaction object using funds on the receiving chain. 79 | - Post this object (a "bid") to the sequencer. 80 | - *Note: if the router does not have enough funds for the transfer, they may also provide only part of the transfer's value.* 81 | - The sequencer will be observing all of the underlying chains. Every X blocks, the sequencer will collect bids for transactions. The sequencer will be responsible for selecting the correct router (or routers!) for a given transaction (can be random). The sequencer will post batches of these bids to a relayer network to submit them to chain. 82 | - When a given bid is submitted to chain, the contracts will do the following: 83 | - Check that there are enough funds available for the transaction. 84 | - Swap the router's AMB-flavored funds for the canonical asset of the chain if needed. 85 | - Send the swapped funds to the correct target (if it is a contract, this will also execute `calldata` against the target). 86 | - Hash the router's params and store a mapping of this hash to the router's address in the contract. 87 | - *At this point, the user's transaction has already been completed!* 88 | - Later, when the slow path message arrives, a heavily batched transaction can be submitted to take all pending hashes received over the AMB and look up whether they have corresponding router addresses in the hash -> router address mapping. If they do, then AMB assets are minted and given to the router. 89 | - *Note: if the router gives the incorrect amount of funds to a user or if they execute the wrong calldata, then the router's param hash will not match the hash coming over the AMB and the router will not get reimbursed. This is the core security mechanism that ensures that routers behave correctly.* 90 | - *Note: Routers will take a 60 minute lockup on their funds when relaying transactions. While this theoretically reduces capital efficiency compared to the existing system, in practice the lack of need to rebalance will mean that routers have more capital available more often regardless.* 91 | -------------------------------------------------------------------------------- /docs/concepts/what-is-connext.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | id: what-is-connext 4 | --- 5 | 6 | # What is Connext? 7 | 8 | :::info 9 | The Core Concepts section is still under development! 10 | ::: 11 | 12 | Welcome! 👋 13 | 14 | Connext is a modular protocol for securely passing funds and data between chains. Developers can use Connext to build crosschain apps (**xApps**) - applications that interact with multiple domains (blockchains and/or rollups) simultaneously. 15 | 16 | ## Why Do We Need xApps? 17 | 18 | Blockchains do not scale to the level of volume needed for mainstream adoption. 19 | 20 | Ethereum and other programmable blockchains solve this problem by [moving users, funds, and data to multiple parallel domains](https://ethereum.org/en/layer-2/) (sidechains, rollups, and other chain-like constructions). This, however, creates a new challenge: a *fragmented* user experience. 21 | 22 | Similar to how Youtube users do not need to understand Google's distributed database infrastructure, decentralized application users should not need to consciously think about what chain they are on, or how to move between chains. In other words, applications should *abstract* the multichain experience by becoming xApps, and do so while retaining the security and trust-minimization properties of the underlying chains. 23 | 24 | ## Design Philosophy 25 | 26 | Connext is built with three core design principles in mind that make it the best option for developers looking to build xApps without compromising on trustlessness. 27 | 28 | ### Modularity 29 | 30 | Connext utilizes a modular hub-and-spoke architecture, which derives its security from Ethereum L1 and *plugs into* the battle-tested **canonical** messaging bridges that underpin the security of each Ethereum-connected domain. 31 | 32 | Messages in Connext are added to a merkle root generated on each spoke domain, which are then optimistically aggregated into a singular root on Ethereum L1. In the event that fraud occurs, the system falls back to using the canonical messaging bridge for each chain ecosystem. In other words, a message passed between Polygon and Optimism is secured by a proof that is posted to Ethereum and verified by the Polygon PoS bridge and Optimism rollup bridge. Similarly, a message passed within the Cosmos ecosystem is verified by IBC. 33 | 34 | This mechanism gives developers the **best possible** trust guarantees for whichever chains they want to build on. For fraud to occur in our Polygon to Optimism example, there would need to be a compromise of Polygon or Optimism's canonical bridges *and* Connext's failsafe mechanisms. 35 | 36 | ### Security 37 | 38 | Bridges and crosschain messaging are some of the most critical infrastructure in the space, with a high potential risk for catastrophe in the event of hacks or bugs. In the past 18 months, almost **$2B** has been lost to bridge hacks. 39 | 40 | Connext utilizes Watchers, automated offchain actors, that observe the network and halt message passing in the event that fraud or a hack is observed. This ensures that damage due to the failure of any individual part of the network is minimized. 41 | 42 | Additionally, Connext follows a strict philosophy of secure development, requiring rigorous external review for code changes and working closely with the security community to educate auditors on bridge security risks and collaborate on creating best practices. 43 | 44 | ### Simplicity 45 | 46 | Migrating to a completely new multichain development workflow can be challenging. 47 | 48 | Rather than reinventing the wheel, Connext tries to mimic and extend existing development patterns as much as possible. The protocol implements a single, simple primitive - `xcall` - which allows devs to asynchronously interact with contracts living on another chain/rollup similarly to how you would `call` a contract living on the same chain/rollup. 49 | 50 | Connext additionally plugs into the tooling and supporting infrastructure that is *already* widely used in the ecosystem. Have a development workflow that isn't well supported by Connext? [Let us know](https://discord.gg/pef9AyEhNz) and our community can help build support for it! 51 | 52 | ## What Can I Build With Connext? 53 | 54 | In short, pretty much anything! Here are some of the ideas that members of our community are working on: 55 | 56 | - Executing the outcome of **DAO votes** across chains 57 | - Lock-and-mint or burn-and-mint **token bridging** 58 | - **Aggregating DEX liquidity** across chains in a single seamless transaction 59 | - Crosschain **vault zaps** and **vault strategy management** 60 | - **Lending funds** on one chain and borrow on another 61 | - Bringing **UniV3 TWAPs** to every chain without introducing oracles 62 | - **NFT bridging** and chain-agnostic NFT marketplaces 63 | - **Storing data on Arweave/Filecoin** directly from within an Ethereum smart contract 64 | 65 | ## Where Do I Go Next? 66 | 67 | If the above information was overwhelming, don't worry! We have plenty more resources to help you learn about Connext: 68 | - If you're a developer and want to start building with `xcall`, check out our [Developer Quickstart](../developers/quickstart) and [Examples](../developers/examples/simple-bridge.md). 69 | - Want to learn more about how the protocol works? Read through the [How Connext Works](./how-it-works/flow.md) section. 70 | - Are you an infrastructure operator? Help run the network by [operating a Connext router](../routers/intro.md). 71 | - Still not sure where to go? Join our [Discord](https://discord.gg/pef9AyEhNz) server and chat with us in the `#dev-hub` channel. 72 | -------------------------------------------------------------------------------- /docs/developers/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Developers", 3 | "position": 2 4 | } 5 | -------------------------------------------------------------------------------- /docs/developers/examples/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Examples", 3 | "position": 3, 4 | "collapsed": false 5 | } 6 | -------------------------------------------------------------------------------- /docs/developers/examples/authenticated-hello.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | id: authenticated-hello 4 | --- 5 | 6 | # Authenticated Greeter 7 | 8 | The `DestinationGreeterAuthenticated` contract sets some permissioning constraints. It only allows its `greeting` to be updated from `SourceGreeterAuthenticated`. In order to enforce this, the contract checks that the caller is the original sender from the origin domain. 9 | 10 | ## Target Contract 11 | 12 | The target contract must implement some checks to uphold its security constraints. 13 | 14 | ```solidity 15 | // SPDX-License-Identifier: UNLICENSED 16 | pragma solidity ^0.8.15; 17 | 18 | import {IXReceiver} from "@connext/interfaces/core/IXReceiver.sol"; 19 | 20 | /** 21 | * @title DestinationGreeterAuthenticated 22 | * @notice Example destination contract that stores a greeting and only allows source to update it. 23 | */ 24 | contract DestinationGreeterAuthenticated is IXReceiver { 25 | // The Connext contract on this domain 26 | address public immutable connext; 27 | 28 | // The domain ID where the source contract is deployed 29 | uint32 public immutable originDomain; 30 | 31 | // The address of the source contract 32 | address public immutable source; 33 | 34 | string public greeting; 35 | 36 | /** @notice A modifier for authenticated calls. 37 | * This is an important security consideration. If the target contract 38 | * function should be authenticated, it must check three things: 39 | * 1) The originating call comes from the expected origin domain. 40 | * 2) The originating call comes from the expected source contract. 41 | * 3) The call to this contract comes from Connext. 42 | */ 43 | modifier onlySource(address _originSender, uint32 _origin) { 44 | require( 45 | _origin == originDomain && 46 | _originSender == source && 47 | msg.sender == connext, 48 | "Expected original caller to be source contract on origin domain and this to be called by Connext" 49 | ); 50 | _; 51 | } 52 | 53 | constructor( 54 | uint32 _originDomain, 55 | address _source, 56 | address _connext 57 | ) { 58 | originDomain = _originDomain; 59 | source = _source; 60 | connext = _connext; 61 | } 62 | 63 | /** @notice Authenticated receiver function. 64 | * @param _callData Calldata containing the new greeting. 65 | */ 66 | function xReceive( 67 | bytes32 _transferId, 68 | uint256 _amount, 69 | address _asset, 70 | address _originSender, 71 | uint32 _origin, 72 | bytes memory _callData 73 | ) external onlySource(_originSender, _origin) returns (bytes memory) { 74 | // Unpack the _callData 75 | string memory newGreeting = abi.decode(_callData, (string)); 76 | 77 | _updateGreeting(newGreeting); 78 | } 79 | 80 | /** @notice Internal function to update the greeting. 81 | * @param newGreeting The new greeting. 82 | */ 83 | function _updateGreeting(string memory newGreeting) internal { 84 | greeting = newGreeting; 85 | } 86 | } 87 | ``` 88 | 89 | ## Source Contract 90 | 91 | Nothing special has to be accounted for on the source contract. 92 | 93 | ```solidity showLineNumbers 94 | // SPDX-License-Identifier: UNLICENSED 95 | pragma solidity ^0.8.15; 96 | 97 | import {IConnext} from "@connext/interfaces/core/IConnext.sol"; 98 | 99 | /** 100 | * @title SourceGreeterAuthenticated 101 | * @notice Example source contract that updates a greeting in DestinationGreeterAuthenticated. 102 | */ 103 | contract SourceGreeterAuthenticated { 104 | // The connext contract on the origin domain. 105 | IConnext public immutable connext; 106 | 107 | constructor(address _connext) { 108 | connext = IConnext(_connext); 109 | } 110 | 111 | /** @notice Updates a greeting variable on the DestinationGreeterAuthenticated contract. 112 | * @param target Address of the DestinationGreeterAuthenticated contract. 113 | * @param destinationDomain The destination domain ID. 114 | * @param newGreeting New greeting to update to. 115 | * @param relayerFee The fee offered to relayers. 116 | */ 117 | function xUpdateGreeting ( 118 | address target, 119 | uint32 destinationDomain, 120 | string memory newGreeting, 121 | uint256 relayerFee 122 | ) external payable { 123 | // Encode the data needed for the target contract call. 124 | bytes memory callData = abi.encode(newGreeting); 125 | 126 | connext.xcall{value: relayerFee}( 127 | destinationDomain, // _destination: Domain ID of the destination chain 128 | target, // _to: address of the target contract 129 | address(0), // _asset: use address zero for 0-value transfers 130 | msg.sender, // _delegate: address that can revert or forceLocal on destination 131 | 0, // _amount: 0 because no funds are being transferred 132 | 0, // _slippage: can be anything between 0-10000 because no funds are being transferred 133 | callData // _callData: the encoded calldata to send 134 | ); 135 | } 136 | } 137 | ``` 138 | 139 | Note that `HelloSource` should be deployed before `HelloTargetAuthenticated` because the latter needs the address of the former in its constructor. 140 | 141 | Now we've enforced that the greeting in `HelloTargetAuthenticated` can only be updated through `HelloSource`! 142 | -------------------------------------------------------------------------------- /docs/developers/examples/ping-pong.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | id: ping-pong 4 | --- 5 | 6 | # Ping Pong 7 | 8 | `Ping` is a contract on some domain and `Pong` is a contract on some other domain. The user sends a ping and a pong will be sent back! 9 | 10 | This example demonstrates how to use nested `xcall`s and a single direction emulating "callback" behavior. 11 | 12 | ## Ping Contract 13 | 14 | The `Ping` contract contains an external `startPingPong` function that the user will call to initiate the flow. It *also* implements `IXReceiver` because it will act as the "target" of an `xcall` from `Pong`. The `xReceive` function here is essentially a callback function - we can verify that something happened in `Pong`'s domain and handle any results passed back. 15 | 16 | ```solidity showLineNumbers 17 | // SPDX-License-Identifier: UNLICENSED 18 | pragma solidity ^0.8.15; 19 | 20 | import {IConnext} from "@connext/interfaces/core/IConnext.sol"; 21 | import {IXReceiver} from "@connext/interfaces/core/IXReceiver.sol"; 22 | 23 | /** 24 | * @title Ping 25 | * @notice Ping side of a PingPong example. 26 | */ 27 | contract Ping is IXReceiver { 28 | // The Connext contract on this domain 29 | IConnext public immutable connext; 30 | 31 | // Number of pings this contract has received 32 | uint256 public pings; 33 | 34 | constructor(address _connext) { 35 | connext = IConnext(_connext); 36 | } 37 | 38 | /** 39 | * @notice Starts the ping pong s. equence. 40 | * @param destinationDomain The destination domain ID. 41 | * @param target Address of the Pong contract on the destination domain. 42 | * @param relayerFee The fee offered to relayers. 43 | */ 44 | function startPingPong( 45 | address target, 46 | uint32 destinationDomain, 47 | uint256 relayerFee 48 | ) external payable { 49 | require( 50 | msg.value == relayerFee, 51 | "Must send gas equal to the specified relayer fee" 52 | ); 53 | 54 | // Include the relayerFee so Pong will use the same fee 55 | // Include the address of this contract so Pong will know where to send the "callback" 56 | bytes memory callData = abi.encode(pings, address(this), relayerFee); 57 | 58 | connext.xcall{value: relayerFee}( 59 | destinationDomain, // _destination: domain ID of the destination chain 60 | target, // _to: address of the target contract (Pong) 61 | address(0), // _asset: use address zero for 0-value transfers 62 | msg.sender, // _delegate: address that can revert or forceLocal on destination 63 | 0, // _amount: 0 because no funds are being transferred 64 | 0, // _slippage: can be anything between 0-10000 because no funds are being transferred 65 | callData // _callData: the encoded calldata to send 66 | ); 67 | } 68 | 69 | /** @notice The receiver function as required by the IXReceiver interface. 70 | * @dev The "callback" function for this example. Will be triggered after Pong xcalls back. 71 | */ 72 | function xReceive( 73 | bytes32 _transferId, 74 | uint256 _amount, 75 | address _asset, 76 | address _originSender, 77 | uint32 _origin, 78 | bytes memory _callData 79 | ) external returns (bytes memory) { 80 | uint256 _pongs = abi.decode(_callData, (uint256)); 81 | 82 | pings++; 83 | } 84 | } 85 | ``` 86 | 87 | ## Pong Contract 88 | 89 | `Pong` will send a nested `xcall` back to `Ping`, including some information that can be acted on. 90 | 91 | ```solidity showLineNumbers 92 | // SPDX-License-Identifier: UNLICENSED 93 | pragma solidity ^0.8.15; 94 | 95 | import {IConnext} from "@connext/interfaces/core/IConnext.sol"; 96 | import {IXReceiver} from "@connext/interfaces/core/IXReceiver.sol"; 97 | 98 | interface IPong { 99 | function sendPong( 100 | uint32 destinationDomain, 101 | address target, 102 | uint256 relayerFee 103 | ) external payable; 104 | } 105 | 106 | /** 107 | * @title Pong 108 | * @notice Pong side of a PingPong example. 109 | */ 110 | contract Pong is IXReceiver { 111 | // The Connext contract on this domain 112 | IConnext public immutable connext; 113 | 114 | // Number of pongs this contract has received 115 | uint256 public pongs; 116 | 117 | constructor(address _connext) { 118 | connext = IConnext(_connext); 119 | } 120 | 121 | /** 122 | * @notice Sends a pong to the Ping contract. 123 | * @param destinationDomain The destination domain ID. 124 | * @param target Address of the Ping contract on the destination domain. 125 | * @param relayerFee The fee offered to relayers. 126 | */ 127 | function sendPong( 128 | uint32 destinationDomain, 129 | address target, 130 | uint256 relayerFee 131 | ) internal { 132 | // Include some data we can use back on Ping 133 | bytes memory callData = abi.encode(pongs); 134 | 135 | connext.xcall{value: relayerFee}( 136 | destinationDomain, // _destination: Domain ID of the destination chain 137 | target, // _to: address of the target contract (Ping) 138 | address(0), // _asset: use address zero for 0-value transfers 139 | msg.sender, // _delegate: address that can revert or forceLocal on destination 140 | 0, // _amount: 0 because no funds are being transferred 141 | 0, // _slippage: can be anything between 0-10000 because no funds are being transferred 142 | callData // _callData: the encoded calldata to send 143 | ); 144 | } 145 | 146 | /** 147 | * @notice The receiver function as required by the IXReceiver interface. 148 | * @dev The Connext bridge contract will call this function. 149 | */ 150 | function xReceive( 151 | bytes32 _transferId, 152 | uint256 _amount, 153 | address _asset, 154 | address _originSender, 155 | uint32 _origin, 156 | bytes memory _callData 157 | ) external returns (bytes memory) { 158 | // Because this call is *not* authenticated, the _originSender will be the Zero Address 159 | // Ping's address was sent with the xcall so it can be decoded and used for the nested xcall 160 | ( 161 | uint256 _pings, 162 | address _pingContract, 163 | uint256 _relayerFee 164 | ) = abi.decode(_callData, (uint256, address, uint256)); 165 | 166 | pongs++; 167 | 168 | // This contract sends a nested xcall with the same relayerFee value used for Ping. That means 169 | // it must own at least that much in native gas to pay for the next xcall. 170 | require( 171 | address(this).balance >= _relayerFee, 172 | "Not enough gas to pay for relayer fee" 173 | ); 174 | 175 | // The nested xcall 176 | sendPong(_origin, _pingContract, _relayerFee); 177 | } 178 | 179 | /** 180 | * @notice This contract can receive gas to pay for nested xcall relayer fees. 181 | */ 182 | receive() external payable {} 183 | 184 | fallback() external payable {} 185 | } 186 | ``` 187 | 188 | An important note for `Pong` is that `sendPong` is *not* `payable` and neither is `xReceive`. So in order for the 2nd `xcall` to work with `relayerFees`, the someone has to send native gas on destination to `Pong`. In practice, this can take the form of a "gas tank" mechanism that can be filled by users or subsidized by protocols. 189 | 190 | Connext is working on an upgrade that will soon allow nested relayer fees to be deducted from the transacting asset, eliminating the need to fund receivers in their native gas token. 191 | -------------------------------------------------------------------------------- /docs/developers/examples/simple-bridge.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | id: simple-bridge 4 | --- 5 | 6 | # Simple Bridge 7 | 8 | The `SimpleBridge` just transfers tokens from a user to another wallet (could be themselves) on a different chain. Since no calldata is involved, no target contract is needed. 9 | 10 | 11 | 12 | In this example, `SimpleBridge` has two functions: 13 | - `xTransfer` bridges any ERC20 token 14 | - The user must first approve a spending allowance of the token to the `SimpleBridge` contract. 15 | - `relayerFee` is paid in native ETH so when `xTransfer` is called, `msg.value` MUST be passed in equal to the specified `relayerFee`. Informaation for calculating relayer fees can be found on [Estimating Fees](../guides/estimating-fees.md) page. 16 | 17 | - `xTransferEth` bridges ETH (for origin/destination chains whose native asset is ETH) 18 | - To send and receive native ETH, the flow is a bit different. Since Connext doesn't accept native ETH as the bridged asset, ETH should be first wrapped into WETH on the origin domain and then the delivered WETH on destination should be unwrapped back to ETH. 19 | - An Unwrapper contract that implements `IXReceive` already exists on all supported networks to be used as the `_to` target in `xcall`. The final recipient on destination should be encoded into the `callData` param for the Unwrapper to send ETH to (demonstrated on line 92 below). 20 | - When sending ETH, `msg.value` = `relayerFee` + `amount`. See example below (note: in Etherscan, the payable field is in `ether` while the other fields are specified in `wei`). 21 | 22 | etherscan xTransferETh 23 | 24 | ```solidity showLineNumbers 25 | // SPDX-License-Identifier: UNLICENSED 26 | pragma solidity ^0.8.15; 27 | 28 | import {IConnext} from "@connext/interfaces/core/IConnext.sol"; 29 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 30 | 31 | interface IWETH { 32 | function deposit() external payable; 33 | function approve(address guy, uint wad) external returns (bool); 34 | } 35 | 36 | /** 37 | * @title SimpleBridge 38 | * @notice Example of a cross-domain token transfer. 39 | */ 40 | contract SimpleBridge { 41 | // The connext contract on the origin domain 42 | IConnext public immutable connext; 43 | 44 | constructor(address _connext) { 45 | connext = IConnext(_connext); 46 | } 47 | 48 | /** 49 | * @notice Transfers non-native assets from one chain to another. 50 | * @dev User should approve a spending allowance before calling this. 51 | * @param token Address of the token on this domain. 52 | * @param amount The amount to transfer. 53 | * @param recipient The destination address (e.g. a wallet). 54 | * @param destinationDomain The destination domain ID. 55 | * @param slippage The maximum amount of slippage the user will accept in BPS. 56 | * @param relayerFee The fee offered to relayers. 57 | */ 58 | function xTransfer( 59 | address token, 60 | uint256 amount, 61 | address recipient, 62 | uint32 destinationDomain, 63 | uint256 slippage, 64 | uint256 relayerFee 65 | ) external payable { 66 | IERC20 _token = IERC20(token); 67 | 68 | require( 69 | _token.allowance(msg.sender, address(this)) >= amount, 70 | "User must approve amount" 71 | ); 72 | 73 | // User sends funds to this contract 74 | _token.transferFrom(msg.sender, address(this), amount); 75 | 76 | // This contract approves transfer to Connext 77 | _token.approve(address(connext), amount); 78 | 79 | connext.xcall{value: relayerFee}( 80 | destinationDomain, // _destination: Domain ID of the destination chain 81 | recipient, // _to: address receiving the funds on the destination 82 | token, // _asset: address of the token contract 83 | msg.sender, // _delegate: address that can revert or forceLocal on destination 84 | amount, // _amount: amount of tokens to transfer 85 | slippage, // _slippage: the maximum amount of slippage the user will accept in BPS (e.g. 30 = 0.3%) 86 | bytes("") // _callData: empty bytes because we're only sending funds 87 | ); 88 | } 89 | 90 | /** 91 | * @notice Transfers native assets from one chain to another. 92 | * @param destinationUnwrapper Address of the Unwrapper contract on destination. 93 | * @param weth Address of the WETH contract on this domain. 94 | * @param amount The amount to transfer. 95 | * @param recipient The destination address (e.g. a wallet). 96 | * @param destinationDomain The destination domain ID. 97 | * @param slippage The maximum amount of slippage the user will accept in BPS. 98 | * @param relayerFee The fee offered to relayers. 99 | */ 100 | function xTransferEth( 101 | address destinationUnwrapper, 102 | address weth, 103 | uint256 amount, 104 | address recipient, 105 | uint32 destinationDomain, 106 | uint256 slippage, 107 | uint256 relayerFee 108 | ) external payable { 109 | // Wrap ETH into WETH to send with the xcall 110 | IWETH(weth).deposit{value: amount}(); 111 | 112 | // This contract approves transfer to Connext 113 | IWETH(weth).approve(address(connext), amount); 114 | 115 | // Encode the recipient address for calldata 116 | bytes memory callData = abi.encode(recipient); 117 | 118 | // xcall the Unwrapper contract to unwrap WETH into ETH on destination 119 | connext.xcall{value: relayerFee}( 120 | destinationDomain, // _destination: Domain ID of the destination chain 121 | destinationUnwrapper, // _to: Unwrapper contract 122 | weth, // _asset: address of the WETH contract 123 | msg.sender, // _delegate: address that can revert or forceLocal on destination 124 | amount, // _amount: amount of tokens to transfer 125 | slippage, // _slippage: the maximum amount of slippage the user will accept in BPS (e.g. 30 = 0.3%) 126 | callData // _callData: calldata with encoded recipient address 127 | ); 128 | } 129 | } 130 | ``` 131 | Information like asset addresses be found in the [Deployments](../../resources/deployments.md) page. -------------------------------------------------------------------------------- /docs/developers/guides/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Guides", 3 | "position": 2, 4 | "collapsed": false 5 | } 6 | -------------------------------------------------------------------------------- /docs/developers/guides/authentication.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | id: authentication 4 | --- 5 | 6 | # Authentication 7 | 8 | Authentication is a critical concept to understand when building xApps. In the context of smart contracts, an authenticated call is one that passes permissioning constraints set by the protocol developer. In most cases this manifests as a modifier that allows a certain set of addresses to call specific smart contract functions - in other words, we are talking about access control. 9 | 10 | For example: 11 | - Uniswap's `swap` [function](https://docs.uniswap.org/protocol/reference/core/UniswapV3Pool#swap) is **unauthenticated** because it is a public function that can be called by anyone. 12 | - Uniswap's `setFeeProtocol` [function](https://docs.uniswap.org/protocol/reference/core/UniswapV3Pool#setfeeprotocol) is **authenticated** because it uses the `onlyFactoryOwner` modifier that prevents anyone but the owner of the contract factory from calling it. You can read more about this at [OpenZeppelin's Ownable contracts](https://docs.openzeppelin.com/contracts/2.x/api/ownership). 13 | 14 | The major impact that an authenticated call can have on users is latency. Authenticated calls are a crucial feature for xApps but in order to validate data transferred between chains, Connext must allow *some* time to elapse before accepting messages as authenticated on destination chains. This latency is both a drawback and a security mechanism of [optimistic bridges](../../concepts/background/verification.md#optimistic). 15 | 16 | ## Checking Origin Data 17 | 18 | Suppose a target contract on the destination domain has a function that should only be callable by a specific source contract on a specific origin domain. 19 | 20 | A custom modifier like `onlySource` below can conduct all the necessary checks to uphold this permissioning constraint. 21 | 22 | ```solidity 23 | contract Target is IXReceiver { 24 | /** @notice A modifier for authenticated calls. 25 | * This is an important security consideration. If the target contract 26 | * function should be authenticated, it must check three things: 27 | * 1) The originating call comes from the expected origin domain. 28 | * 2) The originating call comes from the expected source contract. 29 | * 3) The call to this contract comes from Connext. 30 | */ 31 | modifier onlySource(address _originSender, uint32 _origin) { 32 | require( 33 | _origin == && 34 | _originSender == && 35 | msg.sender == , 36 | "Expected source contract on origin domain called by Connext" 37 | ); 38 | _; 39 | } 40 | 41 | function xReceive( 42 | bytes32 _transferId, 43 | uint256 _amount, 44 | address _asset, 45 | address _originSender, 46 | uint32 _origin, 47 | bytes memory _callData 48 | ) external onlySource(_originSender, _origin) returns (bytes memory) { 49 | // Do stuff that requires authentication 50 | } 51 | } 52 | ``` 53 | 54 | You can find a full example of this at [Authenticated Hello](../examples/authenticated-hello). 55 | -------------------------------------------------------------------------------- /docs/developers/guides/estimating-fees.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | id: estimating-fees 4 | --- 5 | 6 | # Estimating Fees 7 | 8 | There are two types of fees paid to offchain agents for each applicable `xcall`. 9 | 10 | - **Router Fee**: 0.05% of the transferred asset will be levied by routers on destination for their service as fast liquidity providers. 11 | - The 'fast path' is possible when routers have liquidity in the destination asset and are able to provide those assets to the user. This allows users to receive their desired destination assets almost *immediately*. 12 | - Routers will take on the bridge delay and wait for the optimistic period to pass. Once complete, the bridge will 'reconcile' by minting the local destination assets to the routers, making them whole again. 13 | - If an `xcall` goes through the 'slow path' ([authenticated](./authentication)), then users do not pay the router fee. 14 | - Note that routers always provide *and* receive minted assets of the local destination flavor - they never have to rebalance funds! 15 | 16 | - **Relayer Fee**: A fee charged by relayers on top of normal gas costs in exchange for providing a meta-transaction service. 17 | - Relayers execute transactions on the destination chain on behalf of users. 18 | - Users offer a fee bounty to incentivize relayers to execute their destination calls. 19 | - Relayer fees are paid in the origin native asset or the transacting asset and need to be estimated when `xcall` is initiated. Some relayers provide endpoints that can help with estimation. 20 | 21 | 22 | Router fees are fixed and hardcoded into the Connext protocol. Relayer fees, on the other hand, can vary between chains and the service provider. 23 | 24 | ## Estimating Relayer Fees 25 | 26 | For now, we need to rely on offchain tools to estimate relayer fees. The [Connext SDK](./sdk-guides.md) abstracts away some of this complexity. 27 | 28 | The `SdkBase` class includes an `estimateRelayerFee` method that estimates total gas fees including a bump to account for Gelato relayer fees. 29 | 30 | The relayer fee can be paid in either the native asset or the transacting asset (the asset being bridged in the `xcall`). 31 | 32 | [Pay in native asset](#pay-in-native-asset) 33 | 34 | [Pay in transacting asset](#pay-in-transacting-asset) 35 | 36 | ### Pay in native asset 37 | 38 | The resulting estimate will be converted to the native origin asset. 39 | 40 | ```typescript 41 | const {sdkBase} = await create(nxtpConfig); 42 | 43 | const params = { 44 | originDomain: "", 45 | destinationDomain: "", 46 | } 47 | 48 | const relayerFee = await sdkBase.estimateRelayerFee(params); 49 | ``` 50 | 51 | The estimate should be used as the `relayerFee` param for an `xcall` using the SDK. 52 | 53 | ```typescript 54 | const xcallTxReq = await sdkBase.xcall( 55 | ..., 56 | relayerFee: relayerFee 57 | ); 58 | ``` 59 | 60 | Or passed in as the `value` for an `xcall` in a smart contract. 61 | 62 | ```solidity 63 | contract Source { 64 | ... 65 | function crossChainCall() { 66 | ... 67 | connext.xcall{value: relayerFee}(...); 68 | } 69 | } 70 | ``` 71 | 72 | ### Pay in transacting asset 73 | 74 | The resulting estimate will be the relayer fee in USD. 75 | 76 | ```typescript 77 | const {sdkBase} = await create(nxtpConfig); 78 | 79 | const params = { 80 | originDomain: "", 81 | destinationDomain: "", 82 | priceIn: "usd" // use this if you want the estimate in USD 83 | } 84 | 85 | const relayerFeeInTransactingAsset = await sdkBase.estimateRelayerFee(params); 86 | ``` 87 | 88 | The estimate in USD should be converted to the value of the transacting asset (e.g. by using a price feed) and supplied as the `relayerFeeInTransactingAsset` param for an `xcall` using the SDK. 89 | 90 | ```typescript 91 | const xcallTxReq = await sdkBase.xcall( 92 | ..., 93 | relayerFeeInTransactingAsset: relayerFeeInTransactingAsset 94 | ); 95 | ``` 96 | 97 | Or passed in as the `_relayerFee` for an `xcall` in a smart contract. 98 | 99 | ```solidity 100 | contract Source { 101 | ... 102 | function crossChainCall() { 103 | ... 104 | connext.xcall( 105 | ..., 106 | relayerFeeInTransactingAsset 107 | ); 108 | } 109 | } 110 | ``` 111 | 112 | ## Bumping Relayer Fees 113 | 114 | Since gas conditions are impossible to predict, transactions can potentially stay pending on destination if fees aren't high enough. Connext allows the user (or anyone if they are feeling charitable) to increase the original fee until sufficient for relayers. 115 | 116 | Anyone can call the Connext contract function `bumpTransfer` to increase the original relayer fee for an `xcall`. 117 | 118 | [Bumping in native asset](#bump-in-native-asset) 119 | 120 | [Bumping in transacting asset](#bump-in-transacting-asset) 121 | 122 | ### Bump in native asset 123 | 124 | To bump using SDK: 125 | 126 | ```typescript 127 | const bumpTxReq = await sdkBase.bumpTransfer( 128 | domainId: originDomain, 129 | transferId: transferId, 130 | asset: , 131 | relayerFee: 132 | ); 133 | ``` 134 | 135 | To bump from a contract call: 136 | 137 | ```solidity 138 | function bumpTransfer(bytes32 _transferId) external payable; 139 | ``` 140 | 141 | ### Bump in transacting asset 142 | 143 | To bump using SDK: 144 | 145 | ```typescript 146 | const bumpTxReq = await sdkBase.bumpTransfer( 147 | domainId: originDomain, 148 | transferId: transferId, 149 | asset: , 150 | relayerFee: 151 | ); 152 | ``` 153 | 154 | To bump from a contract call: 155 | 156 | ```solidity 157 | function bumpTransfer(bytes32 _transferId, address _relayerFeeAsset, uint256 _relayerFee) external payable; 158 | ``` 159 | 160 | To find the `transferId`, see [Tracking xCalls](./xcall-status). 161 | -------------------------------------------------------------------------------- /docs/developers/guides/handling-failures.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | id: handling-failures 4 | --- 5 | 6 | # Handling Failed xCalls 7 | 8 | There are a few failure conditions to watch out for when using `xcall`. 9 | 10 | ## High Slippage 11 | 12 | When tokens are bridged through Connext, slippage can impact the `xcall` during the swap on origin or destination. If slippage is too high on the origin swap, the `xcall` will just revert. If slippage is too high on the destination swap (after it has already gone through the origin swap), then there are a couple options to consider. 13 | 14 | - Cancel the transfer and bridge back to origin (sender will lose any funds related to the origin slippage) [not available yet]. 15 | - Wait it out until slippage conditions improve (relayers will continuously re-attempt the transfer execution). 16 | - Increase the slippage tolerance. 17 | 18 | ### Increasing Slippage Tolerance 19 | 20 | The [`_delegate`](../reference/contracts/calls#parameters-8) parameter of `xcall` is an address that has rights to update the original slippage tolerance by calling Connext's [forceUpdateSlippage](https://github.com/connext/monorepo/blob/27bbf7871a78b03d8613b06ece2675a57309d573/packages/deployments/contracts/contracts/core/connext/facets/BridgeFacet.sol#L395) function with the following signature: 21 | 22 | ```solidity 23 | function forceUpdateSlippage(TransferInfo calldata _params, uint256 _slippage) external; 24 | ``` 25 | 26 | The `TransferInfo` struct that must be supplied: 27 | 28 | ```solidity 29 | struct TransferInfo { 30 | uint32 originDomain; 31 | uint32 destinationDomain; 32 | uint32 canonicalDomain; 33 | address to; 34 | address delegate; 35 | bool receiveLocal; 36 | bytes callData; 37 | uint256 slippage; 38 | address originSender; 39 | uint256 bridgedAmt; 40 | uint256 normalizedIn; 41 | uint256 nonce; 42 | bytes32 canonicalId; 43 | } 44 | ``` 45 | 46 | The parameters in `TransferInfo` must match the same parameters used in the original `xcall`. It's possible to obtain the original parameters by [querying the subgraph](./xcall-status#querying-subgraphs) (origin *or* destination) with the `transferId` associated with the `xcall`. 47 | 48 | The Connext SDK also exposes an [updateSlippage](../reference/SDK/sdk-base#updateslippage) method for this. 49 | 50 | 51 | ## Reverts on Receiver Contract 52 | 53 | If the call on the receiver contract (also referred to as "target" contract) reverts, funds sent in with the call will end up on the receiver contract. To avoid situations where user funds get stuck on the receivers, developers should build any contract implementing `IXReceive` defensively. 54 | 55 | Ultimately, the goal should be to handle any revert-susceptible code and ensure that the logical owner of funds *always* maintains agency over them. 56 | 57 | ### Try/Catch with External Calls 58 | 59 | One way to guard against unexpected reverts is to use `try/catch` statements which allow contracts to handle errors on external function calls. 60 | 61 | ```solidity 62 | contract TargetContract { 63 | ... 64 | function xReceive( 65 | bytes32 _transferId, 66 | uint256 _amount, 67 | address _asset, 68 | address _originSender, 69 | uint32 _origin, 70 | bytes memory _callData 71 | ) external returns (bytes memory) { 72 | try { 73 | someExternalCall(); 74 | } catch { 75 | // Make sure funds are delivered to logical owner on failing external calls 76 | } 77 | } 78 | } 79 | ``` 80 | 81 | ### Options for Funds on Receiver 82 | 83 | We recommend that xApp developers consider recovery options in case of reverting calls on the receiver. For example, there could be an internal accounting structure to record `transferId`s and allow rightful `originSender`s to rescue their funds from the receiver contract. Note that this approach requires authentication and would cause `xcall`s to go through the slow path. 84 | 85 | Alternatively, the protocol can implement an allowlist for addresses that are able to rescue funds and redirect them to users. 86 | 87 | Connext is actively researching standards and best practices for receiver contracts. Reach out to us if you questions! 88 | -------------------------------------------------------------------------------- /docs/developers/guides/nested-xcalls.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | id: nested-xcalls 4 | --- 5 | 6 | # Nested xCalls 7 | 8 | Cross-chain calls can easily be composed together by `xcall`ing within the `xReceive` function of a target contract. In effect, the target contract becomes the source contract of that nested `xcall`. 9 | 10 | ## xCall in xReceive 11 | 12 | ```solidity 13 | contract Target is IXReceiver { 14 | function xReceive( 15 | bytes32 _transferId, 16 | uint256 _amount, 17 | address _asset, 18 | address _originSender, 19 | uint32 _origin, 20 | bytes memory _callData 21 | ) external returns (bytes memory) { 22 | // After handling the first xcall... 23 | ... 24 | 25 | // Send another xcall within the xReceive function! 26 | connext.xcall{value: relayerFee}(...); 27 | } 28 | } 29 | ``` 30 | 31 | There are many ways to use nested `xcall`s to extend cross-chain functionality. With this technique, it's possible to: 32 | - Emulate the behavior of a "callback" between chains to verify state changes and/or followup asynchronously 33 | - Disperse data to multiple different chains at once 34 | 35 | See this in action in the [Ping Pong](../examples/ping-pong) example. -------------------------------------------------------------------------------- /docs/developers/guides/sdk-frontend-integration.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 7 3 | id: sdk-frontend-integration 4 | --- 5 | 6 | # Integrating the SDK with a Frontend 7 | 8 | A common pattern for the SDK is to use it in a frontend application. This guide will walk you through the steps to integrate the SDK with a frontend application. 9 | 10 | ## Next.JS 11 | 12 | Next.JS is a popular frontend framework that allows you to build server-rendered React applications. It is a great choice for building a frontend application that uses the SDK. 13 | 14 | ### 1. Setup 15 | 16 | Create a new Next.JS application using the `create-next-app` command (Typescript is recommended). 17 | 18 | ```bash 19 | npx create-next-app@latest --typescript 20 | # or 21 | yarn create next-app --typescript 22 | # or 23 | pnpm create next-app --typescript 24 | ``` 25 | 26 | Follow the instructions to create a new Next.JS application. 27 | 28 | ### 2. Install the SDK 29 | 30 | Install the SDK using your package manager of choice. 31 | 32 | ```bash npm2yarn 33 | npm install @connext/sdk 34 | ``` 35 | 36 | ### 3. Configure Next.JS 37 | 38 | The Connext SDK contains some dependencies that must be polyfilled to work on client-side applications. At minimum, your `next.config.js` file should contain the following configuration: 39 | 40 | ```js title="next.config.js" 41 | /** @type {import('next').NextConfig} */ 42 | const nextConfig = { 43 | webpack: (config) => { 44 | config.resolve.fallback = { fs: false }; 45 | return config; 46 | }, 47 | }; 48 | 49 | module.exports = nextConfig; 50 | ``` 51 | 52 | Now you are ready to use the SDK in your Next.JS application! 53 | 54 | For example: 55 | 56 | ```tsx title="pages/index.tsx" 57 | "use client"; // this is a client component 👈🏽 58 | 59 | import styles from "./page.module.css"; 60 | import { create, SdkConfig } from "@connext/sdk"; 61 | import { useEffect } from "react"; 62 | 63 | const inter = Inter({ subsets: ["latin"] }); 64 | 65 | const sdkConfig: SdkConfig = { 66 | signerAddress: "0x2b8aA42fFb2c9c7B9f0B1e1b935F7D8331b6dC7c", 67 | // Use `mainnet` when you're ready... 68 | network: "testnet", 69 | // Add more chains here! Use mainnet domains if `network: mainnet`. 70 | // This information can be found at https://docs.connext.network/resources/supported-chains 71 | chains: { 72 | 1735353714: { // Goerli domain ID 73 | providers: ["https://rpc.ankr.com/eth_goerli"], 74 | }, 75 | 1735356532: { // Optimism-Goerli domain ID 76 | providers: ["https://goerli.optimism.io"], 77 | }, 78 | }, 79 | }; 80 | 81 | export default function Home() { 82 | useEffect(() => { 83 | const run = async () => { 84 | const { sdkBase } = await create(sdkConfig); 85 | console.log('sdkBase: ', sdkBase); 86 | } 87 | run(); 88 | }) 89 | return ( 90 |
91 |
92 |

93 | Get started by editing  94 | src/app/page.tsx 95 |

96 |
97 |
98 | ) 99 | ``` 100 | 101 | ## Create React App (CRA) 102 | 103 | React is a popular frontend framework that allows you to build client-rendered React applications. However, CRA is at end of life and the React team recommends other frameworks instead. 104 | 105 | We highly recommend using NextJS for easier integration. If, however, you still want to use CRA for your project then you should follow these steps. 106 | 107 | ### 1. Setup 108 | 109 | Create a new CRA using the `create-react-app` command. 110 | 111 | ```bash 112 | npx create-react-app my-app 113 | # or 114 | yarn create react-app my-app --template typescript 115 | ``` 116 | 117 | ### 2. Install the SDK 118 | 119 | Install the SDK using your package manager of choice. 120 | 121 | ```bash npm2yarn 122 | npm install @connext/sdk 123 | ``` 124 | 125 | ### 3. Configure CRA 126 | 127 | 1) Install necessary dependencies 128 | 129 | ``` 130 | yarn add -D @craco/craco zlib-browserify 131 | ``` 132 | 133 | 2) Create a `craco.config.js` in your project root with the following contents. 134 | 135 | ```js 136 | const webpack from 'webpack'; 137 | 138 | module.exports = { 139 | webpack: { 140 | configure: webpackConfig => { 141 | webpackConfig['resolve'] = { 142 | fallback: { 143 | fs: false, 144 | path: false, 145 | os: false, 146 | zlib: require.resolve("zlib-browserify"), 147 | }, 148 | } 149 | return webpackConfig; 150 | }, 151 | plugins: [ 152 | // Work around for Buffer is undefined: 153 | // https://github.com/webpack/changelog-v5/issues/10 154 | new webpack.ProvidePlugin({ 155 | Buffer: ['buffer', 'Buffer'], 156 | }), 157 | new webpack.ProvidePlugin({ 158 | process: 'process/browser', 159 | }), 160 | ], 161 | }, 162 | }; 163 | ``` 164 | 165 | 3) Change scripts in `package.json` to use `craco` commands instead of `react-scripts`. 166 | 167 | ```json 168 | "scripts": { 169 | - "start": "react-scripts start", 170 | - "build": "react-scripts build", 171 | - "test": "react-scripts test" 172 | + "start": "craco start", 173 | + "build": "craco build", 174 | + "test": "craco test" 175 | } 176 | ``` -------------------------------------------------------------------------------- /docs/developers/guides/sdk-guides.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | id: sdk-guides 4 | --- 5 | 6 | # SDK 7 | 8 | The Connext SDK allows developers to interact with the Connext protocol in standard Node.js or web environments. 9 | --- 10 | 11 | ## Cross-Chain Transfer 12 | 13 | This example demonstrates how to execute an `xcall` to transfer funds from a wallet on the source domain to the same address on the destination domain. 14 | 15 | ### 1. Setup 16 | 17 | Install [Node.js](https://nodejs.dev/en/learn/how-to-install-nodejs/) and use **Node.js v18**. Follow the instructions to install `nvm`, a node version manager, which will make switching versions easier. 18 | 19 | Create a project folder and initialize the package. Fill out the project information as you please. 20 | 21 | ```bash npm2yarn 22 | mkdir connext-sdk-example && cd connext-sdk-example 23 | npm init 24 | ``` 25 | 26 | We'll be using TypeScript so install the following and generate the `tsconfig.json` file. 27 | 28 | ```bash npm2yarn 29 | npm install --save-dev @types/node @types/chai @types/mocha typescript 30 | npx tsc --init # or `yarn tsc --init` 31 | ``` 32 | 33 | We want to use top-level await so we'll set the compiler options accordingly. 34 | 35 | ```json title="tsconfig.json" 36 | { 37 | "compilerOptions": { 38 | "outDir": "./dist", 39 | "target": "es2017", 40 | "module": "esnext", 41 | "moduleResolution": "node", 42 | "allowSyntheticDefaultImports": true 43 | }, 44 | "exclude": ["node_modules"] 45 | } 46 | ``` 47 | 48 | Add `type` and `scripts` as root-level entries to `package.json` - they may already exist, so just replace them with the following. 49 | 50 | ```json title="package.json" 51 | { 52 | ... 53 | "type": "module", 54 | "scripts": { 55 | "xtransfer": "tsc && node dist/xtransfer.js" 56 | } 57 | ... 58 | } 59 | ``` 60 | 61 | ### 2. Install dependencies 62 | 63 | Install the latest beta version of Connext SDK and ethers. 64 | 65 | ```bash npm2yarn 66 | npm install @connext/sdk 67 | npm install ethers@^5 68 | ``` 69 | 70 | ### 3. The code 71 | 72 | First, we'll configure the SDK. Create a `config.ts` file with the following contents. 73 | 74 | ```ts title="config.ts" showLineNumbers 75 | import { SdkConfig } from "@connext/sdk"; 76 | import { ethers } from "ethers"; 77 | 78 | // Create a Signer and connect it to a Provider on the sending chain 79 | const privateKey = ""; 80 | 81 | let signer = new ethers.Wallet(privateKey); 82 | 83 | // Use the RPC url for the origin chain 84 | const provider = new ethers.providers.JsonRpcProvider("https://rpc.ankr.com/eth_goerli"); 85 | signer = signer.connect(provider); 86 | const signerAddress = await signer.getAddress(); 87 | 88 | const sdkConfig: SdkConfig = { 89 | signerAddress: signerAddress, 90 | // Use `mainnet` when you're ready... 91 | network: "testnet", 92 | // Add more chains here! Use mainnet domains if `network: mainnet`. 93 | // This information can be found at https://docs.connext.network/resources/supported-chains 94 | chains: { 95 | 1735353714: { // Goerli domain ID 96 | providers: ["https://rpc.ankr.com/eth_goerli"], 97 | }, 98 | 1735356532: { // Optimism-Goerli domain ID 99 | providers: ["https://goerli.optimism.io"], 100 | }, 101 | }, 102 | }; 103 | 104 | export { signer, sdkConfig }; 105 | ``` 106 | 107 | Replace `` with your own private key on line 5. 108 | 109 | Notice that the config supports Goerli and Optimism-Goerli. We've also hard-coded the origin chain provider on line 10. 110 | 111 | Now create a `xtransfer.ts` file with the following: 112 | 113 | ```ts title="xtransfer.ts" showLineNumbers 114 | import { create } from "@connext/sdk"; 115 | import { BigNumber } from "ethers"; 116 | import { signer, sdkConfig } from "./config.js"; 117 | 118 | const {sdkBase} = await create(sdkConfig); 119 | 120 | const signerAddress = await signer.getAddress(); 121 | 122 | // xcall parameters 123 | const originDomain = "1735353714"; 124 | const destinationDomain = "1735356532"; 125 | const originAsset = "0x7ea6eA49B0b0Ae9c5db7907d139D9Cd3439862a1"; 126 | const amount = "1000000000000000000"; 127 | const slippage = "10000"; 128 | 129 | // Estimate the relayer fee 130 | const relayerFee = ( 131 | await sdkBase.estimateRelayerFee({ 132 | originDomain, 133 | destinationDomain 134 | }) 135 | ).toString(); 136 | 137 | // Prepare the xcall params 138 | const xcallParams = { 139 | origin: originDomain, // send from Goerli 140 | destination: destinationDomain, // to Mumbai 141 | to: signerAddress, // the address that should receive the funds on destination 142 | asset: originAsset, // address of the token contract 143 | delegate: signerAddress, // address allowed to execute transaction on destination side in addition to relayers 144 | amount: amount, // amount of tokens to transfer 145 | slippage: slippage, // the maximum amount of slippage the user will accept in BPS (e.g. 30 = 0.3%) 146 | callData: "0x", // empty calldata for a simple transfer (byte-encoded) 147 | relayerFee: relayerFee, // fee paid to relayers 148 | }; 149 | 150 | // Approve the asset transfer if the current allowance is lower than the amount. 151 | // Necessary because funds will first be sent to the Connext contract in xcall. 152 | const approveTxReq = await sdkBase.approveIfNeeded( 153 | originDomain, 154 | originAsset, 155 | amount 156 | ) 157 | 158 | if (approveTxReq) { 159 | const approveTxReceipt = await signer.sendTransaction(approveTxReq); 160 | await approveTxReceipt.wait(); 161 | } 162 | 163 | // Send the xcall 164 | const xcallTxReq = await sdkBase.xcall(xcallParams); 165 | xcallTxReq.gasLimit = BigNumber.from("20000000"); 166 | const xcallTxReceipt = await signer.sendTransaction(xcallTxReq); 167 | console.log(xcallTxReceipt); 168 | await xcallTxReceipt.wait(); 169 | ``` 170 | 171 | Most of the parameters are hardcoded in this example. For a detailed description of each parameter, see the [SDK reference for xcall](../reference/SDK/sdk-base#xcall). 172 | 173 | Information like asset addresses be found in the [Deployments](../../../resources/deployments) page. 174 | 175 | ### 4. Run it 176 | 177 | Fire off the cross-chain transfer! 178 | 179 | ```bash npm2yarn 180 | npm run xtransfer 181 | ``` 182 | 183 | ### 5. Track the `xcall` 184 | 185 | We can now use the transaction `hash` from the logged transaction receipt to track the status of this `xcall`. 186 | 187 | [Tracking an xcall](./xcall-status) 188 | 189 | After the transfer is `status: Executed` on the destination side, the transferred tokens should show up in the recipient wallet. 190 | -------------------------------------------------------------------------------- /docs/developers/guides/xcall-status.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | id: xcall-status 4 | --- 5 | 6 | # Tracking xCalls 7 | 8 | Every `xcall` is associated with a unique `transferId` that can be used to track its lifecycle through a cross-chain transaction. 9 | 10 | ## Querying Subgraphs 11 | 12 | You can query the hosted subgraphs on each chain to check the transaction status. 13 | 14 |
15 | 16 | Mainnet Subgraphs 17 | 18 | | Chain | Subgraph | 19 | | --- | --- | 20 | | Ethereum | [v0-Mainnet](https://thegraph.com/hosted-service/subgraph/connext/amarok-runtime-v0-mainnet) | 21 | | Optimism | [v0-Optimism](https://thegraph.com/hosted-service/subgraph/connext/amarok-runtime-v0-optimism) | 22 | | Arbitrum | [v0-Arbitrum](https://thegraph.com/hosted-service/subgraph/connext/amarok-runtime-v0-arbitrum-one) | 23 | | Polygon | [v0-Polygon](https://thegraph.com/hosted-service/subgraph/connext/amarok-runtime-v0-polygon) | 24 | | Binance Smart Chain | [v0-Bnb](https://thegraph.com/hosted-service/subgraph/connext/amarok-runtime-v0-bnb) | 25 | | Gnosis | [v0-Gnosis](https://thegraph.com/hosted-service/subgraph/connext/amarok-runtime-v0-gnosis) | 26 | 27 |
28 | 29 |
30 | 31 | Testnet Subgraphs 32 | 33 | | Chain | Subgraph | 34 | | --- | --- | 35 | | Goerli | [v0-Goerli](https://thegraph.com/hosted-service/subgraph/connext/nxtp-amarok-runtime-v0-goerli) | 36 | | Optimism-Goerli | [v0-Opt-Goerli](https://thegraph.com/hosted-service/subgraph/connext/amarok-runtime-v0-opt-goerli) | 37 | | Mumbai | [v0-Mumbai](https://thegraph.com/hosted-service/subgraph/connext/nxtp-amarok-runtime-v0-mumbai) | 38 | 39 |
40 | 41 | 1. Make note of the transaction hash that interacted with the Connext contract. 42 | 43 | 2. Navigate to the hosted subgraph for the origin domain and query by the xcall's transaction hash or the transfer ID. 44 | 45 | ```graphql 46 | query OriginTransfer { 47 | originTransfers( 48 | where: { 49 | # Query by the transaction hash of the xcall 50 | transactionHash: "", 51 | # Or by the xcall's transfer ID 52 | transferId: "" 53 | } 54 | ) { 55 | # Meta Data 56 | chainId 57 | nonce 58 | transferId 59 | to 60 | delegate 61 | receiveLocal 62 | callData 63 | slippage 64 | originSender 65 | originDomain 66 | destinationDomain 67 | transactionHash 68 | bridgedAmt 69 | status 70 | timestamp 71 | normalizedIn 72 | # Asset Data 73 | asset { 74 | id 75 | adoptedAsset 76 | canonicalId 77 | canonicalDomain 78 | } 79 | } 80 | } 81 | ``` 82 | 83 | 3. Navigate to the hosted subgraph for the destination domain and query by the `transferId` obtained from the origin domain subgraph. 84 | 85 | ```graphql 86 | query DestinationTransfer { 87 | destinationTransfers( 88 | where: { 89 | transferId: "" 90 | } 91 | ) { 92 | # Meta Data 93 | chainId 94 | nonce 95 | transferId 96 | to 97 | callData 98 | originDomain 99 | destinationDomain 100 | delegate 101 | # Asset Data 102 | asset { 103 | id 104 | } 105 | bridgedAmt 106 | # Executed event Data 107 | status 108 | routers { 109 | id 110 | } 111 | originSender 112 | # Executed Transaction 113 | executedCaller 114 | executedTransactionHash 115 | executedTimestamp 116 | executedGasPrice 117 | executedGasLimit 118 | executedBlockNumber 119 | # Reconciled Transaction 120 | reconciledCaller 121 | reconciledTransactionHash 122 | reconciledTimestamp 123 | reconciledGasPrice 124 | reconciledGasLimit 125 | reconciledBlockNumber 126 | routersFee 127 | slippage 128 | } 129 | } 130 | ``` 131 | 132 | 4. If there was a nested `xcall` involved on the destination side, the `executedTransactionHash` from step 3 can be used as the *new* origin-side transaction hash. To trace the nested `xcall`, go back to step 1 using this `executedTransactionHash` but instead consider the current destination domain as the origin domain. 133 | 134 | ## Connextscan 135 | 136 | Another option is using [Connextscan](https://testnet.connextscan.io/) to track the status of any `transferId`. 137 | 138 | In the top right search box, enter the `transferId` of interest. 139 | 140 | Connextscan Search 141 | 142 | Connextscan will pull up current status of the associated `xcall`. This is what it looks like when a transfer is complete. 143 | 144 | Connextscan Search 145 | 146 | 147 | ## XCall Status 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 159 | 162 | 163 | 164 | 167 | 170 | 171 | 172 | 175 | 178 | 179 | 180 | 183 | 186 | 187 | 188 | 191 | 194 | 195 | 196 |
StatusDescription
157 | XCalled 158 | 160 | Transaction has been initiated on origin. 161 |
165 | Executed 166 | 168 | Funds have been delivered and calldata executed on destination, if applicable. If this happens before Reconciled, then this was a fast path transfer (non-authenticated). 169 |
173 | Reconciled 174 | 176 | Funds have been reimbursed to routers. If this happens before Executed, then this was a slow path transfer (authenticated). 177 |
181 | CompletedFast 182 | 184 | Transaction has been Executed and then Reconciled. 185 |
189 | CompletedSlow 190 | 192 | Transaction has been Reconciled and then Executed. 193 |
197 | -------------------------------------------------------------------------------- /docs/developers/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Introduction 6 | 7 | Connext provides the simplest possible experience for building xchain applications (**xApps**). 8 | 9 | Building a xApp requires only two straightforward steps: 10 | 1. Implement `xReceive` in the destination chain contract. This is the function that receives the payload you pass across chains. 11 | 2. Call `xcall` on the origin chain, passing in your payload and [relayer fees](./guides/estimating-fees). 12 | 13 | [Get started with the Quickstart](./quickstart) 14 | 15 | --- 16 | 17 | ## Important Concepts With Guides 18 | 19 | ### Fast Path vs. Slow Path 20 | 21 | Take a moment to review the [Transaction Lifecycle](../concepts/how-it-works/transaction-flow). Here we introduce the concept of "fast path" and "slow path" (authenticated) transfers. The differentiation is crucial to understand for any cross-chain project. Then, try it out with our Authentication guide. 22 | 23 | [Authentication](./guides/authentication) 24 | 25 | ### Relayer Fees 26 | 27 | Check out our guide on what these are and how to estimate them. 28 | 29 | [Estimating Fees](./guides/estimating-fees) 30 | 31 | ### Handling Failures 32 | 33 | You should always build in contingency for failed calls. 34 | 35 | [Handling Failed xCalls](./guides/handling-failures) 36 | 37 | ### Tracking xCalls 38 | 39 | Dive into the current status of an `xcall`. 40 | 41 | [Tracking xCalls](./guides/xcall-status) 42 | 43 | ### Nested xCalls 44 | 45 | You can even chain `xcall`s across domains! :open_mouth: 46 | 47 | [Nested xCalls](./guides/nested-xcalls) 48 | 49 | ### Chain Abstraction 50 | 51 | Create seamless cross-chain interactions without having to switch chains! 🤯 52 | 53 | [Chain Abstraction](./guides/chain-abstraction) 54 | 55 | --- 56 | ## Help 57 | 58 | Have questions or need support? Our core team and vibrant community members are highly active in our Discord server! 59 | 60 | [Chat with us!](https://discord.gg/connext) 61 | -------------------------------------------------------------------------------- /docs/developers/reference/SDK/SdkRouter.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | title: Router 4 | id: sdk-router 5 | --- 6 | 7 | # Class: SdkRouter 8 | 9 | **`Classdesc`** 10 | 11 | SDK class encapsulating router functions. 12 | 13 | ## Hierarchy 14 | 15 | - [`SdkShared`](./sdk-shared) 16 | 17 | ↳ **`SdkRouter`** 18 | 19 | ## Methods 20 | 21 | ### addLiquidityForRouter 22 | 23 | ▸ **addLiquidityForRouter**(`params`): `Promise`<`TransactionRequest`\> 24 | 25 | Returns the transaction request for adding liquidity to a router. 26 | 27 | #### Parameters 28 | 29 | | Name | Type | Description | 30 | | :------ | :------ | :------ | 31 | | `params` | `Object` | addLiquidityForRouter parameters object. | 32 | | `params.amount` | `string` | The amount of the token to add. | 33 | | `params.domainId` | `string` | The domain ID. | 34 | | `params.router` | `string` | The address of the router. | 35 | | `params.tokenAddress` | `string` | The address of the token. | 36 | 37 | #### Returns 38 | 39 | `Promise`<`TransactionRequest`\> 40 | 41 | providers.TransactionRequest object. 42 | 43 | ___ 44 | 45 | ### approveIfNeeded 46 | 47 | ▸ **approveIfNeeded**(`domainId`, `assetId`, `amount`, `infiniteApprove?`): `Promise`<`undefined` \| `TransactionRequest`\> 48 | 49 | Returns the transaction request for an allowance approval. 50 | 51 | #### Parameters 52 | 53 | | Name | Type | Default value | Description | 54 | | :------ | :------ | :------ | :------ | 55 | | `domainId` | `string` | `undefined` | The domain ID. | 56 | | `assetId` | `string` | `undefined` | The address of the token. | 57 | | `amount` | `string` | `undefined` | The amount of the token. | 58 | | `infiniteApprove` | `boolean` | `true` | (optional) Whether to approve an infinite amount. | 59 | 60 | #### Returns 61 | 62 | `Promise`<`undefined` \| `TransactionRequest`\> 63 | 64 | providers.TransactionRequest object. 65 | 66 | #### Inherited from 67 | 68 | [SdkShared](./sdk-shared).[approveIfNeeded](sdk-shared#approveifneeded) 69 | 70 | ___ 71 | 72 | ### calculateCanonicalKey 73 | 74 | ▸ **calculateCanonicalKey**(`domainId`, `canonicalId`): `string` 75 | 76 | Returns the hash of the canonical ID + canonical domain. 77 | 78 | **`Remarks`** 79 | 80 | This key is used as the unique identifier for a canonical token, across all domains. 81 | 82 | #### Parameters 83 | 84 | | Name | Type | Description | 85 | | :------ | :------ | :------ | 86 | | `domainId` | `string` | The canonical domain ID of the token. | 87 | | `canonicalId` | `string` | The canonical ID of the token. | 88 | 89 | #### Returns 90 | 91 | `string` 92 | 93 | #### Inherited from 94 | 95 | [SdkShared](./sdk-shared).[calculateCanonicalKey](sdk-shared#calculatecanonicalkey) 96 | 97 | ___ 98 | 99 | ### changeSignerAddress 100 | 101 | ▸ **changeSignerAddress**(`signerAddress`): `Promise`<`void`\> 102 | 103 | Switches the signer address in the SDK config. 104 | 105 | #### Parameters 106 | 107 | | Name | Type | Description | 108 | | :------ | :------ | :------ | 109 | | `signerAddress` | `string` | The new signer address. | 110 | 111 | #### Returns 112 | 113 | `Promise`<`void`\> 114 | 115 | #### Inherited from 116 | 117 | [SdkShared](./sdk-shared).[changeSignerAddress](sdk-shared#changesigneraddress) 118 | 119 | ___ 120 | 121 | ### getAssetsData 122 | 123 | ▸ **getAssetsData**(): `Promise`<[`AssetData`](./sdk-types/#assetdata)[]\> 124 | 125 | Fetches the list of registered assets. 126 | 127 | #### Returns 128 | 129 | `Promise`<[`AssetData`](./sdk-types/#assetdata)[]\> 130 | 131 | Array of objects containing assets registered to the network, in the form of: 132 | ```ts 133 | { 134 | "local": "0x2983bf5c334743aa6657ad70a55041d720d225db", 135 | "adopted": "0x82af49447d8a07e3bd95bd0d56f35241523fbab1", 136 | "canonical_id": "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", 137 | "canonical_domain": "6648936", 138 | "domain": "1634886255", 139 | "key": "0x12acadfa38ab02479ae587196a9043ee4d8bf52fcb96b7f8d2ba240f03bcd08a", 140 | "id": "0x2983bf5c334743aa6657ad70a55041d720d225db" 141 | }, 142 | ``` 143 | 144 | #### Inherited from 145 | 146 | [SdkShared](./sdk-shared).[getAssetsData](sdk-shared#getassetsdata) 147 | 148 | ___ 149 | 150 | ### getAssetsDataByDomainAndKey 151 | 152 | ▸ **getAssetsDataByDomainAndKey**(`domainId`, `key`): `Promise`<`undefined` \| [`AssetData`](./sdk-types/#assetdata)\> 153 | 154 | Retrieve the asset data for a specific domain and key. 155 | 156 | #### Parameters 157 | 158 | | Name | Type | Description | 159 | | :------ | :------ | :------ | 160 | | `domainId` | `string` | The domain ID. | 161 | | `key` | `string` | The canonical hash of the canonical token. | 162 | 163 | #### Returns 164 | 165 | `Promise`<`undefined` \| [`AssetData`](./sdk-types/#assetdata)\> 166 | 167 | The object containing asset data. 168 | 169 | #### Inherited from 170 | 171 | [SdkShared](./sdk-shared).[getAssetsDataByDomainAndKey](sdk-shared#getassetsdatabydomainandkey) 172 | 173 | ___ 174 | 175 | ### getCanonicalTokenId 176 | 177 | ▸ **getCanonicalTokenId**(`domainId`, `tokenAddress`): `Promise`<[`string`, `string`]\> 178 | 179 | Returns the canonical ID and canonical domain of a token. 180 | 181 | #### Parameters 182 | 183 | | Name | Type | Description | 184 | | :------ | :------ | :------ | 185 | | `domainId` | `string` | The canonical domain ID of the token. | 186 | | `tokenAddress` | `string` | The address of the token. | 187 | 188 | #### Returns 189 | 190 | `Promise`<[`string`, `string`]\> 191 | 192 | #### Inherited from 193 | 194 | [SdkShared](./sdk-shared).[getCanonicalTokenId](sdk-shared#getcanonicaltokenid) 195 | 196 | ___ 197 | 198 | ### getSupported 199 | 200 | ▸ **getSupported**(): `Promise`<[`ConnextSupport`](../modules.md#connextsupport)[]\> 201 | 202 | Fetches the list of supported networks and assets. 203 | 204 | #### Returns 205 | 206 | `Promise`<[`ConnextSupport`](../modules.md#connextsupport)[]\> 207 | 208 | Array of objects containing networks and assets supported by the protocol, in the form of: 209 | 210 | ```ts 211 | { 212 | "name": "arbitrum", 213 | "chainId": 42161, 214 | "domainId": "1634886255", 215 | "assets": [ 216 | "0x82af49447d8a07e3bd95bd0d56f35241523fbab1", 217 | "0xff970a61a04b1ca14834a43f5de4533ebddb5cc8" 218 | ] 219 | }, 220 | ``` 221 | 222 | #### Inherited from 223 | 224 | [SdkShared](SdkShared.md).[getSupported](SdkShared.md#getsupported) 225 | 226 | ___ 227 | 228 | ### isNextAsset 229 | 230 | ▸ **isNextAsset**(`tokenAddress`): `Promise`<`undefined` \| `boolean`\> 231 | 232 | Returns whether the specified token is a Connext-issued (local) token. 233 | 234 | #### Parameters 235 | 236 | | Name | Type | Description | 237 | | :------ | :------ | :------ | 238 | | `tokenAddress` | `string` | The address of the token. | 239 | 240 | #### Returns 241 | 242 | `Promise`<`undefined` \| `boolean`\> 243 | 244 | Boolean or undefined if the specified token is not registered. 245 | 246 | #### Inherited from 247 | 248 | [SdkShared](./sdk-shared).[isNextAsset](sdk-shared#isnextasset) 249 | 250 | ___ 251 | 252 | ### parseConnextTransactionReceipt 253 | 254 | ▸ **parseConnextTransactionReceipt**(`transactionReceipt`): `any` 255 | 256 | Parses a providers.TransactionReceipt for the logs. 257 | 258 | #### Parameters 259 | 260 | | Name | Type | Description | 261 | | :------ | :------ | :------ | 262 | | `transactionReceipt` | `TransactionReceipt` | providers.TransactionReceipt object. | 263 | 264 | #### Returns 265 | 266 | `any` 267 | 268 | Array of providers.Log objects. 269 | 270 | #### Inherited from 271 | 272 | [SdkShared](./sdk-shared).[parseConnextTransactionReceipt](sdk-shared#parseconnexttransactionreceipt) 273 | 274 | ___ 275 | 276 | ### removeRouterLiquidity 277 | 278 | ▸ **removeRouterLiquidity**(`params`): `Promise`<`TransactionRequest`\> 279 | 280 | Returns the transaction request for removing liquidity from a router. 281 | 282 | **`Remarks`** 283 | 284 | This function is permissioned to the router owner only. 285 | 286 | #### Parameters 287 | 288 | | Name | Type | Description | 289 | | :------ | :------ | :------ | 290 | | `params` | `Object` | removeRouterLiquidity parameters object. | 291 | | `params.amount` | `string` | The amount of the token to add. | 292 | | `params.domainId` | `string` | The domain ID. | 293 | | `params.recipient` | `string` | The address where the removed funds will be delivered. | 294 | | `params.tokenAddress` | `string` | The address of the token. | 295 | 296 | #### Returns 297 | 298 | `Promise`<`TransactionRequest`\> 299 | 300 | providers.TransactionRequest object. 301 | 302 | ___ 303 | 304 | ### removeRouterLiquidityFor 305 | 306 | ▸ **removeRouterLiquidityFor**(`params`): `Promise`<`TransactionRequest`\> 307 | 308 | #### Parameters 309 | 310 | | Name | Type | 311 | | :------ | :------ | 312 | | `params` | `Object` | 313 | | `params.amount` | `string` | 314 | | `params.domainId` | `string` | 315 | | `params.recipient` | `string` | 316 | | `params.router` | `string` | 317 | | `params.tokenAddress` | `string` | 318 | 319 | #### Returns 320 | 321 | `Promise`<`TransactionRequest`\> 322 | 323 | ___ 324 | 325 | ### create 326 | 327 | ▸ `Static` **create**(`_config`): `Promise`<[`SdkRouter`](SdkRouter.md)\> 328 | 329 | Create a singleton instance of the SdkRouter class. 330 | 331 | #### Parameters 332 | 333 | | Name | Type | Default value | Description | 334 | | :------ | :------ | :------ | :------ | 335 | | `_config` | `Object` | undefined | SdkConfig object. | 336 | | `_config.chains` | `Record`<`string`, { providers: string[] }\> | undefined | Chain config, at minimum with providers for each chain. | 337 | | `_config.signerAddress` | `string` | undefined| Signer address for transactions. | 338 | | `_config.logLevel` | ``"fatal"`` \| ``"error"`` \| ``"warn"`` \| ``"info"`` \| ``"debug"`` \| ``"trace"`` \| ``"silent"`` | "info" | (optional) Logging severity level. | 339 | | `_config.network` | ``"testnet"`` \| ``"mainnet"`` | "mainnet" | (optional) Blockchain environment to interact with. | 340 | 341 | #### Returns 342 | 343 | `Promise`<[`SdkRouter`](SdkRouter.md)\> 344 | 345 | providers.TransactionRequest object. 346 | 347 | @example: 348 | ```ts 349 | import { SdkRouter } from "@connext/sdk"; 350 | 351 | const config = { 352 | signerAddress: "", 353 | network: "mainnet", 354 | chains: { 355 | 6648936: { // the domain ID for Ethereum Mainnet 356 | providers: ["https://rpc.ankr.com/eth"], 357 | }, 358 | 1869640809: { // the domain ID for Optimism 359 | providers: ["https://mainnet.optimism.io"] 360 | }, 361 | 1886350457: { // the domain ID for Polygon 362 | providers: ["https://polygon-rpc.com"] 363 | }, 364 | }, 365 | } 366 | 367 | const sdkRouter = await SdkRouter.create(config); 368 | ``` 369 | 370 | :::note 371 | 372 | See the [Supported Chains](../../../resources/supported-chains) page for all domain IDs and the [Deployments](../../../resources/deployments) page for all asset addresses. 373 | 374 | ::: 375 | 376 | ___ 377 | 378 | ### domainToChainName 379 | 380 | ▸ `Static` **domainToChainName**(`domainId`): `string` 381 | 382 | Returns the chain name for a specified domain. 383 | 384 | #### Parameters 385 | 386 | | Name | Type | Description | 387 | | :------ | :------ | :------ | 388 | | `domainId` | `string` | The domain ID. | 389 | 390 | #### Returns 391 | 392 | `string` 393 | 394 | The chain name. 395 | 396 | #### Inherited from 397 | 398 | [SdkShared](./sdk-shared).[domainToChainName](sdk-shared#domaintochainname) 399 | 400 | ___ 401 | 402 | ### getBlockNumberFromUnixTimestamp 403 | 404 | ▸ `Static` **getBlockNumberFromUnixTimestamp**(`domainId`, `unixTimestamp`): `Promise`<`number`\> 405 | 406 | #### Parameters 407 | 408 | | Name | Type | Description | 409 | | :------ | :------ | :------ | 410 | | `domainId` | `string` | The domain ID. | 411 | | `unixTimestamp` | `number` | The unix timestamp. | 412 | 413 | #### Returns 414 | 415 | `Promise`<`number`\> 416 | 417 | #### Inherited from 418 | 419 | [SdkShared](./sdk-shared).[getBlockNumberFromUnixTimestamp](sdk-shared#getblocknumberfromunixtimestamp) 420 | -------------------------------------------------------------------------------- /docs/developers/reference/SDK/SdkShared.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | title: Shared 4 | id: sdk-shared 5 | --- 6 | # Class: SdkShared 7 | 8 | **`Classdesc`** 9 | 10 | SDK class encapsulating shared logic to be inherited. 11 | 12 | ## Hierarchy 13 | 14 | - **`SdkShared`** 15 | 16 | ↳ [`SdkBase`](sdk-base) 17 | 18 | ↳ [`SdkRouter`](sdk-router) 19 | 20 | ↳ [`SdkPool`](sdk-pool) 21 | 22 | ↳ [`SdkUtils`](sdk-utils) 23 | 24 | ## Methods 25 | 26 | ### approveIfNeeded 27 | 28 | ▸ **approveIfNeeded**(`domainId`, `assetId`, `amount`, `infiniteApprove?`): `Promise`<`undefined` \| `TransactionRequest`\> 29 | 30 | Returns the transaction request for an allowance approval. 31 | 32 | #### Parameters 33 | 34 | | Name | Type | Default value | Description | 35 | | :------ | :------ | :------ | :------ | 36 | | `domainId` | `string` | `undefined` | The domain ID. | 37 | | `assetId` | `string` | `undefined` | The address of the token. | 38 | | `amount` | `string` | `undefined` | The amount of the token. | 39 | | `infiniteApprove` | `boolean` | `true` | (optional) Whether to approve an infinite amount. | 40 | 41 | #### Returns 42 | 43 | `Promise`<`undefined` \| `TransactionRequest`\> 44 | 45 | providers.TransactionRequest object. 46 | 47 | ___ 48 | 49 | ### calculateCanonicalKey 50 | 51 | ▸ **calculateCanonicalKey**(`domainId`, `canonicalId`): `string` 52 | 53 | Returns the hash of the canonical ID + canonical domain. 54 | 55 | **`Remarks`** 56 | 57 | This key is used as the unique identifier for a canonical token, across all domains. 58 | 59 | #### Parameters 60 | 61 | | Name | Type | Description | 62 | | :------ | :------ | :------ | 63 | | `domainId` | `string` | The canonical domain ID of the token. | 64 | | `canonicalId` | `string` | The canonical ID of the token. | 65 | 66 | #### Returns 67 | 68 | `string` 69 | 70 | ___ 71 | 72 | ### changeSignerAddress 73 | 74 | ▸ **changeSignerAddress**(`signerAddress`): `Promise`<`void`\> 75 | 76 | Switches the signer address in the SDK config. 77 | 78 | #### Parameters 79 | 80 | | Name | Type | Description | 81 | | :------ | :------ | :------ | 82 | | `signerAddress` | `string` | The new signer address. | 83 | 84 | #### Returns 85 | 86 | `Promise`<`void`\> 87 | 88 | ___ 89 | 90 | ### getAssetsData 91 | 92 | ▸ **getAssetsData**(): `Promise`<[`AssetData`](./sdk-types/#assetdata)[]\> 93 | 94 | Fetches the list of registered assets. 95 | 96 | #### Returns 97 | 98 | `Promise`<[`AssetData`](./sdk-types/#assetdata)[]\> 99 | 100 | Array of objects containing assets registered to the network, in the form of: 101 | ```ts 102 | { 103 | "local": "0x2983bf5c334743aa6657ad70a55041d720d225db", 104 | "adopted": "0x82af49447d8a07e3bd95bd0d56f35241523fbab1", 105 | "canonical_id": "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", 106 | "canonical_domain": "6648936", 107 | "domain": "1634886255", 108 | "key": "0x12acadfa38ab02479ae587196a9043ee4d8bf52fcb96b7f8d2ba240f03bcd08a", 109 | "id": "0x2983bf5c334743aa6657ad70a55041d720d225db" 110 | }, 111 | ``` 112 | 113 | ___ 114 | 115 | ### getAssetsDataByDomainAndKey 116 | 117 | ▸ **getAssetsDataByDomainAndKey**(`domainId`, `key`): `Promise`<`undefined` \| [`AssetData`](./sdk-types/#assetdata)\> 118 | 119 | Retrieve the asset data for a specific domain and key. 120 | 121 | #### Parameters 122 | 123 | | Name | Type | Description | 124 | | :------ | :------ | :------ | 125 | | `domainId` | `string` | The domain ID. | 126 | | `key` | `string` | The canonical hash of the canonical token. | 127 | 128 | #### Returns 129 | 130 | `Promise`<`undefined` \| [`AssetData`](./sdk-types/#assetdata)\> 131 | 132 | The object containing asset data. 133 | 134 | ___ 135 | 136 | ### getCanonicalTokenId 137 | 138 | ▸ **getCanonicalTokenId**(`domainId`, `tokenAddress`): `Promise`<[`string`, `string`]\> 139 | 140 | Returns the canonical ID and canonical domain of a token. 141 | 142 | #### Parameters 143 | 144 | | Name | Type | Description | 145 | | :------ | :------ | :------ | 146 | | `domainId` | `string` | The canonical domain ID of the token. | 147 | | `tokenAddress` | `string` | The address of the token. | 148 | 149 | #### Returns 150 | 151 | `Promise`<[`string`, `string`]\> 152 | 153 | ___ 154 | 155 | ### getSupported 156 | 157 | ▸ **getSupported**(): `Promise`<[`ConnextSupport`](./sdk-types/#connextsupport)[]\> 158 | 159 | Fetches the list of supported networks and assets. 160 | 161 | #### Returns 162 | 163 | `Promise`<[`ConnextSupport`](./sdk-types/#connextsupport)[]\> 164 | 165 | Array of objects containing networks and assets supported by the protocol, in the form of: 166 | ```ts 167 | { 168 | "name": "arbitrum", 169 | "chainId": 42161, 170 | "domainId": "1634886255", 171 | "assets": [ 172 | "0x82af49447d8a07e3bd95bd0d56f35241523fbab1", 173 | "0xff970a61a04b1ca14834a43f5de4533ebddb5cc8" 174 | ] 175 | }, 176 | ``` 177 | 178 | ___ 179 | 180 | ### isNextAsset 181 | 182 | ▸ **isNextAsset**(`tokenAddress`): `Promise`<`undefined` \| `boolean`\> 183 | 184 | Returns whether the specified token is a Connext-issued (local) token. 185 | 186 | #### Parameters 187 | 188 | | Name | Type | Description | 189 | | :------ | :------ | :------ | 190 | | `tokenAddress` | `string` | The address of the token. | 191 | 192 | #### Returns 193 | 194 | `Promise`<`undefined` \| `boolean`\> 195 | 196 | Boolean or undefined if the specified token is not registered. 197 | 198 | ___ 199 | 200 | ### parseConnextTransactionReceipt 201 | 202 | ▸ **parseConnextTransactionReceipt**(`transactionReceipt`): `any` 203 | 204 | Parses a providers.TransactionReceipt for the logs. 205 | 206 | #### Parameters 207 | 208 | | Name | Type | Description | 209 | | :------ | :------ | :------ | 210 | | `transactionReceipt` | `TransactionReceipt` | providers.TransactionReceipt object. | 211 | 212 | #### Returns 213 | 214 | `any` 215 | 216 | Array of providers.Log objects. 217 | 218 | ___ 219 | 220 | ### domainToChainName 221 | 222 | ▸ `Static` **domainToChainName**(`domainId`): `string` 223 | 224 | Returns the chain name for a specified domain. 225 | 226 | #### Parameters 227 | 228 | | Name | Type | Description | 229 | | :------ | :------ | :------ | 230 | | `domainId` | `string` | The domain ID. | 231 | 232 | #### Returns 233 | 234 | `string` 235 | 236 | The chain name. 237 | 238 | ___ 239 | 240 | ### getBlockNumberFromUnixTimestamp 241 | 242 | ▸ `Static` **getBlockNumberFromUnixTimestamp**(`domainId`, `unixTimestamp`): `Promise`<`number`\> 243 | 244 | Uses an external API to fetch the block number from a unix timestamp. 245 | 246 | #### Parameters 247 | 248 | | Name | Type | Description | 249 | | :------ | :------ | :------ | 250 | | `domainId` | `string` | The domain ID. | 251 | | `unixTimestamp` | `number` | The unix timestamp. | 252 | 253 | #### Returns 254 | 255 | `Promise`<`number`\> 256 | -------------------------------------------------------------------------------- /docs/developers/reference/SDK/Types.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | title: Types 4 | id: sdk-types 5 | --- 6 | 7 | # Type Aliases 8 | 9 | ### AssetData 10 | 11 | Ƭ **AssetData**: `Object` 12 | 13 | #### Type declaration 14 | 15 | | Name | Type | 16 | | :------ | :------ | 17 | | `local` | `string` | 18 | | `adopted` | `string` | 19 | | `canonical_id` | `string` | 20 | | `canonical_domain` | `string` | 21 | | `domain` | `string` | 22 | | `key` | `string` | 23 | | `id` | `string` | 24 | 25 | ___ 26 | 27 | ### Pool 28 | 29 | Ƭ **Pool**: `Object` 30 | 31 | #### Type declaration 32 | 33 | | Name | Type | 34 | | :------ | :------ | 35 | | `domainId` | `string` | 36 | | `name` | `string` | 37 | | `symbol` | `string` | 38 | | `local` | [`PoolAsset`](#poolasset) | 39 | | `adopted` | [`PoolAsset`](#poolasset) | 40 | | `lpTokenAddress` | `string` | 41 | | `canonicalHash` | `string` | 42 | | `swapFee` | `string` | 43 | | `adminFee` | `string` | 44 | | `address?` | `string` | 45 | 46 | ___ 47 | 48 | ### PoolAsset 49 | 50 | Ƭ **PoolAsset**: `Object` 51 | 52 | #### Type declaration 53 | 54 | | Name | Type | 55 | | :------ | :------ | 56 | | `address` | `string` | 57 | | `name` | `string` | 58 | | `symbol` | `string` | 59 | | `decimals` | `number` | 60 | | `index` | `number` | 61 | | `balance` | `BigNumber` | 62 | 63 | ___ 64 | 65 | ### ConnextSupport 66 | 67 | Ƭ **ConnextSupport**: `Object` 68 | 69 | #### Type declaration 70 | 71 | | Name | Type | 72 | | :------ | :------ | 73 | | `assets` | `string`[] | 74 | | `chainId` | `number` | 75 | | `domainId` | `string` | 76 | | `name` | `string` | 77 | 78 | ___ 79 | 80 | ### XTransferStatus 81 | 82 | Ƭ **XTransferStatus**: `Object` 83 | 84 | #### Type declaration 85 | 86 | | Name | Type | Value 87 | | :------ | :------ | :------ | 88 | | `XCalled` | `string` | "XCalled" | 89 | | `Executed` | `string`| "Executed" 90 | | `Reconciled` | `string` | "Reconciled" | 91 | | `CompletedFast` | `string` | "CompletedFast" | 92 | | `CompletedSlow` | `string` | "CompletedSlow" | 93 | -------------------------------------------------------------------------------- /docs/developers/reference/SDK/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "SDK", 3 | "position": 3 4 | } 5 | -------------------------------------------------------------------------------- /docs/developers/reference/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Reference", 3 | "position": 4, 4 | "collapsed": false 5 | } 6 | -------------------------------------------------------------------------------- /docs/developers/reference/contracts/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Contracts", 3 | "position": 1 4 | } 5 | -------------------------------------------------------------------------------- /docs/developers/reference/contracts/routers.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | title: Routers 4 | id: routers 5 | --- 6 | 7 | # Routers 8 | 9 | This section contains a full API reference of all public functions & events related to routers and router liquidity management. 10 | 11 | --- 12 | 13 | ## Events 14 | 15 | ### RouterAdded 16 | 17 | ```solidity 18 | event RouterAdded(address router, address caller) 19 | ``` 20 | 21 | Emitted when a new router is added 22 | 23 | #### Parameters 24 | 25 | | Name | Type | Description | 26 | | ---- | ---- | ----------- | 27 | | router | address | - The address of the added router | 28 | | caller | address | - The account that called the function | 29 | 30 | ### RouterRemoved 31 | 32 | ```solidity 33 | event RouterRemoved(address router, address caller) 34 | ``` 35 | 36 | Emitted when an existing router is removed 37 | 38 | #### Parameters 39 | 40 | | Name | Type | Description | 41 | | ---- | ---- | ----------- | 42 | | router | address | - The address of the removed router | 43 | | caller | address | - The account that called the function | 44 | 45 | ### RouterRecipientSet 46 | 47 | ```solidity 48 | event RouterRecipientSet(address router, address prevRecipient, address newRecipient) 49 | ``` 50 | 51 | Emitted when the recipient of router is updated 52 | 53 | #### Parameters 54 | 55 | | Name | Type | Description | 56 | | ---- | ---- | ----------- | 57 | | router | address | - The address of the added router | 58 | | prevRecipient | address | - The address of the previous recipient of the router | 59 | | newRecipient | address | - The address of the new recipient of the router | 60 | 61 | ### RouterOwnerProposed 62 | 63 | ```solidity 64 | event RouterOwnerProposed(address router, address prevProposed, address newProposed) 65 | ``` 66 | 67 | Emitted when the owner of router is proposed 68 | 69 | #### Parameters 70 | 71 | | Name | Type | Description | 72 | | ---- | ---- | ----------- | 73 | | router | address | - The address of the added router | 74 | | prevProposed | address | - The address of the previous proposed | 75 | | newProposed | address | - The address of the new proposed | 76 | 77 | ### RouterOwnerAccepted 78 | 79 | ```solidity 80 | event RouterOwnerAccepted(address router, address prevOwner, address newOwner) 81 | ``` 82 | 83 | Emitted when the owner of router is accepted 84 | 85 | #### Parameters 86 | 87 | | Name | Type | Description | 88 | | ---- | ---- | ----------- | 89 | | router | address | - The address of the added router | 90 | | prevOwner | address | - The address of the previous owner of the router | 91 | | newOwner | address | - The address of the new owner of the router | 92 | 93 | ### RouterLiquidityAdded 94 | 95 | ```solidity 96 | event RouterLiquidityAdded(address router, address local, bytes32 key, uint256 amount, address caller) 97 | ``` 98 | 99 | Emitted when a router adds liquidity to the contract 100 | 101 | #### Parameters 102 | 103 | | Name | Type | Description | 104 | | ---- | ---- | ----------- | 105 | | router | address | - The address of the router the funds were credited to | 106 | | local | address | - The address of the token added (all liquidity held in local asset) | 107 | | key | bytes32 | - The hash of the canonical id and domain | 108 | | amount | uint256 | - The amount of liquidity added | 109 | | caller | address | - The account that called the function | 110 | 111 | ### RouterLiquidityRemoved 112 | 113 | ```solidity 114 | event RouterLiquidityRemoved(address router, address to, address local, bytes32 key, uint256 amount, address caller) 115 | ``` 116 | 117 | Emitted when a router withdraws liquidity from the contract 118 | 119 | #### Parameters 120 | 121 | | Name | Type | Description | 122 | | ---- | ---- | ----------- | 123 | | router | address | - The router you are removing liquidity from | 124 | | to | address | - The address the funds were withdrawn to | 125 | | local | address | - The address of the token withdrawn | 126 | | key | bytes32 | | 127 | | amount | uint256 | - The amount of liquidity withdrawn | 128 | | caller | address | - The account that called the function | 129 | 130 | --- 131 | 132 | ## Getters 133 | 134 | ### getRouterApproval 135 | 136 | ```solidity 137 | function getRouterApproval(address _router) public view returns (bool) 138 | ``` 139 | 140 | Returns the approval status of a router for the given router address. 141 | 142 | #### Parameters 143 | 144 | | Name | Type | Description | 145 | | ---- | ---- | ----------- | 146 | | _router | address | The relevant router address | 147 | 148 | #### Return Values 149 | 150 | | Name | Type | Description | 151 | | ---- | ---- | ----------- | 152 | | [0] | bool | True if router is approved | 153 | 154 | ### getRouterRecipient 155 | 156 | ```solidity 157 | function getRouterRecipient(address _router) public view returns (address) 158 | ``` 159 | 160 | Returns the recipient for the specified router 161 | 162 | _The recipient (if set) receives all funds when router liquidity is removed_ 163 | 164 | #### Parameters 165 | 166 | | Name | Type | Description | 167 | | ---- | ---- | ----------- | 168 | | _router | address | The relevant router address | 169 | 170 | #### Return Values 171 | 172 | | Name | Type | Description | 173 | | ---- | ---- | ----------- | 174 | | [0] | address | Recipient address for router | 175 | 176 | ### getRouterOwner 177 | 178 | ```solidity 179 | function getRouterOwner(address _router) public view returns (address) 180 | ``` 181 | 182 | Returns the router owner if it is set, or the router itself if not 183 | 184 | _Uses logic function here to handle the case where router owner is not set. 185 | Other getters within this interface use explicitly the stored value_ 186 | 187 | #### Parameters 188 | 189 | | Name | Type | Description | 190 | | ---- | ---- | ----------- | 191 | | _router | address | The relevant router address | 192 | 193 | #### Return Values 194 | 195 | | Name | Type | Description | 196 | | ---- | ---- | ----------- | 197 | | [0] | address | Owner address of router | 198 | 199 | ### getProposedRouterOwner 200 | 201 | ```solidity 202 | function getProposedRouterOwner(address _router) public view returns (address) 203 | ``` 204 | 205 | Returns the currently proposed router owner 206 | 207 | _All routers must wait for the delay timeout before accepting a new owner_ 208 | 209 | #### Parameters 210 | 211 | | Name | Type | Description | 212 | | ---- | ---- | ----------- | 213 | | _router | address | The relevant router address | 214 | 215 | #### Return Values 216 | 217 | | Name | Type | Description | 218 | | ---- | ---- | ----------- | 219 | | [0] | address | Proposed owner address of router | 220 | 221 | ### getProposedRouterOwnerTimestamp 222 | 223 | ```solidity 224 | function getProposedRouterOwnerTimestamp(address _router) public view returns (uint256) 225 | ``` 226 | 227 | Returns the currently proposed router owner timestamp 228 | 229 | _All routers must wait for the delay timeout before accepting a new owner_ 230 | 231 | #### Parameters 232 | 233 | | Name | Type | Description | 234 | | ---- | ---- | ----------- | 235 | | _router | address | The relevant router address | 236 | 237 | #### Return Values 238 | 239 | | Name | Type | Description | 240 | | ---- | ---- | ----------- | 241 | | [0] | uint256 | Currently proposed router owner timestamp | 242 | 243 | ### routerBalances 244 | 245 | ```solidity 246 | function routerBalances(address _router, address _asset) public view returns (uint256) 247 | ``` 248 | 249 | Gets balance of asset for the specified router. 250 | 251 | #### Parameters 252 | 253 | | Name | Type | Description | 254 | | ---- | ---- | ----------- | 255 | | _router | address | The relevant router address | 256 | | _asset | address | The relevant asset | 257 | 258 | #### Return Values 259 | 260 | | Name | Type | Description | 261 | | ---- | ---- | ----------- | 262 | | [0] | uint256 | Balance the router owns of asset | 263 | 264 | --- 265 | 266 | ## Functions 267 | 268 | ### setupRouter 269 | 270 | ```solidity 271 | function setupRouter(address router, address owner, address recipient) external 272 | ``` 273 | 274 | Used to set router initial properties 275 | 276 | #### Parameters 277 | 278 | | Name | Type | Description | 279 | | ---- | ---- | ----------- | 280 | | router | address | Router address to setup | 281 | | owner | address | Initial Owner of router | 282 | | recipient | address | Initial Recipient of router | 283 | 284 | ### removeRouter 285 | 286 | ```solidity 287 | function removeRouter(address router) external 288 | ``` 289 | 290 | Used to remove routers that can transact crosschain 291 | 292 | #### Parameters 293 | 294 | | Name | Type | Description | 295 | | ---- | ---- | ----------- | 296 | | router | address | Router address to remove | 297 | 298 | ### setRouterRecipient 299 | 300 | ```solidity 301 | function setRouterRecipient(address router, address recipient) external 302 | ``` 303 | 304 | Sets the designated recipient for a router 305 | 306 | _Router should only be able to set this once otherwise if router key compromised, 307 | no problem is solved since attacker could just update recipient_ 308 | 309 | #### Parameters 310 | 311 | | Name | Type | Description | 312 | | ---- | ---- | ----------- | 313 | | router | address | Router address to set recipient | 314 | | recipient | address | Recipient Address to set to router | 315 | 316 | ### proposeRouterOwner 317 | 318 | ```solidity 319 | function proposeRouterOwner(address router, address proposed) external 320 | ``` 321 | 322 | Current owner or router may propose a new router owner 323 | 324 | #### Parameters 325 | 326 | | Name | Type | Description | 327 | | ---- | ---- | ----------- | 328 | | router | address | Router address to set recipient | 329 | | proposed | address | Proposed owner Address to set to router | 330 | 331 | ### acceptProposedRouterOwner 332 | 333 | ```solidity 334 | function acceptProposedRouterOwner(address router) external 335 | ``` 336 | 337 | New router owner must accept role, or previous if proposed is 0x0 338 | 339 | #### Parameters 340 | 341 | | Name | Type | Description | 342 | | ---- | ---- | ----------- | 343 | | router | address | Router address to set recipient | 344 | 345 | ### addRouterLiquidityFor 346 | 347 | ```solidity 348 | function addRouterLiquidityFor(uint256 _amount, address _local, address _router) external payable 349 | ``` 350 | 351 | This is used by anyone to increase a router's available liquidity for a given asset. 352 | 353 | _The liquidity will be held in the local asset, which is the representation if you 354 | are *not* on the canonical domain, and the canonical asset otherwise._ 355 | 356 | #### Parameters 357 | 358 | | Name | Type | Description | 359 | | ---- | ---- | ----------- | 360 | | _amount | uint256 | - The amount of liquidity to add for the router | 361 | | _local | address | - The address of the asset you're adding liquidity for. If adding liquidity of the native asset, routers may use `address(0)` or the wrapped asset | 362 | | _router | address | The router you are adding liquidity on behalf of | 363 | 364 | ### addRouterLiquidity 365 | 366 | ```solidity 367 | function addRouterLiquidity(uint256 _amount, address _local) external payable 368 | ``` 369 | 370 | This is used by any router to increase their available liquidity for a given asset. 371 | 372 | _The liquidity will be held in the local asset, which is the representation if you 373 | are *not* on the canonical domain, and the canonical asset otherwise._ 374 | 375 | #### Parameters 376 | 377 | | Name | Type | Description | 378 | | ---- | ---- | ----------- | 379 | | _amount | uint256 | - The amount of liquidity to add for the router | 380 | | _local | address | - The address of the asset you're adding liquidity for. If adding liquidity of the native asset, routers may use `address(0)` or the wrapped asset | 381 | 382 | ### removeRouterLiquidityFor 383 | 384 | ```solidity 385 | function removeRouterLiquidityFor(uint256 _amount, address _local, address payable _to, address _router) external 386 | ``` 387 | 388 | This is used by any router owner to decrease their available liquidity for a given asset. 389 | 390 | #### Parameters 391 | 392 | | Name | Type | Description | 393 | | ---- | ---- | ----------- | 394 | | _amount | uint256 | - The amount of liquidity to remove for the router | 395 | | _local | address | - The address of the asset you're removing liquidity from. If removing liquidity of the native asset, routers may use `address(0)` or the wrapped asset | 396 | | _to | address payable | The address that will receive the liquidity being removed | 397 | | _router | address | The address of the router | 398 | 399 | ### removeRouterLiquidity 400 | 401 | ```solidity 402 | function removeRouterLiquidity(uint256 _amount, address _local, address payable _to) external 403 | ``` 404 | 405 | This is used by any router to decrease their available liquidity for a given asset. 406 | 407 | #### Parameters 408 | 409 | | Name | Type | Description | 410 | | ---- | ---- | ----------- | 411 | | _amount | uint256 | - The amount of liquidity to remove for the router | 412 | | _local | address | - The address of the asset you're removing liquidity from. If removing liquidity of the native asset, routers may use `address(0)` or the wrapped asset | 413 | | _to | address payable | The address that will receive the liquidity being removed if no router recipient exists. | -------------------------------------------------------------------------------- /docs/developers/reference/contracts/types.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | title: Types 4 | id: contract-types 5 | --- 6 | 7 | ```solidity 8 | /** 9 | * @notice 10 | * @param params - The TransferInfo. These are consistent across sending and receiving chains. 11 | * @param routers - The routers who you are sending the funds on behalf of. 12 | * @param routerSignatures - Signatures belonging to the routers indicating permission to use funds 13 | * for the signed transfer ID. 14 | * @param sequencer - The sequencer who assigned the router path to this transfer. 15 | * @param sequencerSignature - Signature produced by the sequencer for path assignment accountability 16 | * for the path that was signed. 17 | */ 18 | struct ExecuteArgs { 19 | TransferInfo params; 20 | address[] routers; 21 | bytes[] routerSignatures; 22 | address sequencer; 23 | bytes sequencerSignature; 24 | } 25 | 26 | /** 27 | * @notice These are the parameters that will remain constant between the 28 | * two chains. They are supplied on `xcall` and should be asserted on `execute` 29 | * @property to - The account that receives funds, in the event of a crosschain call, 30 | * will receive funds if the call fails. 31 | * 32 | * @param originDomain - The originating domain (i.e. where `xcall` is called) 33 | * @param destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called)\ 34 | * @param canonicalDomain - The canonical domain of the asset you are bridging 35 | * @param to - The address you are sending funds (and potentially data) to 36 | * @param delegate - An address who can execute txs on behalf of `to`, in addition to allowing relayers 37 | * @param receiveLocal - If true, will use the local asset on the destination instead of adopted. 38 | * @param callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty. 39 | * @param slippage - Slippage user is willing to accept from original amount in expressed in BPS (i.e. if 40 | * a user takes 1% slippage, this is expressed as 1_000) 41 | * @param originSender - The msg.sender of the xcall 42 | * @param bridgedAmt - The amount sent over the bridge (after potential AMM on xcall) 43 | * @param normalizedIn - The amount sent to `xcall`, normalized to 18 decimals 44 | * @param nonce - The nonce on the origin domain used to ensure the transferIds are unique 45 | * @param canonicalId - The unique identifier of the canonical token corresponding to bridge assets 46 | */ 47 | struct TransferInfo { 48 | uint32 originDomain; 49 | uint32 destinationDomain; 50 | uint32 canonicalDomain; 51 | address to; 52 | address delegate; 53 | bool receiveLocal; 54 | bytes callData; 55 | uint256 slippage; 56 | address originSender; 57 | uint256 bridgedAmt; 58 | uint256 normalizedIn; 59 | uint256 nonce; 60 | bytes32 canonicalId; 61 | } 62 | ``` -------------------------------------------------------------------------------- /docs/developers/reference/integration/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Integration", 3 | "position": 4 4 | } 5 | -------------------------------------------------------------------------------- /docs/developers/reference/integration/adapters.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | title: Adapters 4 | id: adapters 5 | --- 6 | 7 | # Adapters 8 | 9 | Adapters are contracts that can hook into the normal flow of cross-chain transactions and augment their capabilities without requiring changes in existing contracts. The [connext/integration](https://github.com/connext/connext-integration) repository contains adapters that can be inherited for these purposes. 10 | 11 | ## SwapAdapter 12 | 13 | This adapter contains the logic for swapping tokens. The `SwapAdapter` can be used on either the origin or the destination side to execute a swap. 14 | 15 | ### Using on Origin 16 | 17 | `SwapAndXCall` is a contract that implements `SwapAdapter` and is meant to be used on the origin chain. It swaps the input tokens into desired output tokens before initiating the cross-chain transaction with `xcall`. This is useful in cases where you want users to be able to send any token to your contract and bridge them through Connext. 18 | 19 | ### Using on Destination 20 | 21 | `SwapForwarderXReceiver` also implements `SwapAdapter` but it's used on the destination chain. It swaps the tokens received from the bridge into desired output tokens before proceeding with the "forward call", which contains the rest of the logic that follows on the destination side. The `ForwarderXReceiver` that it implements is detailed in the next section for [Receivers](./receivers). 22 | 23 | ### Swappers 24 | 25 | The `SwapAdapter` holds a registry of `allowedSwappers` which are contracts that implement the `ISwapper` interface: 26 | 27 | ```solidity 28 | interface ISwapper { 29 | function swap( 30 | uint256 _amountIn, 31 | address _tokenIn, 32 | address _tokenOut, 33 | bytes calldata _swapData 34 | ) external payable returns (uint256 amountOut); 35 | } 36 | ``` 37 | 38 | For example, the `UniV3Swapper` implements `swap` which internally calls Uniswap's `ISwapRouter.exactInputSingle` to execute the swap via Uniswap. 39 | 40 | Currently, Connext provides the following Swappers: 41 | 42 | - `OneInchUniswapV3` 43 | - `UniV2Swapper` 44 | - `UniV3Swapper` 45 | -------------------------------------------------------------------------------- /docs/developers/reference/integration/receivers.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | title: Receivers 4 | id: receivers 5 | --- 6 | 7 | # Receivers 8 | 9 | Receivers are contracts that implement the `IXReceiver` interface: 10 | 11 | ```solidity 12 | interface IXReceiver { 13 | function xReceive( 14 | bytes32 _transferId, 15 | uint256 _amount, 16 | address _asset, 17 | address _originSender, 18 | uint32 _origin, 19 | bytes memory _callData 20 | ) external returns (bytes memory); 21 | } 22 | ``` 23 | 24 | These are the main contracts that integrators implement. Connext provides a few abstract receivers that should be inherited in order to gain the built-in security and error handling. 25 | 26 | ## ForwarderXReceiver 27 | 28 | The `ForwarderXReceiver` is used for unauthenticated calls. The receiver has two virtual functions that the integrator should implement to 1) prepare and 2) forward the call. 29 | 30 | ### _prepare 31 | 32 | ```solidity 33 | function _prepare( 34 | bytes32 _transferId, 35 | bytes memory _data, 36 | uint256 _amount, 37 | address _asset 38 | ) internal virtual returns (bytes memory) 39 | ``` 40 | 41 | Preparation steps should be performed in `_prepare`, which can include operations like swapping funds. 42 | 43 | ### _forwardFunctionCall 44 | 45 | ```solidity 46 | function _forwardFunctionCall( 47 | bytes memory _preparedData, 48 | bytes32 _transferId, 49 | uint256 _amount, 50 | address _asset 51 | ) internal virtual returns (bool) 52 | ``` 53 | 54 | The `_forwardFunctionCall` should contain the logic that calls the destination target contract. 55 | 56 | ## AuthForwarderXReceiver 57 | 58 | The `AuthForwarderXReceiver` is used for authenticated calls. It follows the same two-step pattern as the `ForwarderXReceiver` (`_prepare` + `_forwardFunctionCall`). 59 | 60 | ### onlyOrigin 61 | 62 | In addition, the `xReceive` method is guarded by an `onlyOrigin` modifier which ensures that: 63 | 64 | 1. The originating call comes from a registered origin domain. 65 | 2. The originating call comes from the expected origin contract of the origin domain. 66 | 3. The call to this contract comes from Connext. 67 | 68 | These checks guarantee that any successful call to an `AuthForwarderXReceiver` contains validated data. For more information on authentication, see the [Authentication](../../guides/authentication.md) section. 69 | 70 | ### originRegistry 71 | 72 | This contract also holds an `originRegistry` which maps origin domain IDs to origin sender contracts. This registry is checked to uphold requirement #2 for the modifier above. 73 | 74 | The contract is `Ownable` and only the owner can `addOrigin` and `removeOrigin`. All expected origins and senders should be registered in this mapping. -------------------------------------------------------------------------------- /docs/developers/reference/subgraph/Entities.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | title: Entities 4 | --- 5 | 6 | ## Asset 7 | 8 | ```graphql 9 | type Asset @entity { 10 | id: ID! "The local asset address." 11 | key: Bytes "The key associated with the local asset." 12 | canonicalId: Bytes "The canonical identifier for the asset." 13 | canonicalDomain: BigInt "The domain of the canonical identifier for the asset." 14 | adoptedAsset: Bytes "The address of the adopted asset, if applicable." 15 | localAsset: Bytes "The address of the local asset." 16 | blockNumber: BigInt "The block # associated with the local asset, needed in case multiple locals are stored under the same canonicalId." 17 | status: AssetStatus "The status of the asset, as defined by the AssetStatus enumeration." 18 | } 19 | 20 | ``` 21 | 22 | ## AssetStatus 23 | 24 | ```graphql 25 | type AssetStatus @entity { 26 | id: ID! "The key associated with the asset status." 27 | status: Boolean "The status of the asset, represented as a boolean value. True means the asset is active, while false means it is inactive." 28 | } 29 | 30 | ``` 31 | 32 | ## AssetBalance 33 | 34 | ```graphql 35 | type AssetBalance @entity { 36 | id: ID! "The unique identifier for the asset balance, constructed as 'key-router_address'." 37 | amount: BigInt! "The amount of the asset held in the balance." 38 | router: Router! "The router associated with the asset balance." 39 | asset: Asset! "The asset associated with the balance." 40 | feesEarned: BigInt! "The total amount of fees earned for the asset balance." 41 | } 42 | 43 | ``` 44 | 45 | ## Router 46 | 47 | ```graphql 48 | type Router @entity { 49 | id: ID! "The unique identifier for the router." 50 | isActive: Boolean! "A boolean indicating whether the router is currently active or not." 51 | owner: Bytes "The address of the current owner of the router." 52 | recipient: Bytes "The address of the current recipient of router fees." 53 | proposedOwner: Bytes "The address of the proposed new owner of the router, if any." 54 | proposedTimestamp: BigInt "The timestamp of the proposed ownership transfer, if any." 55 | assetBalances: [AssetBalance!]! @derivedFrom(field: "router") "A list of asset balances associated with the router." 56 | } 57 | 58 | ``` 59 | 60 | ## Setting 61 | 62 | ```graphql 63 | type Setting @entity { 64 | id: ID! "The unique identifier for the setting." 65 | maxRoutersPerTransfer: BigInt! "The maximum number of routers allowed in a single transfer." 66 | caller: Bytes! "The address of the caller associated with the setting." 67 | } 68 | 69 | ``` 70 | 71 | ## Relayer 72 | 73 | ```graphql 74 | type Relayer @entity { 75 | id: ID! "The ID of the relayer" 76 | isActive: Boolean! "Indicates whether the relayer is currently active" 77 | relayer: Bytes "The address of the relayer" 78 | } 79 | 80 | ``` 81 | 82 | ## Sequencer 83 | 84 | ```graphql 85 | type Sequencer @entity { 86 | id: ID! "Unique identifier for the sequencer entity" 87 | isActive: Boolean! "Flag indicating if the sequencer is active or not" 88 | sequencer: Bytes "Address of the sequencer" 89 | } 90 | 91 | ``` 92 | 93 | ## TransferStatus 94 | 95 | ```graphql 96 | enum TransferStatus { 97 | XCalled 98 | Executed 99 | Reconciled 100 | CompletedSlow 101 | CompletedFast 102 | } 103 | ``` 104 | 105 | ## OriginTransfer 106 | 107 | ```graphql 108 | type OriginTransfer @entity { 109 | id: ID! "The unique identifier for the origin transfer." 110 | 111 | # Meta 112 | chainId: BigInt "The ID of the chain on which the transfer is taking place." 113 | transferId: Bytes "The unique identifier for the transfer." 114 | nonce: BigInt "A unique nonce for the transfer, used to prevent replay attacks." 115 | status: TransferStatus "The status of the transfer, represented as a TransferStatus enum." 116 | messageHash: Bytes "The hash of the transfer message." 117 | 118 | # CallParams 119 | originDomain: BigInt "The domain of the origin chain." 120 | destinationDomain: BigInt "The domain of the destination chain." 121 | canonicalDomain: BigInt "The domain of the canonical asset." 122 | to: Bytes "The address of the destination contract." 123 | delegate: Bytes "The address of the delegate contract." 124 | receiveLocal: Boolean "A boolean indicating whether the transfer is receiving a local asset." 125 | callData: Bytes "The calldata associated with the transfer." 126 | slippage: BigInt "The maximum amount of slippage allowed for the transfer." 127 | originSender: Bytes "The address of the sender on the origin chain." 128 | bridgedAmt: BigInt "The amount of the asset being transferred." 129 | normalizedIn: BigInt "The normalized amount of the asset being transferred." 130 | canonicalId: Bytes "The canonical ID of the asset being transferred." 131 | 132 | # Asset 133 | asset: Asset "The asset being transferred." 134 | 135 | # Message 136 | message: OriginMessage "The message associated with the transfer." 137 | 138 | # Relayer Fee paid by user 139 | relayerFee: BigInt "The fee paid by the user for the transfer." 140 | bumpRelayerFeeCount: BigInt "The number of times the relayer fee has been bumped." 141 | 142 | # XCalled Transaction 143 | caller: Bytes "The address of the caller." 144 | transactionHash: Bytes "The hash of the transaction." 145 | timestamp: BigInt "The timestamp of the transaction." 146 | gasPrice: BigInt "The price of gas for the transaction." 147 | gasLimit: BigInt "The limit for gas usage in the transaction." 148 | blockNumber: BigInt "The number of the block in which the transaction was included." 149 | txOrigin: Bytes "The address of the original transaction sender." 150 | } 151 | 152 | ``` 153 | 154 | ## DestinationTransfer 155 | 156 | ```graphql 157 | type DestinationTransfer @entity { 158 | id: ID! "unique identifier of the destination transfer" 159 | 160 | # Meta 161 | chainId: BigInt "chain id of the transfer" 162 | transferId: Bytes "unique identifier for the transfer" 163 | nonce: BigInt "number used to prevent replay attacks" 164 | status: TransferStatus "status of the transfer" 165 | routers: [Router!]! "list of routers used for the transfer" 166 | 167 | # CallParams 168 | originDomain: BigInt "domain of the origin chain" 169 | destinationDomain: BigInt "domain of the destination chain" 170 | canonicalDomain: BigInt "canonical domain of the asset" 171 | to: Bytes "recipient address on the destination chain" 172 | delegate: Bytes "optional delegate address on the destination chain" 173 | receiveLocal: Boolean "whether or not to receive the asset locally on the destination chain" 174 | callData: Bytes "optional call data for the recipient" 175 | slippage: BigInt "slippage allowance for routers to adjust exchange rate" 176 | bumpSlippageCount: BigInt "count of times the slippage allowance was increased" 177 | originSender: Bytes "sender address on the origin chain" 178 | bridgedAmt: BigInt "amount of asset bridged from the origin chain" 179 | normalizedIn: BigInt "amount of asset normalized to its canonical representation" 180 | canonicalId: Bytes "unique identifier for the asset" 181 | 182 | # Asset 183 | asset: Asset "asset being transferred" 184 | amount: BigInt "amount of asset being transferred" 185 | 186 | # calculated 187 | routersFee: BigInt "total fee paid to routers for the transfer" 188 | 189 | # Executed Transaction 190 | executedCaller: Bytes "address of the user who initiated the transaction" 191 | executedTransactionHash: Bytes "hash of the executed transaction" 192 | executedTimestamp: BigInt "timestamp of the executed transaction" 193 | executedGasPrice: BigInt "gas price used for the executed transaction" 194 | executedGasLimit: BigInt "gas limit used for the executed transaction" 195 | executedBlockNumber: BigInt "block number of the executed transaction" 196 | executedTxOrigin: Bytes "address of the user who initiated the transaction on the destination chain" 197 | 198 | # Reconciled Transaction 199 | reconciledCaller: Bytes "address of the user who initiated the reconciled transaction" 200 | reconciledTransactionHash: Bytes "hash of the reconciled transaction" 201 | reconciledTimestamp: BigInt "timestamp of the reconciled transaction" 202 | reconciledGasPrice: BigInt "gas price used for the reconciled transaction" 203 | reconciledGasLimit: BigInt "gas limit used for the reconciled transaction" 204 | reconciledBlockNumber: BigInt "block number of the reconciled transaction" 205 | reconciledTxOrigin: Bytes "address of the user who initiated the reconciled transaction on the origin chain" 206 | } 207 | 208 | ``` 209 | 210 | ## OriginMessage 211 | 212 | ```graphql 213 | type OriginMessage @entity { 214 | id: ID! "unique identifier for each instance of the OriginMessage" 215 | 216 | # origin transfer data 217 | transferId: Bytes "ID of the origin transfer" 218 | destinationDomain: BigInt "domain where the transfer is being sent to" 219 | 220 | # Dispatch Transaction 221 | leaf: Bytes "leaf of the Merkle tree of the message" 222 | index: BigInt "index of the message in the Merkle tree" 223 | message: Bytes "the message data" 224 | root: Bytes "root of the Merkle tree of the message" 225 | transactionHash: Bytes "hash of the transaction that dispatched the message" 226 | blockNumber: BigInt "block number of the transaction that dispatched the message" 227 | 228 | # root count RD 229 | rootCount: RootCount "reference to the root count for this message" 230 | } 231 | 232 | ``` 233 | 234 | ## AggregateRoot 235 | 236 | ```graphql 237 | type AggregateRoot @entity { 238 | id: ID! "Unique identifier of the entity" 239 | root: Bytes! "The root hash of a Merkle tree containing transaction messages" 240 | blockNumber: BigInt! "The block number where the root was aggregated" 241 | } 242 | 243 | ``` 244 | 245 | ## ConnectorMeta 246 | 247 | ```graphql 248 | type ConnectorMeta @entity { 249 | id: ID! "ConnectorMeta" 250 | spokeDomain: BigInt "domain of the spoke network" 251 | hubDomain: BigInt "domain of the hub network" 252 | 253 | amb: Bytes "address of the AMB contract used for bridging" 254 | rootManager: Bytes "address of the root manager contract used for managing bridge roots" 255 | mirrorConnector: Bytes "address of the MirrorConnector contract used for interacting with the Mirror network" 256 | } 257 | ``` 258 | 259 | ## RootCount 260 | 261 | ```graphql 262 | type RootCount @entity { 263 | id: ID! "unique identifier for the root count, typically a concatenation of the spoke and hub domain IDs" 264 | count: BigInt "the current root count for the given spoke and hub domain pair" 265 | } 266 | 267 | ``` 268 | 269 | ## RootMessageSent 270 | 271 | ```graphql 272 | type RootMessageSent @entity { 273 | id: ID! "Unique identifier for the root message sent" 274 | 275 | spokeDomain: BigInt "Domain ID for the spoke chain" 276 | hubDomain: BigInt "Domain ID for the hub chain" 277 | root: Bytes "Root hash for the message" 278 | count: BigInt "Number of messages in the root" 279 | 280 | # MessageSent Transaction 281 | caller: Bytes "Address of the transaction sender" 282 | transactionHash: Bytes "Hash of the transaction" 283 | timestamp: BigInt "Timestamp of the transaction" 284 | gasPrice: BigInt "Gas price for the transaction" 285 | gasLimit: BigInt "Gas limit for the transaction" 286 | blockNumber: BigInt "Block number of the transaction" 287 | } 288 | 289 | ``` 290 | -------------------------------------------------------------------------------- /docs/developers/reference/subgraph/Queries.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | title: Sample Queries 4 | --- 5 | 6 | ## Sample Queries 7 | 8 | Below are some sample queries you can use to gather information from the Connext contracts. 9 | 10 | You can build your own queries using a [GraphQL Explorer](https://graphiql-online.com/graphiql) and enter your endpoint to limit the data to exactly what you need. 11 | 12 | ### Get origin domain details of an xcall 13 | 14 | ```graphql 15 | query OriginTransfer { 16 | originTransfers( 17 | where: { 18 | # Query by the transaction hash of the xcall 19 | transactionHash: "", 20 | # Or by the xcall's transfer ID 21 | transferId: "" 22 | } 23 | ) { 24 | # Meta Data 25 | chainId 26 | nonce 27 | transferId 28 | to 29 | delegate 30 | receiveLocal 31 | callData 32 | slippage 33 | originSender 34 | originDomain 35 | destinationDomain 36 | transactionHash 37 | bridgedAmt 38 | status 39 | timestamp 40 | normalizedIn 41 | # Asset Data 42 | asset { 43 | id 44 | adoptedAsset 45 | canonicalId 46 | canonicalDomain 47 | } 48 | } 49 | } 50 | ``` 51 | 52 | ### Get destination domain details of an xcall 53 | 54 | ```graphql 55 | query DestinationTransfer { 56 | destinationTransfers( 57 | where: { 58 | transferId: "" 59 | } 60 | ) { 61 | # Meta Data 62 | chainId 63 | nonce 64 | transferId 65 | to 66 | callData 67 | originDomain 68 | destinationDomain 69 | delegate 70 | # Asset Data 71 | asset { 72 | id 73 | } 74 | bridgedAmt 75 | # Executed event Data 76 | status 77 | routers { 78 | id 79 | } 80 | originSender 81 | # Executed Transaction 82 | executedCaller 83 | executedTransactionHash 84 | executedTimestamp 85 | executedGasPrice 86 | executedGasLimit 87 | executedBlockNumber 88 | # Reconciled Transaction 89 | reconciledCaller 90 | reconciledTransactionHash 91 | reconciledTimestamp 92 | reconciledGasPrice 93 | reconciledGasLimit 94 | reconciledBlockNumber 95 | routersFee 96 | slippage 97 | } 98 | } 99 | ``` 100 | -------------------------------------------------------------------------------- /docs/developers/reference/subgraph/Resources.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | title: Resources 4 | --- 5 | 6 | # Subgraph Resources 7 | 8 | Connext has a GraphQL API Endpoint hosted by [The Graph](https://thegraph.com/docs/about/introduction#what-the-graph-is) called a subgraph for indexing and organizing data from the Connext smart contracts. Subgraph information is serviced by a decentralized group of server operators called Indexers. 9 | 10 | This subgraph is can be used to query Connext bridge transactions, transactions statuses and more. 11 | 12 | ## Subgraphs 13 | 14 |
15 | 16 | Mainnet Subgraphs 17 | 18 | | Chain | Subgraph | 19 | | --- | --- | 20 | | Ethereum | [v0-Mainnet](https://thegraph.com/hosted-service/subgraph/connext/amarok-runtime-v0-mainnet) | 21 | | Optimism | [v0-Optimism](https://thegraph.com/hosted-service/subgraph/connext/amarok-runtime-v0-optimism) | 22 | | Arbitrum | [v0-Arbitrum-One](https://thegraph.com/hosted-service/subgraph/connext/amarok-runtime-v0-arbitrum-one) | 23 | | Polygon | [v0-Polygon](https://thegraph.com/hosted-service/subgraph/connext/amarok-runtime-v0-polygon) | 24 | | Binance Smart Chain | [v0-Bnb](https://thegraph.com/hosted-service/subgraph/connext/amarok-runtime-v0-bnb) | 25 | | Gnosis | [v0-Gnosis](https://thegraph.com/hosted-service/subgraph/connext/amarok-runtime-v0-gnosis) | 26 | 27 |
28 | 29 |
30 | 31 | Testnet Subgraphs 32 | 33 | | Chain | Subgraph | 34 | | --- | --- | 35 | | Goerli | [v0-Goerli](https://thegraph.com/hosted-service/subgraph/connext/nxtp-amarok-runtime-v0-goerli) | 36 | | Optimism-Goerli | [v0-Opt-Goerli](https://thegraph.com/hosted-service/subgraph/connext/amarok-runtime-v0-opt-goerli) | 37 | | Mumbai | [v0-Mumbai](https://thegraph.com/hosted-service/subgraph/connext/nxtp-amarok-runtime-v0-mumbai) | 38 | 39 |
40 | 41 | ## Helpful Links 42 | 43 | [Creating an API Key Video Tutorial](https://www.youtube.com/watch?v=UrfIpm-Vlgs) 44 | 45 | [Managing your API Key & Setting your indexer preferences](https://thegraph.com/docs/en/studio/managing-api-keys/) 46 | 47 | [Explorer Page](https://thegraph.com/explorer/subgraph?id=DfD1tZSmDtjCGC2LeYEQbVzj9j8kNqKAQEsYL27Vg6Sw&view=Playground) 48 | 49 | [Code repo with Connext's subgraph implementation](https://github.com/connext/monorepo/tree/56a166f3ecb50cc10356dd96c257e2e4d47f29e3/packages/deployments/subgraph/src/amarok-runtime-v0) -------------------------------------------------------------------------------- /docs/developers/reference/subgraph/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Subgraphs", 3 | "position": 2 4 | } 5 | -------------------------------------------------------------------------------- /docs/resources/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Resources", 3 | "position": 4 4 | } 5 | -------------------------------------------------------------------------------- /docs/resources/deployed.json: -------------------------------------------------------------------------------- 1 | { 2 | "environments": { 3 | "staging": { 4 | "domains": { 5 | "1735353714": { 6 | "name": "Goerli", 7 | "contracts": { 8 | "Connext": "0x9590e2bB6a93e2a531b0269eE7396cECc3E5d6eA" 9 | }, 10 | "assets": [ 11 | { 12 | "name": "Test Token", 13 | "symbol": "TEST", 14 | "address": "0x7ea6eA49B0b0Ae9c5db7907d139D9Cd3439862a1", 15 | "flavor": "Canonical" 16 | }, 17 | { 18 | "name": "Wrapped Ether", 19 | "symbol": "WETH", 20 | "address": "0x7ea6eA49B0b0Ae9c5db7907d139D9Cd3439862a1", 21 | "flavor": "Canonical" 22 | } 23 | ] 24 | }, 25 | "1735356532": { 26 | "name": "Optimism-Goerli", 27 | "contracts": { 28 | "Connext": "0x9D399235dC47e17ADF7c70e308AA9A6485cA6321" 29 | }, 30 | "assets": [ 31 | { 32 | "name": "TEST", 33 | "symbol": "TEST", 34 | "address": "0x68Db1c8d85C09d546097C65ec7DCBFF4D6497CbF", 35 | "flavor": "Local/Adopted" 36 | }, 37 | { 38 | "name": "Connext Wrapped Ether", 39 | "symbol": "nextWETH", 40 | "address": "0x39B061B7e41DE8B721f9aEcEB6b3f17ECB7ba63E", 41 | "flavor": "Local" 42 | }, 43 | { 44 | "name": "Wrapped Ether", 45 | "symbol": "WETH", 46 | "address": "0x74c6FD7D2Bc6a8F0Ebd7D78321A95471b8C2B806", 47 | "flavor": "Adopted" 48 | } 49 | ], 50 | "providers": ["https://goerli.optimism.io/"] 51 | }, 52 | "9991": { 53 | "name": "Polygon-Mumbai", 54 | "contracts": { 55 | "Connext": "0x54D9cE093622Ac2685D11D9FCF8f1ec02585e128" 56 | }, 57 | "assets": [ 58 | { 59 | "name": "TEST", 60 | "symbol": "TEST", 61 | "address": "0xeDb95D8037f769B72AAab41deeC92903A98C9E16", 62 | "flavor": "Local/Adopted" 63 | }, 64 | { 65 | "name": "Connext Wrapped Ether", 66 | "symbol": "nextWETH", 67 | "address": "0x1E5341E4b7ed5D0680d9066aac0396F0b1bD1E69", 68 | "flavor": "Local" 69 | }, 70 | { 71 | "name": "Wrapped Ether", 72 | "symbol": "WETH", 73 | "address": "0xFD2AB41e083c75085807c4A65C0A14FDD93d55A9", 74 | "flavor": "Adopted" 75 | } 76 | ] 77 | } 78 | } 79 | }, 80 | "production": { 81 | "domains": { 82 | "1735353714": { 83 | "name": "Goerli", 84 | "contracts": { 85 | "Connext": "0x76A4C43783d39539e6e4bC768AfA4651877633d5" 86 | }, 87 | "assets": [ 88 | { 89 | "name": "Test Token", 90 | "symbol": "TEST", 91 | "address": "0x7ea6eA49B0b0Ae9c5db7907d139D9Cd3439862a1", 92 | "flavor": "Canonical" 93 | }, 94 | { 95 | "name": "Wrapped Ether", 96 | "symbol": "WETH", 97 | "address": "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6", 98 | "flavor": "Canonical" 99 | } 100 | ] 101 | }, 102 | "1735356532": { 103 | "name": "Optimism-Goerli", 104 | "contracts": { 105 | "Connext": "0xDa3731880eF51584bBE48E9a5a574D9c15e58E0E" 106 | }, 107 | "assets": [ 108 | { 109 | "name": "Test Token", 110 | "symbol": "TEST", 111 | "address": "0x68Db1c8d85C09d546097C65ec7DCBFF4D6497CbF", 112 | "flavor": "Local/Adopted" 113 | }, 114 | { 115 | "name": "Connext Wrapped Ether", 116 | "symbol": "nextWETH", 117 | "address": "0x39B061B7e41DE8B721f9aEcEB6b3f17ECB7ba63E", 118 | "flavor": "Local" 119 | }, 120 | { 121 | "name": "Wrapped Ether", 122 | "symbol": "WETH", 123 | "address": "0x74c6FD7D2Bc6a8F0Ebd7D78321A95471b8C2B806", 124 | "flavor": "Adopted" 125 | } 126 | ], 127 | "providers": ["https://goerli.optimism.io/"] 128 | }, 129 | "9991": { 130 | "name": "Polygon-Mumbai", 131 | "contracts": { 132 | "Connext": "0x49D842be67bd3810EA65e31023407ec7d347660E" 133 | }, 134 | "assets": [ 135 | { 136 | "name": "Test Token", 137 | "symbol": "TEST", 138 | "address": "0xeDb95D8037f769B72AAab41deeC92903A98C9E16", 139 | "flavor": "Local/Adopted" 140 | }, 141 | { 142 | "name": "Connext Wrapped Ether", 143 | "symbol": "nextWETH", 144 | "address": "0x1E5341E4b7ed5D0680d9066aac0396F0b1bD1E69", 145 | "flavor": "Local" 146 | }, 147 | { 148 | "name": "Wrapped Ether", 149 | "symbol": "WETH", 150 | "address": "0xFD2AB41e083c75085807c4A65C0A14FDD93d55A9", 151 | "flavor": "Adopted" 152 | } 153 | ] 154 | } 155 | } 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /docs/resources/supported-chains.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | id: supported-chains 4 | --- 5 | 6 | # Supported Chains 7 | 8 | ## Domain IDs 9 | 10 | Domain IDs are unique to every bridge and differ from Chain IDs. Connext's `xcall` requires specifying which Domain ID should be the destination of a cross-chain transaction. 11 | 12 | ## Mainnet 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
NameChain IDDomain IDStatus
Ethereum Mainnet16648936
Polygon1371886350457
Optimism101869640809
Arbitrum One421611634886255
Gnosis Chain1006778479
BNB Chain566450786
58 | 59 | ## Testnet 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 |
NameChain IDDomain IDStatus
Goerli51735353714
Optimism-Goerli4201735356532
Mumbai800019991
Arbitrum-Goerli4216131734439522
zkSync Era Testnet2802053862260
Linea Testnet591401668247156
Polygon zkEVM Testnet14421887071092
111 | -------------------------------------------------------------------------------- /docs/routers/Guides/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Guides", 3 | "position": 4, 4 | "collapsed": false 5 | } 6 | -------------------------------------------------------------------------------- /docs/routers/Guides/community-guides.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | # Community Guides 5 | 6 | ## Articles 7 | 8 | ### English 9 | 10 | 1. [Running a Router Guide](https://medium.com/@roojthemighty/how-to-spin-up-a-router-on-connext-network-ver-eng-4ff391b05d94) (Digital Ocean) 11 | 2. [Running a Router Guide](https://teletype.in/@moodman/s83IWlWwfsm) 12 | 3. [Running a Router Guide](https://mirror.xyz/cyberg.eth/vxkEyroJ0vCnAXEuTl36-5UUrYjCf0V6tf59_PPGLQ0) 13 | 4. [Running a Router Guide](https://dramatic-fox-ea1.notion.site/Spinning-up-Connext-Router-20591e06bf2149f0b9d41fa6754469c0#6415e09af8454f78b4233ac8fcacac79) 14 | 5. [Running a Ruter Guide](https://github.com/louwo/Guide-for-routers) 15 | 6. [Adding Liquidity Guide](https://medium.com/@nizeimbaboy.2/how-to-add-liquidity-in-connext-f0f6bfedeabc) 16 | 17 | ### French 18 | 19 | 1. [Running a Router Guide](https://mirror.xyz/0x5214F449553f572F30dE3717CaCA29088A386eEb/BJaHlfi2PoMGN349sIZhim-U1_aa79sIacyZV4ON4As) 20 | 21 | ### Russian 22 | 23 | 1. [Running a Router Guide](https://7nda.medium.com/%D0%B7%D0%B0%D0%BF%D1%83%D1%81%D0%BA-%D1%80%D0%BE%D1%83%D1%82%D0%B5%D1%80%D0%B0-connext-d6335e7e962e) 24 | 2. [Running a Router Guide](https://github.com/cybernekit/RouterSetupGuide) 25 | 3. [Running a Router Guide](https://teletype.in/@landeros/zd69DV9Z1lY) 26 | 4. [Running a Router Guide](https://medium.com/@alexzhurba/spinning-up-connext-router-fe3260912f0a) 27 | 28 | ### Thai 29 | 30 | 1. [Running a Router Guide](https://medium.com/@roojthemighty/how-to-spin-up-a-router-on-connext-network-ver-%E0%B9%84%E0%B8%97%E0%B8%A2-f5405ac3a6dc) (Digital Ocean) 31 | 2. [Running a Router Guide](https://medium.com/@nizeimbaboy.2/how-to-run-node-connext-node-v-%E0%B8%A0%E0%B8%B2%E0%B8%A9%E0%B8%B2%E0%B9%84%E0%B8%97%E0%B8%A2-6a6cd3406e19) (Digital Ocean) 32 | 3. [Running a Router Guide]() 33 | 4. [Running a Router Guide](https://medium.com/@arsarawutpad/%E0%B8%84%E0%B8%B9%E0%B9%88%E0%B8%A1%E0%B8%B7%E0%B8%AD%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B8%95%E0%B8%B4%E0%B8%94%E0%B8%95%E0%B8%B1%E0%B9%89%E0%B8%87-connext-router-testnet-17f941252652) 34 | 5. [Minting $TEST Tokens](https://medium.com/@roojthemighty/how-to-mint-test-tokens-on-connext-testnet-e14c5fbafafe) 35 | 6. [Running a Router and Adding Liquidity Guide](https://docs.google.com/document/d/1mmoVazi3hOC6nAqRJMK1VuKPPomi64zv9oxA0nSncFk/edit?usp=sharing) 36 | 7. [Adding Liquidity Guide](https://medium.com/@nizeimbaboy.2/how-to-add-liquidity-in-connext-2655559eea46) 37 | 8. [Running a Router Guide](https://medium.com/@airdropmaglionaire/run-connext-router-step-by-step-8c565c082b2e) (Google Cloud) 38 | 39 | ### Chinese 40 | 41 | 1. [Running a Router Guide](https://gist.github.com/bynil/ae29155040c0d6c84ddf497a8462d3d6) 42 | 2. [Running a Router Guide](https://mirror.xyz/bullcoin.eth/c-ZKFX4_IsyRM-TJgg8KHoMjtm7E8nov_x9EcErzDeo) 43 | 3. [Running a Router Guide](https://mirror.xyz/exploring.eth/fwb657xWhr5Q3mvoNes0eYT75yZtE6_hqVgOF3dVZSY) 44 | 45 | ### Spanish 46 | 47 | 1. [Running a Router Guide](https://github.com/VArtOff/Connext-Guide/blob/main/Spanish%20Guide.md) 48 | 49 | ## Videos 50 | 51 | ### English 52 | 53 | 1. [Running a Router Guide](https://youtu.be/jwRR45-ycSw) 54 | 2. [Running a Router Guide](https://drive.google.com/drive/folders/1y9a3QDr7z0wvxhiauOSePz9ThkspUdFG) (Local Home Computer) 55 | 3. [Running a Router Guide](https://www.youtube.com/watch?v=TTbssVrhL2s) (Hetzner) 56 | 57 | ### Russian 58 | 59 | 1. [Running a Router Guide](https://www.youtube.com/watch?v=2_OAz9nIls8) 60 | 61 | ### Thai 62 | 63 | 1. [Running a Router Guide](https://www.youtube.com/watch?v=ShNRtdV4URA&t=873s) (Digital Ocean) (Easy to follow) 64 | 3. [Running a Router Guide](https://www.youtube.com/watch?v=Tt6zBupfbF0) (Digital Ocean) 65 | 4. [Running a Router Guide](https://www.youtube.com/watch?v=Do3z5Ikp5ac) 66 | 4. [Adding Liquidity Guide](https://youtu.be/xJ16II1axjU) 67 | 68 | ### Chinese 69 | 70 | 1. Running a Router Guide ([Youtube](https://www.youtube.com/watch?v=E-zGm45dWsc) / [Bilibili](https://www.bilibili.com/video/BV1q3411G7pd/)) 71 | 72 | ### Ukraine 73 | 1. [Running a Router Guide](https://medium.com/@88vgk88/%D0%BD%D0%B0%D0%BB%D0%B0%D1%88%D1%82%D1%83%D0%B2%D0%B0%D0%BD%D0%BD%D1%8F-%D1%80%D0%BE%D1%83%D1%82%D0%B5%D1%80%D0%B0-connext-3cd0fbdc5596) 74 | 75 | ## Script 76 | 1. [Auto setup and update script](https://github.com/NunoyHaxxana/nxtp-router-setup) 77 | - Script for install Connext Router with the latest release and auto update function 78 | 2. [Shell script to download and update to the latest version](https://github.com/NunoyHaxxana/Router-Connext-Quests-2) 79 | - Auto install script with automatic private key generation and auto update function 80 | 81 | ## Tools 82 | 1. [Discord alerting system](https://github.com/NunoyHaxxana/Router-Connext-Quests-3) 83 | - Script for monitoring docker and send alert to Discord 84 | -------------------------------------------------------------------------------- /docs/routers/Guides/liquidity.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | # Providing Liquidity 5 | 6 | ### How it works 7 | 8 | At a high level, routers provide active liquidity with local NextAssets on each destination chain and receive **5bps**/transfer as a fee. 9 | 10 | From a router perspective, you can just just monitor your funds and APY. 11 | 12 | Where necessary, for end users Connext will swap into and out of local and adopted assets through our AMMs. Below is the most complex version of this, where both chains have local≠adopted. 13 | 14 | ![image](../images/flow.png) 15 | 16 | ### How can I add active liquidity to Amarok-v2? 17 | 18 | 22 | 23 | Using USDC as an example, to provide active liquidity on Amarok you will need to get local nextUSDC on the desired chain. 24 | 25 | **Instructions below:** 26 | 27 | 1. Move USDC to Ethereum mainnet 28 | 1. [If moving funds from nxtp-v1] Remove desired amount of USDC from chain on nxtp-v1 with [remove-liquidity endpoint](https://github.com/connext/monorepo/blob/1fc5f3d47e146f67957f8a6943cc8888cb392936/packages/router/example.http#L12-L22). ** 29 | 1. (Note: If removing ALL funds from v1 router, add `"cleanupMode":"true"` and wait until amount f locked tokens equals 0. We phasing this out and and will closely communicate) 30 | 2. Bridge USDC to the desired chain through Connext, specifying to ‘Receive nextAsset‘ in the Bridge UI settings to receive nextUSDC and avoid swaps/slippage. 31 | 32 | ![*Will say ‘Receive nextAsset‘](../images/receiveNextAsset.png) 33 | 34 | 3. Navigate to the ‘Router’ tab on Connextscan 2.0 and click your router ID 35 | 36 | ![Untitled](../images/routerAddresses.png) 37 | 38 | 4. Click ‘Manage Router, and add funds using our new ‘Add Liquidity’ UI feature 39 | 40 | ![Untitled](../images/manageRouter.png) 41 | 42 | ![Untitled](../images/removeRouterLiquidity.png) 43 | 44 | ### (Coming soon) How to increase yield with dual passive/active liquidity 45 | 46 | Connext is partnering with [Themis](https://twitter.com/ThemisProtocol), a Defi lending protocol, to allow you to provide passive liquidity, borrow against your LP tokens, and use loaned funds as active liquidity. 47 | 48 | This will increase your yield and improve capital efficiency. We expect users will further be able to receive liquidity incentives from Themis on top. 49 | 50 | Borrowing will have a fixed low interest rate to enable easier calculation of net returns. 51 | 52 | ![Untitled](../images/themis.png) 53 | 54 | We will confirm when we have a readiness date! -------------------------------------------------------------------------------- /docs/routers/Guides/management.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Managing Your Router 6 | 7 | Routers have three distinct roles for management: 8 | 9 | 1. *Router Signer* - The address associated with the private key that is available to the router at runtime to sign payloads which authorize liquidity to be used to facilitate cross-chain transfers. The *Router Signer* also has the ability to remove the router’s liquidity to the designated recipient. 10 | 11 | 15 | 16 | 2. *Recipient* - The address that will receive funds when liquidity is removed. Example secure options are: a DAO treasury, a secure multisig, a custodial centralized exchange account which you trust. Since this is only a receiver address, it is not required to be able to sign and send transactions (i.e. in the custodial case). 17 | 18 | 22 | 23 | 3. *Router Owner* - The address that is able to set and change the *Recipient* address, as well as change itself to a different *Router Owner* address. The *Router Owner* can also remove the router’s liquidity to the designated recipient. This address should be a secure multisig, since it needs to be able to sign transactions to carry out the functionality. 24 | 25 | 29 | 30 | 31 | ## Initialize a Router 32 | 33 | Use this section if the router has never been initialized. 34 | 35 | ### Using the UI 36 | 37 | Coming soon! 38 | 39 | ### Using the Smart Contract Directly 40 | 41 | 1. Use the Connext repo to find the deployments for the chain you want to set up the router on: 42 | 43 | [monorepo/packages/deployments/contracts/deployments at main · connext/monorepo](https://github.com/connext/monorepo/tree/main/packages/deployments/contracts/deployments) 44 | 45 | 1. Find the `Connext.json` deployment for that chain and copy the address. 46 | 2. Go to the website [louper.dev](https://louper.dev/) and enter the Connext contract address and choose the correct network. 47 | 3. Scroll to the `RoutersFacet` section and select the option for `WRITE` and connect with the *Router Signer* account. 48 | 4. Select the method `initializeRouter` and fill in the details for `_owner` and `_recipient` and execute the transaction. 49 | 5. Notify the Connext team to allowlist your router (this is still a permissioned role!). 50 | 51 | 55 | 56 | ## Modify Router Roles 57 | 58 | Use these instructions to modify a router that has already been initialized. 59 | 60 | ### Using the UI 61 | 62 | Coming soon! 63 | 64 | ### Using the Smart Contract Directly 65 | 66 | 1. Use the [above instructions](https://www.notion.so/Router-Management-b7deba54c150424c978aa6abd4fec7f6) to connect the *Router Owner* wallet to the Connext contract. 67 | 2. Use the functions `setRouterRecipient`, `proposeRouterOwner`, and `acceptProposedRouterOwner` on the `RoutersFacet` to modify the params as necessary. 68 | 69 | ## Remove Liquidity 70 | 71 | ### Using the UI 72 | 73 | 1. Navigate to the ‘Router’ tab on Connextscan 2.0 and click your router ID 74 | 75 | ![Untitled](../images/routerAddresses.png) 76 | 77 | 2. Click ‘Manage Router, and remove funds using our ’Remove Liquidity’ UI feature 78 | 79 | ![Untitled](../images/manageRouter.png) 80 | 81 | ![Untitled](../images/addRouterLiquidity.png) 82 | 83 | ### Using the Smart Contract Directly 84 | 85 | 1. Use the [above instructions](https://www.notion.so/Router-Management-b7deba54c150424c978aa6abd4fec7f6) to connect the *Router Owner* wallet to the Connext contract. 86 | 2. Find the canonical `TokenId` by calling the `adoptedToCanonical` function on the `TokenFacet` and filling in the `_adopted` with the address of the token contract of the “adopted asset” (i.e. USDC). 87 | 3. With this information, call the `removeRouterLiquidity` function. -------------------------------------------------------------------------------- /docs/routers/Reference/configuration.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Configuration 6 | 7 | The router is accepts configuration using the config file `config.json` in the root directory of the [docker-compose repo](https://github.com/connext/router-docker-compose). 8 | 9 | The JSON schema accepts the following keys: 10 | 11 | - `redis`: _Required_. Object containing the following keys to configure an external redis instance: 12 | - `host`: _Required_. The hostname of the redis instance. 13 | - `port`: _Required_. The port of the redis instance. 14 | - `server`: _Required_. Object containing the following keys to configure the HTTP server: 15 | - `adminToken`: _Required_. Secret token used to authenticate admin requests. 16 | - `port`: _Optional_. The port the router will listen on. Defaults to `8080`. 17 | - `host`: _Optional_. The host the router will listen on. Defaults to `0.0.0.0`. 18 | - `web3SignerUrl`: _Recommended_. The URL for a running [Web3Signer](https://docs.web3signer.consensys.net/en/latest/) instance. This is the recommended approach to private key storage. 19 | - `mnemonic`: _Optional, Discouraged_. The mnemonic used to generate the private key. Using the mnemonic directly in the config file is unsafe and not recommended. 20 | - `chains`: _Required_. The chain configuration. A JSON object with the following keyed by [Domain IDs](./developers/testing-against-testnet#domain-ids) with the following object schema as value: 21 | - `providers`: _Required_. An array of providers URLs for a chain. Use a minimum of 1 URL, but additional URLs provide more fallback protection against provider issues. 22 | - `assets`: _Required_. An array of assets. Each asset is a JSON object with the following keys: 23 | - `assetId`: _Required_. The asset ID (ERC20 token address). This needs to represent the "local" asset which is the Connext bridge minted asset. 24 | - `name`: _Required_. The Asset Name. 25 | - `network`: _Required_. `mainnet` or `testnet`. 26 | - `environment`: _Optional_. `production` or `staging`. `mainnet` network config will always be `production`. 27 | - `logLevel`: _Optional_. The log level. Defaults to `info`. Accepts `debug`, `info`, `warn`, `error`, `fatal`, `trace`, `silent`. 28 | - `sequencerUrl`: _Optional_. The URL for the sequencer. Only used to override defaults. 29 | - `cartographerUrl`: _Optional_. The URL for the cartographer. Only used to override defaults. 30 | 31 | ## Example Configuration File 32 | 33 | _These are example RPC URLs. Please get your own RPC URLs!_ 34 | 35 | ```json 36 | { 37 | "chains": { 38 | "1634886255": { 39 | "assets": [ 40 | { 41 | "address": "0x85fb8e2903ad92a2ab0c6a725806636666ee2ab4", 42 | "name": "USDC" 43 | }, 44 | { 45 | "address": "0xfd5c16a50b717338cbcb44e34e10d735709e9cb9", 46 | "name": "WETH" 47 | } 48 | ], 49 | "providers": [ 50 | "https://arb-mainnet.g.alchemy.com/v2/...", 51 | "https://rpc.ankr.com/arbitrum" 52 | ] 53 | }, 54 | "1869640809": { 55 | "assets": [ 56 | { 57 | "address": "0x85FB8e2903Ad92A2ab0C6a725806636666ee2Ab4", 58 | "name": "USDC" 59 | }, 60 | { 61 | "address": "0xfD5C16a50b717338Cbcb44e34e10d735709E9Cb9", 62 | "name": "WETH" 63 | } 64 | ], 65 | "providers": [ 66 | "https://opt-mainnet.g.alchemy.com/v2/...", 67 | "https://rpc.ankr.com/optimism" 68 | ] 69 | }, 70 | "1886350457": { 71 | "assets": [ 72 | { 73 | "address": "0x2ABe2d4F09ea3124DE56AD91ae0950A3B71eCD11", 74 | "name": "USDC" 75 | }, 76 | { 77 | "address": "0x2BD5B3cfB2b16F2B10e7BA41dc1cb93d61B36bB8", 78 | "name": "WETH" 79 | } 80 | ], 81 | "providers": [ 82 | "https://polygon-mainnet.g.alchemy.com/v2/...", 83 | "https://rpc.ankr.com/polygon" 84 | ] 85 | }, 86 | "6450786": { 87 | "assets": [ 88 | { 89 | "address": "0xe4f1ce2dc807084a874e957d5d2ac6502820bc15", 90 | "name": "USDC" 91 | }, 92 | { 93 | "address": "0x6b205aeaae9de574d76d4e45af92998aefca205b", 94 | "name": "WETH" 95 | } 96 | ], 97 | "providers": [ 98 | "https://bsc-dataseed1.binance.org", 99 | "https://bsc-dataseed2.binance.org", 100 | "https://rpc.ankr.com/bsc" 101 | ] 102 | }, 103 | "6648936": { 104 | "assets": [ 105 | { 106 | "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", 107 | "name": "USDC" 108 | }, 109 | { 110 | "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", 111 | "name": "WETH" 112 | } 113 | ], 114 | "providers": ["https://eth-mainnet.alchemyapi.io/v2/...", "https://rpc.ankr.com/eth"] 115 | }, 116 | "6778479": { 117 | "assets": [ 118 | { 119 | "address": "0x67e79CC8d6b7C164Da28864875242b9210BFeb15", 120 | "name": "USDC" 121 | }, 122 | { 123 | "address": "0x735c7e2035ff902EC8F7115355191Cabb05D86fd", 124 | "name": "WETH" 125 | } 126 | ], 127 | "providers": ["https://rpc.gnosischain.com", "https://rpc.ankr.com/gnosis"] 128 | } 129 | }, 130 | "environment": "production", 131 | "logLevel": "debug", 132 | "messageQueue": { 133 | "uri": "amqp://guest:guest@rabbitmq:5672" 134 | }, 135 | "redis": { 136 | "host": "redis", 137 | "port": 6379 138 | }, 139 | "server": { 140 | "adminToken": "supersecret" 141 | }, 142 | "web3signer": "http://signer:9000", 143 | "network": "mainnet" 144 | } 145 | ``` 146 | -------------------------------------------------------------------------------- /docs/routers/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "🏦 Routers", 3 | "position": 3 4 | } 5 | -------------------------------------------------------------------------------- /docs/routers/images/addRouterLiquidity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/docs/routers/images/addRouterLiquidity.png -------------------------------------------------------------------------------- /docs/routers/images/flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/docs/routers/images/flow.png -------------------------------------------------------------------------------- /docs/routers/images/manageRouter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/docs/routers/images/manageRouter.png -------------------------------------------------------------------------------- /docs/routers/images/nat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/docs/routers/images/nat.png -------------------------------------------------------------------------------- /docs/routers/images/receiveNextAsset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/docs/routers/images/receiveNextAsset.png -------------------------------------------------------------------------------- /docs/routers/images/removeRouterLiquidity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/docs/routers/images/removeRouterLiquidity.png -------------------------------------------------------------------------------- /docs/routers/images/routerAddresses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/docs/routers/images/routerAddresses.png -------------------------------------------------------------------------------- /docs/routers/images/themis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/docs/routers/images/themis.png -------------------------------------------------------------------------------- /docs/routers/images/wallet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/docs/routers/images/wallet.png -------------------------------------------------------------------------------- /docs/routers/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | id: routers-intro 4 | --- 5 | 6 | # Basics 7 | 8 | Routers are the active liquidity providers & nodes of the Connext network. 9 | 10 | ## How do routers work? 11 | 12 | 1. Before becoming active in the network, routers provide liquidity on each chain and for each asset they want to support. This liquidity is denominated in `nextAssets` - a Connext-specific unit-of-account that acts as an IOU of locked funds on Ethereum L1. 13 | 14 | 2. Routers observe all chains in the network. For `xcall`s involving their supported chains & assets, routers simulate the transaction on destination, create a **bid** (a signed transaction that executes the destination chain interaction), and submit that bid to the Connext **sequencer** . 15 | 16 | 3. The sequencer waits a fixed period of time to collect bids from routers and then randomly selects from among them. For every batch of transactions, the sequencer will send a corresponding batch of winning bids to a relayer network (e.g. Gelato) to submit the transaction to the destination chain. 17 | 18 | 4. For router transactions that are submitted by the sequencer immediately (see [fast path](../concepts/how-it-works/flow.md#fast-path)), the router effectively *fronts* the transaction funds and calldata on the destination, being repaid by the protocol after the [slow path](../concepts/how-it-works/flow.md#slow-path) completes *if they submitted the transaction with the parameters provided in the origin chain `xcall`*. 19 | 20 | ## Risks 21 | 22 | Routers are largely designed to be as passive and safe for operators as possible. However, there are some risks to be aware of: 23 | 24 | 1. **Hot wallet:** Routers are effectively a "hot wallet" of funds owned by the router operator that can unilaterally spend owned funds in the protocol. This means that proper key management practices are a must for routers that want to operate in production. 25 | 2. **Misconfigured environments:** Router operators should also ensure that they are careful to not expose the router's private API as part of setting up their enviroment. 26 | 3. **Protocol security**: As with any protocol, router operators are ultimately exposed to the risk of Connext's underlying implementation. While this risk is never 0, Connext follows best practices for [auditing](https://github.com/connext/audits), [security bounties](https://immunefi.com/bounty/connext/), and operational practices to keep routers safe. 27 | 28 | Refer to [security.md](./Guides/security.md) and [router community call](https://www.youtube.com/watch?v=rjNcdm1mjCQ) for best practices to mitigate these risks. 29 | 30 | ## Business Model 31 | 32 | The router’s primary business model is to earn transaction fees for providing liquidity and relaying data across chains. 33 | 34 | Routers earn a fee of 5 basis points (0.05%) on all liquidity that is provided for a user transaction. Router liquidity is then subsequently locked up until it can be claimed against the slow path. In effect, this is asa if the router is giving a protocol-level loan to the user for a period of up to 2 hours. In this model, router ROI scales with user demand - routers earn the highest returns if a high percentage of their capital is frequently locked up. 35 | 36 | Routers currently do not take a fee for relaying data itself. There are future plans to implement an EIP-1559-style tip, that can supplement router income for data-only transactions. -------------------------------------------------------------------------------- /docs/routers/spinning-up.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | id: spinning-up 4 | --- 5 | # Spinning Up 6 | 7 | ![image](https://user-images.githubusercontent.com/88688304/178145701-0447ede1-b90a-4d9a-ae0f-dd588a6b34e5.png) 8 | 9 | ## Checklist for Running a Router 10 | 11 | - [Spin up the router](./spinning-up) and [configure](./Reference/configuration) for testnets. 12 | - [Provide liquidity](./liquidity) and gas fees on testnets. 13 | - Test the router on testnets. 14 | - Change configuration to mainnets (use a different private key!), or spin up a new mainnet router. 15 | - Provide liquidity on mainnets. 16 | - Monitor router logs. 17 | 18 | ---- 19 | ## :warning: Requirements 20 | >**Minimum Hardware Requirements**
21 | >:black_square_button: 8GB RAM
22 | >:black_square_button: 30GB Storage
23 | 24 | ## Preparation 25 | 1. **Private key of your wallet** from Metamask.
26 | For safety reason create a new wallet address for router. 27 | You can create it in Metamask extention or get it automatically during installation.
28 | 29 | 30 | 2. **Setup provider endpoints.** You have to add it to `config.json` file to use your own endpoints. 31 | For that we will use the nodes provided by the service [Infura](https://infura.io/). 32 | > You can use also [blastapi.io](https://blastapi.io) as RPC privider to get endpoints for almost any network ([the guide how to get it](https://medium.com/@alexzhurba/adding-rpcs-for-connext-36094191ae4f)). Many other RPC provider services exist as well. 33 | 34 | 2.1 Register at [infura.io](https://infura.io/) and create new project: 35 | 36 | screenshot 37 | 38 | screenshot 39 | 40 | 2.2 Open settings: 41 | 42 | screenshot 43 | 44 | 2.3 And copy your project ID. It will be the same on any network 45 | 46 | screenshot 47 | 48 | **Keep this data handy, you will need it for further installation** 49 | 50 | --- 51 | ## Manual Setup With Docker Compose 52 | 53 | Refer to [https://github.com/connext/router-docker-compose](https://github.com/connext/router-docker-compose) for instructions on spinning up using Docker Compose! 54 | 55 | # #Next Steps 56 | * See the [management guide](./Guides/management.md) for details on router administration. 57 | * See the [liquidity guide](./Guides/liquidity) for details on how to add liquidity to your router. 58 | * See the [security guide](./Reference/configuration) reference for details on the security for the router. 59 | 60 | --- 61 | ## Useful links 62 | - How to deploy your router using helm — [Guide](https://github.com/connext/router-helm)
63 | -------------------------------------------------------------------------------- /docusaurus.config.js: -------------------------------------------------------------------------------- 1 | const lightCodeTheme = require("prism-react-renderer/themes/okaidia"); 2 | const darkCodeTheme = require("prism-react-renderer/themes/okaidia"); 3 | const CardLink = require("./src/remark/CardLink"); 4 | 5 | /** @type {import('@docusaurus/types').DocusaurusConfig} */ 6 | module.exports = { 7 | title: "Connext Documentation", 8 | tagline: "Fast, trust-minimized communication between blockchains.", 9 | url: "https://docs.connext.network", 10 | baseUrl: "/", 11 | onBrokenLinks: "warn", 12 | onBrokenMarkdownLinks: "warn", 13 | favicon: "img/logomark.ico", 14 | organizationName: "connext", // Usually your GitHub org/user name. 15 | projectName: "connext", // Usually your repo name. 16 | customFields: { 17 | description: "Build your next xApp (cross-chain dapp) using Connext.", 18 | }, 19 | themeConfig: { 20 | colorMode: { 21 | defaultMode: 'dark', 22 | disableSwitch: false, 23 | respectPrefersColorScheme: true, 24 | }, 25 | algolia: { 26 | // The application ID provided by Algolia 27 | appId: "Z3QNOPOJN1", 28 | 29 | // Public API key: it is safe to commit it 30 | apiKey: "a196f9d082dfa45a3fb64448a101cf46", 31 | 32 | indexName: "connext", 33 | 34 | // Optional: see doc section below 35 | contextualSearch: true, 36 | 37 | // // Optional: Specify domains where the navigation should occur through window.location instead on history.push. Useful when our Algolia config crawls multiple documentation sites and we want to navigate with window.location.href to them. 38 | // externalUrlRegex: "external\\.com|domain\\.com", 39 | 40 | // Optional: Algolia search parameters 41 | searchParameters: {}, 42 | 43 | // Optional: path for search page that enabled by default (`false` to disable it) 44 | searchPagePath: false, 45 | 46 | //... other Algolia params 47 | }, 48 | navbar: { 49 | title: "Connext Documentation", 50 | logo: { 51 | alt: "Connext documentation", 52 | src: "img/logomark.png", 53 | }, 54 | items: [ 55 | { 56 | type: "doc", 57 | docId: "concepts/what-is-connext", 58 | label: "Concepts", 59 | position: "left", 60 | }, 61 | { 62 | type: "doc", 63 | docId: "developers/intro", 64 | label: "Developers", 65 | position: "left", 66 | }, 67 | { 68 | type: "doc", 69 | docId: "routers/routers-intro", 70 | label: "Routers", 71 | position: "left", 72 | }, 73 | { 74 | type: "doc", 75 | docId: "resources/deployments", 76 | label: "Resources", 77 | position: "left", 78 | } 79 | ], 80 | }, 81 | footer: { 82 | style: "dark", 83 | copyright: `Published in ${new Date().getFullYear()} by Connext.`, 84 | }, 85 | prism: { 86 | additionalLanguages: ["solidity"], 87 | theme: lightCodeTheme, 88 | darkTheme: darkCodeTheme, 89 | }, 90 | }, 91 | plugins: [ 92 | [ 93 | require.resolve('docusaurus-gtm-plugin'), 94 | { 95 | id: 'GTM-MLX9QD8', // GTM Container ID 96 | } 97 | ] 98 | ], 99 | presets: [ 100 | [ 101 | "@docusaurus/preset-classic", 102 | { 103 | docs: { 104 | path: "./docs", 105 | routeBasePath: "/", 106 | sidebarPath: require.resolve("./sidebars.js"), 107 | sidebarCollapsible: true, 108 | editUrl: "https://github.com/connext/documentation/blob/main", 109 | lastVersion: "current", 110 | remarkPlugins: [ 111 | CardLink, 112 | [require('@docusaurus/remark-plugin-npm2yarn'), {sync: true}], 113 | ], 114 | }, 115 | theme: { 116 | customCss: [require.resolve("./src/css/custom.css")], 117 | }, 118 | gtag: { 119 | trackingID: 'G-MPYZEDRVQ0', 120 | anonymizeIP: true, 121 | }, 122 | }, 123 | ], 124 | ], 125 | }; 126 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "documentation", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids" 15 | }, 16 | "dependencies": { 17 | "@docusaurus/core": "^2.1.0", 18 | "@docusaurus/plugin-content-docs": "^2.1.0", 19 | "@docusaurus/preset-classic": "^2.1.0", 20 | "@docusaurus/remark-plugin-npm2yarn": "^2.1.0", 21 | "@emotion/core": "^11.0.0", 22 | "@emotion/css": "^11.10.0", 23 | "@emotion/react": "^11.10.4", 24 | "@emotion/styled": "^11.10.4", 25 | "@heroicons/react": "v1", 26 | "@mdx-js/react": "^1.6.21", 27 | "@svgr/webpack": "^6.3.1", 28 | "clsx": "^1.1.1", 29 | "docusaurus-gtm-plugin": "^0.0.2", 30 | "docusaurus-plugin-matomo": "^0.0.6", 31 | "file-loader": "^6.2.0", 32 | "prism-react-renderer": "^1.2.1", 33 | "react": "^17.0.1", 34 | "react-dom": "^17.0.1", 35 | "url-loader": "^4.1.1" 36 | }, 37 | "browserslist": { 38 | "production": [ 39 | ">0.5%", 40 | "not dead", 41 | "not op_mini all" 42 | ], 43 | "development": [ 44 | "last 1 chrome version", 45 | "last 1 firefox version", 46 | "last 1 safari version" 47 | ] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /sidebars.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // By default, Docusaurus generates a sidebar from the docs folder structure 3 | concepts: [{ type: "autogenerated", dirName: "concepts" }], 4 | developers: [{ type: "autogenerated", dirName: "developers" }], 5 | routers: [{ type: "autogenerated", dirName: "routers" }], 6 | resources: [{ type: "autogenerated", dirName: "resources" }], 7 | }; 8 | -------------------------------------------------------------------------------- /src/components/CardLink.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Link from "@docusaurus/Link"; 3 | import styles from "./CardLink.module.css"; 4 | 5 | export default function CardLink({ href, title }) { 6 | return ( 7 | 8 | » 9 | {title} 10 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /src/components/CardLink.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | border: 1px solid #E6ECF1; 3 | display: flex; 4 | position: relative; 5 | box-shadow: 0 3px 8px 0 rgba(116, 129, 141, 0.1); 6 | transition: border 250ms ease; 7 | align-items: center; 8 | justify-self: stretch; 9 | border-radius: 3px; 10 | margin-top: 32px; 11 | margin-bottom: 32px; 12 | flex-direction: row; 13 | text-decoration: none; 14 | font-weight: 500; 15 | padding: 15px 30px 15px 20px; 16 | transition: box-shadow 0.2s; 17 | } 18 | 19 | .card:hover { 20 | text-decoration: none; 21 | box-shadow: 0 5px 10px 0 rgba(116, 129, 141, 0.2); 22 | transition: box-shadow 0.2s; 23 | } 24 | 25 | html[data-theme='dark'] .card { 26 | background-color: #ffffff05; 27 | border: 0px; 28 | box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.3); 29 | } 30 | 31 | html[data-theme='dark'] .card:hover { 32 | box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.5); 33 | } -------------------------------------------------------------------------------- /src/css/custom.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | /** 3 | * Any CSS included here will be global. The classic template 4 | * bundles Infima by default. Infima is a CSS framework designed to 5 | * work well for content-centric websites. 6 | */ 7 | 8 | /* You can override the default Infima variables here. */ 9 | 10 | @import url('https://fonts.googleapis.com/css2?family=Archivo:ital,wght@0,500;1,400&family=Inter:wght@400;500;600&display=swap'); 11 | :root { 12 | --ifm-color-primary: #9c62f9; 13 | --ifm-color-primary-active: #9c62f9; 14 | --ifm-color-primary-darker: rgb(31, 165, 136); 15 | --ifm-color-primary-darkest: rgb(26, 136, 112); 16 | --ifm-color-primary-light: rgb(70, 203, 174); 17 | --ifm-color-primary-lighter: rgb(102, 212, 189); 18 | --ifm-color-primary-lightest: rgb(146, 224, 208); 19 | --ifm-code-font-size: 95%; 20 | } 21 | 22 | .markdown a { 23 | color: #359ec8; 24 | } 25 | 26 | h1, 27 | h2, 28 | h3, 29 | h4, 30 | h5 { 31 | font-weight: 500; 32 | } 33 | 34 | .menu { 35 | /* background-color: var(--ifm-color-emphasis-0); */ 36 | padding: 1.5rem 1rem !important; 37 | } 38 | 39 | .menu__link--sublist:after { 40 | background: var(--ifm-menu-link-sublist-icon) 50% / 1.5rem 1.5rem; 41 | } 42 | 43 | .container.padding-top--md { 44 | padding-top: 2rem !important; 45 | } 46 | 47 | .table-of-contents { 48 | opacity: 0.7; 49 | } 50 | 51 | .table-of-contents:hover { 52 | opacity: 1; 53 | } 54 | 55 | .table-of-contents__link:hover { 56 | text-decoration: underline; 57 | } 58 | 59 | .menu__link--active, 60 | .navbar__link--active, 61 | .navbar__link:hover 62 | { 63 | color: var(--ifm-color-primary-active); 64 | } 65 | 66 | html[data-theme='dark'] { 67 | --ifm-color-primary: white; 68 | background-position: 0px -30vh; 69 | background-repeat: no-repeat; 70 | background-image: radial-gradient(50% 50% at 50% 50%, rgba(176, 62, 233, 0.1) 10%, rgba(49, 226, 90, 0) 100%); 71 | } 72 | 73 | html[data-theme='light'] { 74 | --ifm-color-primary: black; 75 | --ifm-background-color: #F1F1F2; 76 | 77 | background-position: 0px -30vh; 78 | background-repeat: no-repeat; 79 | background-image: radial-gradient(50% 50% at 50% 50%, rgba(98, 17, 138, 0.1) 10%, rgba(49, 226, 90, 0) 100%); 80 | } 81 | 82 | .DocSearch { 83 | --docsearch-hit-color: var(--ifm-color-primary); 84 | --docsearch-hit-active-color: var(--ifm-color-primary-active); 85 | } 86 | -------------------------------------------------------------------------------- /src/pages/index.module.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/src/pages/index.module.css -------------------------------------------------------------------------------- /src/pages/styles.module.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | /** 3 | * CSS files with the .module.css suffix will be treated as CSS modules 4 | * and scoped locally. 5 | */ 6 | 7 | .buttons { 8 | display: flex; 9 | align-items: center; 10 | justify-content: center; 11 | } -------------------------------------------------------------------------------- /src/remark/CardLink.js: -------------------------------------------------------------------------------- 1 | const visit = require("unist-util-visit"); 2 | 3 | const plugin = (options) => { 4 | const transformer = (root) => { 5 | let transformed = false; 6 | visit(root, "paragraph", (node) => { 7 | if (node.children.length === 1 && node.children[0].type === "link") { 8 | transformed = true; 9 | const { 10 | url, 11 | children: [{ value: title }], 12 | } = node.children[0]; 13 | for (const member in node) { 14 | delete node[member]; 15 | } 16 | node.type = "jsx"; 17 | node.value = ``; 18 | } 19 | }); 20 | if (root.type === "root" && transformed) { 21 | root.children.unshift({ 22 | type: "import", 23 | value: "import CardLink from '@site/src/components/CardLink';", 24 | }); 25 | } 26 | }; 27 | return transformer; 28 | }; 29 | 30 | module.exports = plugin; 31 | -------------------------------------------------------------------------------- /static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/.nojekyll -------------------------------------------------------------------------------- /static/img/background/Architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/background/Architecture.png -------------------------------------------------------------------------------- /static/img/background/HighLevelFlow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/background/HighLevelFlow.png -------------------------------------------------------------------------------- /static/img/basics/diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/basics/diagram.png -------------------------------------------------------------------------------- /static/img/connextLogoBig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/connextLogoBig.png -------------------------------------------------------------------------------- /static/img/connext_Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/connext_Logo.png -------------------------------------------------------------------------------- /static/img/connext_Logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 34 | -------------------------------------------------------------------------------- /static/img/core-concepts/Connext_quick_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/core-concepts/Connext_quick_overview.png -------------------------------------------------------------------------------- /static/img/core-concepts/clusters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/core-concepts/clusters.png -------------------------------------------------------------------------------- /static/img/core-concepts/external.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/core-concepts/external.png -------------------------------------------------------------------------------- /static/img/core-concepts/interoperability_trilemma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/core-concepts/interoperability_trilemma.png -------------------------------------------------------------------------------- /static/img/core-concepts/local.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/core-concepts/local.png -------------------------------------------------------------------------------- /static/img/core-concepts/native.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/core-concepts/native.png -------------------------------------------------------------------------------- /static/img/core-concepts/optimistic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/core-concepts/optimistic.png -------------------------------------------------------------------------------- /static/img/developers/AMB_Architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/developers/AMB_Architecture.png -------------------------------------------------------------------------------- /static/img/developers/chain_abstraction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/developers/chain_abstraction.png -------------------------------------------------------------------------------- /static/img/developers/connext_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/developers/connext_flow.png -------------------------------------------------------------------------------- /static/img/developers/examples/etherscan_xTransferEth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/developers/examples/etherscan_xTransferEth.png -------------------------------------------------------------------------------- /static/img/discord_logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/img/faq/assets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/faq/assets.png -------------------------------------------------------------------------------- /static/img/faq/read_tokenId.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/faq/read_tokenId.png -------------------------------------------------------------------------------- /static/img/github_logo.svg: -------------------------------------------------------------------------------- 1 | 6 | 7 | Logo 8 | 9 | 10 | 14 | 18 | 22 | 26 | 30 | 34 | 38 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /static/img/guides/connextscan_complete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/guides/connextscan_complete.png -------------------------------------------------------------------------------- /static/img/guides/connextscan_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/guides/connextscan_search.png -------------------------------------------------------------------------------- /static/img/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/img/logomark.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/logomark.ico -------------------------------------------------------------------------------- /static/img/logomark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/logomark.png -------------------------------------------------------------------------------- /static/img/quickstart/TEST_Etherscan_approve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/quickstart/TEST_Etherscan_approve.png -------------------------------------------------------------------------------- /static/img/quickstart/greeting_updated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/quickstart/greeting_updated.png -------------------------------------------------------------------------------- /static/img/quickstart/write_contract_etherscan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/quickstart/write_contract_etherscan.png -------------------------------------------------------------------------------- /static/img/quickstart/xUpdateGreeting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/quickstart/xUpdateGreeting.png -------------------------------------------------------------------------------- /static/img/routers/LPs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/routers/LPs.png -------------------------------------------------------------------------------- /static/img/routers/modular_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/routers/modular_architecture.png -------------------------------------------------------------------------------- /static/img/tutorial/docsVersionDropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/tutorial/docsVersionDropdown.png -------------------------------------------------------------------------------- /static/img/tutorial/localeDropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/tutorial/localeDropdown.png -------------------------------------------------------------------------------- /static/img/undraw_docusaurus_tree.svg: -------------------------------------------------------------------------------- 1 | docu_tree -------------------------------------------------------------------------------- /static/img/xcall_snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connext/documentation/00d93fc6cb546159dfa9f2336eb91af0f595a8b3/static/img/xcall_snippet.png -------------------------------------------------------------------------------- /versions.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | --------------------------------------------------------------------------------