2.0.0 is de eerste stabiele release van de Go-modules, dus er valt niets te migreren. De 2.0-migratiegids behandelt dezelfde opsplitsing van mogelijkheden voor Rust en TypeScript.
Installatie
Elke backend is een eigen Go-module, zodat je build en je modulegraaf alleen de backends bevatten die je importeert:
go get github.com/solana-foundation/solana-keychain/go/core/v2 # Interfaces, errors, helpersgo get github.com/solana-foundation/solana-keychain/go/signers/memory/v2 # Local keypair signergo get github.com/solana-foundation/solana-keychain/go/signers/vault/v2 # HashiCorp Vaultgo get github.com/solana-foundation/solana-keychain/go/signers/awskms/v2 # AWS KMSgo get github.com/solana-foundation/solana-keychain/go/signers/gcpkms/v2 # GCP KMSgo get github.com/solana-foundation/solana-keychain/go/signers/privy/v2 # Privygo get github.com/solana-foundation/solana-keychain/go/signers/turnkey/v2 # Turnkeygo get github.com/solana-foundation/solana-keychain/go/signers/fireblocks/v2 # Fireblocksgo get github.com/solana-foundation/solana-keychain/go/signers/cdp/v2 # Coinbase Developer Platformgo get github.com/solana-foundation/solana-keychain/go/signers/crossmint/v2 # Crossmintgo get github.com/solana-foundation/solana-keychain/go/signers/dfns/v2 # Dfnsgo get github.com/solana-foundation/solana-keychain/go/signers/openfort/v2 # Openfortgo get github.com/solana-foundation/solana-keychain/go/signers/para/v2 # Parago get github.com/solana-foundation/solana-keychain/go/signers/utila/v2 # Utilago get github.com/solana-foundation/solana-keychain/go/signers/fordefi/v2 # Fordefi
Modules krijgen de tag go/<module>/v2.0.0 (bijvoorbeeld
go/signers/memory/v2.0.0). Elke module vereist Go 1.25.0, behalve gcpkms,
die Go 1.25.8 vereist vanwege de ondergrens die google.golang.org/api instelt.
Ledger is alleen beschikbaar voor Rust en heeft geen Go-module.
solana-go v2 en v1-transacties
De modules zijn gebouwd op
github.com/solana-foundation/solana-go/v2
v2.0.0 en accepteren de bijbehorende *solana.Transaction. Legacy-, v0- en v1-transacties
(solana.MessageVersionV1) worden ondersteund, behalve door Fireblocks
met UseProgramCall: true, dat alleen legacy en v0 accepteert.
Basisgebruik
Elke signer implementeert de basis-
core.SolanaSigner-interface
(Pubkey, SignMessage, IsAvailable). Methoden nemen een context.Context en
zijn blokkerend. Elke backend implementeert bovendien precies één capability-interface:
core.TransactionSigner:SignTransactionondertekent je transactie zoals aangeleverd.core.ModifyingSigner:ModifyAndSignTransactionlaat de provider de transactie herschrijven en ondertekent deze vervolgens.core.SendingSigner:SignAndSendTransactionlaat de provider de transactie ondertekenen en verzenden.
Elk backendpakket biedt een Config-struct en een New-constructor:
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 transactionreturn nil}
SignTransaction en ModifyAndSignTransaction retourneren een
core.SignedTransaction (EncodedTransaction, Signature, Completeness).
Remote HTTP-backends accepteren een optionele HTTPClient en HTTPClientConfig
(timeouts). De standaardclient dwingt HTTPS af; als je een eigen client opgeeft, wordt dat omzeild
en ben je zelf verantwoordelijk voor de beveiliging ervan.
Signer-mogelijkheden
Een backend die geen transactie kan ondertekenen heeft helemaal geen SignTransaction-methode,
dus de mogelijkheid is voor concrete types een feit op compileertijd en voor een
core.SolanaSigner een type assertion:
| Backend | Mogelijkheid | SignMessage |
|---|---|---|
| memory, vault, privy, turnkey, awskms, gcpkms, fireblocks, dfns, para, openfort | TransactionSigner | Ja |
| cdp | TransactionSigner | Alleen UTF-8-payloads |
| utila | TransactionSigner | Mislukt met CodeSigningFailed |
fordefi black box (fordefi.BlackBoxSigner) | TransactionSigner | Ja |
fordefi native manual (fordefi.NativeManualSigner) | ModifyingSigner | Ja |
fordefi native auto (fordefi.NativeAutoSigner) | SendingSigner | Ja |
| crossmint | SendingSigner | Mislukt met CodeSigningFailed |
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)}
Initialisatie
Er is geen aparte Init-stap. Privy, Fireblocks, Dfns, Crossmint, Para,
Openfort en Utila achterhalen het walletadres binnen New, en daarom hebben hun
constructors een context.Context nodig. Bouw signers altijd via New: een
Crossmint-, Para- of Utila-signer met nulwaarde mislukt met CodeNotInitialized
in plaats van te ondertekenen voor het nuladres.
Ondertekenen en verzenden met elke signer
core.SignAndSendTransaction brengt een transactie on-chain, ongeacht de vorm
van de signer. Een SendingSigner verzendt via zijn provider en negeert de
verzendfunctie; bij elke andere vorm wordt er ondertekend en verzendt jouw functie het base64-resultaat,
dat bij een ModifyingSigner de door de provider herschreven transactie is.
Core heeft geen RPC-afhankelijkheid:
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)})
Batch-ondertekening
Batch-ondertekening wordt aangeboden als losse helpers, gelijktijdig met een optionele vertraging per verzoek voor API's met een rate limit:
sigs, err := core.SignMessages(ctx, signer, [][]byte{msg1, msg2}, core.BatchOptions{MaxConcurrency: 4, // 0 = unboundedRequestDelay: 50 * time.Millisecond,})signed, err := core.SignTransactions(ctx, signer, txs, core.BatchOptions{})
core.SignTransactions accepteert een core.TransactionSigner, dus de
signers die zelf het verzenden beheren (Crossmint, Fordefi native auto) en Fordefi native
manual kunnen er niet mee in batches worden verwerkt; roep ze per transactie aan. Een
signer waarvan de aanroepen werk aan de kant van de provider veroorzaken (Fireblocks met UseProgramCall)
meldt dit via core.BatchServerSideEffects, waarna de batch
sequentieel wordt uitgevoerd.
Backendconfiguratie
Memory
Geef precies één van PrivateKey (ruwe bytes), PrivateKeyString (base58 of een
[1,2,...]-bytearray) of PrivateKeyPath (Solana CLI-keypair-bestand) op:
import "github.com/solana-foundation/solana-keychain/go/signers/memory/v2"signer, err := memory.New(memory.Config{PrivateKeyPath: "/path/to/id.json",})
Go biedt geen betrouwbare manier om geheugen op nul te zetten: de garbage collector kan sleutelbytes kopiëren en bewaren (memory-keypairs en de sleutels die Crossmint en Openfort lokaal afleiden) tot de collectie plaatsvindt. Beschouw het volledige procesgeheugen als gevoelig wanneer je backends met lokale sleutels gebruikt.
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 devnetUseProgramCall: 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 Ed25519WalletSecret: "wallet_secret", // base64 PKCS#8 DERAddress: "base58_address",Network: cdp.NetworkMainnet, // or cdp.NetworkDevnet; required for address lookup tables})
SignMessage van CDP accepteert alleen UTF-8-payloads.
Crossmint
Crossmint kan alleen verzenden: de API voert elke goedgekeurde transactie
serverzijdig uit, dus *crossmint.Signer heeft SignAndSendTransaction en geen
SignTransaction. Je transactie wordt nooit gewijzigd; de geretourneerde handtekening
identificeert de transactie die Crossmint heeft verwerkt, en die kan afwijken van de jouwe als
Crossmint de gas sponsort.
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 ondertekent alleen transacties; SignMessage mislukt, en je verzendt de ondertekende
transactie zelf.
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 is er in drie signertypes, die bij de constructie worden bepaald door Config.Chain en
Config.PushMode. Alle drie ondertekenen berichten:
| Config | Type | Ingangspunt |
|---|---|---|
Chain niet ingesteld | *fordefi.BlackBoxSigner | SignTransaction |
Chain ingesteld, PushMode niet ingesteld of PushModeAuto | *fordefi.NativeAutoSigner | SignAndSendTransaction |
Chain ingesteld, PushMode: PushModeManual | *fordefi.NativeManualSigner | ModifyAndSignTransaction |
fordefi.New kiest op basis van de config en retourneert een core.SolanaSigner;
fordefi.NewBlackBox, fordefi.NewNativeAuto en fordefi.NewNativeManual
retourneren het concrete type en weigeren de configs van de andere modi. API-verzoeken worden
geauthenticeerd met een ECDSA P-256-verzoekhandtekening: geef precies één van
PrivateKeyPEM op, of een RequestSigner om die sleutel in een KMS/HSM te houden.
Native auto-modus: Fordefi kan de blockhash en de fees vervangen, ondertekent vervolgens en verzendt. De modus accepteert alleen een niet-ondertekende transactie waarvan de enige vereiste ondertekenaar de vault is.
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.ChainSolanaMainnetFee: &fordefi.Fee{Type: fordefi.FeeTypePriority,PriorityLevel: fordefi.PriorityMedium,},})sig, err := signer.SignAndSendTransaction(ctx, tx)
Native manual-modus: stel PushMode: fordefi.PushModeManual in. Fordefi herschrijft
het bericht (recente blockhash, Compute Budget-feeinstructies) en ondertekent het
zonder te verzenden. ModifyAndSignTransaction vervangt tx door de
transactie die Fordefi heeft ondertekend: ga altijd verder vanaf die transactie. Fordefi moet de fee
payer zijn en moet vóór elke andere vereiste ondertekenaar ondertekenen, aangezien de herschrijving
bestaande handtekeningen ongeldig maakt. De herschrijving wordt niet vergeleken met het origineel, dus controleer het resultaat voordat je
verzendt.
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-modus: laat Chain niet ingesteld. Fordefi ondertekent exact de bytes van je bericht
en verzendt niet. Gebruik dit met een Fordefi black box-vault.
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),})
Waarom er geen overkoepelend pakket is
Rust heeft een Signer-enum en TypeScript heeft createKeychainSigner; Go heeft
bewust geen van beide. Go elimineert geen dode code over een runtime
dispatch-switch heen, dus een overkoepelend pakket zou de vendor-SDK van elke backend (AWS, GCP
en de rest) in de build van elke gebruiker dwingen. Het importeren van het backendpakket dat je
nodig hebt is de selector. Om tijdens runtime een backend te kiezen, schrijf je de switch in je eigen
code voor alleen de backends die je ondersteunt, en bewaar je het resultaat als een
core.SolanaSigner.
Foutafhandeling
Elke fout is een *core.SignerError met een stabiele Code (CodeConfigError,
CodeHTTPError, CodeRemoteAPIError, CodeSigningFailed,
CodeNotInitialized, CodeBroadcastUnconfirmed en andere). Error() retourneert
alleen een vaste melding per code, nooit sleutelmateriaal of ruwe providerresponses.
Match met errors.As, errors.Is(err, &core.SignerError{Code: ...}) of
core.CodeOf(err).
Bij Crossmint en Fordefi native auto-modus betekent een fout niet dat er niets is
verwerkt. Als de provider de transactie mogelijk heeft geaccepteerd, is de code
core.CodeBroadcastUnconfirmed ("SIGNER_BROADCAST_UNCONFIRMED").
ProviderTxID wordt gezet wanneer het aanmaken is geaccepteerd, en IdempotencyKey bevat
de sleutel die van het bericht is afgeleid. Het opnieuw verzenden van de byte-identieke transactie is
veilig; een opnieuw opgebouwde transactie (bijvoorbeeld met een nieuwe blockhash) is een nieuwe overdracht.
core.SignAndSendTransaction meldt deze code ook wanneer je verzendfunctie
faalt, met de handtekening van de fee payer in TransactionSignature. Fireblocks
PROGRAM_CALL is alleen voor ondertekening en verzendt niets; deze code wordt alleen gemeld wanneer een
poll laat zien dat Fireblocks toch heeft verzonden.
sig, err := core.SignAndSendTransaction(ctx, signer, tx, send)var se *core.SignerErrorif errors.As(err, &se) && se.Code == core.CodeBroadcastUnconfirmed {// Reconcile se.ProviderTxID, se.IdempotencyKey or se.TransactionSignature// with the provider before retrying.}
Zie het beveiligingsmodel voor wat elke ondertekenvorm garandeert, de Go README voor de volledige lijst met modules, en pkg.go.dev voor de API-referentie.
Aangepaste signers toevoegen
Implementeer core.SolanaSigner plus precies één capability-interface, en voeg geen
methode toe die je backend niet kan waarmaken: aanroepers detecteren mogelijkheden via een type assertion.
Zie de gids Signers toevoegen om
aanvullende key management-services te integreren.
Is this page helpful?