> 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/ru/rukovodstva-dlya-razrabotchikov/open-to-solana-users.md).

# Откройте ваш контракт для пользователей Solana

Разверните контракт Solidity в Rome (тестовая сеть Hadrian, основная сеть Rubicon) и откройте его для кошельков Solana — что требуется контракту, как пользователь кошелька Solana вызывает его, адреса для каждой сети и запуск ch

Одна развертка, два типа пользователей. До контракта в Rome могут достучаться пользователи MetaMask со своим EVM-ключом и пользователи кошельков Solana (например, Solflare) со своим ключом Solana — тот же адрес, то же состояние. Эта страница описывает полный путь: развернуть, подготовить контракт к работе с Solana, подключить Solana-канал в вашем приложении и выпустить в mainnet.

## 1. Разверните в нужной сети

Цепочки Rome — стандартные EVM-цели: Hardhat, Foundry, viem и ethers работают без изменений (полное руководство в [Развертывание Solidity-контрактов](/ru/rukovodstva-dlya-razrabotchikov/deploy-solidity.md)).

| Сеть                                         | ID цепочки | RPC                                         | Обозреватель                                                                          | Токен газа    | Как получить газ                                                                                                                                                          |
| -------------------------------------------- | ---------- | ------------------------------------------- | ------------------------------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [**Rubicon**](/ru/seti/rubicon.md) (mainnet) | `7531`     | `https://rubicon.mainnet.romeprotocol.xyz/` | [via-rubicon.mainnet.romeprotocol.xyz](https://via-rubicon.mainnet.romeprotocol.xyz/) | USDC          | Переведите USDC из Ethereum (CCTP) или из Solana с помощью [моста Rome](https://bridge-api.mainnet.romeprotocol.xyz/); он зачисляется как газ                             |
| **Hadrian** (testnet)                        | `200010`   | `https://hadrian.testnet.romeprotocol.xyz/` | [via-hadrian.testnet.romeprotocol.xyz](https://via-hadrian.testnet.romeprotocol.xyz/) | тестовый USDC | Переведите тестовый USDC из тестовой сети ([Краны](/ru/resursy/faucets.md)) или заверните его из кошелька Solana devnet в [Rome App](https://app.devnet.romeprotocol.xyz) |

Газ — это USDC с 18 десятичными знаками на стороне EVM; на какой-либо сети Rome faucet отсутствует. Операции записи стоят больше газа, чем подсказывает интуиция по Ethereum, поскольку основная часть стоимости уходит на создание аккаунтов Solana: адресата, который никогда не использовался, нового токен-аккаунта, развернутого контракта. Используйте `eth_estimateGas`, что и делают стандартные инструменты, и никогда не хардкодьте 21 000. На Hadrian при измерении развертывание контракта размером 10 байт потребовало по оценке и использовало 1 147 921 gas, а нативный перевод на адрес, который никогда не использовался, — 1 086 961, против 21 000 за перевод на уже существующий адрес. Rome списывает фактически использованный газ, который в этих измерениях никогда не превышал оценку. Перед первым развертыванием пополните несколько USDC. После этого проверьте исходный код в обозревателе ([Проверить контракты](/ru/rukovodstva-dlya-razrabotchikov/verify-contracts.md); основной верификатор mainnet — это `https://verify.mainnet.romeprotocol.xyz`).

Разрабатывайте на Hadrian, затем повторно разверните те же артефакты в Rubicon, подменив chain id и адреса основных wrapper'ов mainnet; в контракте между сетями ничего не меняется. Rubicon пока не в публичном реестре, `create-rome-app` или `rome-cli` поэтому инструменты, которые читают значения сети оттуда, не могут нацелиться на нее; заполните значения вручную из [Rubicon](/ru/seti/rubicon.md). Газ в Rubicon — это реальный USDC примерно по цене газа в Hadrian, умноженной на десять, так что развертывание там стоит реальных денег.

## 2. Что делает контракт готовым к Solana

EVM-идентичность пользователя Solana — это его **синтетический адрес**, `keccak256(solana_pubkey)[12:]`: обычный `msg.sender`, с обычным nonce. Большинству контрактов вообще не нужны изменения. Важны три вещи:

* **Принимайте стоимость в ERC-20, а не в `msg.value`.** Средства пользователя Solana — это SPL-токены в его кошельке, которые на стороне EVM видны как wrapper токена (`wUSDC`, `wETH`, `wSOL`). Синтетический адрес не хранит ничего в покое, а активы пользователя поступают в виде wrapper'а, поэтому извлекайте их с помощью `transferFrom` после `approve` и возвращайте с помощью `transfer`. Каждый пользователь один раз предоставляет wrapper'у право SPL delegate перед первым извлечением ([Однократно: предоставьте обёртке](/ru/rukovodstva-dlya-razrabotchikov/dual-lane-app.md#one-time-grant-the-wrapper)). `payable` входная точка работает только после того, как синтетическому адресу был выделен нативный газ (в пути ретрансляции это `rome_composeExternalDepositV1`), чего модель пополнения и вывода не делает. Существующий vault ERC-20, AMM или рынок кредитования уже имеет нужную структуру.
* **Используйте канонические wrapper'ы.** В каждой сети на один mint приходится один wrapper; адреса находятся в [справочнике Contract Addresses](/ru/spravochnik/contract-addresses.md) (у Hadrian это также есть в публичном [реестре](https://github.com/rome-protocol/rome-registry)). Указывайте в конструкторах эти адреса; не развертывайте собственные.
* **Укладывайтесь в атомарный бюджет там, где кошелек ставит подпись.** Кошелек Solana подписывает одну транзакцию Solana, поэтому вызов по Solana-каналу должен в нее укладываться: около 1,4 млн compute units, 64 аккаунта, 4 КБ ([Ограничения](/ru/klyuchevye-ponyatiya/constraints.md)). На Hadrian измерения показывают: перевод, approve и supply для Aave укладываются; swap Uniswap V3 тоже укладывается, но с небольшим запасом (около 1,24 млн CU); borrow для Aave не укладывается и переходит на путь ретрансляции в следующем разделе. Измеряйте по полю Solana-чеки `computeUnitsConsumed`, запрашивая транзакцию с `maxSupportedTransactionVersion: 1` (legs Rome — это транзакции v1; без этого поле показывает 0).

Что вам не нужно: программа Solana, мост, второе развертывание или какой-либо специфичный для Rome Solidity. Если контракт также вызывает программы Solana через precompile, см. [Вызов Solana из EVM](/ru/rukovodstva-dlya-razrabotchikov/call-solana-from-evm.md).

## 3. Позвольте кошельку Solana вызывать его

EVM-путь вашего приложения не меняется (MetaMask + `submitRomeTx`, или обычные viem/ethers).

**Путь SDK — одна транзакция Solana v1 на один вызов.** [`@rome-protocol/sdk`](https://github.com/rome-protocol/rome-sdk-ts) (`submitRomeTxV1`) позволяет прокси собрать одну транзакцию Solana v1 для вашего EVM-вызова (до 64 аккаунтов и 4 КБ, без address lookup table; в вашем коде нет инструкций ComputeBudget, treasure wallet или обнаружения аккаунтов). Кошелек подписывает дважды одним и тем же ключом: сначала читаемое сообщение авторизации (`Авторизация Rome` в одной строке, `0x` и хеш транзакции EVM на следующей строке), который сеть проверяет через программу Ed25519, а затем — саму транзакцию. Приложение отправляет подписанную транзакцию в Solana RPC; вызов возвращает хеш транзакции EVM и ее квитанцию. Перед тем как кошелек подпишет транзакцию, SDK ее проверяет: плательщик — единственный подписант, выполняются только программа Rome и верификатор Ed25519, инструкция Rome содержит именно тот вызов, который авторизовал пользователь, и никакой priority fee нет. Во всех остальных случаях запрос отклоняется.

Если вызов не помещается в одну транзакцию, композер отклоняет его, а SDK передает его прокси на ретрансляцию с той же подписью авторизации, так что пользователь по-прежнему видит один запрос на авторизацию. Тогда результат имеет `route: "relay"`. Правила для ретранслируемых и длинных вызовов приведены в [Ретранслируемые вызовы и длинные вызовы](/ru/rukovodstva-dlya-razrabotchikov/call-evm-from-solana.md#relayed-calls-and-long-calls). Ретранслируемый вызов оплачивается нативным газом сети, поэтому синтетическому адресу нужен баланс газа: `fundSyntheticGas(deps, amountWei)` перемещает газовый токен сети (USDC в Hadrian и Rubicon) из токен-аккаунта кошелька на него, в одной подписанной кошельком транзакции v1.

Этап пополнения (`buildFundLeg`) и создание токен-аккаунта кошелька перед sweep — это обычные инструкции Solana; `submitSolanaInstructionsV1` также отправляет их как транзакции v1, подписанные тем же кошельком, без участия прокси. Сам вызов sweep (`buildSweepLeg`, `HelperProgram.transfer_spl`проходит через `submitRomeTxV1` как и любой другой, а прокси находит токен-аккаунты. `submitRomeTxV1` сам по себе не создает новый аккаунт синтетического адреса: перед первым вызовом, который перемещает средства, проверьте `isSyntheticProvisioned(...)",` и, если это false, отправьте `buildCreatePdaCall(synthetic)` через `submitRomeTxV1` один раз. Полное пошаговое руководство по внесению и выводу с кодом находится в [Создание приложения с двумя каналами](/ru/rukovodstva-dlya-razrabotchikov/dual-lane-app.md); механика описана в [Вызов EVM из Solana](/ru/rukovodstva-dlya-razrabotchikov/call-evm-from-solana.md). Ранее `submitRomeTxSolanaLane`, который собирает устаревшую транзакцию Solana в клиенте, и по-прежнему есть в SDK как более старый путь.

**Откуда берется каждое `deps` значение.** У SDK `deps` объект имеет пять обязательных полей (остальные, такие как `fetchImpl` и тайм-ауты, являются необязательными).

| `deps` поле  | Откуда оно берётся                                                                                               | Геттер реестра (`@rome-protocol/registry` v0.2.0)                                                          |
| ------------ | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `proxyUrl`   | RPC-URL сети                                                                                                     | `getChain(chainId).rpcUrl`                                                                                 |
| `chainId`    | ID сети                                                                                                          | `getChain(chainId).chainId`                                                                                |
| `programId`  | ID программы Rome, на которой работает сеть                                                                      | `getChain(chainId).romeEvmProgramId`                                                                       |
| `соединение` | Solana RPC для кластера сети, куда отправляется подписанная транзакция (devnet для Hadrian, mainnet для Rubicon) | `getChain(chainId).solana.rpc` (публичный devnet URL для Hadrian); для mainnet используйте собственный RPC |
| `подписант`  | кошелька `LaneSigner`, или `Keypair` в скриптах                                                                  | нет                                                                                                        |

Конструкторы leg принимают значения, которых нет в `deps`. Их `mint` (называемое `usdcMint` в пошаговом руководстве) — это mint Solana для газового токена, из `getTokens(chainId)` (запись с `kind: "gas"`, поле `mintId`). Адрес wrapper'а wUSDC не является входным параметром конструктора leg; вы используете его для вызовов ERC-20, и это запись с `kind: "spl_wrapper"` и символом `wUSDC` (поле `address`). Реестр охватывает Hadrian. Для Rubicon заполните их вручную: `proxyUrl` `https://rubicon.mainnet.romeprotocol.xyz/`, `chainId` `7531`, `programId` `RomePq9X3iAoTr813HR7uRarafFDUJty6GdiEceYpzX`, `mint` `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v`, wrapper из таблицы в следующем разделе и Solana mainnet RPC для `соединение`. [Rubicon](/ru/seti/rubicon.md) содержит полный список.

**Внешние endpoints V1 прокси — тот же канал без SDK.** SDK оборачивает атомарную сборку, ретрансляцию и внесение газа (`fundSyntheticGas`). Сырые RPC-методы остаются для клиентов, которые не используют SDK, и включают итеративную сборку, которую SDK не оборачивает. Кошелек подписывает одно сообщение Ed25519 по вызову (читаемая форма `Авторизация Rome\n0x<hash>` или необработанный хеш), а прокси либо собирает транзакцию(и) Solana для подписи кошельком (`rome_composeUnsignedAtomicV1`, `rome_composeUnsignedIterativeV1` + `rome_submitSignedV1Plan`) либо выполняет все самостоятельно с одной подписью кошелька (`rome_relayUnsignedV1`, после `rome_composeExternalDepositV1` (в SDK это `fundSyntheticGas`) пополняет баланс газа синтетического адреса; ретранслируемые вызовы расходуют его, так что пополняйте его, когда он подходит к концу). [Поддержка JSON-RPC](/ru/spravochnik/json-rpc.md)Формы методов в [Вызов EVM из Solana](/ru/rukovodstva-dlya-razrabotchikov/call-evm-from-solana.md#the-external-v1-endpoints). Правила авторизации приведены в

В любом случае контракт видит обычную транзакцию от синтетического адреса, и пользователь никогда не хранит EVM-ключ.

## 4. Адреса wrapper'ов для каждой сети

| Сеть             | `wUSDC` wrapper                              | Другие wrapper'ы                                                                                         |
| ---------------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| Rubicon (7531)   | `0x0952d233b0c254cd375f3bfb3e5869c1a906f9b3` | `wETH` `0x01e8b3573da1d4b7b4b1ce0932cf07c8af0c92e9`, `wSOL` `0xc4e29e0f726a906e93277cbbc37bf27a9848a113` |
| Hadrian (200010) | `0xbce339ba4c3a8de3bb8af1c5539e6ac11da3112d` | `wETH` `0x02aeace038269f9961c93d04dcacd6fb3adfa55f`, `wSOL` `0x39f36444fcb79b3e691544aee2a832ebef54ca9f` |

Нативный газовый токен отображается как `0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee` в списках токенов; это не контракт ERC-20. Wrapper'ы наследуют decimals SPL mint, а не 18: wUSDC — 6, wETH — 8, wSOL — 9.

## 5. Контрольный список перед запуском

1. Развернуто в Hadrian; EVM-путь работает из MetaMask.
2. Каждая входная точка, перемещающая средства, основана на ERC-20 и указывает на канонический wrapper сети.
3. Кошелек Solana, подписывающий транзакции v1 (Solflare уже делает это в devnet; Phantom пока нет), завершает полный цикл на Hadrian: подготовить синтетический адрес (`create_pda`, один раз) → этап пополнения → grant → approve → вызов → этап sweep, используя путь SDK; или путь ретрансляции, если вызов итеративный.
4. У каждого вызова по Solana-каналу `computeUnitsConsumed` значение читается из квитанции Solana и укладывается в атомарный бюджет, либо вызов направляется через ретрансляцию.
5. Предоставление доступа wrapper'у находится в потоке первого депозита вашего приложения для обоих каналов: `isEnabled(user)` проверяется и `approve_spl` отправляется один раз, когда это false ([Однократно: предоставьте обёртке](/ru/rukovodstva-dlya-razrabotchikov/dual-lane-app.md#one-time-grant-the-wrapper)).
6. Исходный код проверен в обозревателе.
7. Повторно развернуто в Rubicon с адресами wrapper'ов mainnet. Rubicon отсутствует в реестре, поэтому его `deps` значения заполняются вручную из [Rubicon](/ru/seti/rubicon.md). Тот же полный цикл один раз выполняется с реальными средствами, используя кошелек, который, как вы проверили, подписывает транзакции v1 в mainnet.

## Что дальше

* [Создание приложения с двумя каналами](/ru/rukovodstva-dlya-razrabotchikov/dual-lane-app.md) — пример vault'а, шаг за шагом, оба кошелька
* [Вызов EVM из Solana](/ru/rukovodstva-dlya-razrabotchikov/call-evm-from-solana.md) — синтетические адреса, обнаружение аккаунтов, внешние endpoints V1
* [Развертывание Solidity-контрактов](/ru/rukovodstva-dlya-razrabotchikov/deploy-solidity.md) · [Проверить контракты](/ru/rukovodstva-dlya-razrabotchikov/verify-contracts.md) · [справочнике Contract Addresses](/ru/spravochnik/contract-addresses.md)


---

# 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/ru/rukovodstva-dlya-razrabotchikov/open-to-solana-users.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.
