> For the complete documentation index, see [llms.txt](https://docs.rome.builders/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rome.builders/vi/huong-dan-cho-nha-phat-trien/from-home.md).

# Từ home: đến Rome từ một chuỗi khác

Cho phép người dùng trên chuỗi khác tiếp cận ứng dụng Rome của bạn mà không cần rời chỗ — đưa tài sản vào, thực hiện hành động, rồi mang chúng ra lại.

Người dùng của bạn không cần phải chuyển sang Rome. Từ chain nhà của họ — một L2 như Arbitrum hoặc Monad, hoặc Solana — họ mang tài sản vào, dùng ứng dụng Rome của bạn, rồi mang tài sản ra lại. Cầu nối nằm on-chain và được ủy quyền bằng chính chữ ký của người dùng; bạn kết nối ứng dụng của mình với nó qua một API.

## Cách nó hoạt động

* **Luồng vào (chain nhà → Rome):** trên lộ trình USDC bằng gas-token qua CCTP, `settle_inbound_bridge_v2` instruction của chương trình Rome ghi có cho người dùng, dưới một **EIP-712** `SettleAuthorization`, nên không có bộ giải quyết đặc quyền nào. Các lộ trình inbound khác không dùng instruction hay chữ ký đó. Wrapper USDC, ETH qua Wormhole và SOL sẽ đến thẳng dưới dạng token wrapper trong tài khoản của người dùng. USDC trên Solana ở một chain có gas token là USDC cần thêm một giao dịch nữa, do người dùng ký, để đổi wrapper thành gas. Báo giá sẽ cho bạn biết lộ trình cần những chữ ký nào.
* **Luồng ra (Rome → chain nhà):** `RomeBridgeWithdraw` (trong [`rome-solidity`](https://github.com/rome-protocol/rome-solidity)) đốt tài sản trên Rome. Sau đó người dùng tự nhận nó trên chain nhà bằng giao dịch của chính họ.
* **Vận chuyển:** Circle **CCTP** cho USDC và **Wormhole** cho cầu token của ETH. Các chain nhà Solana dùng chuyển SPL thông thường đi vào và một lệnh rút Rome đi ra. Wormhole là tuyến inbound chỉ dành cho ETH. Tồn tại một tuyến Wormhole tổng quát chỉ cho outbound, và mỗi tài sản trên đó phải được các operator của Rome bật trước.
* **Điều phối:** phần ngoài chuỗi [`rome-bridge-api`](https://github.com/rome-protocol/rome-bridge-api) đưa ra báo giá cho một lộ trình, xác minh giao dịch trên chain nguồn, và tài trợ phí settle. Nó không giữ tiền và cũng không giữ khóa nào. Nó chỉ có thể kích hoạt những gì người dùng đã ký trước đó.

## Xây dựng nó

API công khai trên devnet tại `https://bridge-api.devnet.romeprotocol.xyz`. `GET /v1/routes` liệt kê mọi lộ trình đang hoạt động (tài sản, tuyến, chiều, chain nguồn, chain Rome, tốc độ). Các lời gọi bên dưới chính là bốn hàm mà SDK bọc trong `@rome-protocol/sdk/bridge` (`requestQuote`, `registerTransfer`, `getTransfer`, `reportStep`). CLI chạy toàn bộ luồng cho bạn: `rome fund` và `rome bridge` cho các lần chuyển và `rome verify --path from-home` cho một chuyến đi khứ hồi, như mô tả trên [Rome CLI](/vi/san-pham/rome-cli.md) trang.

### Mang tài sản vào

1. **Lấy báo giá cho lộ trình.** Gửi chain nguồn, tài sản, số lượng và địa chỉ của người dùng. Chain được đưa vào dưới dạng ID CAIP-2 như `eip155:84532`; `romeChainId` là chain Rome của bạn. Các tên cũ `ethereum` và `solana` vẫn được chấp nhận nhưng đã lỗi thời, và API gắn các phản hồi đó với header `Sunset` . Dạng đầy đủ của request và response nằm trong [tài liệu API](https://github.com/rome-protocol/rome-bridge-api/blob/main/docs/API.md).

   ```bash
   curl -X POST https://bridge-api.devnet.romeprotocol.xyz/v1/quote \
     -H 'Content-Type: application/json' \
     -d '{
       "asset": "USDC",
       "direction": "to-rome",
       "sourceChain": "eip155:84532",
       "romeChainId": "200010",
       "amount": "1000000",
       "sender": { "ethereum": "0xUSER" },
       "recipient": "0xUSER"
     }'
   ```

   Số lượng là số nguyên theo đơn vị cơ sở trong chuỗi (`"1000000"` là 1 USDC). Số lượng ETH tính bằng wei và, khi rút ra, phải là bội số của 10.000.000.000 wei (wrapper có 8 chữ số thập phân); API sẽ từ chối mọi giá trị nhỏ hơn. Phản hồi liệt kê các `bước`. Người dùng ký các giao dịch của mọi bước được đánh dấu `userSigns: true`, theo thứ tự của bước: giao dịch EVM nằm trong `unsignedTxs`, các instruction Solana nằm trong `unsignedTx`. Ký đúng như những gì được trả về. Các bước không cần ký sẽ do sponsor thực hiện sau khi Circle hoặc Wormhole đã xác nhận transfer. Bước nhận ở outbound là ngoại lệ, được mô tả bên dưới: chính người dùng xây nó.
2. **Hãy để người dùng ký.** Với một báo giá CCTP thì đó là phê duyệt USDC và thao tác đốt trên chain nguồn. Nếu báo giá có mục trong `signatureRequests`, người dùng cũng ký EIP-712 đó `SettleAuthorization` một khi hash của burn đã được biết; điền hash của burn vào và truyền kết quả dưới dạng `userSettleSig` trong lời gọi tiếp theo. Chỉ tuyến CCTP dùng gas-token mới có. Các tuyến Wormhole ETH, USDC theo ý định wrapper và Solana thì không có.
3. **Đăng ký transfer.** `POST /v1/transfers` với toàn bộ báo giá và `step1TxHash`, hash của giao dịch cuối cùng ở bước đầu tiên (thao tác đốt). API kiểm tra giao dịch trên chain nguồn có khớp với báo giá hay không và trả về transfer `id`.
4. **Thăm dò** `GET /v1/transfers/{id}` mỗi vài giây cho đến khi `kết quả` là `hoàn tất`. Sau đó người dùng sẽ được cấp vốn trên Rome và có thể dùng ứng dụng của bạn.

Các chain nhà Solana tuân theo cùng cấu trúc nhưng các bước khác nhau. Người dùng gửi một chuyển SPL đến token account của tài khoản Rome của họ. Sau đó SOL đến dưới dạng wrapped SOL sau chuyển khoản đó. Trên một chain có gas token là USDC, như Hadrian, USDC cần một bước thứ hai: một giao dịch Rome do người dùng ký để biến wrapper đã đến thành gas gốc. Mọi token SPL khác đi qua `spl-solana-to-rome` lộ trình, lấy mint trong `splAsset`.

### Rút tài sản ra lại

Bridging out không phải là luồng inbound chạy ngược lại. Nó có nhiều hơn một chữ ký, và người dùng hoàn tất nó trên chain nhà. Hãy lấy báo giá với `direction` được đặt thành `from-rome`. `sourceChain` chỉ phía không phải Rome và `destinationChainId` chọn chain mà người dùng sẽ nhận. Truyền cả hai: `destinationChainId` là thứ quyết định chain nhận, và một báo giá không có nó sẽ mặc định là Ethereum Sepolia, bất kể `sourceChain` nói gì:

```bash
curl -X POST https://bridge-api.devnet.romeprotocol.xyz/v1/quote \
  -H 'Content-Type: application/json' \
  -d '{
    "asset": "USDC",
    "direction": "from-rome",
    "sourceChain": "eip155:84532",
    "destinationChainId": 84532,
    "romeChainId": "200010",
    "amount": "1000000",
    "sender": { "rome": "0xUSER" },
    "recipient": "0xUSER"
  }'
```

Với USDC qua CCTP, báo giá trả về hai bước, và người dùng ký cả hai:

1. **Trên Rome, hai giao dịch theo thứ tự.** Bước đầu tiên cấp `RomeBridgeWithdraw` quyền đại diện trên wUSDC của người dùng trên Solana (`approve_spl`). Quyền cấp bao phủ đúng bằng số lượng của lần đốt này, vì vậy báo giá luôn bao gồm nó và người dùng ký trước mỗi lần đốt. Bước thứ hai đốt wUSDC thông qua `RomeBridgeWithdraw`, bước này khởi động transfer CCTP. Đăng ký transfer với hash của lần đốt. Lần đốt tiêu tốn wUSDC, token mà báo giá gọi là `burnToken`, chứ không phải USDC gas gốc. Số tiền đến dưới dạng gas không phải là thứ bị đốt, vì vậy để đi khứ hồi hãy mang USDC vào với `intent: "wrapper"`.
2. **Trên chain đích, bước nhận.** Thăm dò `GET /v1/transfers/{id}` cho đến khi bước 2 `sẵn sàng`. Sau đó nó mang `message` và `attestation`. Người dùng gọi `receiveMessage(message, attestation)` trên message transmitter của Circle ở chain đích (báo giá nêu tên transmitter và CCTP domain). Không có gì được tài trợ ở đây, nên người dùng cần gas trên chain đó. Báo cáo hash của bước nhận với `POST /v1/transfers/{id}/steps/2`.

ETH qua Wormhole có cùng cấu trúc. Người dùng cấp cùng quyền đại diện trên wETH, đốt wETH trên Rome, và chờ Wormhole guardians ký. Sau đó người dùng đổi ra trên Ethereum bằng giao dịch của chính họ: `completeTransferAndUnwrapETH` trên token bridge mà báo giá nêu (`claimTokenBridge`), dùng signed message (`vaa`) từ bước 2.

Rút về một địa chỉ Solana thì không có bước nhận. USDC là một giao dịch Rome duy nhất rút về account Solana của người dùng. SOL là một bước Rome với ba giao dịch: cấp quyền đại diện tương tự trên wSOL, tạo tùy chọn token account wSOL của người nhận trên Solana (bỏ qua nếu nó đã tồn tại), và thao tác rút qua `RomeBridgeWithdraw`.

**Lần chuyển ra đầu tiên cần một tài khoản đã được kích hoạt.** Một burn CCTP tạo ra một message account trên Solana, và tài khoản của người dùng trên Rome phải có đủ lamport để trả cho nó. Một ví mới thì không, nên lần chuyển ra đầu tiên sẽ thất bại cho đến khi người dùng kích hoạt một lần. Điều cần kiểm tra là tài khoản có ít nhất 15.000.000 lamport. Đọc chúng bằng `account_lamports(bytes32)` trên CPI precompile tại `0xff00000000000000000000000000000000000008`, truyền vào external-auth account của người dùng trên Solana (CLI sẽ làm thao tác đọc này cho bạn). Việc kích hoạt gọi `activate()` trên `SimpleActivator` hợp đồng được liệt kê trong [registry](https://github.com/rome-protocol/rome-registry) cho chain của bạn, và lời gọi này mang theo một khoản thanh toán bằng gas token của chain. Trên Hadrian, đó là 2 USDC. CLI làm việc này bằng `rome activate <chain>`, và `rome bridge --to` sẽ dừng và bảo bạn chạy nó nếu tài khoản chưa sẵn sàng. Kho dự trữ đủ cho một lần đốt, và tiền thuê sẽ quay lại sau khi Circle xác nhận burn, việc này mất khoảng 30 phút. Một lần đốt thứ hai trước khi việc đó xong, hoặc một tài khoản đã bị rút cạn kể từ khi được kích hoạt, sẽ cần `topUpUserPda(lamports)` trên cùng hợp đồng đó, vì `activate()` sẽ revert một khi tài khoản đã được kích hoạt. `rome activate` sẽ chọn đúng lời gọi. Các transfer inbound không cần kích hoạt. Báo giá không bao gồm kích hoạt như một bước, vì vậy ứng dụng của bạn phải kiểm tra tài khoản và đề xuất nó trước báo giá outbound đầu tiên.

## Đọc mã

* [appia](https://github.com/rome-protocol/appia) — một ứng dụng from-home: người dùng mang USDC từ chain nhà của họ và dùng DeFi ở phía Rome mà không cần rời khỏi nó.
* [rome-bridge-api](https://github.com/rome-protocol/rome-bridge-api) — bộ điều phối (báo giá → xác minh → tài trợ).

## Tiếp theo là gì

* [Được cấp vốn](/vi/tai-nguyen/faucets.md) — cùng đường cầu nối đó có thể cấp vốn cho một ví dev mới.
* [Triển khai Solidity](/vi/huong-dan-cho-nha-phat-trien/deploy-solidity.md) — đưa ứng dụng của bạn lên Rome.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.rome.builders/vi/huong-dan-cho-nha-phat-trien/from-home.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
