> 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/ar/adlh-almtw-ryn/call-evm-from-solana.md).

# استدعاء EVM من Solana

اسمح لمحفظة Solana بتشغيل عقود EVM على Rome — من دون مفتاح Ethereum. المحفظة توقّع، وتنتقل معاملتها إلى Solana.

العكس لـ [استدعِ Solana من EVM](/ar/adlh-almtw-ryn/call-solana-from-evm.md): محفظة سولانا (على سبيل المثال Solflare) تستدعي أي عقد EVM على Rome مباشرةً، مع **لا يوجد مفتاح إيثريوم**. هكذا [Aerarium](/ar/alttbyqat-ala-rome/apps.md) يتيح لمستخدمي سولانا الأصليين مشاركة العقود نفسها مع مستخدمي EVM.

الطريقة ذات الاستدعاء الواحد هي الخاصة بـ SDK `submitRomeTxV1`، حيث يقوم البروكسي بتركيب معاملة Solana v1 واحدة للاستدعاء؛ تشرح هذه الصفحة الآلية.

## العناوين الاصطناعية

هوية EVM لمحفظة سولانا هي **العنوان الاصطناعي** — آخر 20 بايت من `keccak256` للمفتاح العام لسولانا ذي 32 بايت:

```
synthetic_evm_address = keccak256(solana_pubkey)[12:]
```

هذا هو `msg.sender` عندما تستدعي المحفظة عقدًا، والهوية المستقرة التي يوجد تحتها الـ nonce والتخزين. الاشتقاق مثبت في البروتوكول، لذا تُطابَق المحفظة دائمًا مع العنوان نفسه.

```javascript
import { syntheticAddress } from "@rome-protocol/sdk";
const from = syntheticAddress(solanaPubkey); // 0x… 20 bytes
```

## العنوان الاصطناعي مجرد وسيط — لا يحتفظ بأي توكنات وهو في حالة سكون

الرصيد القابل للإنفاق لمستخدم سولانا الأصلي يوجد في **محفظة Solana** (كتوكنات SPL)، ويُعرض بنسبة 1:1 على جانب EVM باعتباره **غلاف ERC20SPL** (مثل `wUSDC`). لا يحتفظ العنوان الاصطناعي بشيء في حالة السكون، لذا تتدفق القيمة *من خلال* عبره — وكل خطوة موقعة من محفظة سولانا:

1. **التزويد (مرة واحدة).** لا يوجد PDA الخاص بالمصادقة الخارجية لعنوان اصطناعي جديد تمامًا حتى `create_pda` يعمل — وتُوقَّع التحويلات أدناه بواسطة ذلك الـ PDA. `submitRomeTxSolanaLane` يُنشئه تلقائيًا عند أول استخدام (أو استدعِ `provisionSynthetic` لخطوة "تفعيل" صريحة؛ تحقّق باستخدام `isSyntheticProvisioned`). مع `submitRomeTxV1`، تحقّق من `isSyntheticProvisioned` وأرسل `buildCreatePdaCall` عبره مرة واحدة.
2. **مرحلة التمويل (المحفظة → العنوان الاصطناعي).** انقل التوكن من ATA الخاص بالمحفظة إلى الخاص بالعنوان الاصطناعي — خطوة `ActivateAta` ، المبنية بواسطة `buildFundLeg`. الآن `wrapper.balanceOf(synthetic)` يقرأ ذلك الرصيد، فينفقه العنوان الاصطناعي كتوكين ERC-20 عادي (`transfer` / `transferFrom`) — **وليس** كـ native `msg.value`، وهو لا يحتفظ به.
3. **الاستدعاء(ات) (`DoTxUnsigned`).** ينفذ العنوان الاصطناعي معاملة/معاملات EVM — مثلًا `approve` ثم خزنة `deposit` تسحب عبر `transferFrom`.
4. **مرحلة السحب (العنوان الاصطناعي → المحفظة).** بعد أن يودِع سحب / اقتراض / مطالبة توكنات في العنوان الاصطناعي، `buildSweepLeg` يدفعها مرة أخرى إلى ATA الخاص بمحفظة المستخدم (`HelperProgram.transfer_spl`)، بحيث ينتهي صافي العنوان الاصطناعي إلى لا شيء.

القسم التالي يصف ما الذي يفعله الأقدم `submitRomeTxSolanaLane` يبنيه على جهة العميل. `submitRomeTxV1` يجعل البروكسي يركّب معاملة v1 بدلًا من ذلك، من دون اكتشاف الحسابات أو ComputeBudget أو محفظة الخزينة في كودك؛ انظر [نقاط نهاية external-V1](#the-external-v1-endpoints) أدناه.

## كيف يُبنى الاستدعاء

`submitRomeTxSolanaLane` يتكفل بكل هذا. الآلية:

1. **أنشئ معاملة EIP-1559 غير موقعة** مع `from` = العنوان الاصطناعي — من دون توقيع secp256k1.
2. **اكتشف الحسابات** — استدعِ [`rome_emulateCallAccounts`](/ar/almrja/json-rpc.md) مع `from`, `إلى`, `البيانات`, **و `القيمة`** (عندما يكون الاستدعاء قابلًا للدفع). إن تمرير `القيمة` مهم: يقوم البروكسي بمحاكاة *الفعلي* الاستدعاء، لذا يتم تخصيص أي كتابة تخزين تعتمد على القيمة — مثلًا خانة mapping جديدة — ويُعاد حساب سولانا الخاص بها. احذفه فيغيب ذلك الحساب، وتفشل المعاملة مع *"instruction modified data of a read-only account."*
3. **جمّع معاملة سولانا:** اثنتان من **ComputeBudget** تعليمات (تحتاج EVM الخاصة بـ Rome إلى حد CU أعلى ≈1.35M وإطار heap كبير ≈250 KB — وإعدادات سولانا الافتراضية تفشل) + **`DoTxUnsigned`** التعليمات (RLP غير الموقّع + الحسابات المكتشفة) + حسب السلسلة **محفظة الخزينة** (تدفع لها عملية التنفيذ رسمًا صغيرًا؛ والاكتشاف يستثنيها، لذا يضيفها SDK).
4. **توقّع المحفظة وتُرسل.** الـ **توقّع محفظة سولانا معاملة سولانا (Ed25519) وترسلها إلى Solana RPC — وليس إلى البروكسي.** يتحقق وقت تشغيل سولانا من التوقيع؛ وعلى السلسلة، يشتق البرنامج `msg.sender` من ذلك الموقّع. السلطة هي توقيع سولانا، وليس توقيع إيثريوم. (يُستخدم البروكسي فقط للمحاكاة/الاكتشاف في الخطوة 2.)

يملك PDA الخاص بالمستخدم (`["EXTERNAL_AUTHORITY", synthetic_address]`) حسابات التوكن الخاصة به ويوقّع استدعاءات CPI الخاصة بـ SPL نيابةً عنه — لذا يمكن لمستخدم سولانا الإيداع والاقتراض والمبادلة وتوفير السيولة LP بالكامل من محفظة سولانا الخاصة به.

## نقاط نهاية external-V1

`submitRomeTxV1` هي طريقة الاستدعاء الواحد: تطلب من البروكسي معاملة v1 مركبة، وتتحقق منها، وتطلب من المحفظة توقيعها وترسلها إلى Solana RPC، مع الترحيل عبر البروكسي عندما لا يتسع الاستدعاء. يوفّر البروكسي المسار نفسه كطرائق RPC، لذا يمكن لأي عميل استخدامه من دون SDK (القائمة الكاملة في [دعم JSON-RPC](/ar/almrja/json-rpc.md)):

* `rome_composeUnsignedAtomicV1(rlp, pubkey, signature)` — معاملة Solana v1 واحدة؛ توقّعها المحفظة ويقوم التطبيق ببثها إلى Solana RPC. تُرفض عندما لا يتسع الاستدعاء لمعاملة ذرية واحدة.
* `rome_composeUnsignedIterativeV1(rlp, pubkey, signature)` — كل مرحلة من التنفيذ (ذرية إن اتسعت، وإلا المراحل التكرارية)؛ توقّع المحفظة كل واحدة، `rome_submitSignedV1Plan` وتبثها. القيود على الخطة الطويلة موجودة في [الاستدعاءات المُرحَّلة والاستدعاءات الطويلة](#relayed-calls-and-long-calls).
* `rome_relayUnsignedV1(rlp, pubkey, signature)` — توقيع محفظة واحد، ويتولى دافع البروكسي تنفيذ المراحل ويعيد تجزئة معاملة EVM؛ يدفع العنوان الاصطناعي رسوم غاز Rome، لذا موّله مرة واحدة باستخدام `rome_composeExternalDepositV1`.

**توقيع التفويض.** `rlp` هو جسم EIP-1559 غير الموقّع الخام ذو الحقول التسعة. وتوقّع المحفظة، باستخدام مفتاح Ed25519 الخاص بها، إمّا 32 بايت الخام `keccak256(0x02 ‖ rlp)` أو الرسالة المقروءة

```
تفويض Rome\n0x<64 lowercase hex chars of that hash>
```

كلاهما مقبول؛ والصيغة المقروءة هي ما تعرضه المحفظة بشكل واضح في `signMessage` نافذة المطالبة. يعيد البرنامج حساب التجزئة من الجسم الذي ينفذه ويشترط أن تكون الرسالة الموقعة إحدى الصيغتين بالضبط، لذلك لا يمكن لتوقيع على جسمٍ ما أن يخوّل جسمًا آخر أبدًا، كما أن nonce الخاص بالجسم يمنع إعادة التشغيل.

## الاستدعاءات المُرحَّلة والاستدعاءات الطويلة

بعض الاستدعاءات لا تتسع لمعاملة سولانا واحدة. يشرح هذا القسم ما الذي يحدث حينها، وما القيود التي تنطبق.

### عندما يرفض المركِّب الذري

`rome_composeUnsignedAtomicV1` يرفض استدعاءً لا يتسع لمعاملة ذرية واحدة. `submitRomeTxV1` ثم يرحّل الاستدعاء عبر البروكسي باستخدام **نفس** توقيع التفويض، لذلك لا يُطلب من المحفظة مرةً ثانية. وتكون النتيجة ذات `route: "relay"` ولا يوجد توقيع `سولانا`. مرّر `relayOnRefusal: false` للحصول على الرفض كخطأ بدلًا من ذلك، أو استدعِ `relayV1` بنفسك للترحيل عمدًا.

ثلاثة أشياء يجب معرفتها عن الاستدعاء المُرحَّل:

* **يدفع العنوان الاصطناعي الغاز.** في مسار الترحيل، يرسل البروكسي معاملات سولانا ويدفع ثمنها، ويُدفع ثمن الاستدعاء بعملة الغاز الأصلية للسلسلة من رصيد العنوان الاصطناعي. يجب أن يكون الرصيد على الأقل `gasLimit × maxFeePerGas`. `fundSyntheticGas(deps, amountWei)` يضيف إليه من حساب التوكن الخاص بالمحفظة لعملة الغاز في السلسلة (USDC على Hadrian وRubicon)؛ وتوقّع المحفظة معاملة v1 عادية واحدة، وتحتاج إلى بعض SOL لرسوم سولانا. `amountWei` هي بوحدة wei ذات 18 خانة عشرية الخاصة بالسلسلة ويجب أن تكون مضاعفًا لـ 10^12، وإلا يرفضها البروكسي. من دون SDK، `rome_composeExternalDepositV1` يبني المعاملة نفسها.
* **لا يطرح الـ revert استثناءً.** الاستدعاء المُرحَّل الذي يَرتد على جانب EVM يُحَلّ بشكل طبيعي، مع `receipt.status === "0x0"`. تحقّق من `receipt?.status === "0x1"` قبل اعتبار الاستدعاء منتهيًا. `الإيصال` هو `null` إذا لم يظهر الإيصال في الوقت المناسب.
* **`relayOnRefusal: false` هذا خيار يُتخذ في SDK، وليس قيدًا.** لدى البروكسي بالفعل توقيع التفويض لتلك الحمولة ويمكنه تنفيذها بأي من المسارين، حتى `gasLimit × maxFeePerGas`.

```javascript
const res = await submitRomeTxV1(deps, { to, data, value });
if (res.route === "relay" && res.receipt?.status !== "0x1") {
  // الاستدعاء المُرحَّل الذي ارتد يُحلّ؛ لا يطرح استثناءً
}
```

### الاستدعاءات الطويلة

الاستدعاء الذي يحتاج أكثر من معاملة يعمل كجلسة تكرارية: ينفذ البرنامج أكبر عدد ممكن من خطوات EVM التي تتسع في كل معاملة سولانا ويحفظ حالته بينهما. وهناك طريقتان لتشغيله من محفظة سولانا:

* **رحّله.** `rome_relayUnsignedV1` يأخذ توقيع محفظة واحدًا ويتولى دافع البروكسي إرسال كل مرحلة. ويدفع العنوان الاصطناعي الغاز، كما سبق.
* **وقّع المراحل بنفسك.** `rome_composeUnsignedIterativeV1` يعيد كل مرحلة مع خانة توقيع فارغة، وتوقّع المحفظة كل واحدة، و `rome_submitSignedV1Plan` تبثها بالترتيب. كل مرحلة معاملة سولانا مستقلة لتوقّعها المحفظة، لذا فإن المحفظة التي توقّع معاملة واحدة في كل مرة ستطلب موافقة واحدة لكل مرحلة، إضافةً إلى توقيع التفويض. وتدفع المحفظة رسوم سولانا على كل مرحلة.

القيود:

| الحد                                                        | القيمة           | مصدره                                                                                                     |
| ----------------------------------------------------------- | ---------------- | --------------------------------------------------------------------------------------------------------- |
| المعاملات في استدعاء واحد `rome_submitSignedV1Plan` استدعاء | 64               | يرفض البروكسي خطة أطول                                                                                    |
| المراحل التي سيخطط لها المركِّب التكراري                    | 128              | الحد في المركِّب التكراري لـ Rust Rome SDK، والذي يحدّ الخطة أيضًا `rome_composeUnsignedIterativeV1` يعيد |
| التكرارات في جلسة واحدة                                     | 160              | برنامج Rome EVM؛ بعده تتوقف الجلسة عن الاستئناف، وتحرر أقفال الحسابات وتنتهي                              |
| حجم معاملة سولانا والحسابات                                 | 4 KB، 64 عنوانًا | كل مرحلة هي معاملة Solana v1                                                                              |

تستقر معظم الاستدعاءات الحقيقية في مراحل أقل بكثير من هذه الحدود. حد 64 معاملة في الخطة الموقعة من المحفظة هو الحد الذي ستواجهه أولًا. الاستدعاء الذي يحتاج إلى مراحل أكثر من ذلك لا يمكن بثه عبر `rome_submitSignedV1Plan`.

الاستدعاء الطويل لا يمكنه إجراء استدعاءات CPI لمسار legacy. الاستدعاءات المعدِّلة على الـ precompiles القديمة (`0xff…08`, `0xff…09` و `0x42…16`) تُرفض في جلسة تكرارية مع `CpiProhibitedInIterativeTx`. وتعمل قراءات حالة سولانا والـ precompiles لمسار الكاش (`0xff…04`, `0xff…05`, `0xff…06`, `0xff…0b`) تعمل. الاستدعاء الذي يجري CPIs لمسار legacy يجب أن يتسع لمعاملة ذرية واحدة، أيًّا كان المسار الذي يرسله. انظر [القيود](/ar/almfahym-alasasyh/constraints.md) و [ميزانية الحوسبة](/ar/almfahym-alasasyh/compute-budget.md).

## التطبيقات المرجعية

* **Aerarium** — يشغّل Compound v3 (الإيداع / الاقتراض) من محفظة سولانا عبر `DoTxUnsigned`. وهو المرجع لمسار معاملات legacy الأقدم الموصوف أعلاه، وليس لـ `submitRomeTxV1`.
* **Rome DEX** ليس مثالًا على هذه الصفحة: فجانبه الخاص بسولانا هو برنامج سولانا أصيل توقّع له المحفظة مباشرةً، بينما يشارك جانبه الخاص بـ EVM المجمع نفسه.

لا يحتاج Aerarium إلى جسر أو محفظة ثانية — فالعنوان الاصطناعي يجعل مفتاح سولانا واحدًا حساب EVM من الدرجة الأولى. بالنسبة لنمط v1، اتبع [ابنِ تطبيقًا ثنائي المسار](/ar/adlh-almtw-ryn/dual-lane-app.md).

## ما التالي

* [استدعِ Solana من EVM](/ar/adlh-almtw-ryn/call-solana-from-evm.md) — الاتجاه الآخر، عبر CPI
* [التوافق التشغيلي للرموز](/ar/almfahym-alasasyh/token-interop.md) — كيف تُشارك الأرصدة عبر EVM وسولانا


---

# 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/ar/adlh-almtw-ryn/call-evm-from-solana.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.
