> 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/products/rome-sdk.md).

# Rome SDK

Typed Solidity interfaces for calling Solana programs from EVM contracts, plus the Rust SDK behind Rome's off-chain services.

The Rome SDK provides typed Solidity interfaces for interacting with Solana programs from EVM smart contracts. It's the developer toolkit for building cross-runtime applications on Rome.

## SDKs

Rome has SDKs for three audiences — app builders (TypeScript), contract developers (Solidity), and teams running their own services on Rome (Rust).

### TypeScript SDK (`@rome-protocol/sdk`)

**For dapp and frontend developers** — the SDK most app builders start with. [`@rome-protocol/sdk`](https://github.com/rome-protocol/rome-sdk-ts) wraps the Rome write path so a web app submits Rome transactions correctly: `submitRomeTx` (the correct write path plus gas/fee handling), PDA / ATA derivation, CPI `invoke` / `invoke_signed` encoders, precompile bindings, and a `/bridge` subpath. Repo-first install (npm publish pending):

```bash
npm install github:rome-protocol/rome-sdk-ts#v0.4.0
```

```typescript
import { submitRomeTx } from '@rome-protocol/sdk';
// Submit any Rome EVM write through the correct write path (handles gas/fee encoding).
```

The public [rome-dex](https://github.com/rome-protocol/rome-dex) app uses only a few of the SDK's helpers (PDA and token-account derivation, the CPI `invoke` encoder and the 1.3x gas pad), and [cardo](https://github.com/rome-protocol/cardo) does not depend on it. Neither calls `submitRomeTx` or `submitRomeTxV1`, so read them for how an app calls the CPI precompile, not for the SDK's write path.

**Both lanes, one SDK.** `submitRomeTx` is the EVM lane (MetaMask). For the **Solana lane** — a Solana wallet driving your EVM app — `submitRomeTxV1` mirrors it: the proxy composes one Solana v1 transaction for the call, the wallet signs twice with the same key (a readable authorization message, then the transaction), and Rome runs the call as an EVM transaction from the user's derived identity, with no EVM key. A call that does not fit one transaction is relayed by the proxy with the same authorization signature, and `fundSyntheticGas` tops up the native gas a relayed call spends. A relayed call that reverts resolves with `receipt.status === "0x0"` instead of throwing, so check it; the [relayed calls and long calls](/developer-guides/call-evm-from-solana.md#relayed-calls-and-long-calls) section has the gas rule and the limits. Value moves in and out through `buildFundLeg` / `buildSweepLeg` as an ERC-20 wrapper (e.g. `wUSDC`), not native `msg.value` — the synthetic sender holds nothing at rest — and a first-time synthetic is provisioned once, explicitly, with `buildCreatePdaCall`. The earlier `submitRomeTxSolanaLane`, which builds a legacy Solana transaction in the client, is still in the SDK. See [Build a dual-lane app](/developer-guides/dual-lane-app.md) and [Call EVM from Solana](/developer-guides/call-evm-from-solana.md).

### Solidity SDK (`@rome-protocol/rome-solidity`)

**For Solidity developers.** Provides the precompile interfaces, ERC-20/SPL wrappers, PDA derivation, and CPI utilities. The npm publish is pending; today you consume these from the public [`rome-solidity`](https://github.com/rome-protocol/rome-solidity) repo (git dependency or copied files).

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

### Rust SDK (`rome-sdk`)

**For teams that run their own services on Rome.** A Rust workspace that handles transaction composition, Solana interaction, gas pricing, and block indexing. The Proxy and Hercules are built on it. The source is in [`rome-protocol/rome-sdk`](https://github.com/rome-protocol/rome-sdk). It sends Solana v1 transactions (4 KB, up to 64 accounts).

**Building it.** The workspace expects the repositories [`rome-sdk`](https://github.com/rome-protocol/rome-sdk), [`rome-evm`](https://github.com/rome-protocol/rome-evm) and [`mollusk`](https://github.com/rome-protocol/mollusk) cloned side by side, because it depends on the other two by relative path. That is also why the supported way to use it from another project is a path dependency, not a plain git dependency. You need Rust 1.85 or later and network access for the first build. `rome-evm` has no default network feature, so any build that compiles it needs exactly one of `ci`, `testnet` or `mainnet`; use `ci` for local work, for example `cargo test -p rome-sdk --features ci`. The repository README has the full steps and the feature table.

**Licence.** The Rust SDK is source-available, not open source: it is all rights reserved and may be used for personal, non-commercial purposes. Commercial use needs written permission from Rome Protocol; the repository's `LICENSE` says how to ask.

## Solidity SDK: What's Included

### Precompile Interfaces

Bind an interface to its precompile address:

```solidity
ISystemProgram          constant System   = ISystemProgram(0xFF00000000000000000000000000000000000007);
ICrossProgramInvocation constant Cpi      = ICrossProgramInvocation(0xFF00000000000000000000000000000000000008);
IHelperProgram          constant Helper   = IHelperProgram(0xFF00000000000000000000000000000000000009);
IWithdraw               constant Withdraw = IWithdraw(0x4200000000000000000000000000000000000016);
// Cached track: ISplCached 0xff…05, IAssociatedSplCached 0xff…06, ISystemCached 0xff…04, IWithdrawCached 0xff…0b
```

### SPL Token Operations

Use `IHelperProgram` (`0xff…09`) for user-PDA-signed SPL primitives:

```solidity
// Create the caller's ATA for a mint
Helper.create_ata(user, mint);

// Transfer SPL from the caller's PDA
Helper.transfer_spl(to, tokens, mint);
```

On the cached track, the equivalent operations live on `ISplCached` (`0xff…05`) and `IAssociatedSplCached` (`0xff…06`). See `interface.sol` for all overloads; a contract uses one track consistently.

### PDA Derivation

```solidity
// Derive a user's Solana PDA
bytes32 userPda = RomeEVMAccount.pda(msg.sender);

// Derive PDA with salt (for creating multiple PDAs per user)
bytes32 pda = RomeEVMAccount.pda_with_salt(msg.sender, salt);

// Find arbitrary PDA
(bytes32 pda, uint8 bump) = SystemProgram.find_program_address(programId, seeds);
```

### Cross-Program Invocation

```solidity
// Call any Solana program
ICrossProgramInvocation.AccountMeta[] memory accounts = new ICrossProgramInvocation.AccountMeta[](2);
accounts[0] = ICrossProgramInvocation.AccountMeta(signerPda, true, true);
accounts[1] = ICrossProgramInvocation.AccountMeta(targetAccount, false, true);

CpiProgram.invoke(programId, accounts, instructionData);

// Call with PDA signing
CpiProgram.invoke_signed(programId, accounts, data, seeds);

// Read account data
(uint64 lamports, bytes32 owner, bool isSigner, bool isWritable, bool executable, bytes memory data)
    = CpiProgram.account_info(pubkey);
```

### ERC-20 over SPL Tokens

```solidity
// Deploy wrapper for any SPL mint
ERC20SPLFactory factory = ERC20SPLFactory(FACTORY_ADDRESS);
address wrapper = factory.add_spl_token_with_metadata(splMint);

// Use the wrapper as standard ERC-20
SPL_ERC20 token = SPL_ERC20(wrapper);
token.transfer(recipient, amount);
uint256 balance = token.balanceOf(user);
```

### Borsh Deserialization

```solidity
import {Convert} from "@rome-protocol/rome-solidity/contracts/convert.sol";

// Parse Solana account data (little-endian Borsh format)
(uint64 value, uint256 newOffset) = Convert.read_u64le(data, offset);
(bytes32 pubkey, uint256 newOffset2) = Convert.read_bytes32(data, offset);
```

### Metaplex Metadata

```solidity
import {MplTokenMetadataLib} from "@rome-protocol/rome-solidity/contracts/mpl_token_metadata/lib.sol";

// Load token metadata from Metaplex
MplTokenMetadataLib.Metadata memory meta = MplTokenMetadataLib.load_metadata(
    mintPubkey, mplProgramId, cpiAddress
);
string memory name = meta.name;
string memory symbol = meta.symbol;
```

## Rust SDK: Architecture

The Rust SDK is a Cargo workspace. Its core crates:

| Crate               | Purpose                                                                                                                                            |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `rome-sdk`          | Core API: `Rome` struct, config, transaction types (RheaTx, RemusTx, RomulusTx)                                                                    |
| `rome-evm-client`   | EVM rollup client, TxBuilder, ResourceFactory, emulator integration                                                                                |
| `rome-solana`       | Solana tower, RPC client, transaction batching and tracking                                                                                        |
| `rome-utils`        | RLP, hex, JSON-RPC, authentication utilities                                                                                                       |
| `rome-obs`          | OpenTelemetry observability (traces, metrics, logs)                                                                                                |
| `rome-meteora`      | Meteora DAMM v1 and v2 pool readers for gas pricing                                                                                                |
| `rome-meta-hook`    | Client for the Meta-Hook Router program: Token-2022 transfer-hook configuration, extra account resolution, transfers with compute-budget estimates |
| `rome-jito-bundler` | Jito bundle builder for atomic multi-transaction submission                                                                                        |

### Transaction Types

```rust
// Single rollup transaction
let rhea = RheaTx::new(signed_eth_tx);
let mut tx = rome.compose_rollup_tx(rhea).await?;
let sig = rome.send_and_confirm(&mut *tx).await?;

// Cross-rollup atomic transaction
let remus = RemusTx::new(vec![tx1, tx2]);
let mut tx = rome.compose_cross_rollup_tx(remus).await?;

// Cross-chain atomic transaction (EVM + Solana)
let romulus = RomulusTx::new(eth_txs, sol_ixs);
let mut tx = rome.compose_cross_chain_tx(romulus, signers).await?;
```

### Resource Pooling

The SDK pools Solana keypairs (payers) and holder account indices for parallel transaction submission:

```rust
let resource = resource_factory.get().await?;
let payer = resource.payer();       // Solana keypair
let holder = resource.holder();     // Holder account index
// Resource automatically returned to pool on Drop
```

## SDK Roadmap

### Built and Working

* SPL Token wrappers and precompile interfaces
* Meteora DAMM v1 swaps via CPI
* Oracle Gateway V1 + V2 (Pyth Pull, Switchboard V3)
* System Program helpers, Borsh deserialization
* ERC20SPL Factory + bridge contracts

## What's Next

* [Deploy Solidity](/developer-guides/deploy-solidity.md) — deploy your first contract using the SDK
* [Call Solana from EVM](/developer-guides/call-solana-from-evm.md) — use CPI to interact with Solana programs
* [Contract Addresses](/reference/contract-addresses.md) — deployed SDK contract addresses


---

# 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/products/rome-sdk.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.
