layerzero-messaging — Claude Code skill: OFT bridges between Hedera
A skill for building LayerZero V2 bridges between Hedera and EVM chains: OFT/OApp setup, Endpoint V2 wiring, ULN, DVN and sends via quoteSend.
npx skills add hedera-dev/hedera-skills --skill layerzero-messaging -a claude-codeWhat layerzero-messaging does
The skill covers the OFT pattern: a standard OFT on the EVM side and an HTS-backed connector on Hedera. You link both with setPeer, then send with LayerZero V2 fees. Reference files cover where to source Endpoint, ULN and DVN addresses, plus code sketches for wiring and sending.
Wiring both directions is where most setups break. Each local OApp needs setPeer(remoteEid, remoteOAppAsBytes32), setSendLibrary and setReceiveLibrary (ULN302), setConfig for ExecutorConfig and UlnConfig, and setEnforcedOptions. Before sending, check peers(remoteEid) on both chains.
On Hedera a plain ERC-20 OFT is not the primary path. Use an HTS-backed connector: the constructor creates a fungible token through precompile 0x167, _debit burns on send and _credit mints on receive. Amounts must fit int64. The receiver account has to be associated with the HTS token before inbound transfers arrive. One more gotcha: forge fee simulation can disagree with Hedera JSON-RPC wei/tinybar scaling, so for Hedera → EVM the skill suggests quoting via cast and scaling the native fee.
What it helps with
- Deploy paired OFT tokens across Hedera and an EVM chain
- Link OApps with setPeer in both directions
- Configure ULN, DVN and executor for message sends
- Build an HTS connector with mint and burn via 0x167
- Send a transfer with fees from quoteSend
Example prompts for the agent
- Deploy an OFT on EVM and an HTS connector on Hedera, then setPeer both ways
- Set up send and receive libraries with ULN302 and ExecutorConfig for my OApp
- Quote a send for my remoteEid and send it with the native fee
How to install layerzero-messaging
1Skills CLI (Vercel)
npx skills add hedera-dev/hedera-skills --skill layerzero-messaging -a claude-code2Manually: put the files in place
~/.claude/skills/layerzero-messaging/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/layerzero-messaging/
1Skills CLI (Vercel)
npx skills add hedera-dev/hedera-skills --skill layerzero-messaging -a codex2Manually: put the files in place
.agents/skills/layerzero-messaging/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add hedera-dev/hedera-skills --skill layerzero-messaging -a cursor2Manually: put the files in place
.cursor/skills/layerzero-messaging/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install hedera-dev/hedera-skills layerzero-messaging2Manually: put the files in place
.github/skills/layerzero-messaging/SKILL.md1Skills CLI (Vercel)
npx skills add hedera-dev/hedera-skills --skill layerzero-messaging -a gemini-cli2Platform CLI
gemini skills install https://github.com/hedera-dev/hedera-skills --path plugins/cross-chain/skills/layerzero-messagingManually: put the files in place
.devin/skills/layerzero-messaging/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add hedera-dev/hedera-skills --skill layerzero-messaging -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about layerzero-messaging
How do I install layerzero-messaging in Claude?
Run npx skills add hedera-dev/hedera-skills --skill layerzero-messaging -a claude-code. The skill file then lands at ~/.claude/skills/layerzero-messaging/SKILL.md.
What does layerzero-messaging do?
It helps you build LayerZero V2 bridges between Hedera and EVM: deploy OFT and HTS connectors, configure Endpoint V2, ULN, DVN and executor, and send transfers with quoted fees.
Why can't I use a plain ERC-20 OFT on Hedera?
The primary path on Hedera is an HTS-backed connector: the constructor creates the token via precompile 0x167, sends burn and receives mint. Amounts must fit int64.
Source text
SKILL.md · Apache-2.0
---
name: layerzero-messaging
description: >
LayerZero V2 messaging on Hedera. Use when building OFT / OApp bridges between Hedera and
EVM chains, configuring Endpoint V2 peers and ULN/DVN/executor wiring, sending with
quoteSend + send, implementing HTS-backed OFT connectors (mint/burn via 0x167), or
relaying educational lzReceive flows on testnet.
---
# LayerZero Messaging (Hedera)
**OFT pattern:** deploy paired Omnichain Fungible Tokens — a standard `OFT` on the EVM side and an **HTS connector OFT** on Hedera — then `setPeer` both ways and send with LayerZero V2 fees.
```text
OFT (EVM) ←setPeer→ HTSConnectorOFT (Hedera)
│ send / quoteSend │ _debit burn / _credit mint (HTS 0x167)
└──────── Endpoint V2 + ULN + DVN + Executor ────────┘
```
This skill focuses on **LayerZero V2 OApp/OFT + Hedera HTS**. Educational templates may use **simple workers** and a manual/UI `lzReceive` relay — not the same as production LayerZero Labs verification.
## Quick Reference
| Concept | Rule |
| ------- | ---- |
| Endpoint | `ILayerZeroEndpointV2` per chain |
| Peer | `setPeer(remoteEid, bytes32(uint256(uint160(remoteOApp))))` on **both** sides |
| Send | `quoteSend(SendParam, payInLzToken)` → `send{value: nativeFee}(SendParam, fee, refund)` |
| Receiver | `to` in `SendParam` is `bytes32` (padded address) |
| Hedera OFT | HTS-backed connector — create HTS token, burn on send, mint on receive |
| HTS fee | Deploy connector with native value to pay `createFungibleToken` |
| Approval | User must `approve(connector, amount)` on the **HTS token** before Hedera → EVM `send` |
| IDs | Use LayerZero **EIDs** in peers/`dstEid` — not EVM chain IDs |
See [references/hedera-endpoints.md](references/hedera-endpoints.md) for where to source Endpoint/ULN/DVN addresses. See [references/examples.md](references/examples.md) for wire and send sketches.
## Critical: Wire Both Directions
Incomplete peer config bricks the pathway. For each local OApp:
1. `setPeer(remoteEid, remoteOAppAsBytes32)`
2. `setSendLibrary` / `setReceiveLibrary` (ULN302)
3. `setConfig` — ExecutorConfig (type `1`) on send lib; UlnConfig (type `2`) on send + receive libs
4. `setEnforcedOptions` — e.g. `lzReceive` gas for msgType `1` (token send)
Verify with `peers(remoteEid)` on both chains before sending.
## Critical: Hedera HTS Connector Semantics
On Hedera, do **not** use a plain ERC-20 OFT as the primary path. Use an HTS-backed connector:
- Constructor creates fungible HTS via precompile `0x167` (supply key = connector)
- `_debit`: transfer HTS in → **burn**
- `_credit`: **mint** → transfer HTS out
- Amounts must fit `int64` for HTS mint/burn/transfer
- Associate the receiver account with the HTS token before EVM → Hedera receives
```solidity
// Deploy with value so createFungibleToken fee is paid
new HTSConnectorOFT{ value: htsCreateValue }(name, symbol, lzEndpoint, owner);
```
## Send Flow
```solidity
SendParam memory sendParam = SendParam({
dstEid: remoteEid,
to: bytes32(uint256(uint160(receiver))),
amountLD: amountLD,
minAmountLD: (amountLD * 9) / 10,
extraOptions: OptionsBuilder.newOptions().addExecutorLzReceiveOption(lzReceiveGas, 0),
composeMsg: "",
oftCmd: ""
});
MessagingFee memory fee = IOFT(localOFT).quoteSend(sendParam, false);
IOFT(localOFT).send{ value: fee.nativeFee }(sendParam, fee, payable(refundTo));
```
**Hedera → EVM note:** forge fee simulation can disagree with Hedera JSON-RPC wei/tinybar scaling — often `quote` via `cast` + scaled native fee for that direction.
## Deploy Checklist (generic)
1. Deploy EVM `OFT` (optional premint)
2. Deploy Hedera HTS connector OFT with HTS create value
3. Deploy workers (Labs DVN/executor **or** educational simple workers)
4. Wire both OApps (`setPeer` + libraries + config + enforced options)
5. Associate Hedera account with `htsTokenAddress()`
6. Sync frontend config if applicable; fund relay key if using UI auto-relay
7. Send small amount; track on LayerZero Scan (testnet/mainnet as appropriate)
## Educational Relay
Some templates use **simple DVN/executor mocks** and an explicit `lzReceive` relay step. Treat that as a learning aid — production apps rely on LayerZero’s verification network, not a custom relayer key in the app server.
## Checklist
- [ ] Peers set both ways with correct EIDs (not EVM chain IDs)
- [ ] Send/receive libraries + ULN/executor config applied
- [ ] Hedera side is HTS connector; create fee paid; supply key is connector
- [ ] Receiver associated with HTS token before inbound transfers
- [ ] `quoteSend` native fee attached to `send`
- [ ] Receiver address encoded as `bytes32`
- [ ] Educational disclaimer: not audited / not for mainnet funds
## References
- [references/examples.md](references/examples.md) — OFT, HTS connector, wire, send
- [references/hedera-endpoints.md](references/hedera-endpoints.md) — EIDs vs chain IDs, where to source addresses
- [LayerZero V2 docs](https://docs.layerzero.network/v2)
- [LayerZero deployments metadata](https://metadata.layerzero-api.com/v1/metadata/deployments)
© hedera-dev · Apache-2.0 · hedera-dev/hedera-skills