> 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-solana-from-evm.md).

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

استدعِ برامج Solana من Solidity عبر CPI في Rome والـ precompiles المساعدة.

تسمح الـ precompiles الخاصة بـ Rome لعقود Solidity باستدعاء برامج Solana مباشرة. يشرح هذا الدليل الآليات.

## المتطلبات الأساسية

* واجهات Solidity الخاصة بـ Rome من المستودع العام [`rome-solidity`](https://github.com/rome-protocol/rome-solidity) المستودع (يُثبَّت من GitHub، وليس من npm — انظر [انشر Solidity](/ar/adlh-almtw-ryn/deploy-solidity.md#using-the-rome-solidity-sdk)) — توجد واجهات الـ precompile في [`contracts/interface.sol`](https://github.com/rome-protocol/rome-solidity/blob/master/contracts/interface.sol)
* عقد Rome منشور (انظر [انشر Solidity](/ar/adlh-almtw-ryn/deploy-solidity.md))

اربط كل واجهة بعنوان الـ precompile الخاص بها:

```solidity
import {ICrossProgramInvocation, ISystemProgram, IHelperProgram}
    from "@rome-protocol/rome-solidity/contracts/interface.sol";

ICrossProgramInvocation constant CpiProgram    = ICrossProgramInvocation(0xFF00000000000000000000000000000000000008);
ISystemProgram          constant SystemProgram = ISystemProgram(0xFF00000000000000000000000000000000000007);
IHelperProgram          constant Helper        = IHelperProgram(0xFF00000000000000000000000000000000000009);
```

## الـ precompile الخاص بـ CpiProgram

`CpiProgram` (`0xFF…08`) يوجّه CPI (`invoke` / `invoke_signed`) بالإضافة إلى اختصارات القراءة عبر الحالة (`account_info`, `account_data_at`, `account_u64_at`, `account_lamports`, `pdas_batch_derive`):

```solidity
// استدعِ برنامجًا على Solana
CpiProgram.invoke(programId, accounts, instructionData);

// الاستدعاء بتوقيع PDA: يوقّع PDA الخاص بالسلطة الخارجية لعقدك، بالإضافة إلى واحد
// sub-PDA مملّح لكل إدخال في `salts` (يشتق Rome ["EXTERNAL_AUTHORITY", contract, salt])
CpiProgram.invoke_signed(programId, accounts, data, salts);
```

## تحويل lamports

لعمليات تحويل lamports وSPL البسيطة، استخدم الـ precompile الخاص بـ HelperProgram — لا حاجة إلى CPI مُنشأ يدويًا. العقد الذي يستدعيه يتصرف باعتباره **نفسه**: تنقل التحويلات أدناه lamports والرموز الخاصة بالعقد نفسه (يوقّع PDA الخاص بسلطته الخارجية)، وليس رموز المستخدم. ولكي يسحب عقدٌ رموز SPL الخاصة بالمستخدم إلى حساب رمزي يتحكم فيه، ويعرف لمن تعود، يمنح المستخدم تفويضًا لـ SPL. أمّا ERC-20 `transfer` أو `transferFrom` إلى عقدٍ لا يفعل سوى إضافة رصيد إلى دفتر ضمان wrapper ولا يمنح العقد أي حساب رمزي ينفق منه — انظر [دمج برنامج سولانا](/ar/adlh-almtw-ryn/integrate-solana-program.md).

```solidity
contract Transfers {
    IHelperProgram constant Helper = IHelperProgram(0xFF00000000000000000000000000000000000009);

    // Transfer lamports from this contract's PDA to an EVM address's PDA
    function transferSol(address to, uint64 lamports) external {
        Helper.transfer_lamports(to, lamports);
    }

    // Transfer an SPL token from this contract's PDA-owned token account
    function transferSpl(address to, uint64 tokens, bytes32 mint) external {
        Helper.transfer_spl(to, tokens, mint);
    }

    // أنشئ ATA الخاص بالمتصل لعملة mint
    function createAta(bytes32 mint) external {
        Helper.create_ata(msg.sender, mint);
    }
}
```

`transfer_spl` يملك عدة تغايرات (بما في ذلك نسخة المفوض لـ `transferFrom` تدفقات)؛ انظر `interface.sol`. على المسار المخبأ، استخدم `ISplCached` (`0xff…05`) / `IAssociatedSplCached` (`0xff…06`) بدلًا من ذلك — يستخدم العقد مسارًا واحدًا باستمرار، ولا يمكن إلا للمسار القديم أن `invoke` برنامجًا مخصصًا (انظر [دمج برنامج سولانا](/ar/adlh-almtw-ryn/integrate-solana-program.md)).

## قراءة بيانات الحساب

اقرأ بيانات أي حساب على Solana عبر اختصارات القراءة في CpiProgram:

```solidity
(
    uint64 lamports,
    bytes32 owner,
    bool isSigner,
    bool isWritable,
    bool executable,
    bytes memory data
) = CpiProgram.account_info(accountPubkey);
```

## اشتقاق PDA

اعثر على عناوين Program Derived Addresses من Solidity عبر الـ precompile الخاص بـ System:

```solidity
ISystemProgram.Seed[] memory seeds = new ISystemProgram.Seed[](2);
seeds[0] = ISystemProgram.Seed("my-program-seed");
seeds[1] = ISystemProgram.Seed(abi.encodePacked(someValue));

(bytes32 pda, uint8 bump) = SystemProgram.find_program_address(targetProgramId, seeds);
```

## تحويل Base58

حوّل بين `bytes32` وBase58 (صيغة عناوين Solana):

```solidity
bytes memory base58Str = SystemProgram.bytes32_to_base58(pubkey);
bytes32 pubkey = SystemProgram.base58_to_bytes32(base58Bytes);
```

## استدعاء برامج Solana المخصصة

لاستدعاء أي برنامج على Solana، أنشئ قائمة الحسابات وبيانات التعليمة بنفسك:

```solidity
contract CustomCPI {
    ICrossProgramInvocation constant CpiProgram = ICrossProgramInvocation(0xFF00000000000000000000000000000000000008);
    bytes32 constant MY_PROGRAM = 0x0000000000000000000000000000000000000000000000000000000000000000; // your Solana program ID

    function callMyProgram(bytes32 account1, bytes32 account2, bytes calldata ixData) external {
        ICrossProgramInvocation.AccountMeta[] memory accounts = new ICrossProgramInvocation.AccountMeta[](2);
        accounts[0] = ICrossProgramInvocation.AccountMeta(account1, false, true);
        accounts[1] = ICrossProgramInvocation.AccountMeta(account2, false, false);

        CpiProgram.invoke(MY_PROGRAM, accounts, ixData);
    }
}
```

## القيود الرئيسية

1. **يجب التصريح عن جميع الحسابات مسبقًا.** يجب أن تتضمن معاملة Solana كل حساب سيلامسه CPI — لا يمكن اكتشاف الحسابات ديناميكيًا داخل CPI.
2. **حد عمق CPI: 4 مستويات.** Rome EVM → هدفك → استدعاء الهدف → واحد إضافي. خطط لعمق الاستدعاء.
3. **مفاتيح Solana العامة هي `bytes32`,** ليست عناوين Ethereum بطول 20 بايت.
4. **بيانات التعليمة هي بايتات خام** بالصيغة التي يتوقعها البرنامج الهدف (عادةً Borsh، بنظام little-endian).

## ما التالي

* **شاهد ذلك في تطبيق حقيقي** — [cardo](https://github.com/rome-protocol/cardo) يرسل استدعاءات CPI إلى الـ precompile مباشرة من محفظة المستخدم، من دون عقد وسيط; [rome-dex](https://github.com/rome-protocol/rome-dex) (dual-lane AMM) يفعل الشيء نفسه، ولديه أيضًا عقد موجّه بلا وصاية; [aerarium](https://github.com/rome-protocol/aerarium) هو تطبيق إقراض لا يستدعي برامج Solana من Solidity.
* [دمج برنامج سولانا](/ar/adlh-almtw-ryn/integrate-solana-program.md) — هوية المستخدم على Solana، والتوقيع بصفتها، وقاعدة المسار الواحد، وتوفير الحسابات لبرنامج حقيقي في الجهة الأخرى
* [مرجع البرنامج المسبق](/ar/almrja/precompiles.md) — كل محدد على كل precompile
* [استدعِ EVM من Solana](/ar/adlh-almtw-ryn/call-evm-from-solana.md) — العكس: تشغيل عقود EVM من محفظة Solana
* [التوافق التشغيلي للرموز](/ar/almfahym-alasasyh/token-interop.md) — كيف تعمل رموز ERC-20 وSPL معًا
* [القيود](/ar/almfahym-alasasyh/constraints.md) — عمق CPI والقيود الأخرى


---

# 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-solana-from-evm.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.
