Go

2.0.0, Go modüllerinin ilk kararlı sürümüdür; bu nedenle taşınacak bir şey yoktur. 2.0 geçiş kılavuzu, Rust ve TypeScript için aynı yetenek ayrımını ele alır.

Kurulum

Her arka uç kendi Go modülüdür; bu sayede derlemeniz ve modül grafiğiniz yalnızca içe aktardığınız arka uçları içerir:

go get github.com/solana-foundation/solana-keychain/go/core/v2 # Interfaces, errors, helpers
go get github.com/solana-foundation/solana-keychain/go/signers/memory/v2 # Local keypair signer
go get github.com/solana-foundation/solana-keychain/go/signers/vault/v2 # HashiCorp Vault
go get github.com/solana-foundation/solana-keychain/go/signers/awskms/v2 # AWS KMS
go get github.com/solana-foundation/solana-keychain/go/signers/gcpkms/v2 # GCP KMS
go get github.com/solana-foundation/solana-keychain/go/signers/privy/v2 # Privy
go get github.com/solana-foundation/solana-keychain/go/signers/turnkey/v2 # Turnkey
go get github.com/solana-foundation/solana-keychain/go/signers/fireblocks/v2 # Fireblocks
go get github.com/solana-foundation/solana-keychain/go/signers/cdp/v2 # Coinbase Developer Platform
go get github.com/solana-foundation/solana-keychain/go/signers/crossmint/v2 # Crossmint
go get github.com/solana-foundation/solana-keychain/go/signers/dfns/v2 # Dfns
go get github.com/solana-foundation/solana-keychain/go/signers/openfort/v2 # Openfort
go get github.com/solana-foundation/solana-keychain/go/signers/para/v2 # Para
go get github.com/solana-foundation/solana-keychain/go/signers/utila/v2 # Utila
go get github.com/solana-foundation/solana-keychain/go/signers/fordefi/v2 # Fordefi

Modüller go/<module>/v2.0.0 biçiminde etiketlenir (örneğin go/signers/memory/v2.0.0). gcpkms hariç her modül Go 1.25.0 gerektirir; gcpkms, google.golang.org/api tarafından belirlenen alt sınır nedeniyle Go 1.25.8 gerektirir. Ledger yalnızca Rust'a özgüdür ve Go modülü yoktur.

solana-go v2 ve v1 İşlemleri

Modüller github.com/solana-foundation/solana-go/v2 v2.0.0 üzerine inşa edilmiştir ve onun *solana.Transaction türünü alır. Legacy, v0 ve v1 (solana.MessageVersionV1) işlemleri desteklenir; yalnızca UseProgramCall: true ile kullanılan Fireblocks bunun dışındadır ve yalnızca legacy ile v0 kabul eder.

Temel Kullanım

Her imzalayıcı, temel core.SolanaSigner arayüzünü (Pubkey, SignMessage, IsAvailable) uygular. Metotlar bir context.Context alır ve engelleyicidir (blocking). Her arka uç ayrıca tam olarak bir yetenek arayüzü uygular:

  • core.TransactionSigner: SignTransaction, işleminizi olduğu gibi imzalar.
  • core.ModifyingSigner: ModifyAndSignTransaction, sağlayıcının işlemi yeniden yazmasına izin verir, ardından imzalar.
  • core.SendingSigner: SignAndSendTransaction, işlemin sağlayıcı tarafından imzalanıp yayınlanmasını sağlar.

Her arka uç paketi bir Config struct'ı ve bir New yapıcısı sunar:

import (
"context"
"fmt"
"github.com/solana-foundation/solana-go/v2"
"github.com/solana-foundation/solana-keychain/go/core/v2"
"github.com/solana-foundation/solana-keychain/go/signers/memory/v2"
)
func signWithKeychain(ctx context.Context, tx *solana.Transaction) error {
signer, err := memory.New(memory.Config{PrivateKeyPath: "/path/to/id.json"})
if err != nil {
return err
}
if !signer.IsAvailable(ctx) {
return core.NewSignerError(core.CodeNotAvailable, "signer offline")
}
result, err := signer.SignTransaction(ctx, tx)
if err != nil {
return err
}
fmt.Println("signature:", result.Signature)
fmt.Println("complete:", result.IsComplete())
// result.EncodedTransaction is the base64 wire transaction
return nil
}

SignTransaction ve ModifyAndSignTransaction, bir core.SignedTransaction (EncodedTransaction, Signature, Completeness) döndürür. Uzak HTTP arka uçları isteğe bağlı bir HTTPClient ve HTTPClientConfig (zaman aşımları) kabul eder. Varsayılan istemci HTTPS'i zorunlu kılar; kendi istemcinizi sağlarsanız bu zorunluluk atlanır ve güvenlik duruşu sizin sorumluluğunuzda olur.

İmzalayıcı Yetenekleri

İşlem imzalayamayan bir arka uçta SignTransaction metodu hiç bulunmaz; dolayısıyla yetenek, somut türler için derleme zamanında belli olan bir olgudur, bir core.SolanaSigner için ise tür doğrulamasıyla (type assertion) anlaşılır:

Arka uçYetenekSignMessage
memory, vault, privy, turnkey, awskms, gcpkms, fireblocks, dfns, para, openfortTransactionSignerEvet
cdpTransactionSignerYalnızca UTF-8 yükleri
utilaTransactionSignerCodeSigningFailed ile başarısız olur
fordefi black box (fordefi.BlackBoxSigner)TransactionSignerEvet
fordefi native manual (fordefi.NativeManualSigner)ModifyingSignerEvet
fordefi native auto (fordefi.NativeAutoSigner)SendingSignerEvet
crossmintSendingSignerCodeSigningFailed ile başarısız olur
switch s := signer.(type) {
case core.SendingSigner:
sig, err := s.SignAndSendTransaction(ctx, tx)
case core.ModifyingSigner:
signed, err := s.ModifyAndSignTransaction(ctx, tx)
case core.TransactionSigner:
signed, err := s.SignTransaction(ctx, tx)
}

Başlatma

Ayrı bir Init adımı yoktur. Privy, Fireblocks, Dfns, Crossmint, Para, Openfort ve Utila cüzdan adresini New içinde çözümler; yapıcılarının bir context.Context almasının nedeni budur. İmzalayıcıları her zaman New ile oluşturun: sıfır değerli bir Crossmint, Para veya Utila imzalayıcısı, sıfır adres için imzalamak yerine CodeNotInitialized hatasıyla başarısız olur.

Herhangi Bir İmzalayıcıyla İmzalama ve Gönderme

core.SignAndSendTransaction, imzalayıcının yapısı ne olursa olsun bir işlemi zincire ulaştırır. Bir SendingSigner, işlemi sağlayıcısı üzerinden yayınlar ve gönderme fonksiyonunu yok sayar; diğer tüm yapılar imzalar ve base64 sonucu sizin fonksiyonunuz yayınlar. Bir ModifyingSigner için bu sonuç, sağlayıcısının yeniden yazdığı işlemdir. Core'un herhangi bir RPC bağımlılığı yoktur:

import "github.com/solana-foundation/solana-go/v2/rpc"
client := rpc.New("https://api.devnet.solana.com")
sig, err := core.SignAndSendTransaction(ctx, signer, tx,
func(ctx context.Context, encoded string) (solana.Signature, error) {
return client.SendEncodedTransaction(ctx, encoded)
})

Toplu İmzalama

Toplu imzalama, serbest yardımcı fonksiyonlar olarak sunulur; eşzamanlı çalışır ve hız sınırlı API'ler için isteğe bağlı olarak istek başına kademeli gecikme uygulanabilir:

sigs, err := core.SignMessages(ctx, signer, [][]byte{msg1, msg2}, core.BatchOptions{
MaxConcurrency: 4, // 0 = unbounded
RequestDelay: 50 * time.Millisecond,
})
signed, err := core.SignTransactions(ctx, signer, txs, core.BatchOptions{})

core.SignTransactions bir core.TransactionSigner alır; bu nedenle yayını kendisi yöneten imzalayıcılar (Crossmint, Fordefi native auto) ve Fordefi native manual bu yolla toplu işlenemez; bunları her seferinde tek bir işlemle çağırın. Çağrıları sağlayıcı tarafında iş oluşturan bir imzalayıcı (UseProgramCall ile Fireblocks) bunu core.BatchServerSideEffects aracılığıyla bildirir ve toplu işlem bu durumda ardışık olarak çalışır.

Arka Uç Yapılandırması

Memory

PrivateKey (ham bayt), PrivateKeyString (base58 veya bir [1,2,...] bayt dizisi) ya da PrivateKeyPath (Solana CLI keypair dosyası) seçeneklerinden tam olarak birini sağlayın:

import "github.com/solana-foundation/solana-keychain/go/signers/memory/v2"
signer, err := memory.New(memory.Config{
PrivateKeyPath: "/path/to/id.json",
})

Go'da belleği sıfırlamanın güvenilir bir yolu yoktur: çöp toplayıcı, toplama gerçekleşene kadar anahtar baytlarını kopyalayıp tutabilir (memory keypair'leri ile Crossmint ve Openfort'un yerel olarak türettiği anahtarlar dahil). Yerel anahtar kullanan arka uçları kullanırken sürecin tüm belleğini hassas kabul edin.

HashiCorp Vault

import "github.com/solana-foundation/solana-keychain/go/signers/vault/v2"
signer, err := vault.New(vault.Config{
VaultAddr: "https://vault.example.com:8200",
Token: "hvs.xxxxx",
KeyName: "my-solana-key",
Pubkey: "base58_public_key",
})

AWS KMS

import "github.com/solana-foundation/solana-keychain/go/signers/awskms/v2"
signer, err := awskms.New(ctx, awskms.Config{
KeyID: "alias/my-solana-key",
PublicKey: "base58_public_key",
Region: "us-east-1", // optional
})

GCP KMS

import "github.com/solana-foundation/solana-keychain/go/signers/gcpkms/v2"
signer, err := gcpkms.New(ctx, gcpkms.Config{
KeyName: "projects/my-project/locations/us-east1/keyRings/my-ring/cryptoKeys/my-key/cryptoKeyVersions/1",
PublicKey: "base58_public_key",
})
if err != nil {
return err
}
defer signer.Close()

Privy

import "github.com/solana-foundation/solana-keychain/go/signers/privy/v2"
signer, err := privy.New(ctx, privy.Config{
AppID: "app_id",
AppSecret: "app_secret",
WalletID: "wallet_id",
})

Turnkey

import "github.com/solana-foundation/solana-keychain/go/signers/turnkey/v2"
signer, err := turnkey.New(turnkey.Config{
APIPublicKey: "api_public_key",
APIPrivateKey: "api_private_key",
OrganizationID: "org_id",
PrivateKeyID: "private_key_id",
PublicKey: "base58_public_key",
})

Fireblocks

import "github.com/solana-foundation/solana-keychain/go/signers/fireblocks/v2"
signer, err := fireblocks.New(ctx, fireblocks.Config{
APIKey: "api_key",
PrivateKeyPEM: "-----BEGIN RSA PRIVATE KEY-----\n...",
VaultAccountID: "0",
AssetID: "SOL", // or "SOL_TEST" for devnet
UseProgramCall: false, // true signs via sign-only PROGRAM_CALL (legacy/v0, hot wallet)
})

CDP (Coinbase Developer Platform)

import "github.com/solana-foundation/solana-keychain/go/signers/cdp/v2"
signer, err := cdp.New(cdp.Config{
APIKeyID: "api_key_id",
APIKeySecret: "api_key_secret", // base64 Ed25519
WalletSecret: "wallet_secret", // base64 PKCS#8 DER
Address: "base58_address",
Network: cdp.NetworkMainnet, // or cdp.NetworkDevnet; required for address lookup tables
})

CDP'nin SignMessage metodu yalnızca UTF-8 yüklerini kabul eder.

Crossmint

Crossmint yalnızca göndericidir: API'si onaylanan her işlemi sunucu tarafında yürütür; bu nedenle *crossmint.Signer türünde SignAndSendTransaction vardır, SignTransaction yoktur. İşleminiz hiçbir zaman değiştirilmez; döndürülen imza, Crossmint'in zincire işlediği işlemi tanımlar ve Crossmint gas ücretini sponsorlarsa bu işlem sizinkinden farklı olabilir.

import "github.com/solana-foundation/solana-keychain/go/signers/crossmint/v2"
signer, err := crossmint.New(ctx, crossmint.Config{
APIKey: "api_key",
WalletLocator: "wallet_locator",
SignerSecret: "", // optional xmsk1_ secret: auto-approves what Crossmint presents
})
sig, err := signer.SignAndSendTransaction(ctx, tx)

Dfns

import "github.com/solana-foundation/solana-keychain/go/signers/dfns/v2"
signer, err := dfns.New(ctx, dfns.Config{
AuthToken: "auth_token",
CredID: "cred_id",
PrivateKeyPEM: "-----BEGIN EC PRIVATE KEY-----\n...",
WalletID: "wallet_id",
})

Openfort

import "github.com/solana-foundation/solana-keychain/go/signers/openfort/v2"
signer, err := openfort.New(ctx, openfort.Config{
SecretKey: "sk_live_...",
AccountID: "acc_...",
WalletSecret: "wallet_secret", // base64 PKCS#8 DER or PEM
})

Para

import "github.com/solana-foundation/solana-keychain/go/signers/para/v2"
signer, err := para.New(ctx, para.Config{
APIKey: "sk_...",
WalletID: "wallet_id",
})

Utila

Utila yalnızca işlem imzalar; SignMessage başarısız olur ve imzalanmış işlemi siz kendiniz yayınlarsınız.

import "github.com/solana-foundation/solana-keychain/go/signers/utila/v2"
signer, err := utila.New(ctx, utila.Config{
ServiceAccountEmail: "sa@example.com",
ServiceAccountPrivateKeyPEM: "-----BEGIN PRIVATE KEY-----\n...",
VaultID: "vault_id",
WalletID: "wallet_id",
Network: "networks/solana-devnet",
})

Fordefi

Fordefi üç imzalayıcı türüyle gelir; bunlar oluşturma sırasında Config.Chain ve Config.PushMode ile belirlenir. Üçü de mesaj imzalar:

ConfigTürGiriş noktası
Chain ayarlanmamış*fordefi.BlackBoxSignerSignTransaction
Chain ayarlı, PushMode ayarlanmamış veya PushModeAuto*fordefi.NativeAutoSignerSignAndSendTransaction
Chain ayarlı, PushMode: PushModeManual*fordefi.NativeManualSignerModifyAndSignTransaction

fordefi.New yapılandırmaya göre yönlendirme yapar ve bir core.SolanaSigner döndürür; fordefi.NewBlackBox, fordefi.NewNativeAuto ve fordefi.NewNativeManual somut türü döndürür ve diğer modların yapılandırmalarını reddeder. API istekleri bir ECDSA P-256 istek imzasıyla doğrulanır: PrivateKeyPEM seçeneğini ya da bu anahtarı bir KMS/HSM içinde tutmak için bir RequestSigner seçeneğini, tam olarak birini sağlayın.

Native auto modu: Fordefi blockhash ve ücretleri değiştirebilir, ardından imzalar ve yayınlar. Yalnızca gerekli tek imzalayıcısı vault olan, imzalanmamış bir işlemi kabul eder.

import "github.com/solana-foundation/solana-keychain/go/signers/fordefi/v2"
signer, err := fordefi.NewNativeAuto(ctx, fordefi.Config{
AccessToken: os.Getenv("FORDEFI_ACCESS_TOKEN"),
VaultID: os.Getenv("FORDEFI_VAULT_ID"),
PublicKey: os.Getenv("FORDEFI_PUBLIC_KEY"), // Solana vault address (base58)
PrivateKeyPEM: string(pemBytes),
Chain: fordefi.ChainSolanaDevnet, // or fordefi.ChainSolanaMainnet
Fee: &fordefi.Fee{
Type: fordefi.FeeTypePriority,
PriorityLevel: fordefi.PriorityMedium,
},
})
sig, err := signer.SignAndSendTransaction(ctx, tx)

Native manual modu: PushMode: fordefi.PushModeManual olarak ayarlayın. Fordefi mesajı yeniden yazar (güncel blockhash, Compute Budget ücret talimatları) ve yayınlamadan imzalar. ModifyAndSignTransaction, tx değerini Fordefi'nin imzaladığı işlemle değiştirir: her zaman bundan devam edin. Fordefi ücret ödeyen olmalı ve diğer tüm gerekli imzalayıcılardan önce imzalamalıdır, çünkü yeniden yazma mevcut imzaları geçersiz kılar. Yeniden yazma için fark (diff) çıkarılmaz; bu nedenle yayınlamadan önce sonucu inceleyin.

signer, err := fordefi.NewNativeManual(ctx, fordefi.Config{
AccessToken: os.Getenv("FORDEFI_ACCESS_TOKEN"),
VaultID: os.Getenv("FORDEFI_VAULT_ID"),
PublicKey: os.Getenv("FORDEFI_PUBLIC_KEY"),
PrivateKeyPEM: string(pemBytes),
Chain: fordefi.ChainSolanaDevnet,
PushMode: fordefi.PushModeManual,
})
signed, err := signer.ModifyAndSignTransaction(ctx, tx)

Black box modu: Chain değerini ayarlamadan bırakın. Fordefi tam olarak sizin mesaj baytlarınızı imzalar ve yayınlamaz. Bunu bir Fordefi black box vault ile kullanın.

signer, err := fordefi.NewBlackBox(ctx, fordefi.Config{
AccessToken: os.Getenv("FORDEFI_ACCESS_TOKEN"),
VaultID: os.Getenv("FORDEFI_BB_VAULT_ID"),
PublicKey: os.Getenv("FORDEFI_BB_PUBLIC_KEY"),
PrivateKeyPEM: string(pemBytes),
})

Neden Çatı Paket Yok?

Rust'ta bir Signer enum'u, TypeScript'te createKeychainSigner vardır; Go'da bilerek ikisi de yoktur. Go, çalışma zamanı yönlendirme switch'i boyunca ölü kodu elemez; bu yüzden bir çatı paket, her arka ucun satıcı SDK'sını (AWS, GCP ve diğerleri) her tüketicinin derlemesine dahil etmeye zorlardı. İhtiyacınız olan arka uç paketini içe aktarmak, seçicinin kendisidir. Çalışma zamanında bir arka uç seçmek için, switch'i yalnızca desteklediğiniz arka uçlar üzerinden kendi kodunuzda yazın ve sonucu bir core.SolanaSigner olarak tutun.

Hata Yönetimi

Her hata, kararlı bir Code değerine (CodeConfigError, CodeHTTPError, CodeRemoteAPIError, CodeSigningFailed, CodeNotInitialized, CodeBroadcastUnconfirmed ve diğerleri) sahip bir *core.SignerError'dır. Error(), her kod için yalnızca sabit bir mesaj döndürür; anahtar materyalini veya ham sağlayıcı yanıtlarını asla döndürmez. errors.As, errors.Is(err, &core.SignerError{Code: ...}) veya core.CodeOf(err) ile eşleştirin.

Crossmint ve Fordefi native auto modunda, bir hata hiçbir şeyin zincire işlenmediği anlamına gelmez. Sağlayıcı işlemi kabul etmiş olabileceği durumda kod core.CodeBroadcastUnconfirmed ("SIGNER_BROADCAST_UNCONFIRMED") olur. Oluşturma isteği kabul edildiğinde ProviderTxID ayarlanır ve IdempotencyKey, mesajdan türetilen anahtarı taşır. Bayt düzeyinde özdeş işlemi yeniden göndermek güvenlidir; yeniden oluşturulmuş bir işlem (örneğin yeni bir blockhash ile) yeni bir transferdir. core.SignAndSendTransaction, gönderme fonksiyonunuz başarısız olduğunda da bu kodu bildirir; ücret ödeyenin imzası TransactionSignature içinde yer alır. Fireblocks PROGRAM_CALL yalnızca imzalama yapar ve anahtar göndermez; bu kodu yalnızca bir sorgulama Fireblocks'un yine de yayın yaptığını gösterdiğinde bildirir.

sig, err := core.SignAndSendTransaction(ctx, signer, tx, send)
var se *core.SignerError
if errors.As(err, &se) && se.Code == core.CodeBroadcastUnconfirmed {
// Reconcile se.ProviderTxID, se.IdempotencyKey or se.TransactionSignature
// with the provider before retrying.
}

Her imzalama yapısının neyi garanti ettiği için güvenlik modeline, tam modül listesi için Go README dosyasına, API referansı için ise pkg.go.dev adresine bakın.

Özel İmzalayıcı Ekleme

core.SolanaSigner arayüzünü ve tam olarak bir yetenek arayüzünü uygulayın; arka ucunuzun yerine getiremeyeceği hiçbir metodu eklemeyin: çağıranlar yeteneği tür doğrulamasıyla tespit eder. Ek anahtar yönetim hizmetlerini entegre etmek için İmzalayıcı Ekleme kılavuzuna bakın.

Is this page helpful?

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