Skip to content

Commit a039e8a

Browse files
Add Relay bridge guide, create Bridging sidebar section, fix USDC naming (#225)
- Add bridge-usdc-relay.mdx with full Relay integration guide (quote, execute, status) - Create 'Bridging' sidebar section nesting Stargate and Relay guides - Rename USDC references to 'Bridged USDC' / 'USDC.e' on Tempo side (Circle C&D) - Replace em dashes with hyphens across both guides Amp-Thread-ID: https://ampcode.com/threads/T-019d4fbd-7519-75b6-960e-3c3326e6a3da Co-authored-by: Amp <amp@ampcode.com>
1 parent bb6bc1a commit a039e8a

File tree

4 files changed

+484
-76
lines changed

4 files changed

+484
-76
lines changed
Lines changed: 123 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,56 @@
11
---
2-
title: Bridge USDC via Stargate
3-
description: Bridge USDC to and from Tempo using Stargate and LayerZero. Includes source chain addresses, cast commands, and TypeScript examples with viem.
2+
title: Bridge via LayerZero
3+
description: Bridge tokens to and from Tempo using LayerZero. Covers Stargate pools and standard OFT adapters with cast commands and TypeScript examples.
44
---
55

6-
import { Tabs, Tab } from 'vocs'
6+
# Bridge via LayerZero
77

8-
# Bridge USDC via Stargate
8+
[LayerZero](https://layerzero.network) is the omnichain messaging protocol that powers token bridging on Tempo. Tokens are bridged using the [OFT (Omnichain Fungible Token)](https://docs.layerzero.network/v2/developers/evm/oft/quickstart) standard - the source chain locks or burns tokens and the destination chain mints the bridged equivalent.
99

10-
[Stargate](https://stargate.finance/) uses [LayerZero](https://layerzero.network) to enable 1&#58;1 USDC bridging between Tempo and other chains. Stargate locks USDC on the source chain and mints **USDC.e** (Bridged USDC) on Tempo, typically in under a minute.
10+
There are two flavors of OFT on Tempo:
1111

12-
## Contracts on Tempo
12+
- **Stargate** - an application built on LayerZero that manages liquidity pools. Tokens like USDC.e and EURC.e use Stargate's `sendToken()` interface.
13+
- **Standard OFT** - token issuers (e.g. Tether for USDT0) deploy their own OFT adapters using LayerZero's `send()` interface directly.
14+
15+
Both use the same underlying LayerZero endpoint on Tempo.
16+
17+
## Bridged tokens on Tempo
18+
19+
| Token | Address | Bridge |
20+
|-------|---------|--------|
21+
| **USDC.e** (Bridged USDC) | [`0x20C000000000000000000000b9537d11c60E8b50`](https://explore.tempo.xyz/address/0x20C000000000000000000000b9537d11c60E8b50) | Stargate |
22+
| **EURC.e** (Bridged EURC) | [`0x20c0000000000000000000001621e21F71CF12fb`](https://explore.tempo.xyz/address/0x20c0000000000000000000001621e21F71CF12fb) | Stargate |
23+
| **USDT0** | [`0x20c00000000000000000000014f22ca97301eb73`](https://explore.tempo.xyz/address/0x20c00000000000000000000014f22ca97301eb73) | OFT |
24+
| **frxUSD** | [`0x20c0000000000000000000003554d28269e0f3c2`](https://explore.tempo.xyz/address/0x20c0000000000000000000003554d28269e0f3c2) | OFT |
25+
| **cUSD** | [`0x20c0000000000000000000000520792dcccccccc`](https://explore.tempo.xyz/address/0x20c0000000000000000000000520792dcccccccc) | OFT |
26+
| **stcUSD** | [`0x20c0000000000000000000008ee4fcff88888888`](https://explore.tempo.xyz/address/0x20c0000000000000000000008ee4fcff88888888) | OFT |
27+
| **GUSD** | [`0x20c0000000000000000000005c0bac7cef389a11`](https://explore.tempo.xyz/address/0x20c0000000000000000000005c0bac7cef389a11) | OFT |
28+
| **rUSD** | [`0x20c0000000000000000000007f7ba549dd0251b9`](https://explore.tempo.xyz/address/0x20c0000000000000000000007f7ba549dd0251b9) | OFT |
29+
| **wsrUSD** | [`0x20c000000000000000000000aeed2ec36a54d0e5`](https://explore.tempo.xyz/address/0x20c000000000000000000000aeed2ec36a54d0e5) | OFT |
30+
31+
See the full token list at [tokenlist.tempo.xyz](https://tokenlist.tempo.xyz/list/4217).
32+
33+
## LayerZero contracts on Tempo
1334

1435
| Contract | Address |
1536
|----------|---------|
16-
| **USDC.e** (Bridged USDC) | [`0x20C000000000000000000000b9537d11c60E8b50`](https://explore.tempo.xyz/address/0x20C000000000000000000000b9537d11c60E8b50) |
17-
| **StargateOFTUSDC** | [`0x8c76e2F6C5ceDA9AA7772e7efF30280226c44392`](https://explore.tempo.xyz/address/0x8c76e2F6C5ceDA9AA7772e7efF30280226c44392) |
1837
| **EndpointV2** | [`0x20Bb7C2E2f4e5ca2B4c57060d1aE2615245dCc9C`](https://explore.tempo.xyz/address/0x20Bb7C2E2f4e5ca2B4c57060d1aE2615245dCc9C) |
1938
| **LZEndpointDollar** | [`0x0cEb237E109eE22374a567c6b09F373C73FA4cBb`](https://explore.tempo.xyz/address/0x0cEb237E109eE22374a567c6b09F373C73FA4cBb) |
2039

2140
Tempo's LayerZero Endpoint ID is **`30410`**.
2241

23-
## Source chain contracts
42+
## Stargate tokens
43+
44+
[Stargate](https://stargate.finance/) manages liquidity pools for USDC.e and EURC.e. Use the Stargate `sendToken()` interface for these tokens.
45+
46+
### Stargate contracts on Tempo
47+
48+
| Token | Stargate OFT Contract |
49+
|-------|----------------------|
50+
| **USDC.e** | [`0x8c76e2F6C5ceDA9AA7772e7efF30280226c44392`](https://explore.tempo.xyz/address/0x8c76e2F6C5ceDA9AA7772e7efF30280226c44392) |
51+
| **EURC.e** | [`0x7753Dc8d4bd48Db599Da21E08b1Ab1D6FDFfdC71`](https://explore.tempo.xyz/address/0x7753Dc8d4bd48Db599Da21E08b1Ab1D6FDFfdC71) |
2452

25-
Use the Stargate pool contract on the source chain to bridge USDC to Tempo, and the StargateOFTUSDC contract on Tempo to bridge back.
53+
### Source chain Stargate pools
2654

2755
| Chain | LZ Endpoint ID | Stargate USDC Pool |
2856
|-------|---------------:|--------------------|
@@ -33,23 +61,20 @@ Use the Stargate pool contract on the source chain to bridge USDC to Tempo, and
3361
| Polygon | `30109` | [`0x9Aa02D4Fae7F58b8E8f34c66E756cC734DAc7fe4`](https://polygonscan.com/address/0x9Aa02D4Fae7F58b8E8f34c66E756cC734DAc7fe4) |
3462
| Avalanche | `30106` | [`0x5634c4a5FEd09819E3c46D86A965Dd9447d86e47`](https://snowtrace.io/address/0x5634c4a5FEd09819E3c46D86A965Dd9447d86e47) |
3563

36-
## Bridge to Tempo
64+
### Bridge to Tempo via Stargate
3765

38-
### Using the Stargate app
66+
#### Using the Stargate app
3967

4068
1. Go to [stargate.finance](https://stargate.finance/)
41-
2. Select your source chain (e.g. Ethereum) and USDC
69+
2. Select your source chain and token (USDC or EURC)
4270
3. Set **Tempo** as the destination chain
4371
4. Enter the amount, approve, and send
4472

45-
### Using cast (Foundry)
73+
#### Using cast (Foundry)
4674

47-
Bridge USDC from Base to Tempo using `cast`. This calls `sendToken` on the Stargate pool on the source chain. This example uses [taxi mode](#bus-vs-taxi-mode) for immediate delivery.
75+
This example bridges USDC from Base to Tempo. Replace addresses for other tokens or source chains.
4876

49-
#### Step 1 — Get a quote fee estimate from Stargate router
50-
51-
Use the same parameters you will pass to `sendToken`. Returns `(nativeFee, lzTokenFee)`.
52-
Take the first returned number as `<NATIVE_FEE>`.
77+
##### Step 1 - Get a quote
5378

5479
```bash
5580
cast call 0x27a16dc786820B16E5c9028b75B99F6f604b5d26 \
@@ -59,9 +84,9 @@ cast call 0x27a16dc786820B16E5c9028b75B99F6f604b5d26 \
5984
--rpc-url https://mainnet.base.org
6085
```
6186

62-
#### Step 2 — Approve USDC on Base
87+
Take the first returned number as `<NATIVE_FEE>`.
6388

64-
Approve the Stargate router to spend USDC.
89+
##### Step 2 - Approve token on source chain
6590

6691
```bash
6792
cast send 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 \
@@ -72,34 +97,26 @@ cast send 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 \
7297
--private-key $PRIVATE_KEY
7398
```
7499

75-
#### Step 3 Send bridge transaction
100+
##### Step 3 - Send bridge transaction
76101

77102
```bash
78103
cast send 0x27a16dc786820B16E5c9028b75B99F6f604b5d26 \
79104
'sendToken((uint32,bytes32,uint256,uint256,bytes,bytes,bytes),(uint256,uint256),address)' \
80105
"(30410,$(cast abi-encode 'f(address)' <TEMPO_WALLET_ADDRESS>),<AMOUNT>,<MIN_AMOUNT>,0x,0x,0x)" \
81106
"(<NATIVE_FEE>,0)" \
82-
<SOURCE_BASE_ADDRESS> \
107+
<SOURCE_ADDRESS> \
83108
--value <NATIVE_FEE> \
84109
--rpc-url https://mainnet.base.org \
85110
--private-key $PRIVATE_KEY
86111
```
87112

88-
#### Step 4 — Verify transaction status
89-
90-
Track the bridge with the transaction hash returned by `sendToken`:
113+
##### Step 4 - Verify transaction status
91114

92115
```text
93116
https://scan.layerzero-api.com/v1/messages/tx/<SOURCE_TX_HASH>
94117
```
95118

96-
Once delivered, view the destination transaction on Tempo:
97-
98-
```text
99-
https://explore.tempo.xyz/tx/<DESTINATION_TX_HASH>
100-
```
101-
102-
### Using TypeScript (viem)
119+
#### Using TypeScript (viem)
103120

104121
```typescript
105122
import { createWalletClient, createPublicClient, http, parseUnits, pad } from 'viem'
@@ -219,7 +236,7 @@ const msgFee = await publicClient.readContract({
219236
args: [sendParam, false],
220237
})
221238

222-
// 2. Approve USDC
239+
// 2. Approve token
223240
await walletClient.writeContract({
224241
address: usdc,
225242
abi: erc20Abi,
@@ -237,18 +254,15 @@ await walletClient.writeContract({
237254
})
238255
```
239256

240-
## Bridge from Tempo
241-
242-
To bridge USDC.e from Tempo back to another chain, call `sendToken` on the **StargateOFTUSDC** contract on Tempo. The process is the same — quote, approve, send — but the source contract and destination EID are swapped.
257+
### Bridge from Tempo via Stargate
243258

244-
### Using cast (Foundry)
259+
To bridge from Tempo back to another chain, call `sendToken` on the Stargate OFT contract on Tempo. The process is the same - quote, approve, send - but the source contract and destination EID are swapped.
245260

246-
Bridge USDC.e from Tempo to Base using `cast`. This calls `sendToken` on the **StargateOFTUSDC** contract on Tempo. This example uses [taxi mode](#bus-vs-taxi-mode) for immediate delivery.
261+
#### Using cast (Foundry)
247262

248-
#### Step 1 — Quote the fee
263+
This example bridges USDC.e from Tempo to Base.
249264

250-
Use the same parameters you will pass to `sendToken`. Returns `(nativeFee, lzTokenFee)`.
251-
Take the first returned number as `<NATIVE_FEE>` (in stablecoin units, not ETH).
265+
##### Step 1 - Quote the fee
252266

253267
```bash
254268
cast call 0x8c76e2F6C5ceDA9AA7772e7efF30280226c44392 \
@@ -258,9 +272,9 @@ cast call 0x8c76e2F6C5ceDA9AA7772e7efF30280226c44392 \
258272
--rpc-url https://rpc.tempo.xyz
259273
```
260274

261-
#### Step 2 — Approve USDC.e on Tempo
275+
Take the first returned number as `<NATIVE_FEE>` (in stablecoin units, not ETH).
262276

263-
Approve the StargateOFTUSDC contract to spend USDC.e.
277+
##### Step 2 - Approve token on Tempo
264278

265279
```bash
266280
cast send 0x20C000000000000000000000b9537d11c60E8b50 \
@@ -271,9 +285,9 @@ cast send 0x20C000000000000000000000b9537d11c60E8b50 \
271285
--private-key $PRIVATE_KEY
272286
```
273287

274-
#### Step 3 Send bridge transaction
288+
##### Step 3 - Send bridge transaction
275289

276-
No `--value` is needed on Tempo the messaging fee is paid in a TIP-20 stablecoin via [EndpointDollar](#endpointdollar).
290+
No `--value` is needed on Tempo - the messaging fee is paid in a TIP-20 stablecoin via [EndpointDollar](#endpointdollar).
277291

278292
```bash
279293
cast send 0x8c76e2F6C5ceDA9AA7772e7efF30280226c44392 \
@@ -285,17 +299,13 @@ cast send 0x8c76e2F6C5ceDA9AA7772e7efF30280226c44392 \
285299
--private-key $PRIVATE_KEY
286300
```
287301

288-
#### Step 4 — Verify transaction status
289-
290-
Track the bridge with the transaction hash returned by `sendToken`:
302+
##### Step 4 - Verify transaction status
291303

292304
```text
293305
https://scan.layerzero-api.com/v1/messages/tx/<SOURCE_TX_HASH>
294306
```
295307

296-
Once delivered, view the destination transaction on the destination chain explorer.
297-
298-
### Using TypeScript (viem)
308+
#### Using TypeScript (viem)
299309

300310
```typescript
301311
import { createWalletClient, createPublicClient, http, parseUnits, pad } from 'viem'
@@ -310,7 +320,7 @@ const walletClient = createWalletClient({
310320
transport: http(),
311321
})
312322

313-
// StargateOFTUSDC on Tempo
323+
// Stargate OFT for USDC.e on Tempo
314324
const stargateOFT = '0x8c76e2F6C5ceDA9AA7772e7efF30280226c44392' as const
315325
// USDC.e on Tempo
316326
const usdce = '0x20C000000000000000000000b9537d11c60E8b50' as const
@@ -338,15 +348,15 @@ const msgFee = await publicClient.readContract({
338348
args: [sendParam, false],
339349
})
340350

341-
// 2. Approve USDC.e
351+
// 2. Approve token
342352
await walletClient.writeContract({
343353
address: usdce,
344354
abi: erc20Abi,
345355
functionName: 'approve',
346356
args: [stargateOFT, amount],
347357
})
348358

349-
// 3. Send the bridge transaction (no value fee handled via EndpointDollar)
359+
// 3. Send the bridge transaction (no value - fee handled via EndpointDollar)
350360
await walletClient.writeContract({
351361
address: stargateOFT,
352362
abi: stargateAbi,
@@ -355,36 +365,24 @@ await walletClient.writeContract({
355365
})
356366
```
357367

358-
## EndpointDollar
359-
360-
Tempo has no native gas token, so there is no `msg.value`. Standard LayerZero endpoints require `msg.value` to pay messaging fees, which doesn't work on Tempo.
361-
362-
**LZEndpointDollar** ([`0x0cEb237E109eE22374a567c6b09F373C73FA4cBb`](https://explore.tempo.xyz/address/0x0cEb237E109eE22374a567c6b09F373C73FA4cBb)) is an adapter contract that routes LayerZero messaging fees through a TIP-20 stablecoin instead of `msg.value`. It wraps the standard `EndpointV2` so that Stargate's OFT contracts can function on Tempo without modification.
363-
364-
This is transparent for end users:
365-
366-
- **Bridging to Tempo** — fees are paid in native gas on the source chain (ETH, MATIC, AVAX, etc.) as normal.
367-
- **Bridging from Tempo**`LZEndpointDollar` automatically deducts the messaging fee from a TIP-20 stablecoin. No `msg.value` is needed.
368-
- **Developers** don't need to interact with `LZEndpointDollar` directly. The StargateOFTUSDC contract handles it internally.
369-
370-
## Bus vs. Taxi mode
368+
### Bus vs. Taxi mode
371369

372370
Stargate offers two delivery modes:
373371

374372
| Mode | `oftCmd` | Delivery | Cost |
375373
|------|----------|----------|------|
376-
| **Taxi** | `0x` (empty) | Immediate message sent right away | Higher gas cost |
377-
| **Bus** | `0x00` (1 byte) | Batched waits for other passengers | Lower gas cost |
374+
| **Taxi** | `0x` (empty) | Immediate - message sent right away | Higher gas cost |
375+
| **Bus** | `0x00` (1 byte) | Batched - waits for other passengers | Lower gas cost |
378376

379-
All examples above use taxi mode for immediate delivery. To use bus mode, set `oftCmd` to `0x00`:
377+
All examples above use taxi mode. To use bus mode, set `oftCmd` to `0x00`:
380378

381379
```bash
382-
# cast bus mode
380+
# cast - bus mode
383381
oftCmd=0x00
384382
```
385383

386384
```typescript
387-
// viem bus mode
385+
// viem - bus mode
388386
const sendParam = {
389387
// ...
390388
oftCmd: '0x00' as const, // bus mode
@@ -395,9 +393,60 @@ const sendParam = {
395393
Bus mode is not available on all routes. If a bus route is not configured for your source/destination pair, the transaction will revert. Use taxi mode (`0x`) for guaranteed delivery.
396394
:::
397395

396+
## Standard OFT tokens
397+
398+
Tokens like USDT0, frxUSD, cUSD, and others are bridged using the standard LayerZero OFT `send()` interface. Each token issuer deploys their own OFT adapter contract. The `send()` interface uses the same `SendParam` struct as Stargate but calls `send()` instead of `sendToken()`.
399+
400+
To bridge a standard OFT token, you need the OFT adapter contract address on the source chain. Refer to the token issuer's documentation for their deployment addresses:
401+
402+
- **USDT0** - [Tether](https://tether.io)
403+
- **frxUSD** - [Frax](https://docs.frax.com)
404+
- **cUSD** - [Coinbase](https://docs.cdp.coinbase.com)
405+
406+
The flow is the same as Stargate - quote, approve, send - but you call `send()` on the OFT adapter instead of `sendToken()` on a Stargate pool:
407+
408+
```bash
409+
# Quote
410+
cast call <OFT_ADAPTER> \
411+
'quoteSend((uint32,bytes32,uint256,uint256,bytes,bytes,bytes),bool)((uint256,uint256))' \
412+
"(30410,$(cast abi-encode 'f(address)' <TEMPO_ADDRESS>),<AMOUNT>,<MIN_AMOUNT>,0x,0x,0x)" \
413+
false \
414+
--rpc-url <SOURCE_RPC>
415+
416+
# Approve
417+
cast send <TOKEN_ADDRESS> \
418+
'approve(address,uint256)' \
419+
<OFT_ADAPTER> \
420+
<AMOUNT> \
421+
--rpc-url <SOURCE_RPC> \
422+
--private-key $PRIVATE_KEY
423+
424+
# Send
425+
cast send <OFT_ADAPTER> \
426+
'send((uint32,bytes32,uint256,uint256,bytes,bytes,bytes),(uint256,uint256),address)' \
427+
"(30410,$(cast abi-encode 'f(address)' <TEMPO_ADDRESS>),<AMOUNT>,<MIN_AMOUNT>,0x,0x,0x)" \
428+
"(<NATIVE_FEE>,0)" \
429+
<REFUND_ADDRESS> \
430+
--value <NATIVE_FEE> \
431+
--rpc-url <SOURCE_RPC> \
432+
--private-key $PRIVATE_KEY
433+
```
434+
435+
## EndpointDollar
436+
437+
Tempo has no native gas token, so there is no `msg.value`. Standard LayerZero endpoints require `msg.value` to pay messaging fees, which doesn't work on Tempo.
438+
439+
**LZEndpointDollar** ([`0x0cEb237E109eE22374a567c6b09F373C73FA4cBb`](https://explore.tempo.xyz/address/0x0cEb237E109eE22374a567c6b09F373C73FA4cBb)) is an adapter contract that routes LayerZero messaging fees through a TIP-20 stablecoin instead of `msg.value`. It wraps the standard `EndpointV2` so that OFT contracts can function on Tempo without modification.
440+
441+
This is transparent for end users:
442+
443+
- **Bridging to Tempo** - fees are paid in native gas on the source chain (ETH, MATIC, AVAX, etc.) as normal.
444+
- **Bridging from Tempo** - `LZEndpointDollar` automatically deducts the messaging fee from a TIP-20 stablecoin. No `msg.value` is needed.
445+
- **Developers** don't need to interact with `LZEndpointDollar` directly. The OFT contracts on Tempo handle it internally.
446+
398447
## Further reading
399448

400-
- [Stargate documentation](https://stargateprotocol.gitbook.io/stargate/v2-developer-docs)
401449
- [LayerZero V2 documentation](https://docs.layerzero.network/v2)
450+
- [Stargate documentation](https://stargateprotocol.gitbook.io/stargate/v2-developer-docs)
402451
- [Bridges & Exchanges on Tempo](/ecosystem/bridges)
403452
- [Getting Funds on Tempo](/guide/getting-funds)

0 commit comments

Comments
 (0)