Polybridge is a sophisticated cross-chain messaging protocol built on top of Polymer, enabling seamless action chaining and bidirectional message passing between different blockchains.
- 🔄 Bidirectional Messaging: Support for back-and-forth communication between chains
- 🔗 Action Chaining: Chain multiple cross-chain actions in sequence
- 🛡️ Secure Message Passing: Utilizes Polymer's Prover API
- 🎯 Action Tracking: Track the state of actions across multiple chains
- 🔍 Detailed Event Logging: Clear visibility into cross-chain operations
A simple example demonstrating number increment across chains:
- Client initiates on Chain A (value = 1)
- Relayer bridges to Chain B (value = 2)
- Relayer bridges back to Chain A (value = 3)
A more complex example showing NFT bridging between chains:
- Client mints NFT on Chain A
- Bridge to Chain B:
- Client initiates the bridge and locks NFT on Chain A
- Relayer mints and locks NFT on Chain B
- Complete Bridge:
- Relayer burns NFT on Chain A
- Relayer unlocks NFT on Chain B
- Node.js v18+
npm
oryarn
- A wallet with some testnet ETH on the following testnets:
- Optimism Sepolia
- Base Sepolia
- Polymer API Key for requesting the cross-chain proof
-
Clone the repository:
git clone https://github.com/stevenlei/polybridge.git cd polybridge
-
Install dependencies:
npm install
-
Set up environment variables:
cp .env.example .env
-
Edit
.env
with your configuration:PRIVATE_KEY= OPTIMISM_SEPOLIA_RPC= BASE_SEPOLIA_RPC= POLYMER_API_KEY=
OPTIMISM_SEPOLIA_CONTRACT_ADDRESS
andBASE_SEPOLIA_CONTRACT_ADDRESS
will be set automatically after contract deployment, please note that both examples use the same contract address env variables for simplicity.
Deploy Contracts
# For Counter Example
npm run deploy:counter:optimism
npm run deploy:counter:base
# For NFT Example
npm run deploy:nft:optimism
npm run deploy:nft:base
Start the relayer
npm run relayer
Run the test
# For Counter Example
npm run test:counter
# For NFT Example
npm run test:nft
-
PolyBridge Contract
Base contract for cross-chain messaging. To use this contract:
-
Inherit from
PolyBridge
:contract YourContract is PolyBridge { constructor(address _polymerProver) PolyBridge(_polymerProver) {} }
-
Register functions that can be called cross-chain:
// In your constructor registerFunction(bytes4(keccak256("yourFunction(uint256)")));
-
Call
bridge()
to initiate cross-chain actions which will be validated and executed by the relayer:// In your function function startCrossChainAction() external returns (bytes32) { // The target function selector bytes4 targetFunction = bytes4(keccak256("targetFunction(uint256)")); // The value to pass to the target function uint256 value = 42; return bridge(targetFunction, abi.encode(value)); }
-
Implement
_executeFunction()
to handle incoming calls from the relayer:function _executeFunction( bytes4 selector, bytes memory payload ) internal override returns (bool) { if (selector == bytes4(keccak256("targetFunction(uint256)"))) { // Decode the payload and get the value uint256 value = abi.decode(payload, (uint256)); // Call the target function return targetFunction(value); } revert("Unknown function selector"); }
-
-
Relayer
- Monitors chains for events
- Requests proofs from Polymer API
- Submit proofs to destination chain
- Handles bidirectional message passing
Located in contracts/example/CrossChainCounter.sol
, demonstrates a complete counter bridge flow:
updateNumberStep1_calledByClientOnChainA
: Client initiates on Chain AupdateNumberStep2_calledByRelayerOnChainB
: Relayer executes on Chain BupdateNumberStep3_calledByRelayerOnChainA
: Relayer completes on Chain A
Each step:
- Updates a number value
- Emits an event for tracking
- Bridges to the next chain if needed
The function names are intentionally verbose for better readability.
Located in contracts/example/CrossChainNFT.sol
, demonstrates a complete NFT bridge flow:
mintOnChainA
: Client mints NFT on Chain AbridgeToChainB
: Client mints NFT on Chain AmintOnChainB
: Relayer mints and locks NFT on Chain BburnOnChainA
: Relayer burns NFT on Chain AunlockOnChainB
: Relayer unlocks NFT on Chain B
Each step:
- Emits an event for tracking
- Bridges to the next chain if needed
This is a proof of concept and is not intended for production use. It may contain bugs, vulnerabilities, or other issues that make it unsuitable for use in a production environment. I am not responsible for any issues that may arise from using this project on mainnet.
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.