Skip to main content
Bu sayfa yapay zekâ tarafından otomatik olarak çevrilmiştir. İngilizce sürüm esas alınır.İngilizce sürümü görüntüle →

Kurulum

Bu sayfadaki her örnek, raydium-sdk-V2-demo/src/clmm içindeki bir dosyaya karşılık gelir; ilgili GitHub bağlantısı her bölümün yanında yer alır. Başlangıç yapılandırması, demo deposundaki config.ts.template dosyasını takip eder (kaynak). Karmaşık bir entegrasyonda disableFeatureCheck: true ayarını kullanmanızı öneririz:

CLMM havuzu oluşturma

Kaynak: src/clmm/createPool.ts
SDK şunları yapar:
  • Türetme işleminden önce mint1/mint2 değerlerini bayt sırasına göre sıralar.
  • sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64) değerini hesaplar.
  • observation ve tick_array_bitmap_extension hesaplarını oluşturur.
  • ammConfig ile tanımlanan havuz oluşturma ücretini öder.

Seçilen aralıkta pozisyon açma

Kaynak: src/clmm/createPosition.ts
SDK, aralığın dokunduğu tick dizilerini hesaplar ve bunları hesap olarak iletir. Ayrı bir init talimatı eklemeniz gerekmez; init-tick-array talimatı yoktur. OpenPosition* eksik bir tick dizisini kendisi oluşturur ve masrafını ödeyen cüzdan öder.

Mevcut bir pozisyonda likiditeyi artırma

Kaynak: src/clmm/increaseLiquidity.ts

Likiditeyi azaltma (ve aynı anda ücretleri toplama)

Kaynak: src/clmm/decreaseLiquidity.ts ve src/clmm/closePosition.ts
Yalnızca işlem ücretlerini ve ödülleri toplamak için decreaseLiquidity çağrısını liquidity = new BN(0) ile yapın. Talimatın yan etkisi, token_fees_owed_{0,1} ve reward_amount_owed alanlarını kapatıp bu tutarları dışarı aktarmaktır. İkisini de toplamanın tek yolu budur. Likiditeyi ve ücretleri sıfırladıktan sonra pozisyonu tamamen kapatmak için son decreaseLiquidity çağrısında ownerInfo: { closePosition: true } değerini geçirin. SDK, ClosePosition talimatını ekler ve NFT’yi yakar.
Kısıtlı ihraççı pozisyonları uyumlu bir kapatma oluşturucusu gerektirir. Bu pozisyonların dondurulmuş bir NFT token hesabı vardır. CLMM hesabı yakmadan önce çözebilsin diye ClosePosition, pozisyonun havuz kimliğini ilk kalan hesap olarak eklemelidir. Program kaynak dalında bir SDK değişikliği yer almaz. Kısıtlı ihraççı pozisyonu oluşturmayı etkinleştirmeden önce SDK sürümünüzün dondurulmuş kapatma yolunu açıkça desteklediğini doğrulayın.
Doğrudan bir Anchor istemcisi kullanıyorsanız bildirilen hesapları olduğu gibi bırakın ve havuzu ekleyin:
Her kapatma işleminde poolId değerini geçebilirsiniz. CLMM bu değeri yalnızca positionNftAccount donmuşsa okur. Böylece tek bir istemci yolu hem eski hem yeni pozisyonlarla uyumlu kalır.

Ödül(ler)i toplama

Kaynak: src/clmm/harvestAllRewards.ts
harvestAllRewards, geçirilen her havuzdaki her pozisyonu gezer. İşlem ücretlerini ve ödülleri kapatan sıfır likiditeli DecreaseLiquidity çağrılarını (ve varsa UpdateRewardInfos talimatlarını) gruplandırır. Gerektiğinde bunları birden fazla işleme böler.

Swap

Kaynak: src/clmm/swap.ts Bu örnek, PoolUtils.computeAmountOutFormat yerine swapInternal ile simülasyon yapan src/clmm/swap.ts dosyasını yansıtır.
Simülasyon, tick haritasını zincir dışında on-chain programla aynı mantıkla gezer ve çıkan miktarı (amountCalculated) ile swap’ın dokunacağı tam hesap listesini (accounts) döndürür. Simülasyonun döndürdüğü remainingAccounts değerlerini her zaman iletin: eksik olursa swap, yol boyunca NotEnoughTickArrayAccount hatasıyla geri döner; fazla veya eski hesaplar ise yalnızca gereksiz hesaplama maliyeti yaratır.
PoolUtils.computeAmountOutFormat hâlâ mevcuttur, ancak bir ComputeClmmPoolInfo nesnesi (getPoolInfoFromRpc fonksiyonunun döndürdüğü computePoolInfo, API pool nesnesi değil) ve iki ek zorunlu argüman — tickarrayBitmapExtension ve blockTimestamp — gerektirir. Ayrıca raydium.clmm.fetchTickArrays adında bir metot yoktur (fetchTickArrays bağımsız bir fonksiyondur; modül düzeyindeki yardımcılar PoolUtils.fetchMultiplePoolTickArrays ile getPoolInfoFromRpc tarafından döndürülen tickData ve tickArrays değerleridir).

Özelleştirilebilir bir CLMM havuzu oluşturma

createCustomizablePool, havuz oluşturma anında dinamik ücret ve tek taraflı ücret anahtarlarını sunan giriş noktasıdır. createPool ile aynı yapıyı kullanır, ancak buna iki ek parametre eklenir:
enableDynamicFee, dynamicFeeConfigId ve startTime parametreleri yoktur. Dinamik ücretleri etkinleştiren şey dynamicFeeConfig parametresinin verilmesidir — bu parametreyi atlarsanız hata almadan sabit ücretli bir havuz oluşturursunuz. Ayrıca SDK enum üyeleri TokenOnlyA / TokenOnlyB olarak adlandırılırken, on-chain Rust enum’ı bunları Token0Only / Token1Only olarak yazar; sayısal değerler eşleşir (FromInput = 0).
Varsayılan ücretli ve dinamik ücret kullanmayan yol için createPool çalışmaya devam eder. Bu iki ayardan birine ihtiyacınız olduğunda createCustomizablePool kullanın. Zincir üstü hesap listesi için products/clmm/instructions sayfasına bakın.

Limit emirleri

Limit emri, kullanıcının girdisini tek bir tick’te bekletir ve bir swap o tick’i geçtiğinde FIFO sırasıyla gerçekleştirilir. Çıktılar, uzlaşma (settle) anında sahibinin ATA hesabına gönderilir; emrin doldurulması için sahibinin çevrimiçi olması gerekmez.

Limit emri açma

Havuz başına bir limit emri yapılandırma hesabı yoktur ve getClmmLimitOrderConfigs() yardımcı fonksiyonu da yoktur — emirler tick’e göre anahtarlanır.
SDK, LimitOrderState PDA’sını (owner, nonce PDA, order nonce) üçlüsünden türetir, cüzdan başına LimitOrderNonce değerini artırır ve emri o tick’teki FIFO kohortuna ekler.

Açık bir emri artırma / azaltma

decreaseLimitOrder yalnızca emrin doldurulmamış kısmından miktar çıkarabilir; dolmuş kısım uzlaşmaya kadar kilitli kalır. Emir tamamen dolmuşsa her iki talimat da InvalidOrderPhase hatasıyla geri döner.

Dolmuş bir emri uzlaştırma

settleLimitOrder, emrin unfilled_ratio_x64 değerini kohort takipçisiyle karşılaştırır, dolan çıktıyı hesaplar ve bunu sahibinin ATA hesabına aktarır. Sahibi bu işlemi kendisi çağırabilir; zincir dışı bir operasyonel bekçi olan limit_order_admin da sahibi adına çağırabilir — çıktı yine sahibine gider. Tamamen uzlaştırılmış emirleri kapatıp kira bedelini geri almak için tekil emirlerde closeLimitOrder, toplu olarak closeAllLimitOrder kullanın. Birçok emri birden uzlaştırmak için settleAllLimitOrder, bir v0 işlemine sığabildiği kadar SettleLimitOrder çağrısı ekler.

Bir cüzdanın bekleyen emirlerini listeleme (zincir dışı)

Aktif emirler uç noktası, dolmamış ve kısmen dolmuş emirleri tek bir yanıtta döndürür (totalAmount / filledAmount / pendingSettle alanları aşamaları ayırt eder). Kapanmış emirlerin geçmişi için /limit-order/history/order/list-by-user?wallet=… (cüzdan başına, nextPageId ile sayfalanmış) kullanın; belirli bir emrin tüm olay günlüğü için /limit-order/history/event/list-by-pda?pda=… kullanın.

Rust CPI iskeleti

SwapV2 için kalan hesap sırası:
Swap hiçbir zaman genişletmeye ihtiyaç duymuyorsa onu atlayın; aksi halde o, ilk kalan hesap olur.

Yaygın hatalar

  • Tick uç noktalarının aralığa uymaması → TickAndSpacingNotMatch. Her zaman TickUtil.getPriceAndTick ile hizalayın (TickUtil, tekil olarak yazılır).
  • SwapV2 içinde yeterli tick dizisi verilmemesi → NotEnoughTickArrayAccount. Listeyi swapInternal(...).accounts çıktısından alın.
  • Bitmap uzantısı olmadan tam aralıklı pozisyon → Uzantı PDA’sı yazılabilir olmalıdır. SDK bunu otomatik olarak yönetir.
  • sqrt_price_x64 değerini price ile karıştırmak → Burada 2 katı farkı oluşturan bir karışıklık özellikle sorunludur. Emin değilseniz, fiyatı SDK’ya okunabilir bir fiyattan hesaplatın.
  • Ödülleri çok sık toplamak → Her toplama işlemi sıfır likiditeli bir DecreaseLiquidity işlemidir ve bir işlem maliyeti doğurur. Birden fazla pozisyon için harvestAllRewards ile toplu işlem yapın ve execute çağrısının { sequentially: true } parametresine ihtiyaç duyduğunu unutmayın.
  • NFT hesaplarını kendiniz kapatmak → ClosePosition, NFT’yi yakar ve ilişkili ATA’sını kapatır. Token-2022 NFT mint’ini de kapatır. Klasik SPL Token mint’i ise, bu program mint’leri kapatamadığı için arzı sıfır olarak kalır. Desteklenen hesapları ayrıca kapatmayın; aksi halde işlem geri alınır.
  • Limit emrini aralığa uymayan bir tick’te açmak → TickAndSpacingNotMatch. Her zaman dışa aktarılan getOrderTick yardımcı fonksiyonu ile tick değerini hizalayın.
  • Tamamen gerçekleşmiş bir emirde decreaseLimitOrder çağırmak → InvalidOrderPhase. Bunun yerine önce settleLimitOrder, ardından closeLimitOrder kullanın.
  • Bir enableDynamicFee bayrağı beklemek → Böyle bir bayrak yoktur. dynamicFeeConfig parametresini atlamak, hata vermeden sessizce sabit ücretli bir havuz oluşturur. Dinamik ücret istiyorsanız, yapılandırma hesabının PublicKey değerini /tr/main/clmm-dynamic-config sayfasından seçerek geçirin.

Sırada ne var

Kaynaklar: