From 402e77a3c9997b668e37b8de82d549bef786566f Mon Sep 17 00:00:00 2001 From: Damian Parrino Date: Fri, 24 Jan 2025 14:49:19 -0300 Subject: [PATCH 01/17] Create omnibridge.svg --- website/static/docs/assets/omnibridge.svg | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 website/static/docs/assets/omnibridge.svg diff --git a/website/static/docs/assets/omnibridge.svg b/website/static/docs/assets/omnibridge.svg new file mode 100644 index 00000000000..3678886cf1c --- /dev/null +++ b/website/static/docs/assets/omnibridge.svg @@ -0,0 +1,4 @@ + + + +
Omni Relayer
Ethereum
NEAR
ETH Tokens
dApp
Page-1 Cross-check path6508 path6510 polyline6512 Smart Contract(NEAR) Page-1 Cross-check path6508 path6510 polyline6512 Smart Contract(Ethereum)
NEAR Assets
OmniBridge SDK
(bridge-sdk-js)
\ No newline at end of file From acfad5e7656b43aa810c8477b141bcaf3afa1821 Mon Sep 17 00:00:00 2001 From: Damian Parrino Date: Fri, 24 Jan 2025 17:31:37 -0300 Subject: [PATCH 02/17] add omnibridge --- docs/1.concepts/abstraction/omnibridge.md | 87 +++++++++++++++++++++++ website/sidebars.js | 1 + 2 files changed, 88 insertions(+) create mode 100644 docs/1.concepts/abstraction/omnibridge.md diff --git a/docs/1.concepts/abstraction/omnibridge.md b/docs/1.concepts/abstraction/omnibridge.md new file mode 100644 index 00000000000..f7cf515eb26 --- /dev/null +++ b/docs/1.concepts/abstraction/omnibridge.md @@ -0,0 +1,87 @@ +--- +id: omnibridge +title: OmniBridge +--- + +The [OmniBridge](https://github.com/Near-One/omni-bridge) is a technical solution that allows users to transfer tokens between different blockchain networks, including Near, Solana, Ethereum, Base, and Arbitrum. This interoperability enhances liquidity and access to assets across ecosystems. + +OmniBridge's implementation includes smart contracts and blockchain relayers leveraging NEAR [Multi-Party Computation (MPC)](chain-signatures.md#multi-party-computation-service) and [Chain Signatures](chain-signatures.md) technology to facilitate cross-chain asset transfers in a secure and efficient manner. + + + +## Key Features + +- **Cross-Chain Functionality:** Enables asset movements between Near, Solana, and Ethereum seamlessly. +- **Decentralized Mechanism:** Utilizes smart contracts to ensure secure transfers without relying on a centralized authority. +- **User-Friendly Interface:** Designed to simplify the process for end-users looking to swap assets. + +### Supported Chains + +Currently supported chains: + +- Ethereum (ETH) +- NEAR +- Solana (SOL) +- Arbitrum (ARB) +- Base + +## Architecture + +The Omnibridge uses relayers that handle the cross-chain communication. The [omni-relayer](https://github.com/Near-One/omni-bridge/tree/main/omni-relayer) monitors events on the source chain and facilitate the corresponding actions on the target chain. +Smart contracts are deployed on both chains to manage the locking and minting/burning of tokens during the transfer process. + +![Omnibridge](/docs/assets/omnibridge.svg) +_OmniBridge architecture diagram_ + +### Components + +- **User Interface (dApp)**: users initiate cross-chain transactions using a dApp. +- **Bridge SDK**: either the [`bridge-sdk-js`](https://github.com/Near-One/bridge-sdk-js) for JavaScript developers or [`bridge-sdk-rs`](https://github.com/Near-One/bridge-sdk-rs) for Rust developers. +- **Smart Contracts**: the smart contracts on each blockchain, indicating function calls for locking/minting assets. +- **Omni Relayer**: facilitate communication by monitoring events on one chain and executing actions on the other. +- **Assets**: tokens and assets, such as `$ETH` and `$NEAR`, to illustrate assets being transferred between chains. + +## Use Cases + +- **Decentralized Applications (dApps)**: developers can build applications that require inter-chain interoperability, enhancing their usability and functionality. +- **Tooling for Existing dApps**: Allows existing projects to easily integrate cross-chain capabilities, expanding their reach. +- **DeFi Applications:** Enable liquidity across different DeFi platforms by allowing users to move their tokens freely. +- **NFTs and Gaming:** Facilitate the trading or transfer of digital assets among different blockchain networks. + +## SDKs + +Currently, NEAR's OmniBridge solution provides client SDKs in [JavaScript](#javascript) and [Rust](#rust). + +### JavaScript + +The Omnibridge JavaScript SDK, available in the [`bridge-sdk-js`](https://github.com/Near-One/bridge-sdk-js) repository, provides JS developers with tools to interact with the OmniBridge easily. + +:::warning +The JavaScript OmniBridge SDK is currently under heavy development and should be considered highly unstable. The API surface is subject to frequent and breaking changes without notice. While we encourage exploration and feedback, we strongly advise against using this in production environments at this time. +::: + +#### Key Features + +- **Simple API:** Developers can integrate cross-chain capabilities into their applications with straightforward method calls. +- **Event Listening:** Capable of listening for blockchain events, which aids in tracking the status of asset transfers. +- **Support for Multiple Tokens:** The SDK is equipped to handle various tokens, making it versatile for different use cases. + +### Rust + +The Omnibridge Rust SDK, available in the [`bridge-sdk-rs`](https://github.com/Near-One/bridge-sdk-rs) repository, serves as a specialized toolkit for Rust developers, and provides tools for cross-chain asset transfers and cross-chain features while maintaining a focus on performance and security. + +#### Key Features + + - **Simplicity**: The SDK simplifies complex operations, allowing developers to implement cross-chain functionalities without needing extensive knowledge of the underlying blockchain interactions. + - **Bridges Functionality**: Encapsulates functions necessary to interact with the OmniBridge, including initiating token transfers and managing various transaction states. + - **Event Handling**: Provides capabilities for monitoring events from the bridge, facilitating real-time tracking of asset movements. + +## Learn more + +If you are a developer looking to deep dive into Omnibridge, we recommend checking these GitHub repositories: + +:::info GitHub +- [Omni-Bridge](https://github.com/Near-One/omni-bridge) +- [bridge-sdk-js](https://github.com/Near-One/bridge-sdk-js) +- [bridge-sdk-rs](https://github.com/Near-One/bridge-sdk-rs) +::: diff --git a/website/sidebars.js b/website/sidebars.js index 37a672d29da..b5bab641b20 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -82,6 +82,7 @@ const sidebar = { // 'build/chain-abstraction/nft-chain-keys', ] }, + "concepts/abstraction/omnibridge", 'build/chain-abstraction/fastauth-sdk', "build/chain-abstraction/data-availability", ] From 948751109df11af7b3055de0122988cd441f9b81 Mon Sep 17 00:00:00 2001 From: Josh Ford Date: Mon, 10 Feb 2025 17:21:54 -0800 Subject: [PATCH 03/17] 2430 suggestions (#2461) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: update near logo (#2453) * Add Lantstool examples for RPC - Access Keys (#2456) * Chain abstraction overview update (#2420) * update * Update what-is.md * Update docs/2.build/1.chain-abstraction/what-is.md Co-authored-by: Josh Ford * update * Update what-is.md * Update what-is.md * Update what-is.md * diagram * 2379 suggestions (#2457) * fix: simplify intro & overview * feat: expand upon what is CA * feat: enhance intent/solver layer * feat: improve chain sig section * feat: improve omnibridge section * fix: remove duplicate section * fix: remove realyers * fix: remove use-cases -> locate elsewhere * fix: rethink intro based on article updates * fix: minor edits --------- Co-authored-by: Josh Ford * feat: reorg omnibridge docs and add hackmd content * fix: update omnibridge overview and consolidate into one file --------- Co-authored-by: Volodymyr Bilyk Co-authored-by: Damián Parrino --- README.md | 2 +- docs/1.concepts/abstraction/omnibridge.md | 120 +++++++--------- docs/2.build/1.chain-abstraction/what-is.md | 130 +++++++++++++----- docs/2.build/5.primitives/linkdrop.md | 2 +- docs/5.api/rpc/access-keys.md | 18 +++ website/.prettierrc | 6 + website/package.json | 1 + website/src/components/codetabs.js | 4 +- website/src/components/github.js | 86 +++++++----- .../LantstoolLabel/LantstoolLabel.js | 0 .../LantstoolLabel/LantstoolLabel.module.scss | 0 .../lantstool/TryOutOnLantstool.jsx | 33 +++++ .../static/docs/assets/chain-abstract-1.svg | 1 + website/static/docs/assets/near-logo.png | Bin 0 -> 46625 bytes website/static/docs/assets/near_logo.png | Bin 8601 -> 0 bytes website/yarn.lock | 11 +- 16 files changed, 275 insertions(+), 139 deletions(-) create mode 100644 website/.prettierrc rename website/src/components/{ => lantstool}/LantstoolLabel/LantstoolLabel.js (100%) rename website/src/components/{ => lantstool}/LantstoolLabel/LantstoolLabel.module.scss (100%) create mode 100644 website/src/components/lantstool/TryOutOnLantstool.jsx create mode 100644 website/static/docs/assets/chain-abstract-1.svg create mode 100644 website/static/docs/assets/near-logo.png delete mode 100644 website/static/docs/assets/near_logo.png diff --git a/README.md b/README.md index 443615c8728..57b747cbd29 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

- +


diff --git a/docs/1.concepts/abstraction/omnibridge.md b/docs/1.concepts/abstraction/omnibridge.md index f7cf515eb26..476ceafdb8c 100644 --- a/docs/1.concepts/abstraction/omnibridge.md +++ b/docs/1.concepts/abstraction/omnibridge.md @@ -3,85 +3,71 @@ id: omnibridge title: OmniBridge --- -The [OmniBridge](https://github.com/Near-One/omni-bridge) is a technical solution that allows users to transfer tokens between different blockchain networks, including Near, Solana, Ethereum, Base, and Arbitrum. This interoperability enhances liquidity and access to assets across ecosystems. - -OmniBridge's implementation includes smart contracts and blockchain relayers leveraging NEAR [Multi-Party Computation (MPC)](chain-signatures.md#multi-party-computation-service) and [Chain Signatures](chain-signatures.md) technology to facilitate cross-chain asset transfers in a secure and efficient manner. - +The [Omni Bridge](https://github.com/Near-One/omni-bridge) is a trustless multi-chain bridge that combines [Chain Signatures](chain-signatures.md) for cross-chain transaction execution with a verification layer allowing NEAR smart contracts to confirm transactions on foreign chains. This creates a fully trustless system where NEAR can both initiate and verify cross-chain operations, effectively positioning NEAR as a settlement layer for cross-chain transactions. +Unlike traditional bridges that rely on light clients for cross-chain verification (which can be computationally expensive and slow), Omni Bridge uses NEAR's Chain Signatures - a multi-party computation (MPC) system that enables secure cross-chain message verification without the computational overhead of light client verification. This approach reduces verification times from hours to minutes and significantly reduces gas costs across all supported chains. ## Key Features -- **Cross-Chain Functionality:** Enables asset movements between Near, Solana, and Ethereum seamlessly. -- **Decentralized Mechanism:** Utilizes smart contracts to ensure secure transfers without relying on a centralized authority. -- **User-Friendly Interface:** Designed to simplify the process for end-users looking to swap assets. - -### Supported Chains +- **Simple API:** Developers can integrate cross-chain capabilities into their applications with straightforward method calls +- **Event Listening:** - Capable of listening for blockchain events, which aids in tracking the status of asset transfers +- **Support for Multiple Tokens:** The SDK is equipped to handle various tokens, making it versatile for different use cases +- **Fast Transaction Processing:** Reduces cross-chain verification times from hours to minutes compared to traditional light client approaches +- **Gas Efficient:** - Significantly lower gas costs across supported chains due to the Chain Signatures verification system -Currently supported chains: - -- Ethereum (ETH) -- NEAR -- Solana (SOL) -- Arbitrum (ARB) -- Base ## Architecture -The Omnibridge uses relayers that handle the cross-chain communication. The [omni-relayer](https://github.com/Near-One/omni-bridge/tree/main/omni-relayer) monitors events on the source chain and facilitate the corresponding actions on the target chain. -Smart contracts are deployed on both chains to manage the locking and minting/burning of tokens during the transfer process. - -![Omnibridge](/docs/assets/omnibridge.svg) -_OmniBridge architecture diagram_ - -### Components - -- **User Interface (dApp)**: users initiate cross-chain transactions using a dApp. -- **Bridge SDK**: either the [`bridge-sdk-js`](https://github.com/Near-One/bridge-sdk-js) for JavaScript developers or [`bridge-sdk-rs`](https://github.com/Near-One/bridge-sdk-rs) for Rust developers. -- **Smart Contracts**: the smart contracts on each blockchain, indicating function calls for locking/minting assets. -- **Omni Relayer**: facilitate communication by monitoring events on one chain and executing actions on the other. -- **Assets**: tokens and assets, such as `$ETH` and `$NEAR`, to illustrate assets being transferred between chains. +The Omni Bridge consists of three core components: + +1. **Deterministic Address Derivation**: + - Every NEAR account can mathematically derive addresses on other chains through derivation paths + - Ensures the same NEAR account always controls the same set of addresses across all supported chains + +2. **Bridge Smart Contract**: + - Coordinates with the MPC network to generate secure signatures + - Handles token locking and requesting signatures for outbound transfers + - Implements the Bridge Token Factory pattern for managing both native and bridged tokens + +3. **MPC Service**: + - Decentralized network of nodes that jointly sign transactions + - No single node can create valid signatures alone + - Uses threshold cryptography for security + - Eliminates need for challenge periods through MPC threshold guarantees + +```mermaid +flowchart LR + NEAR[NEAR Chain] + MPC[MPC Network] + Other[Destination Chain] + + NEAR -- 1. Lock tokens --> NEAR + NEAR -- 2. Request signature --> MPC + MPC -- 3. Generate signature --> Other + Other -- 4. Mint/release tokens --> Other +``` + +## Supported Chains + +Currently supported chains with their verification methods: + +- Ethereum (Light client + Chain Signatures) +- Bitcoin (Light client + Chain Signatures) +- Solana (Currently Wormhole, transitioning to Chain Signatures) +- Base (Currently Wormhole, transitioning to Chain Signatures) +- Arbitrum (Currently Wormhole, transitioning to Chain Signatures) ## Use Cases -- **Decentralized Applications (dApps)**: developers can build applications that require inter-chain interoperability, enhancing their usability and functionality. -- **Tooling for Existing dApps**: Allows existing projects to easily integrate cross-chain capabilities, expanding their reach. -- **DeFi Applications:** Enable liquidity across different DeFi platforms by allowing users to move their tokens freely. -- **NFTs and Gaming:** Facilitate the trading or transfer of digital assets among different blockchain networks. - -## SDKs - -Currently, NEAR's OmniBridge solution provides client SDKs in [JavaScript](#javascript) and [Rust](#rust). - -### JavaScript - -The Omnibridge JavaScript SDK, available in the [`bridge-sdk-js`](https://github.com/Near-One/bridge-sdk-js) repository, provides JS developers with tools to interact with the OmniBridge easily. - -:::warning -The JavaScript OmniBridge SDK is currently under heavy development and should be considered highly unstable. The API surface is subject to frequent and breaking changes without notice. While we encourage exploration and feedback, we strongly advise against using this in production environments at this time. -::: - -#### Key Features - -- **Simple API:** Developers can integrate cross-chain capabilities into their applications with straightforward method calls. -- **Event Listening:** Capable of listening for blockchain events, which aids in tracking the status of asset transfers. -- **Support for Multiple Tokens:** The SDK is equipped to handle various tokens, making it versatile for different use cases. - -### Rust - -The Omnibridge Rust SDK, available in the [`bridge-sdk-rs`](https://github.com/Near-One/bridge-sdk-rs) repository, serves as a specialized toolkit for Rust developers, and provides tools for cross-chain asset transfers and cross-chain features while maintaining a focus on performance and security. - -#### Key Features - - - **Simplicity**: The SDK simplifies complex operations, allowing developers to implement cross-chain functionalities without needing extensive knowledge of the underlying blockchain interactions. - - **Bridges Functionality**: Encapsulates functions necessary to interact with the OmniBridge, including initiating token transfers and managing various transaction states. - - **Event Handling**: Provides capabilities for monitoring events from the bridge, facilitating real-time tracking of asset movements. +- **Cross-Chain Token Transfers:** Enable fast, secure token movements between supported chains +- **Bridge Token Factory:** Deploy and manage bridged token contracts automatically +- **Native Token Management:** Lock and release native tokens during cross-chain transfers +- **Cross-Chain Contract Calls:** (Coming soon) Enable complex interactions between contracts on different chains ## Learn more -If you are a developer looking to deep dive into Omnibridge, we recommend checking these GitHub repositories: +Proceed to the [Omni Bridge Deep Dive](omni-deep.md) to get a deeper understanding of how Omni Bridge works. We also recommend checking these GitHub repositories: -:::info GitHub -- [Omni-Bridge](https://github.com/Near-One/omni-bridge) -- [bridge-sdk-js](https://github.com/Near-One/bridge-sdk-js) -- [bridge-sdk-rs](https://github.com/Near-One/bridge-sdk-rs) -::: +- [Near-One/omni-bridge](https://github.com/Near-One/omni-bridge) - Omni Bridge repository +- [Near-One/bridge-sdk-js](https://github.com/Near-One/bridge-sdk-js) - JavaScript SDK +- [Near-One/bridge-sdk-rs](https://github.com/Near-One/bridge-sdk-rs) - Rust SDK diff --git a/docs/2.build/1.chain-abstraction/what-is.md b/docs/2.build/1.chain-abstraction/what-is.md index c5adf3e7652..5ab68d28990 100644 --- a/docs/2.build/1.chain-abstraction/what-is.md +++ b/docs/2.build/1.chain-abstraction/what-is.md @@ -1,61 +1,129 @@ --- id: what-is -title: What is Chain Abstraction? +title: What is Chain Abstraction? --- - import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -import {CodeTabs, Language, Github} from "@site/src/components/codetabs" - -The idea behind `chain abstraction` is quite simple: **blockchain** technology should be **abstracted away** from the user experience. In other words, people should **not realize** when they are **using a blockchain**, nor **which blockchain** they are using. +import {CodeTabs, Language, Github} from "@site/src/components/codetabs"; ![img](/docs/assets/welcome-pages/chain-abstraction-landing.png) -To help on this task, NEAR Protocol provides services that allow to **create** and **recover accounts** using **email addresses**, use the account **without acquiring funds**, and **control accounts** in **other chains**. All in the most **seamless** way possible. +# What is Chain Abstraction? ---- +Blockchain development today faces a critical challenge: users need to understand complex blockchain concepts, manage multiple wallets, and deal with different networks just to use basic applications. Chain abstraction solves this by making blockchain technology invisible to end users while preserving all of the underlying benefits. -## Relayers: Cover gas fees -Allowing users to start using a dApp without having to acquire funds is a powerful tool to increase user adoption. NEAR Protocol provides a service that allows developers to subsidize gas fees for their users. +## Why Chain Abstraction Matters -This concept, known as "Account Abstraction" in other chains, is a **built-in feature** in NEAR. User can wrap transactions in messages known as **meta-transaction**, that any other account can relay to the network. +For **developers**, chain abstraction means: -:::tip -In NEAR the relayers simply attach NEAR to cover gas fees, and pass the transaction to the network. There, the transaction is executed as if the **user had sent it**. +- Building cross-chain applications without managing multiple blockchain integrations +- Focusing on application logic instead of blockchain complexity +- Reaching users regardless of their preferred blockchain network + +For **users**, it means: + +- Using blockchain applications as easily as traditional web apps +- No need to understand which blockchain they're interacting with or if they are even using one +- A seamless experience across different networks and tokens + +:::info Example +Imagine building a digital art marketplace where users can purchase NFTs from different blockchains (Ethereum, Solana, etc.). Without chain abstraction, you'd need to: + +- Implement multiple blockchain connections +- Handle different wallet types +- Manage cross-chain transfers +- Build complex UIs to explain blockchain concepts + +With chain abstraction, both you and your users just focus on the core experience: browsing and trading art. All blockchain complexity is handled automatically behind the scenes. ::: -
+## Overview + +NEAR's chain abstraction framework consists of three core technologies that work together to create seamless cross-chain experiences: + +1. [**Intent / Solver Layer**](#intent--solver-layer): A decentralized system where users express desired outcomes (like "swap Token A for Token B at the best price") without specifying technical details. A network of solvers then competes to fulfill these intents optimally, handling complex cross-chain operations behind the scenes. + +2. [**Chain Signatures**](#chain-signatures): Enables NEAR accounts, including smart contracts, to sign and execute transactions on other blockchains (like Bitcoin or Ethereum), allowing cross-chain interactions. + +3. [**OmniBridge**](#omnibridge): A trustless multi-chain asset bridge that combines Chain Signatures for cross-chain transaction execution with a verification layer allowing NEAR smart contracts to confirm transactions on foreign chains. This creates a fully trustless system where NEAR can both initiate and verify cross-chain operations. + +### Intent / Solver Layer + +The Intent / Solver Layer (aka [NEAR Intents](https://pages.near.org/blog/introducing-near-intents/)) is a new type of transaction that allows information, requests, assets, and actions to be exchanged between users, services, and AI agents. -## Multi-chain signatures: One account, multiple chains -Currently, users and applications are siloed in different chains. This means that a user needs to create a new account for each chain they want to use. This is not only cumbersome for the user, but also for the developer who needs to maintain different codebases for each chain. +This represents a paradigm shift in how users and AI agents interact with blockchain networks. Instead of directly executing complex transactions across multiple chains, users simply declare what they want to achieve, and the network determines how to make it happen. -NEAR Protocol provides a multi-chain signature service that allows users to use their NEAR Account to sign transactions in **other chains**. This means that a user can use the same account to interact with **Ethereum**, **Binance Smart Chain**, **Avalanche**, and **NEAR**. +Here's how it works: + +1. **Users/Agents Submit Intents**: Express desired outcomes without specifying the technical details (e.g., "Get the best price for my Bitcoin across all DEXs and CEXs") +2. **Solver Network Competes**: A decentralized network of solvers (both AI agents and traditional market makers) compete to fulfill these intents optimally +3. **Cross-Chain Execution**: The best solution is automatically executed, potentially spanning multiple chains and services + +:::info Example +Instead of a user having to: + +1. Bridge assets between chains +2. Find the best trading venues +3. Execute multiple transactions +4. Handle different wallet requirements + +They simply submit an intent: "Swap Token A for Token B at the best price" +The Intent Layer handles all complexity across Web2 and Web3 behind the scenes. +::: + +For developers, the Intent Layer provides: + +- A unified framework for building cross-chain applications +- Access to both AI agents and traditional solvers for transaction optimization +- Built-in liquidity aggregation across DeFi and CeFi +- Support for complex use cases beyond simple swaps, including: + - Cross-chain stablecoin operations + - DeFi programmability for non-smart contract assets + - Account-based trading (AccountFi) + - AI agent interactions and negotiations :::info -Multi-chain signatures work by combining **smart contracts** that produce signatures, with indexers that listen for these signatures, and relayers that submit the transactions to other networks. This allows users to hold assets and use applications in **any** network, only needing to have a single NEAR account. +NEAR Intents are designed to power both traditional DeFi operations and the emerging AI economy, creating a unified transaction framework for Web2 and Web3 interactions. ::: -
+### Chain Signatures -## Fast-Auth: Email onboarding -One of the first barriers that new users face when entering the world of Web3 is the need to create a crypto wallet. This generally implies the need to choose a wallet, create and store a recovery phrase, and obtain deposit funds to start using the account. +Chain Signatures enable NEAR accounts, including smart contracts, to sign and execute transactions across many blockchain protocols. By using [Multi-Party Computation (MPC)](../../1.concepts/abstraction/chain-signatures.md#multi-party-computation-service), this technology allows a single NEAR account to control accounts and assets on external chains like Bitcoin, Ethereum, and Base. -With FastAuth, users only need to provide an email address to create a NEAR account. Using the same email address the user will be able to use their account across applications and devices. +Key benefits include: -:::warning -FastAuth is being deprecated, stay tuned for updates -::: +- Single Account, Multi-Chain Operations: Manage multiple blockchain interactions from one NEAR account +- Reduced Development Overhead: Write smart contracts on NEAR that directly sign cross-chain transactions +- Secure Transaction Signing: Leverage decentralized MPC for trustless signature generation ---- +For example, this enables dApps built on NEAR to interact with Bitcoin's UTXO model or Ethereum's account model, powering use cases like cross-chain DeFi protocols, atomic swaps, and NFT marketplaces. + +:::tip +To learn more about Chain Signatures, the concepts, and how to implement it, check these articles: + +- [What are Chain Signatures?](../../1.concepts/abstraction/chain-signatures.md) +- [Getting started with Chain Signatures](chain-signatures/getting-started.md) +- [Implementing Chain Signatures](chain-signatures/chain-signatures.md) + +::: -## Chain Abstraction: The Holistic View +### OmniBridge -The combination of these services allows to create a **seamless** user experience, in which users can use blockchain-based applications without realizing they are using a blockchain. +The [OmniBridge](https://github.com/Near-One/omni-bridge) extends NEAR's chain abstraction capabilities by combining two key elements: Chain Signatures for cross-chain transaction execution, and a verification layer that allows NEAR smart contracts to confirm the state and transactions on foreign chains. This creates a trustless bridge where NEAR contracts can both initiate and verify cross-chain operations. -Users will simply login with an email, and a **zero-fund** account will be created for them. No seed phrases to remember, no private keys to safe keep, and no need to acquire funds. +1. **Chain Signatures Integration**: + - NEAR smart contracts can generate derivation addresses on other blockchains + - These contracts can directly sign and execute transactions on external chains -Once having their account, apps can ask the user to create meta-transactions and send them to any relayer. The relayer will pass the transaction to the network, attaching NEAR to pay for the execution fees. The transaction will then be executed as if the user had sent it, since the relayer is only there to attach NEAR to the submission. +2. **State Verification Layer (Omniprover)**: + - Allows NEAR smart contracts to verify the state and transactions on foreign chains + - Supports different verification methods based on the target chain (e.g., light client proofs) + - Ensures trustless verification of incoming transfers and state changes from external chains + - For example, when receiving assets from Ethereum, NEAR contracts can verify the deposit actually occurred -If the user wants to interact with other blockchains, they can use their account to interact with a multi-chain signature relayer, which will relay the transaction to the right network, covering GAS fees. +3. **Decentralized Relayer Network**: + - Open participation model for relayers + - Trustless and incentivized system + - Ensures efficient transaction processing and state updates across chains -As an example, this would allow users to collect NFTs across different chains, without ever needing to explicitly create an account or acquire crypto. All with just a single email login. +This architecture creates a fully trustless bridge by combining NEAR's ability to execute transactions on foreign chains (via Chain Signatures) with the capability to independently verify the results of those transactions (via Omniprover). diff --git a/docs/2.build/5.primitives/linkdrop.md b/docs/2.build/5.primitives/linkdrop.md index 78dcd6a06ac..ca0ae217291 100644 --- a/docs/2.build/5.primitives/linkdrop.md +++ b/docs/2.build/5.primitives/linkdrop.md @@ -7,7 +7,7 @@ import {FeatureList, Column, Feature} from "@site/src/components/featurelist" import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import { Github } from "@site/src/components/codetabs" -import { LantstoolLabel } from '@site/src/components/LantstoolLabel/LantstoolLabel'; +import { LantstoolLabel } from '@site/src/components/lantstool/LantstoolLabel/LantstoolLabel'; Linkdrops allow users to distribute assets and onboard people to Web3 apps through a simple web link. diff --git a/docs/5.api/rpc/access-keys.md b/docs/5.api/rpc/access-keys.md index 652f421a8fa..259959ca5ce 100644 --- a/docs/5.api/rpc/access-keys.md +++ b/docs/5.api/rpc/access-keys.md @@ -5,6 +5,8 @@ title: Access Keys import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; +import { LantstoolLabel } from '@site/src/components/lantstool/LantstoolLabel/LantstoolLabel'; +import { TryOutOnLantstool } from '@site/src/components/lantstool/TryOutOnLantstool'; The RPC API enables you to retrieve information about an account's access keys. @@ -68,6 +70,10 @@ http post https://rpc.testnet.near.org jsonrpc=2.0 id=dontcare method=query \ ``` + + }> + +
@@ -285,6 +291,10 @@ http post https://rpc.testnet.near.org jsonrpc=2.0 id=dontcare method=query \ ``` + + }> + +
@@ -614,6 +624,10 @@ http post https://rpc.testnet.near.org jsonrpc=2.0 id=dontcare method=EXPERIMENT ``` + + }> + +
@@ -797,6 +811,10 @@ http post https://rpc.testnet.near.org jsonrpc=2.0 id=dontcare method=EXPERIMENT ``` + + }> + +
diff --git a/website/.prettierrc b/website/.prettierrc new file mode 100644 index 00000000000..e22ef4447e1 --- /dev/null +++ b/website/.prettierrc @@ -0,0 +1,6 @@ +{ + "printWidth": 100, + "singleQuote": true, + "trailingComma": "all", + "endOfLine": "lf" +} \ No newline at end of file diff --git a/website/package.json b/website/package.json index 14a298750e8..46bbd3b06e3 100644 --- a/website/package.json +++ b/website/package.json @@ -20,6 +20,7 @@ "crypto-browserify": "^3.12.0", "file-loader": "^6.2.0", "monaco-editor-webpack-plugin": "^7.1.0", + "prettier": "^3.4.2", "process": "^0.11.10", "replace-in-file": "^5.0.2", "serve": "^11.3.2", diff --git a/website/src/components/codetabs.js b/website/src/components/codetabs.js index bbebbbc3905..989a0df0498 100644 --- a/website/src/components/codetabs.js +++ b/website/src/components/codetabs.js @@ -55,8 +55,8 @@ export function Language({ children, language, showSingleFName }) { } } -export function Github({ url, start, end, language, fname, metastring }) { - return GitHubInternal({ url, start, end, language, fname, metastring }); +export function Github({ url, start, end, language, fname, metastring, withSourceLink }) { + return GitHubInternal({ url, start, end, language, fname, metastring, withSourceLink }); } /* AUX function */ diff --git a/website/src/components/github.js b/website/src/components/github.js index b58f0391f17..0641a6d4693 100644 --- a/website/src/components/github.js +++ b/website/src/components/github.js @@ -1,5 +1,5 @@ -import CodeBlock from '@theme/CodeBlock' -import { useEffect, useState } from 'react' +import CodeBlock from '@theme/CodeBlock'; +import { useEffect, useState } from 'react'; function toRaw(ref) { const fullUrl = ref.slice(ref.indexOf('https')); @@ -9,63 +9,81 @@ function toRaw(ref) { } async function fetchCode(url, fromLine, toLine) { - let res + let res; // check if stored in cache - const validUntil = localStorage.getItem(`${url}-until`) + const validUntil = localStorage.getItem(`${url}-until`); if (validUntil && validUntil > Date.now()) { - res = localStorage.getItem(url) + res = localStorage.getItem(url); } else { try { - res = await ((await fetch(url)).text()) - localStorage.setItem(url, res) - localStorage.setItem(`${url}-until`, Date.now() + 60000) - } catch { return "Error fetching code, please try reloading" } + res = await (await fetch(url)).text(); + localStorage.setItem(url, res); + localStorage.setItem(`${url}-until`, Date.now() + 60000); + } catch { + return 'Error fetching code, please try reloading'; + } } - let body = res.split('\n') + let body = res.split('\n'); fromLine = fromLine ? Number(fromLine) - 1 : 0; toLine = toLine ? Number(toLine) : body.length; body = body.slice(fromLine, toLine); // Remove indentation on nested code const preceedingSpace = body.reduce((prev, line) => { - if (line.length === 0) return prev + if (line.length === 0) return prev; - const spaces = line.match(/^\s+/) - if (spaces) return Math.min(prev, spaces[0].length) + const spaces = line.match(/^\s+/); + if (spaces) return Math.min(prev, spaces[0].length); - return 0 - }, Infinity) + return 0; + }, Infinity); - return body.map((line) => line.slice(preceedingSpace)).join('\n') + return body.map((line) => line.slice(preceedingSpace)).join('\n'); } -export function GitHubInternal({ url, start, end, language, fname, metastring }) { +export function GitHubInternal({ + url, + start, + end, + language, + fname, + metastring, + withSourceLink = true, +}) { const [code, setCode] = useState('Loading...'); useEffect(() => { const rawUrl = toRaw(url); const promise = fetchCode(rawUrl, start, end); - promise.then(res => setCode(res)); - }) + promise.then((res) => setCode(res)); + }); - return
- - {code} - -
- See full example on GitHub + return ( +
+ + {code} + + {withSourceLink && ( + + )}
-
; + ); } -export default GitHubInternal; \ No newline at end of file +export default GitHubInternal; diff --git a/website/src/components/LantstoolLabel/LantstoolLabel.js b/website/src/components/lantstool/LantstoolLabel/LantstoolLabel.js similarity index 100% rename from website/src/components/LantstoolLabel/LantstoolLabel.js rename to website/src/components/lantstool/LantstoolLabel/LantstoolLabel.js diff --git a/website/src/components/LantstoolLabel/LantstoolLabel.module.scss b/website/src/components/lantstool/LantstoolLabel/LantstoolLabel.module.scss similarity index 100% rename from website/src/components/LantstoolLabel/LantstoolLabel.module.scss rename to website/src/components/lantstool/LantstoolLabel/LantstoolLabel.module.scss diff --git a/website/src/components/lantstool/TryOutOnLantstool.jsx b/website/src/components/lantstool/TryOutOnLantstool.jsx new file mode 100644 index 00000000000..5307734016e --- /dev/null +++ b/website/src/components/lantstool/TryOutOnLantstool.jsx @@ -0,0 +1,33 @@ +import { Github } from '../codetabs'; + +/** + * Lantstool link looks like this: + * https://app.lantstool.dev/import/gh/lantstool/examples.near-protocol/main/path-to-file.json + * GitHub link looks like this: + * https://github.com/lantstool/examples.near-protocol/blob/main/path-to-file.json + */ + +export const TryOutOnLantstool = ({ + user = 'lantstool', + repo = 'examples.near-protocol', + branch = 'main', + path, +}) => ( + <> +

+ Try it out on{' '} + + Lantstool + +

+ + +); diff --git a/website/static/docs/assets/chain-abstract-1.svg b/website/static/docs/assets/chain-abstract-1.svg new file mode 100644 index 00000000000..04651fc968d --- /dev/null +++ b/website/static/docs/assets/chain-abstract-1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/static/docs/assets/near-logo.png b/website/static/docs/assets/near-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f6efa4c7a7c903cf4cb34e56cae75438f68ff0ff GIT binary patch literal 46625 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 G Date: Tue, 11 Feb 2025 12:44:31 -0800 Subject: [PATCH 04/17] fix: move to omnibridge directory --- .../abstraction/{omnibridge.md => omnibridge/overview.md} | 5 +++-- website/sidebars.js | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) rename docs/1.concepts/abstraction/{omnibridge.md => omnibridge/overview.md} (98%) diff --git a/docs/1.concepts/abstraction/omnibridge.md b/docs/1.concepts/abstraction/omnibridge/overview.md similarity index 98% rename from docs/1.concepts/abstraction/omnibridge.md rename to docs/1.concepts/abstraction/omnibridge/overview.md index 476ceafdb8c..58393fc015e 100644 --- a/docs/1.concepts/abstraction/omnibridge.md +++ b/docs/1.concepts/abstraction/omnibridge/overview.md @@ -1,6 +1,7 @@ --- -id: omnibridge -title: OmniBridge +id: overview +sidebar_label: Omni Bridge +title: Omni Bridge --- The [Omni Bridge](https://github.com/Near-One/omni-bridge) is a trustless multi-chain bridge that combines [Chain Signatures](chain-signatures.md) for cross-chain transaction execution with a verification layer allowing NEAR smart contracts to confirm transactions on foreign chains. This creates a fully trustless system where NEAR can both initiate and verify cross-chain operations, effectively positioning NEAR as a settlement layer for cross-chain transactions. diff --git a/website/sidebars.js b/website/sidebars.js index 510d78f4303..b8a02c5ac19 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -82,7 +82,7 @@ const sidebar = { // 'build/chain-abstraction/nft-chain-keys', ] }, - "concepts/abstraction/omnibridge", + "concepts/abstraction/omnibridge/overview", 'build/chain-abstraction/fastauth-sdk', "build/chain-abstraction/data-availability", ] From 87c21af9e11a96242c3106a4d9021708e9f8fd43 Mon Sep 17 00:00:00 2001 From: Josh Ford Date: Tue, 11 Feb 2025 12:58:53 -0800 Subject: [PATCH 05/17] fix: update architecture description & chain sig link --- docs/1.concepts/abstraction/omnibridge/overview.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/1.concepts/abstraction/omnibridge/overview.md b/docs/1.concepts/abstraction/omnibridge/overview.md index 58393fc015e..aef53a31ef9 100644 --- a/docs/1.concepts/abstraction/omnibridge/overview.md +++ b/docs/1.concepts/abstraction/omnibridge/overview.md @@ -4,7 +4,7 @@ sidebar_label: Omni Bridge title: Omni Bridge --- -The [Omni Bridge](https://github.com/Near-One/omni-bridge) is a trustless multi-chain bridge that combines [Chain Signatures](chain-signatures.md) for cross-chain transaction execution with a verification layer allowing NEAR smart contracts to confirm transactions on foreign chains. This creates a fully trustless system where NEAR can both initiate and verify cross-chain operations, effectively positioning NEAR as a settlement layer for cross-chain transactions. +The [Omni Bridge](https://github.com/Near-One/omni-bridge) is a trustless multi-chain bridge that combines [Chain Signatures](../chain-signatures.md) for cross-chain transaction execution with a verification layer allowing NEAR smart contracts to confirm transactions on foreign chains. This creates a fully trustless system where NEAR can both initiate and verify cross-chain operations, effectively positioning NEAR as a settlement layer for cross-chain transactions. Unlike traditional bridges that rely on light clients for cross-chain verification (which can be computationally expensive and slow), Omni Bridge uses NEAR's Chain Signatures - a multi-party computation (MPC) system that enables secure cross-chain message verification without the computational overhead of light client verification. This approach reduces verification times from hours to minutes and significantly reduces gas costs across all supported chains. @@ -21,8 +21,9 @@ Unlike traditional bridges that rely on light clients for cross-chain verificati The Omni Bridge consists of three core components: -1. **Deterministic Address Derivation**: - - Every NEAR account can mathematically derive addresses on other chains through derivation paths +1. **Chain Signatures**: + - Omni Bridge uses [Chain Signatures](../chain-signatures.md) to derviive chain-specific address & sign messages + - Every NEAR account can mathematically derive nearly infinate addresses on other chains through derivation paths - Ensures the same NEAR account always controls the same set of addresses across all supported chains 2. **Bridge Smart Contract**: From 2998d5eb0023e25f6570c3d11c7a34b705a25b8f Mon Sep 17 00:00:00 2001 From: Josh Ford Date: Tue, 11 Feb 2025 16:11:37 -0800 Subject: [PATCH 06/17] fix: update intro and add background --- .../abstraction/omnibridge/overview.md | 58 ++++++++++--------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/docs/1.concepts/abstraction/omnibridge/overview.md b/docs/1.concepts/abstraction/omnibridge/overview.md index aef53a31ef9..8724338df41 100644 --- a/docs/1.concepts/abstraction/omnibridge/overview.md +++ b/docs/1.concepts/abstraction/omnibridge/overview.md @@ -4,49 +4,51 @@ sidebar_label: Omni Bridge title: Omni Bridge --- -The [Omni Bridge](https://github.com/Near-One/omni-bridge) is a trustless multi-chain bridge that combines [Chain Signatures](../chain-signatures.md) for cross-chain transaction execution with a verification layer allowing NEAR smart contracts to confirm transactions on foreign chains. This creates a fully trustless system where NEAR can both initiate and verify cross-chain operations, effectively positioning NEAR as a settlement layer for cross-chain transactions. +The [Omni Bridge](https://github.com/Near-One/omni-bridge) is a multi-chain bridge that represents a significant advancement in cross-chain communication. Traditional bridge implementations often rely on computationally expensive light clients, leading to high gas costs and long verification times. Omni Bridge takes a different approach by leveraging [Chain Signatures](../chain-signatures.md) and its decentralized [Multi-Party Computation (MPC) Service](../chain-signatures#multi-party-computation-service) to create a fully trustless system where NEAR can both initiate and verify cross-chain operations securely. This innovative architecture enables efficient asset transfers between blockchain networks while dramatically reducing verification times and lowering gas costs across all supported chains. -Unlike traditional bridges that rely on light clients for cross-chain verification (which can be computationally expensive and slow), Omni Bridge uses NEAR's Chain Signatures - a multi-party computation (MPC) system that enables secure cross-chain message verification without the computational overhead of light client verification. This approach reduces verification times from hours to minutes and significantly reduces gas costs across all supported chains. +## Background -## Key Features +The journey toward truly trustless cross-chain communication took a significant leap forward when the NEAR team [created the first trustless bridge with Ethereum](https://near.org/blog/the-rainbow-bridge-is-live) (Rainbow Bridge). This pioneering achievement demonstrated that completely trustless cross-chain communication was possible, marking a crucial step toward the vision of chain abstraction. However, this approach relied on implementing a NEAR light client directly on Ethereum - essentially requiring Ethereum to understand and verify NEAR's complex blockchain rules. While secure, this approach faced several significant technical challenges that led to high gas costs and long verification times. For example, with Rainbow Bridge, transactions from NEAR to Ethereum take between 4 and 8 hours due to the 4-hour challenge period and block submission intervals driven by Ethereum's high gas costs. -- **Simple API:** Developers can integrate cross-chain capabilities into their applications with straightforward method calls -- **Event Listening:** - Capable of listening for blockchain events, which aids in tracking the status of asset transfers -- **Support for Multiple Tokens:** The SDK is equipped to handle various tokens, making it versatile for different use cases -- **Fast Transaction Processing:** Reduces cross-chain verification times from hours to minutes compared to traditional light client approaches -- **Gas Efficient:** - Significantly lower gas costs across supported chains due to the Chain Signatures verification system +More importantly, this approach becomes increasingly impractical when connecting to multiple chains, as each chain would require its own light client implementation. Some chains, such as Bitcoin, don't even support smart contracts, making it technically infeasible to implement a NEAR light client. While we still need to support light clients of different networks on NEAR (which is significantly easier to implement), a different approach is needed for verifying NEAR state on foreign chains. +Omni Bridge introduces a more elegant solution using Chain Signatures. Instead of running light clients on each destination chain, it leverages Chain Signature's MPC Service to enable secure cross-chain message verification without the overhead of light client verification. This new approach reduces verification times from hours to minutes while significantly reducing gas costs across all supported chains. -## Architecture +## How it works -The Omni Bridge consists of three core components: +The Omni Bridge consists of two core components: -1. **Chain Signatures**: - - Omni Bridge uses [Chain Signatures](../chain-signatures.md) to derviive chain-specific address & sign messages +1. [**Chain Signatures**](../chain-signatures.md): + - Omni Bridge uses to dervive chain-specific address & sign messages - Every NEAR account can mathematically derive nearly infinate addresses on other chains through derivation paths - Ensures the same NEAR account always controls the same set of addresses across all supported chains + - Uses a decentralized [MPC Service](../chain-signatures#multi-party-computation-service) to jointly sign messages + - MPC threshold guarantees eliminate the need for challenge periods -2. **Bridge Smart Contract**: + +2. [**Bridge Smart Contract**](https://github.com/Near-One/omni-bridge): - Coordinates with the MPC network to generate secure signatures - Handles token locking and requesting signatures for outbound transfers - Implements the Bridge Token Factory pattern for managing both native and bridged tokens - -3. **MPC Service**: - - Decentralized network of nodes that jointly sign transactions - - No single node can create valid signatures alone - - Uses threshold cryptography for security - - Eliminates need for challenge periods through MPC threshold guarantees + - Coordinates token locking and signature requests in a single transaction + - Leverages NEP-141's transfer-and-call functionality for single tran + - Implements the Bridge Token Factory pattern for managing tokens + - Records transfer state and initiates MPC signature requests ```mermaid -flowchart LR - NEAR[NEAR Chain] - MPC[MPC Network] - Other[Destination Chain] - - NEAR -- 1. Lock tokens --> NEAR - NEAR -- 2. Request signature --> MPC - MPC -- 3. Generate signature --> Other - Other -- 4. Mint/release tokens --> Other +sequenceDiagram + participant User + participant NEAR as Bridge Contract
NEAR + participant MPC as MPC Service
(off-chain) + participant Other as Destination Chain + + User->>NEAR:1. Submits transfer
token request + NEAR->>NEAR: 2. Locks tokens + NEAR->>MPC: 3. Request signature + MPC->>MPC: 3. Signs message + MPC-->>NEAR: 4. Return signed msg + NEAR->>Other: 5. Broadcast signed msg to destination chain + Other->>Other: 4. Mint/release tokens ``` ## Supported Chains From d18fdb31ad065b01f5000bd55210d9179406c07b Mon Sep 17 00:00:00 2001 From: Josh Ford Date: Tue, 11 Feb 2025 17:11:38 -0800 Subject: [PATCH 07/17] feat: enhance background --- .../abstraction/omnibridge/overview.md | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/docs/1.concepts/abstraction/omnibridge/overview.md b/docs/1.concepts/abstraction/omnibridge/overview.md index 8724338df41..9382c5642dd 100644 --- a/docs/1.concepts/abstraction/omnibridge/overview.md +++ b/docs/1.concepts/abstraction/omnibridge/overview.md @@ -8,13 +8,27 @@ The [Omni Bridge](https://github.com/Near-One/omni-bridge) is a multi-chain brid ## Background -The journey toward truly trustless cross-chain communication took a significant leap forward when the NEAR team [created the first trustless bridge with Ethereum](https://near.org/blog/the-rainbow-bridge-is-live) (Rainbow Bridge). This pioneering achievement demonstrated that completely trustless cross-chain communication was possible, marking a crucial step toward the vision of chain abstraction. However, this approach relied on implementing a NEAR light client directly on Ethereum - essentially requiring Ethereum to understand and verify NEAR's complex blockchain rules. While secure, this approach faced several significant technical challenges that led to high gas costs and long verification times. For example, with Rainbow Bridge, transactions from NEAR to Ethereum take between 4 and 8 hours due to the 4-hour challenge period and block submission intervals driven by Ethereum's high gas costs. +The journey toward truly trustless cross-chain communication took a significant leap forward when the NEAR team [created the first trustless bridge with Ethereum](https://near.org/blog/the-rainbow-bridge-is-live) (Rainbow Bridge). This pioneering achievement demonstrated that completely trustless cross-chain communication was possible, marking a crucial step toward the vision of chain abstraction. However, this approach relied on implementing a NEAR light client directly on Ethereum - essentially requiring Ethereum to understand and verify NEAR's complex blockchain rules. + +Omni Bridge introduces a more elegant solution using Chain Signatures. Instead of running light clients on each destination chain, it leverages Chain Signature's MPC Service to enable secure cross-chain message verification without the overhead of light client verification. This new approach reduces verification times from hours to minutes while significantly reducing gas costs across all supported chains. + +### Issues with Light Clients + +A light client is a smart contract that lets one blockchain verify events happening on another blockchain. In Rainbow Bridge's case, the Ethereum light client needs to track NEAR's blocks, verify its validators' signatures, and confirm transactions. This comes with major technical challenges: it requires storing two weeks of Ethereum block data, maintaining an updated list of NEAR validators and their stakes, and most crucially, verifying NEAR's ED25519 signatures - a process Ethereum wasn't built for. This verification is computationally expensive, making the whole process slow, costly, and ultimately a major bottleneck. + +For example, with Rainbow Bridge, transactions from NEAR to Ethereum take between 4 and 8 hours due to the 4-hour challenge period and block submission intervals driven by Ethereum's high gas costs. More importantly, this approach becomes increasingly impractical when connecting to multiple chains, as each chain would require its own light client implementation. Some chains, such as Bitcoin, don't even support smart contracts, making it technically infeasible to implement a NEAR light client. While we still need to support light clients of different networks on NEAR (which is significantly easier to implement), a different approach is needed for verifying NEAR state on foreign chains. -Omni Bridge introduces a more elegant solution using Chain Signatures. Instead of running light clients on each destination chain, it leverages Chain Signature's MPC Service to enable secure cross-chain message verification without the overhead of light client verification. This new approach reduces verification times from hours to minutes while significantly reducing gas costs across all supported chains. +### Token Standards and Cross-Chain Communication + +Before exploring how Chain Signatures solves these issues, it's important to understand how tokens work on NEAR. [NEP-141](https://nomicon.io/Standards/Tokens/FungibleToken/Core), NEAR's fungible token standard, has a key feature that sets it apart from Ethereum's ERC-20: built-in composability through transfer-and-call functionality. + +When a token transfer happens on NEAR using `ft_transfer_call`, the token contract first transfers the tokens and then automatically calls the specified `ft_on_transfer` method on the receiver contract. While these operations happen in sequence within the same transaction, the receiver contract has the ability to reject the transfer, causing the tokens to be refunded. This atomic behavior ensures the integrity and safety of bridge operations by preventing partial execution states. + +For more information see [Fungible Tokens](../../../2.build/5.primitives/ft.md). -## How it works +## How Omni Bridge works The Omni Bridge consists of two core components: From 4e30afb2936bc16e766ce94176ca72227f06178b Mon Sep 17 00:00:00 2001 From: Josh Ford Date: Tue, 11 Feb 2025 18:45:37 -0800 Subject: [PATCH 08/17] feat: separate implementation and roadmap into separate docs --- .../abstraction/omnibridge/how-it-works.md | 76 ++++++ .../abstraction/omnibridge/implementation.md | 250 ++++++++++++++++++ .../abstraction/omnibridge/overview.md | 89 +------ .../abstraction/omnibridge/roadmap.md | 61 +++++ website/sidebars.js | 9 +- 5 files changed, 409 insertions(+), 76 deletions(-) create mode 100644 docs/1.concepts/abstraction/omnibridge/how-it-works.md create mode 100644 docs/1.concepts/abstraction/omnibridge/implementation.md create mode 100644 docs/1.concepts/abstraction/omnibridge/roadmap.md diff --git a/docs/1.concepts/abstraction/omnibridge/how-it-works.md b/docs/1.concepts/abstraction/omnibridge/how-it-works.md new file mode 100644 index 00000000000..a763bf493aa --- /dev/null +++ b/docs/1.concepts/abstraction/omnibridge/how-it-works.md @@ -0,0 +1,76 @@ +--- +id: how-it-works +sidebar_label: How It Works +title: How Omni Bridge Works +--- + +## Background + +The journey toward truly trustless cross-chain communication took a significant leap forward when the NEAR team [created the first trustless bridge with Ethereum](https://near.org/blog/the-rainbow-bridge-is-live) (Rainbow Bridge). This pioneering achievement demonstrated that completely trustless cross-chain communication was possible, marking a crucial step toward the vision of chain abstraction. However, this approach relied on implementing a NEAR light client directly on Ethereum - essentially requiring Ethereum to understand and verify NEAR's complex blockchain rules. + +Omni Bridge introduces a more elegant solution using Chain Signatures. Instead of running light clients on each destination chain, it leverages Chain Signature's MPC Service to enable secure cross-chain message verification without the overhead of light client verification. This new approach reduces verification times from hours to minutes while significantly reducing gas costs across all supported chains. + +### Issues with Light Clients + +A light client is a smart contract that lets one blockchain verify events happening on another blockchain. In Rainbow Bridge's case, the Ethereum light client needs to track NEAR's blocks, verify its validators' signatures, and confirm transactions. This comes with major technical challenges: it requires storing two weeks of Ethereum block data, maintaining an updated list of NEAR validators and their stakes, and most crucially, verifying NEAR's ED25519 signatures - a process Ethereum wasn't built for. This verification is computationally expensive, making the whole process slow, costly, and ultimately a major bottleneck. + +For example, with Rainbow Bridge, transactions from NEAR to Ethereum take between 4 and 8 hours due to the 4-hour challenge period and block submission intervals driven by Ethereum's high gas costs. More importantly, this approach becomes increasingly impractical when connecting to multiple chains, as each chain would require its own light client implementation. Some chains, such as Bitcoin, don't even support smart contracts, making it technically infeasible to implement a NEAR light client. + +While we still need to support light clients of different networks on NEAR (which is significantly easier to implement), a different approach is needed for verifying NEAR state on foreign chains. + +### Token Standards and Cross-Chain Communication + +Before exploring how Chain Signatures solves these issues, it's important to understand how tokens work on NEAR. [NEP-141](https://nomicon.io/Standards/Tokens/FungibleToken/Core), NEAR's fungible token standard, has a key feature that sets it apart from Ethereum's ERC-20: built-in composability through transfer-and-call functionality. + +When a token transfer happens on NEAR using `ft_transfer_call`, the token contract first transfers the tokens and then automatically calls the specified `ft_on_transfer` method on the receiver contract. While these operations happen in sequence within the same transaction, the receiver contract has the ability to reject the transfer, causing the tokens to be refunded. This atomic behavior ensures the integrity and safety of bridge operations by preventing partial execution states. + +For more information see [Fungible Tokens](../../../2.build/5.primitives/ft.md). + +## How Omni Bridge works + +Instead of maintaining complex light clients on destination chains, Chain Signatures introduces a fundamentally different approach based on three core components: + +1. **Deterministic Address Derivation** - Every NEAR account can mathematically derive addresses on other chains through derivation paths. This isn't just a mapping - it's a cryptographic derivation that ensures the same NEAR account always controls the same set of addresses across all supported chains. + +2. **Bridge Smart Contract** - A central contract on NEAR coordinates with the MPC network to generate secure signatures for cross-chain transactions. This contract handles the token locking and requesting of signatures for outbound transfers + +3. **MPC Service** - A decentralized network of nodes that jointly sign transactions without ever reconstructing a full private key. The security comes from threshold cryptography - no single node or small group of nodes can create valid signatures alone. + + +```mermaid +sequenceDiagram + title: High-Level Overview of NEAR to External Chain Transfer + participant User + participant NEAR as Bridge Contract
NEAR + participant MPC as MPC Service
(off-chain) + participant Other as Destination Chain + + User->>NEAR:1. Submits transfer
token request + NEAR->>NEAR: 2. Locks tokens + NEAR->>MPC: 3. Request signature + MPC->>MPC: 3. Signs message + MPC-->>NEAR: 4. Return signed msg + NEAR->>Other: 5. Broadcast signed msg to destination chain + Other->>Other: 4. Mint/release tokens +``` + +### Putting It All Together + +Chain Signatures fundamentally changes the verification mechanism for cross-chain messages. Here's what this means in practice: + +The light client approach requires destination chains to verify ED25519 signatures from NEAR validators. Chain Signatures replaces this with a single MPC signature verification. Destination chains only need to verify one signature using their native signature verification schemes - typically ECDSA for EVM chains. + +NEP-141's transaction guarantees handle the security of token locking. A transfer creates two operations within a single transaction: +1. Lock tokens and record the transfer state +2. Request MPC signature for the destination chain + +The Locker contract requests signatures from the MPC network, which then generates signatures for valid transfer requests. This replaces the need for challenge periods - the security derives from the MPC threshold guarantees rather than optimistic assumptions. + +Adding new chains becomes a matter of implementing three standard components: +1. Chain-specific address derivation +2. MPC signature verification (or transaction signing for chains like Bitcoin) +3. Bridge contract deployment +4. Communication path for transfers back to NEAR (currently using Wormhole for newer chains) + +While we still need light clients on NEAR for receiving transfers from other chains, this approach makes it feasible to support a wider range of chains without implementing complex verification logic on each destination chain. + diff --git a/docs/1.concepts/abstraction/omnibridge/implementation.md b/docs/1.concepts/abstraction/omnibridge/implementation.md new file mode 100644 index 00000000000..c531822558b --- /dev/null +++ b/docs/1.concepts/abstraction/omnibridge/implementation.md @@ -0,0 +1,250 @@ +--- +id: implementation-details +sidebar_label: Implementation Details +title: Implementation Details +--- + +The Omni Bridge is a sophisticated cross-chain bridge infrastructure that enables secure and efficient token transfers between NEAR Protocol and various other blockchain networks. This document provides a detailed technical overview of the bridge's architecture, covering its core components, security model, and operational mechanisms. By leveraging a combination of Multi-Party Computation (MPC), chain-specific light clients, and a permissionless relayer network, the bridge achieves a robust balance of security, decentralization, and user experience. + +## The Bridge Token Factory Pattern + +At the core of Omni Bridge is the Bridge Token Factory contract on NEAR that serves as both a token factory and custodian. This unified contract handles both native tokens from the source chain and bridged tokens created by the factory itself. This design simplifies maintenance and reduces complexity compared to having separate contracts. + +The contract has several key responsibilities: + +### For bridged tokens (tokens originally from other chains): + +* Deploys new token contracts when bridging tokens for the first time +* Mints tokens when receiving valid transfer messages +* Burns tokens when initiating transfers back to the origin chain + +### For native NEAR tokens: + +* Acts as a custodian by locking tokens during transfers +* Releases tokens when receiving valid transfer messages +* Manages token operations through the NEP-141 standard + +### Transfer Lifecycle + +A transfer's lifecycle includes several states, shown below for a NEAR to Ethereum transfer of native NEAR tokens: + +```mermaid +stateDiagram-v2 + [*] --> Initiated: User calls transfer + Initiated --> Locked: Tokens locked in bridge + Locked --> Signed: MPC signature generated + Signed --> Completed: Tokens released on Ethereum + Completed --> [*] +``` + +--- + +## Message Signing and Verification + +For most chains, the bridge uses a payload-based message signing system (with Bitcoin being a notable exception requiring full transaction signing). + +### Message Types + +The bridge supports several types of signed messages: + +* **Transfer Messages** + * Initiation messages + * Finalization messages +* **Token Messages** + * Deployment messages + * Metadata update messages + +### Payload Structure + +Messages are encoded using Borsh serialization and contain: + +| Component | Description | +|-----------|-------------| +| Message Type | Identifier for the message category | +| Chain Info | Chain IDs and relevant addresses | +| Operation Data | Amounts, recipients, fees, etc. | + +### Signature Process + +1. NEAR contract creates and stores the message payload +2. MPC network observers detect valid payloads +3. Nodes jointly sign the payload +4. Signature is verified on destination chains + +:::tip Key Benefits +* Clearer message intent through structured payloads +* More efficient signature verification on destination chains +* Standardized message format across chains +::: + +## Transaction Flow: NEAR to Other Chains + +Here's an overview of how transfers are processed from NEAR to different destination chains: + +```mermaid +flowchart TD + Start[User Initiates Transfer] --> TokenCheck{Token Type?} + + TokenCheck -->|NEAR Native| Lock[Lock in Bridge Contract] + TokenCheck -->|Bridged Token| Burn[Burn Token] + + Lock --> MPCSign[Request MPC Signature] + Burn --> MPCSign + + MPCSign --> Chain{Destination Chain} + + Chain -->|Ethereum| EVMBridge[EVM Bridge Contract] + Chain -->|Bitcoin| BTCBridge[Bitcoin Script] + Chain -->|Other| WormBridge[Wormhole Bridge] + + EVMBridge --> Mint[Mint/Release Tokens] + BTCBridge --> Mint + WormBridge --> Mint + + Mint --> End[Transfer Complete] +``` + +### Transfer Process + +Let's follow what happens when a user wants to transfer tokens from NEAR to another chain: + +#### 1. Initiation + +The user starts by calling the token contract with: + +* Amount to transfer +* Destination chain and address +* Fee preferences (whether to pay fees in the token being transferred or in NEAR) + +#### 2. Token Lock + +The token contract transfers tokens to the locker contract, which: + +* Validates the transfer message +* Assigns a unique nonce +* Records the pending transfer +* Emits a transfer event + +#### 3. MPC Signing + +The bridge contract: + +* Requests signature generation +* MPC nodes jointly generate and aggregate signature +* Maintains threshold security throughout process + +#### 4. Destination Chain + +The Bridge Token Factory on the destination chain: + +* Verifies the MPC signature +* Mints equivalent tokens +* Fees are minted on NEAR side for relayers + +--- + +## Transaction Flow: Other Chains to NEAR + +The reverse flow varies based on the source chain: + +### 1. Ethereum + +Uses NEAR light client for maximum security: + +* Burning tokens on source chain +* Submitting proof to NEAR +* Verifying proof through light client +* Releasing tokens to recipient + +### 2. Solana + +Currently using Wormhole for: + +* Message passing between chains +* Transaction verification +* Integration with NEAR token factory system + +### 3. Other Chains + +Initially using Wormhole for: + +* Message passing between chains +* Transaction verification +* Will transition to Chain Signatures + +--- + +## Security Model + +### Trust Assumptions + +Omni Bridge requires different trust assumptions depending on the chain connection: + +#### For Chain Signatures: + +* NEAR Protocol security (2/3+ honest validators) +* MPC network security (2/3+ honest nodes) +* No single entity controls enough MPC nodes to forge signatures +* Correct implementation of the signing protocol + +#### For Ethereum/Bitcoin connections: + +* Light client security +* Finality assumptions (e.g., sufficient block confirmations) +* Chain-specific consensus assumptions + +#### For interim Wormhole connections: + +* Wormhole Guardian network security +* We acknowledge this is a temporary trust assumption until Chain Signatures integration is complete + +--- + +## Relayer Network + +Relayers are permissionless infrastructure operators who monitor for bridge events and execute cross-chain transactions. Unlike many bridge designs, our relayers cannot: + +* Forge transfers +* Steal funds +* Censor transactions (users can self-relay) +* Front-run transactions for profit + +:::info +The relayer's role is purely operational - executing valid transfers and collecting predetermined fees. Multiple relayers can operate simultaneously, creating competition for faster execution and lower fees. +::: + +--- + +## Fee Structure + +Bridge fees are unified and processed on NEAR, with components including: + +### Execution Fees + +* Destination chain gas costs +* Source chain storage costs +* Relayer operational costs +* MPC signing costs + +### Fee Payment Options + +* Native tokens of source chain +* The token being transferred + +:::note +Fees dynamically adjust based on gas prices across different chains to ensure reliable execution. +::: + +### Design Goals + +The fee structure is designed to: + +* Ensure relayer economic viability +* Prevent economic attacks +* Allow fee market competition +* Cover worst-case execution costs + +:::tip +Users can bypass relayers entirely by executing their own transfers, paying only the necessary gas fees on each chain. This creates a natural ceiling on relayer fees. +::: + diff --git a/docs/1.concepts/abstraction/omnibridge/overview.md b/docs/1.concepts/abstraction/omnibridge/overview.md index 9382c5642dd..b962ef8992d 100644 --- a/docs/1.concepts/abstraction/omnibridge/overview.md +++ b/docs/1.concepts/abstraction/omnibridge/overview.md @@ -1,91 +1,30 @@ --- id: overview -sidebar_label: Omni Bridge -title: Omni Bridge +sidebar_label: Overview +title: Omni Bridge Overview --- -The [Omni Bridge](https://github.com/Near-One/omni-bridge) is a multi-chain bridge that represents a significant advancement in cross-chain communication. Traditional bridge implementations often rely on computationally expensive light clients, leading to high gas costs and long verification times. Omni Bridge takes a different approach by leveraging [Chain Signatures](../chain-signatures.md) and its decentralized [Multi-Party Computation (MPC) Service](../chain-signatures#multi-party-computation-service) to create a fully trustless system where NEAR can both initiate and verify cross-chain operations securely. This innovative architecture enables efficient asset transfers between blockchain networks while dramatically reducing verification times and lowering gas costs across all supported chains. +The [Omni Bridge](https://github.com/Near-One/omni-bridge) is a multi-chain asset bridge that facilitates secure and efficient asset transfers between different blockchain networks. It solves key challenges in cross-chain communication by leveraging [Chain Signatures](https://docs.near.org/concepts/abstraction/chain-signatures) and its decentralized [Multi-Party Computation (MPC) service](https://docs.near.org/concepts/abstraction/chain-signatures#multi-party-computation-service) to enable trustless cross-chain asset transfers. -## Background - -The journey toward truly trustless cross-chain communication took a significant leap forward when the NEAR team [created the first trustless bridge with Ethereum](https://near.org/blog/the-rainbow-bridge-is-live) (Rainbow Bridge). This pioneering achievement demonstrated that completely trustless cross-chain communication was possible, marking a crucial step toward the vision of chain abstraction. However, this approach relied on implementing a NEAR light client directly on Ethereum - essentially requiring Ethereum to understand and verify NEAR's complex blockchain rules. - -Omni Bridge introduces a more elegant solution using Chain Signatures. Instead of running light clients on each destination chain, it leverages Chain Signature's MPC Service to enable secure cross-chain message verification without the overhead of light client verification. This new approach reduces verification times from hours to minutes while significantly reducing gas costs across all supported chains. - -### Issues with Light Clients - -A light client is a smart contract that lets one blockchain verify events happening on another blockchain. In Rainbow Bridge's case, the Ethereum light client needs to track NEAR's blocks, verify its validators' signatures, and confirm transactions. This comes with major technical challenges: it requires storing two weeks of Ethereum block data, maintaining an updated list of NEAR validators and their stakes, and most crucially, verifying NEAR's ED25519 signatures - a process Ethereum wasn't built for. This verification is computationally expensive, making the whole process slow, costly, and ultimately a major bottleneck. - -For example, with Rainbow Bridge, transactions from NEAR to Ethereum take between 4 and 8 hours due to the 4-hour challenge period and block submission intervals driven by Ethereum's high gas costs. - -More importantly, this approach becomes increasingly impractical when connecting to multiple chains, as each chain would require its own light client implementation. Some chains, such as Bitcoin, don't even support smart contracts, making it technically infeasible to implement a NEAR light client. While we still need to support light clients of different networks on NEAR (which is significantly easier to implement), a different approach is needed for verifying NEAR state on foreign chains. - -### Token Standards and Cross-Chain Communication - -Before exploring how Chain Signatures solves these issues, it's important to understand how tokens work on NEAR. [NEP-141](https://nomicon.io/Standards/Tokens/FungibleToken/Core), NEAR's fungible token standard, has a key feature that sets it apart from Ethereum's ERC-20: built-in composability through transfer-and-call functionality. - -When a token transfer happens on NEAR using `ft_transfer_call`, the token contract first transfers the tokens and then automatically calls the specified `ft_on_transfer` method on the receiver contract. While these operations happen in sequence within the same transaction, the receiver contract has the ability to reject the transfer, causing the tokens to be refunded. This atomic behavior ensures the integrity and safety of bridge operations by preventing partial execution states. - -For more information see [Fungible Tokens](../../../2.build/5.primitives/ft.md). - -## How Omni Bridge works - -The Omni Bridge consists of two core components: - -1. [**Chain Signatures**](../chain-signatures.md): - - Omni Bridge uses to dervive chain-specific address & sign messages - - Every NEAR account can mathematically derive nearly infinate addresses on other chains through derivation paths - - Ensures the same NEAR account always controls the same set of addresses across all supported chains - - Uses a decentralized [MPC Service](../chain-signatures#multi-party-computation-service) to jointly sign messages - - MPC threshold guarantees eliminate the need for challenge periods - - -2. [**Bridge Smart Contract**](https://github.com/Near-One/omni-bridge): - - Coordinates with the MPC network to generate secure signatures - - Handles token locking and requesting signatures for outbound transfers - - Implements the Bridge Token Factory pattern for managing both native and bridged tokens - - Coordinates token locking and signature requests in a single transaction - - Leverages NEP-141's transfer-and-call functionality for single tran - - Implements the Bridge Token Factory pattern for managing tokens - - Records transfer state and initiates MPC signature requests - -```mermaid -sequenceDiagram - participant User - participant NEAR as Bridge Contract
NEAR - participant MPC as MPC Service
(off-chain) - participant Other as Destination Chain - - User->>NEAR:1. Submits transfer
token request - NEAR->>NEAR: 2. Locks tokens - NEAR->>MPC: 3. Request signature - MPC->>MPC: 3. Signs message - MPC-->>NEAR: 4. Return signed msg - NEAR->>Other: 5. Broadcast signed msg to destination chain - Other->>Other: 4. Mint/release tokens -``` +To learn more see [How Omni Bridge Works](./how-it-works.md). ## Supported Chains -Currently supported chains with their verification methods: +Omni Bridge launches with a hybrid architecture, utilizing different verification methods based on chain-specific requirements and technical constraints. This approach allows us to support multiple chains from day one while progressively transitioning to full Chain Signatures integration. -- Ethereum (Light client + Chain Signatures) -- Bitcoin (Light client + Chain Signatures) -- Solana (Currently Wormhole, transitioning to Chain Signatures) -- Base (Currently Wormhole, transitioning to Chain Signatures) -- Arbitrum (Currently Wormhole, transitioning to Chain Signatures) +Initial launch includes: -## Use Cases +- **Ethereum** - _(Light client + Chain Signatures)_ +- **Bitcoin** - _(Light client + Chain Signatures)_ +- **Solana** - _(Currently Wormhole, transitioning to Chain Signatures)_ +- **Base** - _(Currently Wormhole, transitioning to Chain Signatures)_ +- **Arbitrum** - _(Currently Wormhole, transitioning to Chain Signatures)_ -- **Cross-Chain Token Transfers:** Enable fast, secure token movements between supported chains -- **Bridge Token Factory:** Deploy and manage bridged token contracts automatically -- **Native Token Management:** Lock and release native tokens during cross-chain transfers -- **Cross-Chain Contract Calls:** (Coming soon) Enable complex interactions between contracts on different chains +See [Omni Bridge Roadmap](./roadmap.md) for more details. -## Learn more - -Proceed to the [Omni Bridge Deep Dive](omni-deep.md) to get a deeper understanding of how Omni Bridge works. We also recommend checking these GitHub repositories: +## Resources - [Near-One/omni-bridge](https://github.com/Near-One/omni-bridge) - Omni Bridge repository - [Near-One/bridge-sdk-js](https://github.com/Near-One/bridge-sdk-js) - JavaScript SDK - [Near-One/bridge-sdk-rs](https://github.com/Near-One/bridge-sdk-rs) - Rust SDK + diff --git a/docs/1.concepts/abstraction/omnibridge/roadmap.md b/docs/1.concepts/abstraction/omnibridge/roadmap.md new file mode 100644 index 00000000000..dc236ff479b --- /dev/null +++ b/docs/1.concepts/abstraction/omnibridge/roadmap.md @@ -0,0 +1,61 @@ +--- +id: roadmap +sidebar_label: Roadmap +title: Omni Bridge Roadmap +--- + +Omni Bridge launches with a hybrid architecture, utilizing different verification methods based on chain-specific requirements and technical constraints. This approach allows us to support multiple chains from day one while progressively transitioning to full Chain Signatures integration. + +## Supported Chains +Initial launch includes: + +- **Ethereum** - _(Light client + Chain Signatures)_ +- **Bitcoin** - _(Light client + Chain Signatures)_ +- **Solana** - _(Currently Wormhole, transitioning to Chain Signatures)_ +- **Base** - _(Currently Wormhole, transitioning to Chain Signatures)_ +- **Arbitrum** - _(Currently Wormhole, transitioning to Chain Signatures)_ + +## Migration Path + +1. **Phase 1: Hybrid Operation** +- ETH/BTC: Light client verification +- Other chains: Wormhole message passing +- All NEAR outbound: Chain Signatures + +During this phase, cross-chain messages follow different verification paths depending on direction and chain. NEAR outbound transfers already utilize Chain Signatures, while inbound transfers vary by source chain. + +2. **Phase 2: Full Chain Signatures** +- Progressive transition of all chains +- Removal of Wormhole dependency +- Enhanced decentralization + +Phase 2 represents our move to a unified verification model. Each chain will transition to Chain Signatures verification as implementation and audits complete, gradually removing the hybrid architecture's complexity. + +## Future Development +1. **Protocol Improvements** +- Enhanced fee mechanisms +- Cross-chain contract calls +- New token standards support + +Beyond basic asset transfers, we're expanding the bridge's capabilities. Enhanced fee mechanisms will better handle gas price volatility, while cross-chain contract calls will enable more complex interactions. + +2. **Infrastructure** +- Expanded relayer network +- Improved monitoring tools +- Enhanced developer tooling + +Infrastructure development focuses on reliability and usability. An expanded relayer network improves transfer speeds and reliability, while better monitoring and developer tools make integration and maintenance easier. + +## Get Involved + +### Areas for Contribution +- Chain integrations +- Performance optimization +- Security analysis +- Developer tools + +The code is open source and we welcome contributions from the community. Whether you're interested in adding support for new chains, optimizing performance, or building developer tools, there's room for meaningful contribution. + +Bridge infrastructure is a fundamental component of a multi-chain future. Through Chain Signatures, we're creating a more efficient, secure, and scalable approach to cross-chain communication. Join us in building it. + + diff --git a/website/sidebars.js b/website/sidebars.js index b8a02c5ac19..68b8a6887b3 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -82,7 +82,14 @@ const sidebar = { // 'build/chain-abstraction/nft-chain-keys', ] }, - "concepts/abstraction/omnibridge/overview", + { + "Omni Bridge": [ + "concepts/abstraction/omnibridge/overview", + "concepts/abstraction/omnibridge/how-it-works", + "concepts/abstraction/omnibridge/implementation-details", + "concepts/abstraction/omnibridge/roadmap", + ] + }, 'build/chain-abstraction/fastauth-sdk', "build/chain-abstraction/data-availability", ] From 6a1e042d5d84c4ac0fe90891ed3fd7acb53d8f9b Mon Sep 17 00:00:00 2001 From: Josh Ford Date: Tue, 11 Feb 2025 18:51:45 -0800 Subject: [PATCH 09/17] fix: update omni bridge overview in what-is chain abstraction --- docs/2.build/1.chain-abstraction/what-is.md | 39 +++++++++++++-------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/docs/2.build/1.chain-abstraction/what-is.md b/docs/2.build/1.chain-abstraction/what-is.md index 5ab68d28990..625e4b3e484 100644 --- a/docs/2.build/1.chain-abstraction/what-is.md +++ b/docs/2.build/1.chain-abstraction/what-is.md @@ -45,7 +45,7 @@ NEAR's chain abstraction framework consists of three core technologies that work 2. [**Chain Signatures**](#chain-signatures): Enables NEAR accounts, including smart contracts, to sign and execute transactions on other blockchains (like Bitcoin or Ethereum), allowing cross-chain interactions. -3. [**OmniBridge**](#omnibridge): A trustless multi-chain asset bridge that combines Chain Signatures for cross-chain transaction execution with a verification layer allowing NEAR smart contracts to confirm transactions on foreign chains. This creates a fully trustless system where NEAR can both initiate and verify cross-chain operations. +3. [**OmniBridge**](#omnibridge): A multi-chain asset bridge that combines Chain Signatures with chain-specific verification methods for secure and efficient cross-chain transfers. Using a hybrid approach of MPC-based signatures and light clients, it significantly reduces verification times from hours to minutes while lowering gas costs across supported chains. The bridge serves as both a token factory and custodian, managing native and bridged tokens through a unified interface. ### Intent / Solver Layer @@ -109,21 +109,30 @@ To learn more about Chain Signatures, the concepts, and how to implement it, che ### OmniBridge -The [OmniBridge](https://github.com/Near-One/omni-bridge) extends NEAR's chain abstraction capabilities by combining two key elements: Chain Signatures for cross-chain transaction execution, and a verification layer that allows NEAR smart contracts to confirm the state and transactions on foreign chains. This creates a trustless bridge where NEAR contracts can both initiate and verify cross-chain operations. +The [OmniBridge](../../1.concepts/abstraction/omnibridge/overview.md) is a multi-chain asset bridge that combines Chain Signatures with chain-specific verification methods to enable secure and efficient cross-chain asset transfers. Unlike traditional bridges that rely solely on light clients (which can be computationally expensive and slow), OmniBridge uses a hybrid approach that significantly reduces verification times from hours to minutes while lowering gas costs across all supported chains. -1. **Chain Signatures Integration**: - - NEAR smart contracts can generate derivation addresses on other blockchains - - These contracts can directly sign and execute transactions on external chains +The bridge architecture consists of three core components: -2. **State Verification Layer (Omniprover)**: - - Allows NEAR smart contracts to verify the state and transactions on foreign chains - - Supports different verification methods based on the target chain (e.g., light client proofs) - - Ensures trustless verification of incoming transfers and state changes from external chains - - For example, when receiving assets from Ethereum, NEAR contracts can verify the deposit actually occurred +1. **Bridge Token Factory**: + - Unified contract serving as both token factory and custodian + - Deploys and manages bridged token contracts + - Handles token locking and minting through NEP-141 standard + - Manages both native and bridged tokens through a single interface -3. **Decentralized Relayer Network**: - - Open participation model for relayers - - Trustless and incentivized system - - Ensures efficient transaction processing and state updates across chains +2. **Message Signing System**: + - Uses Chain Signatures' MPC network for secure cross-chain message verification + - Supports structured message types for transfers and token operations + - Eliminates need for traditional challenge periods through MPC threshold guarantees + - Enables permissionless relayer network for efficient transaction processing -This architecture creates a fully trustless bridge by combining NEAR's ability to execute transactions on foreign chains (via Chain Signatures) with the capability to independently verify the results of those transactions (via Omniprover). +3. **Chain-Specific Verification**: + - Hybrid verification approach based on each chain's requirements: + - Ethereum/Bitcoin: Light client + Chain Signatures + - Solana/Base/Arbitrum: Currently using Wormhole, transitioning to Chain Signatures + - Progressive migration path toward full Chain Signatures integration + +This architecture creates a robust bridge system that combines NEAR's ability to execute transactions on foreign chains with secure verification methods, while maintaining a clear path toward increased decentralization through full Chain Signatures adoption. + +:::info +For detailed implementation information and current status, see the [OmniBridge documentation](../../1.concepts/abstraction/omnibridge/overview.md). +::: From dee11bb5d60a34595356111fc3315f31f7c34135 Mon Sep 17 00:00:00 2001 From: Josh Ford Date: Tue, 11 Feb 2025 19:12:52 -0800 Subject: [PATCH 10/17] fix: update what-is and implementation --- .../abstraction/omnibridge/how-it-works.md | 45 ++++++++++--------- docs/2.build/1.chain-abstraction/what-is.md | 37 +++++++-------- 2 files changed, 40 insertions(+), 42 deletions(-) diff --git a/docs/1.concepts/abstraction/omnibridge/how-it-works.md b/docs/1.concepts/abstraction/omnibridge/how-it-works.md index a763bf493aa..a35a1c4d48f 100644 --- a/docs/1.concepts/abstraction/omnibridge/how-it-works.md +++ b/docs/1.concepts/abstraction/omnibridge/how-it-works.md @@ -26,7 +26,7 @@ When a token transfer happens on NEAR using `ft_transfer_call`, the token contra For more information see [Fungible Tokens](../../../2.build/5.primitives/ft.md). -## How Omni Bridge works +## Enter Chain Signatures Instead of maintaining complex light clients on destination chains, Chain Signatures introduces a fundamentally different approach based on three core components: @@ -36,31 +36,13 @@ Instead of maintaining complex light clients on destination chains, Chain Signat 3. **MPC Service** - A decentralized network of nodes that jointly sign transactions without ever reconstructing a full private key. The security comes from threshold cryptography - no single node or small group of nodes can create valid signatures alone. +## Putting It All Together -```mermaid -sequenceDiagram - title: High-Level Overview of NEAR to External Chain Transfer - participant User - participant NEAR as Bridge Contract
NEAR - participant MPC as MPC Service
(off-chain) - participant Other as Destination Chain - - User->>NEAR:1. Submits transfer
token request - NEAR->>NEAR: 2. Locks tokens - NEAR->>MPC: 3. Request signature - MPC->>MPC: 3. Signs message - MPC-->>NEAR: 4. Return signed msg - NEAR->>Other: 5. Broadcast signed msg to destination chain - Other->>Other: 4. Mint/release tokens -``` - -### Putting It All Together - -Chain Signatures fundamentally changes the verification mechanism for cross-chain messages. Here's what this means in practice: +As we've learned, Chain Signatures fundamentally changes the verification mechanism for cross-chain messages. Here's what this means in practice: The light client approach requires destination chains to verify ED25519 signatures from NEAR validators. Chain Signatures replaces this with a single MPC signature verification. Destination chains only need to verify one signature using their native signature verification schemes - typically ECDSA for EVM chains. -NEP-141's transaction guarantees handle the security of token locking. A transfer creates two operations within a single transaction: +NEP-141's transaction guarantees handle the security of token locking. A transfer creates two operations within a **single transaction**: 1. Lock tokens and record the transfer state 2. Request MPC signature for the destination chain @@ -74,3 +56,22 @@ Adding new chains becomes a matter of implementing three standard components: While we still need light clients on NEAR for receiving transfers from other chains, this approach makes it feasible to support a wider range of chains without implementing complex verification logic on each destination chain. + +```mermaid +sequenceDiagram + title: High-Level Overview of NEAR to External Chain Transfer + participant User as User Account + participant Bridge as Omni Bridge
Locker Contract + participant MPC as MPC Service
(off-chain) + participant Other as Destination Chain + + note over User, Bridge: NEAR Blockchain + + User->>Bridge:1. Submits transfer
token request + Bridge->>Bridge: 2. Locks tokens + Bridge->>MPC: 3. Request signature + MPC->>MPC: 3. Signs message + MPC-->>Bridge: 4. Return signed msg + Bridge->>Other: 5. Broadcast signed msg to destination chain + Other->>Other: 4. Mint/release tokens +``` diff --git a/docs/2.build/1.chain-abstraction/what-is.md b/docs/2.build/1.chain-abstraction/what-is.md index 625e4b3e484..86f1b4d2fa0 100644 --- a/docs/2.build/1.chain-abstraction/what-is.md +++ b/docs/2.build/1.chain-abstraction/what-is.md @@ -109,29 +109,26 @@ To learn more about Chain Signatures, the concepts, and how to implement it, che ### OmniBridge -The [OmniBridge](../../1.concepts/abstraction/omnibridge/overview.md) is a multi-chain asset bridge that combines Chain Signatures with chain-specific verification methods to enable secure and efficient cross-chain asset transfers. Unlike traditional bridges that rely solely on light clients (which can be computationally expensive and slow), OmniBridge uses a hybrid approach that significantly reduces verification times from hours to minutes while lowering gas costs across all supported chains. +The [OmniBridge](../../1.concepts/abstraction/omnibridge/overview.md) is a multi-chain asset bridge that combines Chain Signatures with chain-specific verification methods to enable secure and efficient cross-chain asset transfers. It consists of three core components: -The bridge architecture consists of three core components: +1. **Chain Signatures Integration**: + - Enables NEAR smart contracts to generate and control accounts on other blockchains + - Allows direct signing and execution of transactions on external chains + - Provides secure message signing through MPC network -1. **Bridge Token Factory**: +2. **Verification Layer**: + - Hybrid verification approach combining MPC signatures and light clients + - Chain-specific verification methods based on target chain requirements + - Significantly reduces verification times from hours to minutes + - Lowers gas costs across all supported chains + +3. **Bridge Token Factory**: - Unified contract serving as both token factory and custodian - - Deploys and manages bridged token contracts - - Handles token locking and minting through NEP-141 standard - - Manages both native and bridged tokens through a single interface - -2. **Message Signing System**: - - Uses Chain Signatures' MPC network for secure cross-chain message verification - - Supports structured message types for transfers and token operations - - Eliminates need for traditional challenge periods through MPC threshold guarantees - - Enables permissionless relayer network for efficient transaction processing - -3. **Chain-Specific Verification**: - - Hybrid verification approach based on each chain's requirements: - - Ethereum/Bitcoin: Light client + Chain Signatures - - Solana/Base/Arbitrum: Currently using Wormhole, transitioning to Chain Signatures - - Progressive migration path toward full Chain Signatures integration - -This architecture creates a robust bridge system that combines NEAR's ability to execute transactions on foreign chains with secure verification methods, while maintaining a clear path toward increased decentralization through full Chain Signatures adoption. + - Manages both native and bridged tokens through NEP-141 standard + - Handles token locking, minting, and burning operations + - Supports permissionless relayer network for efficient processing + +This architecture creates a robust bridge system that combines NEAR's ability to execute transactions on foreign chains with secure verification methods, while maintaining high efficiency and security through MPC threshold guarantees. :::info For detailed implementation information and current status, see the [OmniBridge documentation](../../1.concepts/abstraction/omnibridge/overview.md). From 6128dc2a5aef45f9ba5d7c5dec9aa56e2b86874a Mon Sep 17 00:00:00 2001 From: Damian Parrino Date: Wed, 12 Feb 2025 08:33:35 -0300 Subject: [PATCH 11/17] change path --- .../omnibridge/how-it-works.md | 0 .../omnibridge/implementation.md | 0 .../omnibridge/overview.md | 0 .../omnibridge/roadmap.md | 0 website/sidebars.js | 8 ++++---- 5 files changed, 4 insertions(+), 4 deletions(-) rename docs/{1.concepts/abstraction => chain-abstraction}/omnibridge/how-it-works.md (100%) rename docs/{1.concepts/abstraction => chain-abstraction}/omnibridge/implementation.md (100%) rename docs/{1.concepts/abstraction => chain-abstraction}/omnibridge/overview.md (100%) rename docs/{1.concepts/abstraction => chain-abstraction}/omnibridge/roadmap.md (100%) diff --git a/docs/1.concepts/abstraction/omnibridge/how-it-works.md b/docs/chain-abstraction/omnibridge/how-it-works.md similarity index 100% rename from docs/1.concepts/abstraction/omnibridge/how-it-works.md rename to docs/chain-abstraction/omnibridge/how-it-works.md diff --git a/docs/1.concepts/abstraction/omnibridge/implementation.md b/docs/chain-abstraction/omnibridge/implementation.md similarity index 100% rename from docs/1.concepts/abstraction/omnibridge/implementation.md rename to docs/chain-abstraction/omnibridge/implementation.md diff --git a/docs/1.concepts/abstraction/omnibridge/overview.md b/docs/chain-abstraction/omnibridge/overview.md similarity index 100% rename from docs/1.concepts/abstraction/omnibridge/overview.md rename to docs/chain-abstraction/omnibridge/overview.md diff --git a/docs/1.concepts/abstraction/omnibridge/roadmap.md b/docs/chain-abstraction/omnibridge/roadmap.md similarity index 100% rename from docs/1.concepts/abstraction/omnibridge/roadmap.md rename to docs/chain-abstraction/omnibridge/roadmap.md diff --git a/website/sidebars.js b/website/sidebars.js index 68b8a6887b3..639181c424a 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -84,10 +84,10 @@ const sidebar = { }, { "Omni Bridge": [ - "concepts/abstraction/omnibridge/overview", - "concepts/abstraction/omnibridge/how-it-works", - "concepts/abstraction/omnibridge/implementation-details", - "concepts/abstraction/omnibridge/roadmap", + "chain-abstraction/omnibridge/overview", + "chain-abstraction/omnibridge/how-it-works", + "chain-abstraction/omnibridge/implementation-details", + "chain-abstraction/omnibridge/roadmap", ] }, 'build/chain-abstraction/fastauth-sdk', From 491f59b0c8fad068bbb6fc558c0c3ac721f2212a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1n=20Parrino?= Date: Wed, 12 Feb 2025 09:28:02 -0300 Subject: [PATCH 12/17] Apply suggestions from code review --- docs/2.build/1.chain-abstraction/what-is.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/2.build/1.chain-abstraction/what-is.md b/docs/2.build/1.chain-abstraction/what-is.md index 86f1b4d2fa0..dda752328b3 100644 --- a/docs/2.build/1.chain-abstraction/what-is.md +++ b/docs/2.build/1.chain-abstraction/what-is.md @@ -109,7 +109,7 @@ To learn more about Chain Signatures, the concepts, and how to implement it, che ### OmniBridge -The [OmniBridge](../../1.concepts/abstraction/omnibridge/overview.md) is a multi-chain asset bridge that combines Chain Signatures with chain-specific verification methods to enable secure and efficient cross-chain asset transfers. It consists of three core components: +The [OmniBridge](../../chain-abstraction/omnibridge/overview.md) is a multi-chain asset bridge that combines Chain Signatures with chain-specific verification methods to enable secure and efficient cross-chain asset transfers. It consists of three core components: 1. **Chain Signatures Integration**: - Enables NEAR smart contracts to generate and control accounts on other blockchains @@ -131,5 +131,5 @@ The [OmniBridge](../../1.concepts/abstraction/omnibridge/overview.md) is a multi This architecture creates a robust bridge system that combines NEAR's ability to execute transactions on foreign chains with secure verification methods, while maintaining high efficiency and security through MPC threshold guarantees. :::info -For detailed implementation information and current status, see the [OmniBridge documentation](../../1.concepts/abstraction/omnibridge/overview.md). +For detailed implementation information and current status, see the [OmniBridge documentation](../../chain-abstraction/omnibridge/overview.md). ::: From beeb65cd7ee57e699dbc9191c532c2309e6526f8 Mon Sep 17 00:00:00 2001 From: Damian Parrino Date: Wed, 12 Feb 2025 09:53:17 -0300 Subject: [PATCH 13/17] Update how-it-works.md --- docs/chain-abstraction/omnibridge/how-it-works.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/chain-abstraction/omnibridge/how-it-works.md b/docs/chain-abstraction/omnibridge/how-it-works.md index a35a1c4d48f..acc57cb880a 100644 --- a/docs/chain-abstraction/omnibridge/how-it-works.md +++ b/docs/chain-abstraction/omnibridge/how-it-works.md @@ -6,7 +6,7 @@ title: How Omni Bridge Works ## Background -The journey toward truly trustless cross-chain communication took a significant leap forward when the NEAR team [created the first trustless bridge with Ethereum](https://near.org/blog/the-rainbow-bridge-is-live) (Rainbow Bridge). This pioneering achievement demonstrated that completely trustless cross-chain communication was possible, marking a crucial step toward the vision of chain abstraction. However, this approach relied on implementing a NEAR light client directly on Ethereum - essentially requiring Ethereum to understand and verify NEAR's complex blockchain rules. +The journey toward truly trustless cross-chain communication took a significant leap forward when the NEAR team [created the first trustless bridge with Ethereum](https://near.org/blog/the-rainbow-bridge-is-live) (Rainbow Bridge). This pioneering achievement demonstrated that completely trustless cross-chain communication was possible, marking a crucial step toward the vision of chain abstraction. However, this approach relied on implementing a NEAR light client directly on Ethereum - essentially requiring Ethereum to understand and verify NEAR's complex blockchain rules. Omni Bridge introduces a more elegant solution using Chain Signatures. Instead of running light clients on each destination chain, it leverages Chain Signature's MPC Service to enable secure cross-chain message verification without the overhead of light client verification. This new approach reduces verification times from hours to minutes while significantly reducing gas costs across all supported chains. @@ -14,7 +14,7 @@ Omni Bridge introduces a more elegant solution using Chain Signatures. Instead o A light client is a smart contract that lets one blockchain verify events happening on another blockchain. In Rainbow Bridge's case, the Ethereum light client needs to track NEAR's blocks, verify its validators' signatures, and confirm transactions. This comes with major technical challenges: it requires storing two weeks of Ethereum block data, maintaining an updated list of NEAR validators and their stakes, and most crucially, verifying NEAR's ED25519 signatures - a process Ethereum wasn't built for. This verification is computationally expensive, making the whole process slow, costly, and ultimately a major bottleneck. -For example, with Rainbow Bridge, transactions from NEAR to Ethereum take between 4 and 8 hours due to the 4-hour challenge period and block submission intervals driven by Ethereum's high gas costs. More importantly, this approach becomes increasingly impractical when connecting to multiple chains, as each chain would require its own light client implementation. Some chains, such as Bitcoin, don't even support smart contracts, making it technically infeasible to implement a NEAR light client. +For example, with Rainbow Bridge, transactions from NEAR to Ethereum take between 4 and 8 hours due to the 4-hour challenge period and block submission intervals driven by Ethereum's high gas costs. More importantly, this approach becomes increasingly impractical when connecting to multiple chains, as each chain would require its own light client implementation. Some chains, such as Bitcoin, don't even support smart contracts, making it technically infeasible to implement a NEAR light client. While we still need to support light clients of different networks on NEAR (which is significantly easier to implement), a different approach is needed for verifying NEAR state on foreign chains. @@ -24,7 +24,7 @@ Before exploring how Chain Signatures solves these issues, it's important to und When a token transfer happens on NEAR using `ft_transfer_call`, the token contract first transfers the tokens and then automatically calls the specified `ft_on_transfer` method on the receiver contract. While these operations happen in sequence within the same transaction, the receiver contract has the ability to reject the transfer, causing the tokens to be refunded. This atomic behavior ensures the integrity and safety of bridge operations by preventing partial execution states. -For more information see [Fungible Tokens](../../../2.build/5.primitives/ft.md). +For more information see [Fungible Tokens](../../2.build/5.primitives/ft.md). ## Enter Chain Signatures @@ -74,4 +74,4 @@ sequenceDiagram MPC-->>Bridge: 4. Return signed msg Bridge->>Other: 5. Broadcast signed msg to destination chain Other->>Other: 4. Mint/release tokens -``` +``` From f49c39e8f9b5031470eda2df4ab4aee2db0d4a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1n=20Parrino?= Date: Wed, 12 Feb 2025 09:57:10 -0300 Subject: [PATCH 14/17] Delete website/static/docs/assets/omnibridge.svg --- website/static/docs/assets/omnibridge.svg | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 website/static/docs/assets/omnibridge.svg diff --git a/website/static/docs/assets/omnibridge.svg b/website/static/docs/assets/omnibridge.svg deleted file mode 100644 index 3678886cf1c..00000000000 --- a/website/static/docs/assets/omnibridge.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Omni Relayer
Ethereum
NEAR
ETH Tokens
dApp
Page-1 Cross-check path6508 path6510 polyline6512 Smart Contract(NEAR) Page-1 Cross-check path6508 path6510 polyline6512 Smart Contract(Ethereum)
NEAR Assets
OmniBridge SDK
(bridge-sdk-js)
\ No newline at end of file From b9a19b028d869f95f92d2917975ae953bebde676 Mon Sep 17 00:00:00 2001 From: Josh Ford Date: Thu, 13 Feb 2025 09:05:46 -0800 Subject: [PATCH 15/17] feat: add more references to SDK for higher visibility --- docs/chain-abstraction/omnibridge/how-it-works.md | 5 +++++ docs/chain-abstraction/omnibridge/implementation.md | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/docs/chain-abstraction/omnibridge/how-it-works.md b/docs/chain-abstraction/omnibridge/how-it-works.md index acc57cb880a..553b3974a68 100644 --- a/docs/chain-abstraction/omnibridge/how-it-works.md +++ b/docs/chain-abstraction/omnibridge/how-it-works.md @@ -75,3 +75,8 @@ sequenceDiagram Bridge->>Other: 5. Broadcast signed msg to destination chain Other->>Other: 4. Mint/release tokens ``` + +To get started building with Omni Bridge, see: + +- [Bridge SDK JS](https://github.com/near-one/bridge-sdk-js) Omni Bridge implementation in JavaScript +- [Bridge SDK Rust](https://github.com/near-one/bridge-sdk-rs) Omni Bridge implementation in Rust \ No newline at end of file diff --git a/docs/chain-abstraction/omnibridge/implementation.md b/docs/chain-abstraction/omnibridge/implementation.md index c531822558b..55de4ef7788 100644 --- a/docs/chain-abstraction/omnibridge/implementation.md +++ b/docs/chain-abstraction/omnibridge/implementation.md @@ -6,6 +6,13 @@ title: Implementation Details The Omni Bridge is a sophisticated cross-chain bridge infrastructure that enables secure and efficient token transfers between NEAR Protocol and various other blockchain networks. This document provides a detailed technical overview of the bridge's architecture, covering its core components, security model, and operational mechanisms. By leveraging a combination of Multi-Party Computation (MPC), chain-specific light clients, and a permissionless relayer network, the bridge achieves a robust balance of security, decentralization, and user experience. +For referece code implementations, see: + +- [Bridge SDK JS](https://github.com/near-one/bridge-sdk-js) Omni Bridge implementation in JavaScript +- [Bridge SDK Rust](https://github.com/near-one/bridge-sdk-rs) Omni Bridge implementation in Rust + +--- + ## The Bridge Token Factory Pattern At the core of Omni Bridge is the Bridge Token Factory contract on NEAR that serves as both a token factory and custodian. This unified contract handles both native tokens from the source chain and bridged tokens created by the factory itself. This design simplifies maintenance and reduces complexity compared to having separate contracts. From db10a07e0028bf6b0b7e0ca8e28f9ec7658d3e99 Mon Sep 17 00:00:00 2001 From: Josh Ford Date: Thu, 13 Feb 2025 09:46:15 -0800 Subject: [PATCH 16/17] fix: add improvement suggestions --- docs/chain-abstraction/omnibridge/implementation.md | 3 ++- docs/chain-abstraction/omnibridge/roadmap.md | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/chain-abstraction/omnibridge/implementation.md b/docs/chain-abstraction/omnibridge/implementation.md index 55de4ef7788..afdf6d1e107 100644 --- a/docs/chain-abstraction/omnibridge/implementation.md +++ b/docs/chain-abstraction/omnibridge/implementation.md @@ -122,6 +122,7 @@ The user starts by calling the token contract with: * Amount to transfer * Destination chain and address * Fee preferences (whether to pay fees in the token being transferred or in NEAR) +* Fees are minted on NEAR side for relayers #### 2. Token Lock @@ -146,7 +147,6 @@ The Bridge Token Factory on the destination chain: * Verifies the MPC signature * Mints equivalent tokens -* Fees are minted on NEAR side for relayers --- @@ -215,6 +215,7 @@ Relayers are permissionless infrastructure operators who monitor for bridge even * Steal funds * Censor transactions (users can self-relay) * Front-run transactions for profit +* Do not create additional security assumptions :::info The relayer's role is purely operational - executing valid transfers and collecting predetermined fees. Multiple relayers can operate simultaneously, creating competition for faster execution and lower fees. diff --git a/docs/chain-abstraction/omnibridge/roadmap.md b/docs/chain-abstraction/omnibridge/roadmap.md index dc236ff479b..760ccb8382e 100644 --- a/docs/chain-abstraction/omnibridge/roadmap.md +++ b/docs/chain-abstraction/omnibridge/roadmap.md @@ -54,6 +54,10 @@ Infrastructure development focuses on reliability and usability. An expanded rel - Security analysis - Developer tools +- [Near-One/omni-bridge](https://github.com/Near-One/omni-bridge) - Omni Bridge repository +- [Near-One/bridge-sdk-js](https://github.com/Near-One/bridge-sdk-js) - JavaScript SDK +- [Near-One/bridge-sdk-rs](https://github.com/Near-One/bridge-sdk-rs) - Rust SDK + The code is open source and we welcome contributions from the community. Whether you're interested in adding support for new chains, optimizing performance, or building developer tools, there's room for meaningful contribution. Bridge infrastructure is a fundamental component of a multi-chain future. Through Chain Signatures, we're creating a more efficient, secure, and scalable approach to cross-chain communication. Join us in building it. From cf1a55dd07ea251300378e524b49f26fbc8ab956 Mon Sep 17 00:00:00 2001 From: Josh Ford Date: Thu, 13 Feb 2025 09:47:19 -0800 Subject: [PATCH 17/17] fix: infeasible -> impossible --- docs/chain-abstraction/omnibridge/how-it-works.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chain-abstraction/omnibridge/how-it-works.md b/docs/chain-abstraction/omnibridge/how-it-works.md index 553b3974a68..ac381461309 100644 --- a/docs/chain-abstraction/omnibridge/how-it-works.md +++ b/docs/chain-abstraction/omnibridge/how-it-works.md @@ -14,7 +14,7 @@ Omni Bridge introduces a more elegant solution using Chain Signatures. Instead o A light client is a smart contract that lets one blockchain verify events happening on another blockchain. In Rainbow Bridge's case, the Ethereum light client needs to track NEAR's blocks, verify its validators' signatures, and confirm transactions. This comes with major technical challenges: it requires storing two weeks of Ethereum block data, maintaining an updated list of NEAR validators and their stakes, and most crucially, verifying NEAR's ED25519 signatures - a process Ethereum wasn't built for. This verification is computationally expensive, making the whole process slow, costly, and ultimately a major bottleneck. -For example, with Rainbow Bridge, transactions from NEAR to Ethereum take between 4 and 8 hours due to the 4-hour challenge period and block submission intervals driven by Ethereum's high gas costs. More importantly, this approach becomes increasingly impractical when connecting to multiple chains, as each chain would require its own light client implementation. Some chains, such as Bitcoin, don't even support smart contracts, making it technically infeasible to implement a NEAR light client. +For example, with Rainbow Bridge, transactions from NEAR to Ethereum take between 4 and 8 hours due to the 4-hour challenge period and block submission intervals driven by Ethereum's high gas costs. More importantly, this approach becomes increasingly impractical when connecting to multiple chains, as each chain would require its own light client implementation. Some chains, such as Bitcoin, don't even support smart contracts, making it technically impossible to implement a NEAR light client. While we still need to support light clients of different networks on NEAR (which is significantly easier to implement), a different approach is needed for verifying NEAR state on foreign chains.