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 ve sağlayıcı bağımlılığı gerektiren her backend için bir ek paketi yükleyin:

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, ancak use_program_call=True ile kullanılan Fireblocks yalnızca legacy ve v0 kabul eder.

Memory, Vault ve Para paket kökünden içe aktarılabilir. Diğer tüm backend'ler kendi alt modülünden içe aktarılır (örneğin solana_keychain.aws_kms) ve ek paketi olmadan içe aktarıldığında, yüklenmesi gereken ek paketin adını belirten bir ImportError hatası verir. Ledger yalnızca Rust'ta bulunur.

Temel Kullanım

Her backend'in bir yapılandırma dataclass'ı ve kullanıma hazır bir signer döndüren asenkron bir create_<backend>_signer factory'si vardır. Tüm imzalama metotları 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ğinizden farklı bir nesne olan değiştirici (modifying) bir signer kullanırken işleme bu nesneden devam edin.

Birleşik Factory

create_keychain_signer bir backend adı ve o backend'in yapılandırma dataclass'ını alır, backend'i tembel (lazy) biçimde içe aktarır; bu sayede yalnızca kullandığınız ek paketlerin yüklenmesi 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 yapılandırma, SignerErrorCode.CONFIG_ERROR ile SignerError hatası verir. Factory'nin dönüş tipi temel SolanaSigner olarak belirtilmiştir; bu nedenle 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ına sahip, tek kullanımlık bir istemci kullanır; temel URL için HTTPS zorunludur ve yönlendirmeler reddedilir.

Signer Yetenekleri

Her backend, SolanaSigner ABC'sinin (pubkey, sign_message, is_available) alt sınıfıdır ve ayrıca tam olarak bir yetenek sınıfı içerir:

  • TransactionSigner: sign_transaction(tx) işleminizi yerinde imzalar ve bir SignedTransaction döndürür. Yayınlamayı 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ınlamadan imzalar. Nesneniz değiştirilmez; döndürülen SignedTransaction.transaction üzerinden devam edin.
  • SendingSigner: sign_and_send_transaction(tx) sağlayıcı üzerinden imzalar ve yayınlar, zincire giren 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 yükleri, aksi halde SERIALIZATION_ERROR
utilaTransactionSignerSIGNING_FAILED hatası verir
fordefi kara kutu (FordefiBlackBoxSigner)TransactionSignerEvet
fordefi yerel manuel (FordefiNativeManualSigner)ModifyingSignerEvet
fordefi yerel otomatik (FordefiNativeAutoSigner)SendingSignerEvet
crossmintSendingSignerSIGNING_FAILED hatası verir

isinstance ile daraltın. Tüm yetenek sınıfları paket kökünden 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_* factory'leri ve create_keychain_signer, gerekli kurulumu sizin için 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, bir base58 veya "[1,2,...]" dizesinden, 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. Bu backend'i geliştirme ve test için kullanın.

HashiCorp Vault

Anahtar, transit motorunda bir ed25519 anahtarı olmalıdır. Düz HTTP yalnızca vault server -dev için kullanılan bir 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ı için anahtar kimliği, ARN veya takma addı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; dolayısıyla Fireblocks işlemi ne yeniden yazar ne de yayınlar ve yayınlamayı her zamanki gibi siz yaparsınız. Bir hot wallet 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önderim yapar. API'si onaylanmış bir işlemi her zaman sunucu tarafında yürütür ve gas ücretini karşılar; 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 sizin işleminizden farklı olabilir. signer_secret (bir xmsk1_... delege edilmiş signer gizli anahtarı) ayarlandığında 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 üç imzalama modu vardır; bunlar oluşturma sırasında chain ve push_mode ile belirlenir. create_fordefi_signer sınıfı seçer, her sınıf başka bir mod için hazırlanmış yapılandırmayı reddeder ve üçü de mesajları imzalar:

ModYapılandırmaSınıfMetot
Kara kutuchain ayarlanmamışFordefiBlackBoxSignersign_transaction
Yerel otomatikchain ayarlı, push_mode ayarlanmamış veya "auto"FordefiNativeAutoSignersign_and_send_transaction
Yerel manuelchain ayarlı, push_mode="manual"FordefiNativeManualSignermodify_and_sign_transaction

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

Yerel otomatik mod: chain değerini ("solana_devnet" veya "solana_mainnet") ayarlayın; Fordefi blockhash'i 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)

Yerel manuel mod: chain değerini ayarlayın ve push_mode="manual" kullanı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 yerini alır; bu yüzden her zaman result.transaction üzerinden devam edin. Fordefi ücret ödeyen olmalı ve gerekli diğer imzalayanlardan önce imzalamalıdır: zaten imza taşıyan bir işlem kabul edilir, ancak yeniden yazma bu imzaları geçersiz kılar. Yeniden yazmanın farkı (diff) çıkarılmaz; 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

İncelenen 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.

Kara kutu modu: chain değerini atlayın. Fordefi mesajınızın tam bayt dizisini imzalar ve yayınlamaz. Bunu bir Fordefi kara kutu 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önderim fonksiyonunuz hiçbir zaman çağrılmaz. Bir TransactionSigner veya ModifyingSigner imzalar ve base64 kodlu sonucu gönderim 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önderim fonksiyonu olmayan, yalnızca imzalama yapan 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 değerine sahip 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; anahtar materyalini veya ham sağlayıcı yanıtlarını asla içermez. status_code ve provider_error_code, hata bir sağlayıcı yanıtından kaynaklandığında ayarlanır.

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

  • Crossmint ve Fordefi yerel otomatik modda, 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 transferdir.
  • sign_and_send_transaction içinde, başarısız olan bir gönderim fonksiyonu bu hatayı, transaction_signature değeri tamamlanan işlemin imzasına ayarlanmış şekilde verir.
  • Fireblocks, bunu yalnızca bir yoklama (poll), yalnızca imzalama olarak gönderilmiş bir use_program_call işleminin buna rağmen Fireblocks tarafından yayınlandığını gösterirse verir.
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 verir. Sağlayıcının iptalden önce kabul ettiği bir kimliği kurtarmak için, Crossmint veya Fordefi yerel otomatik yapılandırmasının 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 yapı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ırlayamaz; bu nedenle yerel anahtarlı backend'lerde (Memory ile uzak backend yapılandırmalarında tutulan API anahtarları ve PEM'ler) tüm işlem belleğini hassas kabul edin. Her imzalama yapısının neyi garanti ettiği için güvenlik modeline bakın.

Özel Signer Ekleme

Backend'inize uyan tek bir yetenek sınıfını (TransactionSigner, ModifyingSigner veya SendingSigner) solana_keychain.core içinden alt sınıf olarak türetin. Ek anahtar yönetim 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.