# Rome SDK

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.

## Two SDKs

Rome has two SDKs serving different purposes:

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

**For Solidity developers.** Provides precompile interfaces, ERC-20/SPL wrappers, PDA derivation, and CPI utilities. Install via npm and import into your Solidity contracts.

```bash
npm install @rome-protocol/solidity-sdk
```

```solidity
import {SplToken, CpiProgram, SystemProgram} from "@rome-protocol/solidity-sdk/contracts/core/Precompiles.sol";
import {SPL_ERC20} from "@rome-protocol/solidity-sdk/contracts/token/ERC20SPL.sol";
import {RomeEVMAccount} from "@rome-protocol/solidity-sdk/contracts/core/RomeEVMAccount.sol";
```

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

**For infrastructure operators.** A Rust workspace of 9 crates that handles transaction composition, Solana interaction, gas pricing, block indexing, and service orchestration. Used by Proxy, Hercules, and Rhea.

## Solidity SDK: What's Included

### Precompile Interfaces

Pre-bound singleton constants for all Rome precompiles:

```solidity
// Available globally after import
ISplToken constant SplToken;                    // 0xff...05
IAssociatedSplToken constant AssociatedSplToken; // 0xff...06
ISystemProgram constant SystemProgram;           // 0xff...07
ICrossProgramInvocation constant CpiProgram;     // 0xff...08
IWithdraw constant Withdraw;                     // 0x42...16
```

### SPL Token Operations

```solidity
// Read token account state
ISplToken.Account memory acc = SplToken.account_state(tokenAccountPubkey);
uint64 balance = acc.amount;
bytes32 owner = acc.owner;

// Transfer tokens
SplToken.transfer(recipientAta, mintPubkey, amount);

// Initialize a new token account
SplToken.initialize_account3(newAccount, mintPubkey, ownerPubkey);
```

### 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);
```

### Token Registry

```solidity
TokenRegistry registry = TokenRegistry(REGISTRY_ADDRESS);

// Register with cross-chain metadata
registry.registerToken(splMint, TokenOrigin.WormholeWrapped, externalAddr, chainId);

// Look up by external token
TokenEntry memory entry = registry.getTokenByExternal(2, ethUsdcAddress);
```

### Borsh Deserialization

```solidity
import {Convert} from "@rome-protocol/solidity-sdk/contracts/core/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/solidity-sdk/contracts/programs/metadata/MplTokenMetadataLib.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 9-crate workspace:

| 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-geth`       | OP-Geth Engine API integration for block building                               |
| `rome-utils`      | RLP, hex, JSON-RPC, authentication utilities                                    |
| `rome-obs`        | OpenTelemetry observability (traces, metrics, logs)                             |
| `rome-da`         | Celestia data availability layer                                                |
| `rome-meteora`    | Meteora DEX AMM pool adapters for gas pricing                                   |
| `rome-meta-hook`  | Token-2022 Transfer Hook router client                                          |

### 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
* Token Registry with cross-chain metadata

### In Progress

* JupiterRouter (Solidity interface for Jupiter swaps)
* Meta-Hook Router SDK client

### Planned (Phase 2)

| Interface | Protocol               |
| --------- | ---------------------- |
| IJupiter  | Jupiter DEX aggregator |
| IDrift    | Drift perpetuals       |
| IKamino   | Kamino lending         |
| IMeteora  | Meteora liquidity      |
| IOndoGM   | Ondo RWA               |

### Planned (Phase 3)

| Interface     | Program           |
| ------------- | ----------------- |
| IStakeProgram | Solana Stake      |
| IVoteProgram  | Solana Vote       |
| ISlotHashes   | SlotHashes Sysvar |

## 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: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rome.builders/products/rome-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
