Skip to content

Commit 8018c5a

Browse files
committed
docs(fassets): add OFT peers discovery section to auto-redemption guide
1 parent 7d7547f commit 8018c5a

File tree

2 files changed

+211
-0
lines changed

2 files changed

+211
-0
lines changed

docs/fassets/developer-guides/12-fassets-autoredeem.mdx

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import CodeBlock from "@theme/CodeBlock";
1111
import FassetRedeemComposer from "!!raw-loader!/examples/developer-hub-solidity/FAssetRedeemComposer.sol";
1212
import bridgeToHyperEVM from "!!raw-loader!/examples/developer-hub-javascript/bridgeToHyperEVM.ts";
1313
import autoRedeemHyperEVM from "!!raw-loader!/examples/developer-hub-javascript/autoRedeemHyperEVM.ts";
14+
import getOftPeers from "!!raw-loader!/examples/developer-hub-javascript/getOftPeers.ts";
1415

1516
# FAsset Auto-Redemption
1617

@@ -555,6 +556,89 @@ A: Get them from Hyperliquid testnet faucet or DEX.
555556

556557
---
557558

559+
## Discovering Available Bridge Routes
560+
561+
### Script: `getOftPeers.ts`
562+
563+
### What It Is
564+
565+
This utility script discovers all configured LayerZero peers for the FXRP OFT Adapter on Coston2. It scans all LayerZero V2 testnet endpoints to find which EVM chains have been configured as valid bridge destinations.
566+
567+
### Why Use It
568+
569+
Before bridging FXRP to another chain, you need to know which chains are supported. This script:
570+
571+
- Automatically discovers all configured peer addresses
572+
- Shows which EVM chains you can bridge FXRP to/from
573+
- Provides the peer contract addresses for each chain
574+
- Outputs results in both human-readable and JSON formats
575+
576+
### How It Works
577+
578+
1. **Loads V2 Testnet Endpoints**: Dynamically retrieves all LayerZero V2 testnet endpoint IDs from the `@layerzerolabs/lz-definitions` package
579+
2. **Queries Peers**: For each endpoint, calls the `peers()` function on the OFT Adapter contract
580+
3. **Filters Results**: Only shows endpoints that have a non-zero peer address configured
581+
4. **Formats Output**: Displays results in a table format and as JSON for programmatic use
582+
583+
### How to Run
584+
585+
```bash
586+
yarn hardhat run scripts/layerzero/getOFTPeers.ts --network coston2
587+
```
588+
589+
### Expected Output
590+
591+
```
592+
=== FXRP OFT Adapter Peers Discovery ===
593+
594+
OFT Adapter: 0xCd3d2127935Ae82Af54Fc31cCD9D3440dbF46639
595+
Network: Coston2 (Flare Testnet)
596+
597+
Scanning 221 LayerZero V2 Testnet endpoints...
598+
599+
✅ Bsc (EID: 40102): 0xac7c4a07670589cf83b134a843bfe86c45a4bf4e
600+
✅ Sepolia (EID: 40161): 0x81672c5d42f3573ad95a0bdfbe824faac547d4e6
601+
✅ Hyperliquid (EID: 40362): 0x14bfb521e318fc3d5e92a8462c65079bc7d4284c
602+
603+
============================================================
604+
SUMMARY: Configured Peers
605+
============================================================
606+
607+
Found 3 configured peer(s):
608+
609+
| Chain | EID | Peer Address |
610+
|-------|-----|--------------|
611+
| Bsc | 40102 | 0xac7c4a07670589cf83b134a843bfe86c45a4bf4e |
612+
| Sepolia | 40161 | 0x81672c5d42f3573ad95a0bdfbe824faac547d4e6 |
613+
| Hyperliquid | 40362 | 0x14bfb521e318fc3d5e92a8462c65079bc7d4284c |
614+
615+
--- Available Routes ---
616+
You can bridge FXRP to/from the following chains:
617+
618+
• Bsc
619+
• Sepolia
620+
• Hyperliquid
621+
```
622+
623+
### Using the Results
624+
625+
Once you've identified available peers, you can:
626+
627+
1. **Bridge to any discovered chain**: Update the destination EID in `bridgeToHyperEVM.ts` to target a different chain
628+
2. **Verify peer addresses**: Use the peer addresses to interact with OFT contracts on other chains
629+
3. **Build integrations**: Use the JSON output to programmatically determine available routes
630+
631+
<details>
632+
<summary>View `getOftPeers.ts` source code</summary>
633+
634+
<CodeBlock language="typescript" title="scripts/layerzero/getOFTPeers.ts">
635+
{getOftPeers}
636+
</CodeBlock>
637+
638+
</details>
639+
640+
---
641+
558642
## Support & Resources
559643

560644
- **LayerZero Docs**: https://docs.layerzero.network/
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/**
2+
* Get all LayerZero peers for the FXRP OFT Adapter on Coston2
3+
*
4+
* Usage:
5+
* yarn hardhat run scripts/layerzero/getOFTPeers.ts --network coston2
6+
*/
7+
8+
import { web3 } from "hardhat";
9+
import { EndpointId } from "@layerzerolabs/lz-definitions";
10+
11+
// FXRP OFT Adapter on Coston2
12+
const OFT_ADAPTER_ADDRESS = "0xCd3d2127935Ae82Af54Fc31cCD9D3440dbF46639";
13+
14+
// Minimal OApp ABI for peers function
15+
const OAPP_ABI = [
16+
{
17+
inputs: [{ internalType: "uint32", name: "eid", type: "uint32" }],
18+
name: "peers",
19+
outputs: [{ internalType: "bytes32", name: "", type: "bytes32" }],
20+
stateMutability: "view",
21+
type: "function",
22+
},
23+
];
24+
25+
// Get ALL V2 Testnet endpoints dynamically from the EndpointId enum
26+
function getAllV2TestnetEndpoints(): { name: string; eid: number }[] {
27+
const endpoints: { name: string; eid: number }[] = [];
28+
29+
for (const [key, value] of Object.entries(EndpointId)) {
30+
// Only include V2 testnet endpoints (they end with _V2_TESTNET and have numeric values)
31+
if (key.endsWith("_V2_TESTNET") && typeof value === "number") {
32+
// Convert key like "SEPOLIA_V2_TESTNET" to "Sepolia"
33+
const name = key
34+
.replace("_V2_TESTNET", "")
35+
.split("_")
36+
.map((word) => word.charAt(0) + word.slice(1).toLowerCase())
37+
.join(" ");
38+
endpoints.push({ name, eid: value });
39+
}
40+
}
41+
42+
// Sort by EID for consistent output
43+
return endpoints.sort((a, b) => a.eid - b.eid);
44+
}
45+
46+
const V2_TESTNET_ENDPOINTS = getAllV2TestnetEndpoints();
47+
48+
const ZERO_BYTES32 =
49+
"0x0000000000000000000000000000000000000000000000000000000000000000";
50+
51+
async function main() {
52+
console.log("=== FXRP OFT Adapter Peers Discovery ===\n");
53+
console.log(`OFT Adapter: ${OFT_ADAPTER_ADDRESS}`);
54+
console.log(`Network: Coston2 (Flare Testnet)\n`);
55+
56+
const oftAdapter = new web3.eth.Contract(OAPP_ABI, OFT_ADAPTER_ADDRESS);
57+
58+
const configuredPeers: { name: string; eid: number; peer: string }[] = [];
59+
const errors: { name: string; eid: number; error: string }[] = [];
60+
61+
console.log(
62+
`Scanning ${V2_TESTNET_ENDPOINTS.length} LayerZero V2 Testnet endpoints...\n`,
63+
);
64+
65+
for (const endpoint of V2_TESTNET_ENDPOINTS) {
66+
try {
67+
const peer = await oftAdapter.methods.peers(endpoint.eid).call();
68+
69+
if (peer && peer !== ZERO_BYTES32) {
70+
// Convert bytes32 to address (last 20 bytes)
71+
const peerAddress = "0x" + peer.slice(-40);
72+
configuredPeers.push({
73+
name: endpoint.name,
74+
eid: endpoint.eid,
75+
peer: peerAddress,
76+
});
77+
console.log(
78+
`✅ ${endpoint.name} (EID: ${endpoint.eid}): ${peerAddress}`,
79+
);
80+
}
81+
} catch (error: any) {
82+
// Some endpoints might not exist or the contract might revert
83+
errors.push({
84+
name: endpoint.name,
85+
eid: endpoint.eid,
86+
error: error.message?.slice(0, 50) || "Unknown error",
87+
});
88+
}
89+
}
90+
91+
console.log("\n" + "=".repeat(60));
92+
console.log("SUMMARY: Configured Peers");
93+
console.log("=".repeat(60) + "\n");
94+
95+
if (configuredPeers.length === 0) {
96+
console.log("No peers configured for the FXRP OFT Adapter.\n");
97+
} else {
98+
console.log(`Found ${configuredPeers.length} configured peer(s):\n`);
99+
100+
console.log("| Chain | EID | Peer Address |");
101+
console.log("|-------|-----|--------------|");
102+
for (const peer of configuredPeers) {
103+
console.log(`| ${peer.name} | ${peer.eid} | ${peer.peer} |`);
104+
}
105+
106+
console.log("\n--- Available Routes ---");
107+
console.log("You can bridge FXRP to/from the following chains:\n");
108+
for (const peer of configuredPeers) {
109+
console.log(` • ${peer.name}`);
110+
}
111+
}
112+
113+
if (errors.length > 0) {
114+
console.log(
115+
`\n(${errors.length} endpoints had errors or are not available)`,
116+
);
117+
}
118+
119+
// Export as JSON for programmatic use
120+
console.log("\n--- JSON Output ---");
121+
console.log(JSON.stringify(configuredPeers, null, 2));
122+
}
123+
124+
main().catch((error) => {
125+
console.error(error);
126+
process.exit(1);
127+
});

0 commit comments

Comments
 (0)