Python

Sürüm 2.0, Python paketinin ilk kararlı sürümüdür. 2.0 geçiş kılavuzu, Rust ve TypeScript ile ortak olan imzalama yapılarını kapsar.

Kurulum

Temel paketi kurun; ayrıca sağlayıcı bağımlılığı gerektiren her backend için birer ek paket (extra) kurun:

pip install solana-keychain # memory, vault and para
pip install 'solana-keychain[aws-kms]' # AWS KMS (boto3)
pip install 'solana-keychain[gcp-kms]' # GCP KMS (google-cloud-kms)
pip install 'solana-keychain[privy]' # Privy
pip install 'solana-keychain[turnkey]' # Turnkey
pip install 'solana-keychain[fireblocks]' # Fireblocks
pip install 'solana-keychain[cdp]' # Coinbase Developer Platform
pip install 'solana-keychain[crossmint]' # Crossmint
pip install 'solana-keychain[dfns]' # Dfns
pip install 'solana-keychain[openfort]' # Openfort
pip install 'solana-keychain[utila]' # Utila
pip install 'solana-keychain[fordefi]' # Fordefi
# Several at once
pip install 'solana-keychain[aws-kms,privy]'

Python 3.10 veya üzeri gerekir. İşlemler, solders VersionedTransaction nesneleridir; legacy, v0 ve v1 mesajlarının tümü kabul edilir; yalnızca use_program_call=True ile kullanılan Fireblocks bunun dışındadır ve yalnızca legacy ve v0 kabul eder.

Memory, Vault ve Para paket kök dizininden içe aktarılabilir. Diğer tüm backend'ler kendi alt modüllerinden içe aktarılır (örneğin solana_keychain.aws_kms); ilgili ek paket (extra) kurulmadan içe aktarılırsa, kurulması gereken ek paketin adını belirten bir ImportError hatası oluşur. Ledger yalnızca Rust'ta desteklenir.

Temel Kullanım

Her backend'in bir config dataclass'ı ve kullanıma hazır bir signer döndüren asenkron bir create_<backend>_signer fabrika fonksiyonu vardır. Tüm imzalama yöntemleri coroutine'dir:

import asyncio
from solana_keychain import MemorySigner
from solders.transaction import VersionedTransaction
async def sign(transaction: VersionedTransaction) -> str:
signer = MemorySigner.from_private_key_file("/path/to/id.json")
print("Signing with:", signer.pubkey)
# Check availability (useful for remote signers)
if not await signer.is_available():
raise RuntimeError("Signer offline")
result = await signer.sign_transaction(transaction)
print("Signature:", result.signature)
print("Fully signed:", result.is_complete)
return result.encoded_transaction # base64 wire transaction

sign_transaction, encoded_transaction, signature, is_complete ve transaction alanlarını içeren bir SignedTransaction döndürür. transaction, yetkili imzalı işlemdir: özellikle sonucu sizin ilettiğiniz nesneden farklı bir nesne olan değiştiren (modifying) bir signer ile çalışırken işleme bu nesneden devam edin.

Birleşik Fabrika

create_keychain_signer, bir backend adı ve o backend'in config dataclass'ını alır; backend'i tembel (lazy) olarak içe aktarır, bu nedenle yalnızca kullandığınız ek paketlerin kurulu olması yeterlidir:

from solana_keychain import create_keychain_signer
from solana_keychain.privy import PrivySignerConfig
signer = await create_keychain_signer(
"privy",
PrivySignerConfig(
app_id="your-app-id",
app_secret="your-app-secret",
wallet_id="your-wallet-id",
),
)

Adlar SUPPORTED_BACKENDS içinde listelenir: aws-kms, cdp, crossmint, dfns, fireblocks, fordefi, gcp-kms, memory, openfort, para, privy, turnkey, utila ve vault. Bilinmeyen bir ad veya yanlış sınıfa ait bir config, SignerErrorCode.CONFIG_ERROR ile SignerError hatası oluşturur. Fabrikanın dönüş türü temel SolanaSigner olarak tanımlıdır; bu yüzden imzalamadan önce isinstance ile daraltın (bkz. Signer Yetenekleri).

Uzak HTTP İstemcileri

Uzak HTTP backend'leri, özel TLS veya proxy kullanımı için isteğe bağlı bir http_client (bir httpx.AsyncClient) kabul eder. Ayarlanmadığında her istek, 60 saniyelik zaman aşımı olan tek kullanımlık bir istemci kullanır; temel URL'de HTTPS zorunludur ve yönlendirmeler reddedilir.

Signer Yetenekleri

Her backend, SolanaSigner ABC sınıfını (pubkey, sign_message, is_available) ve ayrıca tam olarak bir yetenek sınıfını alt sınıf olarak türetir:

  • TransactionSigner: sign_transaction(tx) işleminizi yerinde imzalar ve bir SignedTransaction döndürür. Yayını (broadcast) siz yaparsınız.
  • ModifyingSigner: modify_and_sign_transaction(tx), sağlayıcının işlemi yeniden yazmasına izin verir, ardından yayın yapmadan imzalar. Nesneniz değişmeden kalır; döndürülen SignedTransaction.transaction üzerinden devam edin.
  • SendingSigner: sign_and_send_transaction(tx), sağlayıcı üzerinden imzalar ve yayınlar, ardından zincire işlenen işlemin Signature değerini döndürür. İşleminiz hiçbir zaman değiştirilmez.
BackendYetenek sınıfısign_message
memory, vault, privy, turnkey, aws-kms, fireblocks, gcp-kms, dfns, para, openfortTransactionSignerEvet
cdpTransactionSignerYalnızca UTF-8 payload'lar; aksi halde SERIALIZATION_ERROR
utilaTransactionSignerSIGNING_FAILED hatası verir
fordefi black box (FordefiBlackBoxSigner)TransactionSignerEvet
fordefi native manual (FordefiNativeManualSigner)ModifyingSignerEvet
fordefi native auto (FordefiNativeAutoSigner)SendingSignerEvet
crossmintSendingSignerSIGNING_FAILED hatası verir

isinstance ile daraltın. Tüm yetenek sınıfları paket kök dizininden dışa aktarılır:

from solana_keychain import ModifyingSigner, SendingSigner, TransactionSigner
if isinstance(signer, SendingSigner):
signature = await signer.sign_and_send_transaction(transaction)
elif isinstance(signer, ModifyingSigner):
result = await signer.modify_and_sign_transaction(transaction)
elif isinstance(signer, TransactionSigner):
result = await signer.sign_transaction(transaction)

Başlatma

create_* fabrikaları ve create_keychain_signer, gereken kurulumu sizin yerinize yapar. Privy, Fireblocks, Dfns, Crossmint, Para, Openfort veya Utila signer sınıfını doğrudan oluşturursanız, kullanmadan önce await signer.init() çağırın. O zamana kadar pubkey ve tüm imzalama çağrıları SignerErrorCode.NOT_INITIALIZED hatası verir.

Backend Yapılandırması

Memory

Bir Solana CLI keypair dosyasından, base58 veya "[1,2,...]" biçimli bir dizeden, ham baytlardan ya da bir solders Keypair nesnesinden oluşturun:

from solana_keychain import MemorySigner, MemorySignerConfig, create_memory_signer
from solders.keypair import Keypair
signer = MemorySigner.from_private_key_file("/path/to/id.json")
signer = MemorySigner.from_private_key_string("base58_private_key")
signer = MemorySigner.from_bytes(secret_key_bytes) # 64 or 32 bytes
signer = await create_memory_signer(MemorySignerConfig(keypair=Keypair()))

Anahtar işlem belleğinde durur ve Python bunu sıfırlayamaz (zeroize). Bu backend'i geliştirme ve test için kullanın.

HashiCorp Vault

Anahtar, transit engine içinde bir ed25519 anahtarı olmalıdır. Düz HTTP yalnızca vault server -dev için, loopback adresinde kabul edilir:

from solana_keychain import VaultSignerConfig, create_vault_signer
signer = await create_vault_signer(
VaultSignerConfig(
api_base_url="https://vault.example.com:8200",
token="hvs.xxxxx",
key_name="my-solana-key",
public_key="base58_public_key",
)
)

AWS KMS

key_id, bir ECC_NIST_EDWARDS25519 anahtarının anahtar kimliği (ID), ARN'si veya takma adıdır. Özel kimlik bilgileri veya uç noktalar için önceden oluşturulmuş bir boto3 KMS client iletin; bu durumda region yok sayılır:

from solana_keychain.aws_kms import AwsKmsSignerConfig, create_aws_kms_signer
signer = await create_aws_kms_signer(
AwsKmsSignerConfig(
key_id="alias/my-solana-key",
public_key="base58_public_key",
region="us-east-1", # optional, defaults to the AWS config chain
)
)

GCP KMS

Anahtar sürümü bir EC_SIGN_ED25519 anahtarı olmalıdır. client isteğe bağlı olarak önceden oluşturulmuş bir KeyManagementServiceAsyncClient alır:

from solana_keychain.gcp_kms import GcpKmsSignerConfig, create_gcp_kms_signer
signer = await create_gcp_kms_signer(
GcpKmsSignerConfig(
key_name="projects/my-project/locations/us-east1/keyRings/my-ring/cryptoKeys/my-key/cryptoKeyVersions/1",
public_key="base58_public_key",
)
)

Privy

from solana_keychain.privy import PrivySignerConfig, create_privy_signer
signer = await create_privy_signer(
PrivySignerConfig(
app_id="app_id",
app_secret="app_secret",
wallet_id="wallet_id",
)
)

Bir yetkilendirme anahtarıyla korunan cüzdanlar, authorization_context olarak bir PrivyAuthorizationConfig alır.

Turnkey

from solana_keychain.turnkey import TurnkeySignerConfig, create_turnkey_signer
signer = await create_turnkey_signer(
TurnkeySignerConfig(
api_public_key="api_public_key", # hex P-256
api_private_key="api_private_key", # hex P-256
organization_id="org_id",
private_key_id="private_key_id",
public_key="base58_public_key",
)
)

Fireblocks

from solana_keychain.fireblocks import FireblocksSignerConfig, create_fireblocks_signer
signer = await create_fireblocks_signer(
FireblocksSignerConfig(
api_key="api_key",
private_key_pem="-----BEGIN RSA PRIVATE KEY-----\n...",
vault_account_id="0",
asset_id="SOL", # or "SOL_TEST" for devnet
)
)

use_program_call=True, RAW yerine PROGRAM_CALL işlemiyle imzalar. Yalnızca imzalama olarak gönderilir; böylece Fireblocks işlemi ne yeniden yazar ne de yayınlar, yayını her zamanki gibi siz yaparsınız. Sıcak (hot) cüzdan gerektirir ve çalışma alanınız için Fireblocks tarafından etkinleştirilmiş olmalıdır.

CDP (Coinbase Developer Platform)

from solana_keychain.cdp import CdpSignerConfig, create_cdp_signer
signer = await create_cdp_signer(
CdpSignerConfig(
api_key_id="api_key_id",
api_key_secret="api_key_secret",
wallet_secret="wallet_secret",
address="base58_address",
network="solana", # or "solana-devnet"; required for address lookup tables
)
)

Crossmint

from solana_keychain.crossmint import CrossmintSignerConfig, create_crossmint_signer
signer = await create_crossmint_signer(
CrossmintSignerConfig(
api_key="api_key",
wallet_locator="wallet_locator",
)
)
signature = await signer.sign_and_send_transaction(transaction)

Crossmint yalnızca göndermeye yöneliktir. API'si onaylanmış bir işlemi her zaman sunucu tarafında yürütür ve gas ücretini sponsorlar; bu nedenle CrossmintSigner bir SendingSigner'dır ve sign_message SIGNING_FAILED hatası verir. Döndürülen imza, Crossmint'in zincire işlediği işlemi tanımlar; bu işlem sizinkinden farklı olabilir. signer_secret ayarlandığında (bir xmsk1_... delegated-signer secret'ı) işlemler otomatik olarak onaylanır; bu da neyin onaylanacağı kararını Crossmint'e devreder.

Dfns

from solana_keychain.dfns import DfnsSignerConfig, create_dfns_signer
signer = await create_dfns_signer(
DfnsSignerConfig(
auth_token="auth_token",
cred_id="cred_id",
private_key_pem="-----BEGIN EC PRIVATE KEY-----\n...",
wallet_id="wallet_id",
)
)

Openfort

from solana_keychain.openfort import OpenfortSignerConfig, create_openfort_signer
signer = await create_openfort_signer(
OpenfortSignerConfig(
secret_key="sk_...",
account_id="acc_...",
wallet_secret="wallet_secret",
)
)

Para

from solana_keychain import ParaSignerConfig, create_para_signer
signer = await create_para_signer(
ParaSignerConfig(
api_key="sk_...",
wallet_id="wallet_uuid",
)
)

Utila

Utila yalnızca işlemleri imzalar; sign_message SIGNING_FAILED hatası verir.

from solana_keychain.utila import UtilaSignerConfig, create_utila_signer
signer = await create_utila_signer(
UtilaSignerConfig(
service_account_email="sa@example.com",
service_account_private_key_pem="-----BEGIN PRIVATE KEY-----\n...",
vault_id="vault_id",
wallet_id="wallet_id",
network="networks/solana-devnet",
)
)

Fordefi

Fordefi'nin, oluşturma sırasında chain ve push_mode ile belirlenen üç imzalama modu vardır. create_fordefi_signer sınıfı seçer, her sınıf başka bir sınıf için hazırlanmış config'i reddeder ve üçü de mesaj imzalar:

ModConfigSınıfYöntem
Black boxchain ayarlanmamışFordefiBlackBoxSignersign_transaction
Native autochain ayarlanmış, push_mode ayarlanmamış veya "auto"FordefiNativeAutoSignersign_and_send_transaction
Native manualchain ayarlanmış, push_mode="manual"FordefiNativeManualSignermodify_and_sign_transaction

API istekleri ECDSA P-256 istek imzasıyla doğrulanır: anahtarı private_key_pem olarak verin veya request_signer olarak bir FordefiRequestSigner alt sınıfı ileterek anahtarı bir KMS/HSM içinde tutun.

Native auto modu: chain değerini ("solana_devnet" veya "solana_mainnet") ayarlayın; Fordefi blockhash ve ücretleri değiştirebilir, ardından işlemi kendisi imzalar ve yayınlar. Yalnızca gerekli tek imzalayanın vault olduğu imzasız bir işlemi kabul eder. fee, Fordefi'ye olduğu gibi iletilir:

import os
from solana_keychain.fordefi import FordefiSignerConfig, create_fordefi_signer
signer = await create_fordefi_signer(
FordefiSignerConfig(
access_token=os.environ["FORDEFI_ACCESS_TOKEN"],
vault_id=os.environ["FORDEFI_VAULT_ID"],
public_key=os.environ["FORDEFI_PUBLIC_KEY"], # vault address (base58)
private_key_pem=open("./secret/private.pem").read(),
chain="solana_devnet",
fee={"type": "custom", "priority_fee": "1000"}, # optional
)
)
signature = await signer.sign_and_send_transaction(transaction)

Native manual modu: chain değerini ve push_mode="manual" ayarlarını yapın. Fordefi mesajı yeniden yazar (güncel blockhash, Compute Budget ücret talimatları) ve imzalar, ancak yayınlamaz. Döndürülen işlem, gönderdiğiniz işlemin yerine geçer; bu yüzden her zaman result.transaction üzerinden devam edin. Fordefi ücret ödeyen (fee payer) olmalı ve diğer tüm gerekli imzalayanlardan önce imzalamalıdır: zaten imza taşıyan bir işlem kabul edilir, ancak yeniden yazma bu imzaları geçersiz kılar. Yeniden yazma işlemi fark (diff) olarak sunulmaz; bu yüzden yayınlamadan önce sonucu inceleyin ve gecikmeden yayınlayın, çünkü Fordefi yeni blockhash'in geçerlilik sona erme yüksekliğini döndürmez.

signer = await create_fordefi_signer(
FordefiSignerConfig(
access_token=os.environ["FORDEFI_ACCESS_TOKEN"],
vault_id=os.environ["FORDEFI_VAULT_ID"],
public_key=os.environ["FORDEFI_PUBLIC_KEY"],
private_key_pem=open("./secret/private.pem").read(),
chain="solana_devnet",
push_mode="manual",
)
)
result = await signer.modify_and_sign_transaction(transaction)
... # inspect result.transaction, then add any remaining signatures

İncelediğiniz işlemi İmzala ve Gönder bölümündeki gibi yayınlayın; gönderim başarısız olursa yeniden denemeden önce durumu mutabakata bağlayın (reconcile).

Black box modu: chain değerini atlayın. Fordefi, mesajınızın baytlarını olduğu gibi imzalar ve yayınlamaz. Bunu bir Fordefi black box vault ile kullanın.

signer = await create_fordefi_signer(
FordefiSignerConfig(
access_token=os.environ["FORDEFI_ACCESS_TOKEN"],
vault_id=os.environ["FORDEFI_BB_VAULT_ID"],
public_key=os.environ["FORDEFI_BB_PUBLIC_KEY"],
private_key_pem=open("./secret/private.pem").read(),
)
)

İmzala ve Gönder

sign_and_send_transaction, signer'ın yapısı ne olursa olsun bir işlemi zincire ulaştırır. Bir SendingSigner sağlayıcısı üzerinden yayınlar ve gönderme fonksiyonunuz hiç çağrılmaz. Bir TransactionSigner veya ModifyingSigner imzalar, base64 kodlu sonucu ise gönderme fonksiyonunuz yayınlar (paketin RPC istemcisi yoktur):

import httpx
from solana_keychain import sign_and_send_transaction
from solders.signature import Signature
async def send(encoded: str) -> Signature:
async with httpx.AsyncClient() as client:
response = await client.post(
"https://api.devnet.solana.com",
json={
"jsonrpc": "2.0",
"id": 1,
"method": "sendTransaction",
"params": [encoded, {"encoding": "base64"}],
},
)
return Signature.from_string(response.json()["result"])
signature = await sign_and_send_transaction(signer, transaction, send)

Gönderme fonksiyonu olmayan, yalnızca imzalayan bir signer CONFIG_ERROR hatası verir; imzalamadan sonra hâlâ imzası eksik olan bir işlem ise SIGNING_FAILED hatası verir.

Hata Yönetimi

Her hata, SignerErrorCode içinden sabit bir code taşıyan bir SignerError'dır: BROADCAST_UNCONFIRMED, CONFIG_ERROR, EXPECTED_SOLANA_SIGNER, HTTP_ERROR, INVALID_PRIVATE_KEY, INVALID_PUBLIC_KEY, IO_ERROR, NOT_AVAILABLE, NOT_INITIALIZED, OTHER, PARSING_ERROR, REMOTE_API_ERROR, SERIALIZATION_ERROR ve SIGNING_FAILED. Mesaja değil code değerine göre eşleştirin: str() ve repr() yalnızca sabit, genel bir mesaj taşır; asla anahtar materyali veya ham sağlayıcı yanıtları içermez. Hata bir sağlayıcı yanıtından kaynaklandığında status_code ve provider_error_code ayarlanır.

SignerErrorCode.BROADCAST_UNCONFIRMED ("SIGNER_BROADCAST_UNCONFIRMED"), işlemin zincire işlenmiş olabileceği anlamına gelir:

  • Crossmint ve Fordefi native auto'da, oluşturma isteği kabul edildiğinde provider_transaction_id ayarlanır ve idempotency_key, oluşturma isteğinin gönderildiği mesajdan türetilen anahtarı taşır. Bayt düzeyinde aynı işlemi yeniden göndermek güvenlidir; yeniden oluşturulmuş bir işlem (örneğin yeni bir blockhash ile) yeni bir transfer sayılır.
  • sign_and_send_transaction kaynaklı durumda, başarısız olan bir gönderme fonksiyonu bu hatayı, transaction_signature değeri tamamlanan işlemin imzasına ayarlanmış şekilde oluşturur.
  • Fireblocks, bu hatayı yalnızca bir yoklama (poll), use_program_call işleminin yalnızca imzalama olarak gönderilmesine rağmen Fireblocks tarafından yayınlandığını gösterirse oluşturur.
from solana_keychain import SignerError, SignerErrorCode
try:
signature = await sign_and_send_transaction(signer, transaction, send)
except SignerError as error:
if error.code is SignerErrorCode.BROADCAST_UNCONFIRMED:
reconcile(
error.provider_transaction_id,
error.idempotency_key,
error.transaction_signature,
)
raise

İptal edilen bir çağrı, hiçbir alan taşımayan asyncio.CancelledError hatasını yeniden oluşturur. İptalden önce sağlayıcının kabul ettiği bir kimliği kurtarmak için, Crossmint veya Fordefi native auto config'inin pending_transaction_id alanına bir PendingTransactionId() (solana_keychain.core içinden) iletin ve iptalden sonra .get() ile okuyun. Yeniden denemeden önce sağlayıcıyla mutabakat sağlayın.

Keychain, işlemin ne yaptığını değil, imzalama adımını doğrular: sağlayıcının döndürdüğü imza, eklenmeden önce yerel olarak hesaplanan mesaja karşı ed25519 ile doğrulanır. Python anahtar arabelleklerini sıfırlayamadığı için, yerel anahtar kullanan backend'lerde (Memory ve uzak backend config'lerinde tutulan API anahtarları ile PEM'ler) işlemin tüm belleğini hassas kabul edin. Her imzalama yapısının neyi garanti ettiği için güvenlik modeline bakın.

Özel Signer'lar Ekleme

Arka ucunuzla eşleşen tek yetenek sınıfını (TransactionSigner, ModifyingSigner veya SendingSigner) solana_keychain.core içinden alt sınıf olarak türetin. Ek anahtar yönetimi hizmetlerini entegre etmek için İmzalayıcı Ekleme kılavuzuna bakın.

Kaynaklar

Is this page helpful?

© 2026 Solana Vakfı. Tüm hakları saklıdır.