This guide will help you get familiar with LxLy.js, configure your code to interact with Agglayer chains, and bridge assets from the Polygon zkEVM testnet to the Silicon Sepolia testnet using the Unified Bridge and lxly.js. In this guide you will:
- Configure your environment
- Bridge your asset using bridge API
- Check its status using the Transaction API
- Use the claim API to claim the transaction on the destination chain.
Before you begin, ensure that you have the following:
- Node.js & npm:
- Node.js: v14.0.0 or later
- npm: v6.0.0 or later
- Hardhat Wallet:
A Hardhat wallet (or similar) configured for testing. - Testnet ETH:
Acquire test ETH (from a faucet) for the Sepolia testnet.
Make sure your config.js contains the correct network settings, RPC endpoints, bridge contract addresses, and account details. (See the AggLayer Unified Bridge repository for a sample configuration.)
This file initializes your connection with the Unified Bridge using lxly.js. It configures network providers (using HDWalletProvider or similar) for both the source and destination networks.
const getLxLyClient = async (network = 'testnet') => {
const lxLyClient = new LxLyClient();
return await lxLyClient.init({
log: true,
network: network,
providers: {
// zkEVM cardona
1: {
provider: new HDWalletProvider([config.user1.privateKey], config.configuration[1].rpc),
configuration: {
bridgeAddress: config.configuration[1].bridgeAddress,
bridgeExtensionAddress: config.configuration[1].bridgeExtensionAddress,
isEIP1559Supported: false
},
defaultConfig: {
from: config.user1.address
}
},
// silcion sepolia
16: {
provider: new HDWalletProvider([config.user1.privateKey], config.configuration[16].rpc),
configuration: {
bridgeAddress: config.configuration[16].bridgeAddress,
bridgeExtensionAddress: config.configuration[16].bridgeExtensionAddress,
isEIP1559Supported: false
},
defaultConfig: {
from: config.user1.address
}
}
}
});
}In this step, you will initiate a cross-chain asset transfer from the Sepolia testnet to zkEVM (Agglayer).
What Happens:
- BRIDGED State:
When you call thebridgeAssetAPI, the transaction is initiated on the source chain.
Script Walkthrough: bridge_asset.js
const { getLxLyClient, tokens } = require('./utils/utils_lxly');
const execute = async () => {
// Initialize the lxly client
const client = await getLxLyClient();
// Define source network ID (zkEVM Testnet)
const sourceNetworkId = 1;
// Get the API for the Ether token on the source network
const token = client.erc20(tokens[sourceNetworkId].ether, sourceNetworkId);
// Define destination network ID (Silicon sepolia)
const destinationNetworkId = 16;
// Bridge a specific amount of Ether (in wei)
const result = await token.bridgeAsset("10000000000000000", config.user1.address, destinationNetworkId);
// Log the transaction hash and receipt
const txHash = await result.getTransactionHash();
console.log("txHash", txHash);
const receipt = await result.getReceipt();
console.log("receipt", receipt);
}
execute()
.then(() => {})
.catch(err => {
console.error("Error bridging asset:", err);
})
.finally(() => {
process.exit(0);
});How to Run:
node bridge_asset.jsBefore proceeding with claiming the asset, you need to verify its current status using the Transaction API. This step is typically performed using Postman or a cURL command.
- Testnet:
https://api-gateway.polygon.technology/api/v3/transactions/testnet?userAddress={userAddress} - Mainnet:
https://api-gateway.polygon.technology/api/v3/transactions/mainnet?userAddress={userAddress}
Using Postman, import the API endpoint to check the status of your transaction. This query will return details such as the token bridged, the amount, and the current state of the transaction.
After querying the Bridge API, you will receive information on the transaction states. The key states are:
-
BRIDGED:
The transaction has been initiated on the source chain (Sepolia) via thebridgeAssetAPI. -
READY_TO_CLAIM:
The asset is now available on the destination chain (zkEVM / AggLayer) and is awaiting claim. -
CLAIMED:
The asset has been successfully claimed on the destination chain after using theclaimAssetAPI.
These states are verified by querying the API (for example, via Postman).
Once the Bridge API shows that the asset is READY_TO_CLAIM, you can claim it on the destination chain using the claim API.
- CLAIMED State:
The asset moves from a pending state to claimed after executing the claim.
const { getLxLyClient, tokens } = require('./utils/utils_lxly');
const execute = async () => {
// Replace with your actual bridge transaction hash from the bridge_asset.js output
const bridgeTransactionHash = "0x1fc6858b20c75189a9fa8f3ae60c2a255cc3c41a058781f33daa57fc0f80b81a";
// Initialize the lxly client
const client = await getLxLyClient();
// Define source network ID (zkEVM Testnet)
const sourceNetworkId = 1;
// Define destination network ID (Silicon sepolia)
const destinationNetworkId = 16;
// Get the API for the Ether token on the destination network
const token = client.erc20(tokens[destinationNetworkId].ether, destinationNetworkId);
// Claim the bridged asset using the claimAsset API
const result = await token.claimAsset(bridgeTransactionHash, sourceNetworkId, { returnTransaction: false });
console.log("Claim result:", result);
// Log the transaction hash and receipt for the claim transaction
const txHash = await result.getTransactionHash();
console.log("Claim txHash:", txHash);
const receipt = await result.getReceipt();
console.log("Claim receipt:", receipt);
}
execute()
.then(() => {})
.catch(err => {
console.error("Error claiming asset:", err);
});How to run:
node claim_asset.jsAfter claiming the asset, verify the final state using the Bridge API: Use Postman or a cURL command to ensure that the transaction state has been updated to CLAIMED.