> 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/tr/temel-kavramlar/token-interop.md).

# Token Uyumluluğu

ERC-20 ve SPL token'ların Rome üzerinde nasıl aynı temel hesap olduğu.

Rome, bir ERC-20 tokenını ve onun altında yatan SPL tokenını tek bir paylaşılan hesap olarak temsil eder. Bu sayfa, tokenların EVM ve Solana arasında nasıl çalıştığını açıklar.

## Paylaşılan durum modeli

Rome, tokenları bir tarafta kilitleyip diğer tarafta sarılmış kopyalar basmaz. Rome’daki bir ERC-20 tokenı **şeffaf bir sarmalayıcıdır** Solana'daki bir SPL token hesabının üzerinde — ERC-20 bakiyesi *olduğu* SPL bakiyesidir.

<figure><img src="https://4222476421-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F671PKS8ZQSNqtoC8PGvz%2Fuploads%2Fgit-blob-65af9700f322d308e2cb17da3d107f87b51201a7%2Ftoken-interop.svg?alt=media" alt="An ERC-20 wrapper over the same SPL token account on Solana"><figcaption></figcaption></figure>

* Köprü gecikmesi yok — ERC-20 bakiyesi SPL bakiyesidir
* Likidite parçalanması yok — her iki taraftaki DeFi aynı tokenları görür
* Köprü riski yok — istismar edilecek ayrı bir emanet hesabı yoktur

> Aşağıdaki içe aktarma yolları `@rome-protocol/rome-solidity`. Paket npm'de yok; onu herkese açık [`rome-solidity`](https://github.com/rome-protocol/rome-solidity) deposundan `npm install github:rome-protocol/rome-solidity`, veya `forge install rome-protocol/rome-solidity` bir yeniden eşleme ile; sarmalayıcı ve fabrika sözleşmeleri için Foundry altında ayrıca OpenZeppelin gerekir (bkz. [Solidity Sözleşmelerini Dağıtma](/tr/gelistirici-kilavuzlari/deploy-solidity.md#using-the-rome-solidity-sdk)). Precompile arayüzleri şurada bulunur: [`contracts/interface.sol`](https://github.com/rome-protocol/rome-solidity/blob/master/contracts/interface.sol).

## Sarmalayıcı sözleşmesi

`SPL_ERC20` (ve bunun önbellekli yol varyantı `SPL_ERC20_cached`, fabrika silahlı bir transfer kancası olan bir tanesi hariç her mint için bunu dağıtır; bkz. [Token-2022 mintleri](#token-2022-mints)) bir SPL mint üzerinde tam bir ERC-20 arayüzü sağlar:

* `balanceOf()` — kullanıcının ATA bakiyesini Solana'dan okur (bir sözleşme adresi için sarmalayıcının kendi defterini okur, aşağıya bakın)
* `transfer()` / `transferFrom()` — tokenları Solana'da taşır
* `approve()` / `allowance()` — harcayana özel ERC-20 yetkileri EVM depolamasında tutulur (bir SPL token hesabının EVM tarzı yetkileri yoktur). Bunlar aşağıdaki tek seferlik izinden ayrıdır: kullanıcının tokenlarını hiç hareket ettirebilmek için sarmalayıcı o kullanıcının SPL delegesi olarak davranır ve kullanıcı bu hakkı her cüzdan için bir kez verir
* `totalSupply()` — SPL mint arzını okur

Bir sözleşme tek seferlik izni gönderemez; bu nedenle bir sözleşmenin tokenları sarmalayıcının kendi token hesabında tutulur ve sarmalayıcının defterinde izlenir. `balanceOf(contract)` o defteri okur.

## Fabrika

`ERC20SPLFactory` herhangi bir SPL mint için bir sarmalayıcı dağıtır:

```solidity
import {ERC20SPLFactory} from "@rome-protocol/rome-solidity/contracts/erc20spl/erc20spl_factory.sol";

// Özetin adını/sembolünü mintin Token-2022 meta verisinden veya Metaplex'ten yükleyerek bir sarmalayıcı dağıtın
address wrapper = factory.add_spl_token_with_metadata(splMint);

// Veya adı/sembolü elle belirtin
address wrapper = factory.add_spl_token_no_metadata(splMint, "USD Coin", "USDC");
```

Canlı fabrika adresi, `canlı` kayıt defterinin girdilerinden (v0.2.0): Hadrian `0x37c13e4ff21fb914eb24014dcbd0f8dbeaa31078`. Daha önceki fabrikalar hâlâ zincir üzerindedir ancak `kullanımdan kaldırılmış` veya `emekliye ayrılmış` içinde [registry](https://github.com/rome-protocol/rome-registry/tree/main/chains); bunları kullanmayın. Kayıt defteri tek doğru kaynaktır; bu yüzden canlı adresi ondan okuyun (bkz. [Sözleşmeler listesini okumak](/tr/referans/contract-addresses.md#reading-the-contracts-list)) ve kodunuza kopyalamak yerine bunu yapın.

## Kanonik mintler

Zincir üzerinde bir token kayıt defteri sözleşmesi yoktur. Kanonik sarmalayıcılar ve gas/köprü tokenları, zincir dışı [`rome-protocol/registry`](https://github.com/rome-protocol/rome-registry); izinsiz olarak oluşturulan sarmalayıcılar `add_spl_token_no_metadata` zincir üzerindeki `TokenCreated` olayından keşfedilir. Bu, her varlığın likiditeyi parçalamadan tek bir kanonik SPL mint'e eşlenmiş kalmasını sağlar.

## Solidity'den SPL işlemleri

Kullanıcı-PDA imzalı SPL temel işlemleri için **HelperProgram** ön derlemeyi (`0xFF…09`) — ATA oluşturma, SPL transferleri ve gas↔lamports dönüşümü:

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

IHelperProgram helper = IHelperProgram(0xFF00000000000000000000000000000000000009);

helper.create_ata(user, mint);              // mint için kullanıcının ATA'sını oluşturur
helper.transfer_spl(to, tokens, mint);      // çağıranın PDA'sından SPL aktarır
```

`transfer_spl` birden fazla aşırı yüklemesi vardır (şunun için bir delege varyantı dahil: `transferFrom` akışlar); kesin imzalar için bkz. `interface.sol` Kesin imzalar için bakın. Önbellekli yolda eşdeğer işlemler şurada bulunur: `ISplCached` (`0xFF…05`) ve `IAssociatedSplCached` (`0xFF…06`). Bir sözleşme tek bir yolu tutarlı şekilde kullanır.

## Cüzdan başına tek seferlik izin

Sarmalayıcı, kullanıcının tokenlarını şu sıfatla taşır: **SPL delegesi** o kullanıcının token hesabının. Bu nedenle bir cüzdan, sarmalayıcı onun adına herhangi bir şey taşıyabilmeden önce, bu hakkı her sarmalayıcı için bir kez vermek zorundadır. Bu izin, Helper ön derlemesine tek bir çağrıdır (`0xff00000000000000000000000000000000000009`):

```solidity
helper.approve_spl(wrapper, type(uint64).max, mint);   // approve_spl(wrapper, 2^64-1, mint)
```

`approve_spl` kullanıcının kendi hesabı tarafından imzalanır; bu yüzden onu sarmalayıcı veya sizin sözleşmeniz değil, kullanıcı gönderir. Mint `mint_id()` sarmalayıcı üzerindedir.

* **Buna kimin ihtiyacı var.** Tokenlarını taşımak istediği her sarmalayıcı için her EVM cüzdanı ve her Solana kullanıcısının sentetik adresi. Tokenları `transferFrom` yalnızca sarmalayıcıya izin vermiş kullanıcılar için çalışır.
* **Nasıl kontrol edilir.** Çağırın `isEnabled(user)` sarmalayıcı üzerinde. Şunu döndürür: `true` izin verildikten sonra.
* **Eksik olduğunda nasıl görünür.** Transfer SPL hatasıyla geri alınır `0x4` (sahip uyuşmazlığı).
* **Her token hesabı için bir delege.** Bir SPL token hesabının tek bir delegesi vardır. Aynı token hesabında başka bir programa, örneğin bir köprüye veya bir yönlendiriciye izin vermek, sarmalayıcının izninin yerini alır ve kullanıcı tekrar izin verene kadar sarmalayıcı o kullanıcı için çalışmayı durdurur. Şunu kontrol edin: `isEnabled` önceden verilmiş bir iznin hâlâ orada olduğunu varsaymak yerine, transferden önce.

Bu [çift şeritli uygulama kılavuzu](/tr/gelistirici-kilavuzlari/dual-lane-app.md#one-time-grant-the-wrapper) her iki şerit için de tam kodu içerir.

## Yatırma ve çekme

* **EVM'ye** — SPL tarafı kullanıcının PDA'sına ait ATA'ya kredi yazar; ERC-20 sarmalayıcısı bakiyeyi anında yansıtır. Zincirler arası gelen transferler, köprü üzerindeki kullanıcı imzalı bir yetkilendirme aracılığıyla güvene ihtiyaç duymadan kesinleşir.
* **Gas'ı gas tokenına sarın** — şunu çağırın: `Çekim` ön derlemeyi (`0x42…16`). `withdraw_to_ata(wei)` yerel gas'ı yakar ve gas tokenının kendi ondalık basamakları cinsinden eşdeğer tutarı çağıranın token hesabına krediler; gas tokenının sarmalayıcısı (örneğin wUSDC) bunu daha sonra bir bakiye olarak gösterir. `withdraw_to_pda(wei)` çağıranın PDA'sına lamport öder ve yalnızca gazı SOL olan bir zincirde geçerlidir; gaz olarak USDC kullanan Hadrian ve Rubicon'da geri alınır, bu yüzden şunu kullanın: `withdraw_to_ata` orada. Tutar 18 ondalıklı gas birimlerindedir ve gas-token birimlerinin tam sayısı olmalıdır: USDC-gaz zincirinde 10^12'nin katı (bir 6 ondalıklı birim), aksi halde çağrı geri alınır. `HelperProgram.deposit_from_ata(wei)` ters yönde gider ve çağıranın token hesabındaki gas tokenını aynı kat olma kuralıyla yeniden yerel gas'a çevirir. Bunlar gas-token dönüşümleridir; diğer tokenlar için bir çıkış değildir.
* **Solana'ya çıkışta, herhangi başka bir token** — sarmalayıcının kendi bakiyesi zaten SPL bakiyesidir; bu yüzden onu dışarı taşımak bir SPL transferidir:
  * `HelperProgram.transfer_spl_to_signer(amount, mint)` çağıranın tokenlarını işlemi imzalayan Solana cüzdanının token hesabına gönderir. Bu, Solana cüzdanı kullanıcıları için dönüş ayağıdır.
  * `RomeBridgeWithdraw.bridgeOutToSolana(solanaRecipient, amount, mint)` bunları herhangi bir Solana cüzdanına gönderir. Köprü sözleşmesi için kullanıcının iznine ihtiyaç duyar (`approve_spl(bridge, …)`, yukarıdaki tek-delege notuna bakın) ve alıcının token hesabı mevcut olmalıdır; `ensureRecipientAta(solanaRecipient, mint)` onu oluşturur.
  * `RomeBridgeWithdraw` ayrıca CCTP üzerinden USDC'yi başka bir zincirde yakar (`burnUSDC`) ve diğer varlıkları Wormhole üzerinden gönderir (`burnETH`, `burnToWormhole`).

Canlı `RomeBridgeWithdraw` adresi kayıt defterinden alın.

## Gaz tokeni

Her zincirin kendi gas tokenı vardır — Meteora DAMM havuzu (v1 veya v2, yapılandırılabilir) üzerinden fiyatlanan herhangi bir SPL token. Açık zincirler (Rubicon ve Hadrian) USDC kullanır; Hadrian'da test USDC, Rubicon'da gerçek USDC vardır. Evrensel bir varsayılan gas tokenı yoktur.

## Token-2022 mintleri

Fabrika ayrıca Token-2022 mintlerini de sarar. Helper ön derlemesine mintin ne olduğunu şu şekilde sorar: `mint_info(mint)` (seçici `0xe24bf5d4`), ve yanıta göre sarmalayıcıyı seçer. `mint_info` beş değer döndürür:

| Değer          | Anlam                                                                                |
| -------------- | ------------------------------------------------------------------------------------ |
| `tokenProgram` | mintin sahibi olan token programı (klasik SPL Token programı veya Token-2022)        |
| `ondalıklar`   | mintin ondalık basamakları                                                           |
| `hookProgram`  | transfer-hook programı; hook yoksa veya hook mevcut ama etkin değilse sıfır          |
| `feeBps`       | baz puan cinsinden transfer ücreti; yoksa veya sıfıra ayarlanmışsa sıfır             |
| `extensions`   | mintin taşıdığı Token-2022 uzantılarının bir bit haritası; N uzantı türü için N. bit |

Bir mint ne alır:

| Mint                                                                                         | Sarmalayıcı                                                                                                        | `wrapper_kind_by_mint` |
| -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------- |
| Sıradan bir mint, hooksuz bir Token-2022 minti veya hook'u mevcut ama etkin olmayan bir mint | önbellekli sarmalayıcı (`SPL_ERC20_cached`)                                                                        | `1`                    |
| Etkinleştirilmiş bir transfer hook'una sahip bir Token-2022 minti                            | hook'lu sarmalayıcı (`SPL_ERC20_Token2022Hooked`), fabrikanın şu yöntemiyle dağıtılır: `hooked_wrapper_deployer()` | `2`                    |

Transfer ücreti olan bir mint önbellekli sarmalayıcıyı alır ve onun `Transfer` olayı, gönderilen tutarı değil, ücretten sonra ulaşan tutarı bildirir. Bir mintin fabrikadan hangi türü aldığına şununla bakabilirsiniz: `wrapper_kind_by_mint(mint)`; canlı Hadrian fabrikasında USDC, ETH ve SOL sarmalayıcılarının hepsi şunu döndürür: `1`.

Neler reddedilir:

* Etkinleştirilmiş bir transfer hook'una sahip bir mint sıradan sarmalayıcılardan birini alamaz. Bunu doğrudan dağıtmak `SPL_ERC20` veya `SPL_ERC20_cached` şu hatayla geri alınır: `ArmedTransferHookUnsupported(mint, hookProgram)`. Fabrika üzerinden bu durum bunun yerine hook'lu sarmalayıcıya gider.
* SPL mint olmayan bir adres, `mint_info` şu hatayla geri alınmasına neden olur: `Invalid SPL mint account: <address>`.
* Zaten bir sarmalayıcısı olan bir mint şu hatayla geri alınır: `Token mevcut`, ve zaten kullanımda olan bir sembol şu hatayla geri alınır: `Bu sembole sahip token mevcut`.
* `add_spl_token_with_metadata` adı ve sembolü önce mintin kendi Token-2022 meta verisinden, sonra Metaplex'ten okur. Mintin hiçbiri yoksa şu hatayla geri alınır: `Mint ad belirtmiyor: add_spl_token_no_metadata kullanın`.

Hook'lu sarmalayıcının davranışı:

* Token-2022 her transferde hook'u çalıştırır ve hook transfera bağlı hesaplara ihtiyaç duyar. Sarmalayıcı bunları kendisi çıkaramaz; bu yüzden çağıran, mintin extra-account-metas listesinden tam hesap listesini çözümler ve bunu iletir. Sarmalayıcı bu listenin sabit kısmını (hook programı ve doğrulama hesabı) kontrol eder ve olduğu gibi aktarır.
* Düz `transfer`, `transferFrom` ve `bridgeOutToSolana` şu hatayla geri alınmasına neden olur: `HookAccountPlanRequired`. Şunları kullanın: `transferWithHookAccounts`, `transferFromWithHookAccounts` ve `bridgeOutToSolanaWithHookAccounts`, bunlar hesap listesini ek bir argüman olarak alır.
* Sarmalayıcı dağıtıldıktan sonra mintin hook programı değişirse, transferler şu hatayla geri alınır: `HookConfigurationChanged`.
* Tokenları doğrudan çapraz program çağrısıyla, yani eski yolla taşır ve önbellekli yolu kullanmaz. Bir sözleşme tek bir yolu tutarlı biçimde kullanır; eski yoldaki çağrılar yalnızca atomik yürütmede çalışır, bu yüzden hook'lu sarmalayıcıyı kullanan bir çağrı tek bir atomik işleme sığmalıdır.
* Sözleşme bakiyeleri için bir defter tutmaz. Bir sözleşmeye gönderilen tokenlar sözleşmenin kendi token hesabına düşer ve sözleşme bunları ancak `approve_spl` sarmalayıcının kendisine izin verdikten sonra iletebilir.
* Aynı [tek seferlik izne](#one-time-grant-per-wallet) diğer tüm sarmalayıcılar gibi ihtiyaç duyar.

## Kısıtlamalar

* SPL token miktarları `uint64` (maks. 18.446.744.073.709.551.615)
* ERC-20 yetkileri (`approve` / `yetki`) EVM depolamasındadır. Sarmalayıcı, kullanıcının SPL delegesi olarak tokenları taşır; kullanıcı bu izni her sarmalayıcı için bir kez verir (bkz. [Cüzdan başına tek seferlik izin](#one-time-grant-per-wallet))
* ERC-20 sarmalayıcı sembolleri her fabrika için benzersiz olmalıdır

## Sırada Ne Var

* [Sözleşme Adresleri](/tr/referans/contract-addresses.md) — ön derlemeler ve zincir başına adresler
* [EVM'den Solana'yı çağırma](/tr/gelistirici-kilavuzlari/call-solana-from-evm.md) — Solidity'den CPI ve SPL işlemleri


---

# 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/tr/temel-kavramlar/token-interop.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.
