Αναβαθμίζετε από την 1.x; Δείτε τον οδηγό μετάβασης στην 2.0.
Εγκατάσταση
Εγκαταστήστε το ενιαίο πακέτο ή μεμονωμένους υπογράφοντες ανάλογα με τις ανάγκες σας:
# Umbrella package (includes all signers)pnpm add @solana/keychain# Or install individual packagespnpm add @solana/keychain-core # Core interfaces (required for custom signers)pnpm add @solana/keychain-memory # Local keypair signerpnpm add @solana/keychain-vault # HashiCorp Vaultpnpm add @solana/keychain-aws-kms # AWS KMSpnpm add @solana/keychain-gcp-kms # GCP KMSpnpm add @solana/keychain-privy # Privypnpm add @solana/keychain-turnkey # Turnkeypnpm add @solana/keychain-fireblocks # Fireblockspnpm add @solana/keychain-cdp # Coinbase Developer Platformpnpm add @solana/keychain-crossmint # Crossmintpnpm add @solana/keychain-dfns # Dfnspnpm add @solana/keychain-openfort # Openfortpnpm add @solana/keychain-para # Parapnpm add @solana/keychain-utila # Utilapnpm add @solana/keychain-fordefi # Fordefi# Kit client plugins (keychainSigner / keychainPayer / keychainIdentity)pnpm add @solana/keychain-kit-plugin
Απαιτεί @solana/kit 8.1 ή νεότερο. Οι συναλλαγές v1
(createTransactionMessage({ version: 1 })) υποστηρίζονται, εκτός από το Fireblocks
με useProgramCall: true, το οποίο δέχεται μόνο legacy και v0.
Βασική Χρήση
Ενιαίο Factory (Συνιστάται για εφαρμογές που θέλουν να υποστηρίζουν πολλαπλούς υπογράφοντες)
Χρησιμοποιήστε το createKeychainSigner με μια διακριτή διαμόρφωση για να
δημιουργήσετε οποιοδήποτε backend:
import { createKeychainSigner } from "@solana/keychain";import { signTransactionWithSigners } from "@solana/signers"; // requires @solana/signers >= 8.1const signer = await createKeychainSigner({backend: "privy",appId: "your-app-id",appSecret: "your-app-secret",walletId: "your-wallet-id"});// Sign an already-compiled transactionconst signedTx = await signTransactionWithSigners([signer],compiledTransaction);
Ή εγκαταστήστε ένα μεμονωμένο πακέτο υπογράφοντος για μικρότερο footprint εξαρτήσεων:
import { createPrivySigner } from "@solana/keychain-privy";const signer = await createPrivySigner({appId: "your-app-id",appSecret: "your-app-secret",walletId: "your-wallet-id"});
Χρήση με Μηνύματα Συναλλαγών
Κάθε backend εκτός από το Crossmint και τη native λειτουργία του Fordefi επιστρέφει έναν
SolanaTransactionSigner, ο οποίος είναι ένας TransactionPartialSigner του Kit και λειτουργεί
με τους βοηθητικούς partial-signer του @solana/signers παρακάτω. Τα backend με managed broadcast
εξετάζονται στην ενότητα Δυνατότητες Signer.
import type { SolanaTransactionSigner } from "@solana/keychain-core";import { signTransactionMessageWithSigners } from "@solana/signers";import {createTransactionMessage,setTransactionMessageFeePayerSigner,pipe} from "@solana/kit";async function signWithKeychain(signer: SolanaTransactionSigner) {// Check availability (useful for remote signers)if (!(await signer.isAvailable())) {throw new Error("Signer offline");}// Use with @solana/kit transaction builderconst transaction = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(signer, tx)// ... set a lifetime and add instructions);// Sign with the standard signers APIconst signedTx = await signTransactionMessageWithSigners(transaction);return signedTx;}
Υπογραφή και αποστολή με οποιονδήποτε Signer
Η signAndSendTransaction από το @solana/keychain-core φέρνει μια συναλλαγή στο
blockchain όποια κι αν είναι η μορφή του signer. Οι signers αποστολής μεταδίδουν μέσω του
παρόχου τους· κάθε άλλη μορφή χρησιμοποιεί τη sendTransaction που περνάτε εσείς (ο πυρήνας δεν έχει
εξάρτηση από RPC):
import { signAndSendTransaction } from "@solana/keychain-core";const signature = await signAndSendTransaction(signer, transaction, {sendTransaction: (tx) =>sendAndConfirmTransaction(tx, { commitment: "confirmed" })});
Χρήση με Kit Client (πρόσθετο keychainSigner)
Το @solana/keychain-kit-plugin εγκαθιστά απευθείας ένα keychain signer σε έναν
Kit client, συνδέοντάς το ως payer και
identity, ώστε να παρακάμψετε τη χειροκίνητη ρύθμιση pipe που φαίνεται
παραπάνω:
import { createClient } from "@solana/kit";import { keychainSigner } from "@solana/keychain-kit-plugin";const client = await createClient().use(keychainSigner({backend: "privy",appId: process.env.PRIVY_APP_ID!,appSecret: process.env.PRIVY_APP_SECRET!,walletId: process.env.PRIVY_WALLET_ID!}));client.payer; // SolanaTransactionSigner, also a Kit TransactionPartialSignerclient.identity; // same signer instance
Το plugin δέχεται την ίδια διαμόρφωση με ετικέτα backend όπως η createKeychainSigner,
εκτός από το Crossmint και τη native λειτουργία του Fordefi (με ορισμένο chain). Αυτά τα backend ξαναγράφουν
τη συναλλαγή στην πλευρά του διακομιστή, επομένως δεν μπορούν να λειτουργήσουν ως client payer ή
identity· το plugin τα απορρίπτει κατά τη μεταγλώττιση και κατά την εκτέλεση. Συμπεριλαμβάνεται μόνο το
backend στο οποίο γίνεται η δρομολόγηση (τα πακέτα backend φορτώνονται μέσω δυναμικού
import()).
Χρησιμοποιήστε keychainPayer ή keychainIdentity για να ορίσετε έναν μόνο
ρόλο και να συνδυάσετε backends σε έναν μόνο client:
import { createClient } from "@solana/kit";import { keychainIdentity, keychainPayer } from "@solana/keychain-kit-plugin";const client = await createClient().use(keychainPayer({backend: "memory",privateKeyPath: `${process.env.HOME}/.config/solana/id.json`})).use(keychainIdentity({ backend: "turnkey", ...turnkeyConfig }));
Έχετε ήδη έναν SolanaTransactionSigner; Είναι έγκυρος TransactionPartialSigner
dου Kit, οπότε μπορείτε να τον εγκαταστήσετε με το
@solana/kit-plugin-signer
αντί γι' αυτό (pnpm add @solana/kit-plugin-signer):
import { createClient } from "@solana/kit";import { signer } from "@solana/kit-plugin-signer";import { createKeychainSigner } from "@solana/keychain";const mySigner = await createKeychainSigner({backend: "vault",...vaultConfig});const client = createClient().use(signer(mySigner));
Ακύρωση και μη επιβεβαιωμένες μεταδόσεις
Οι signTransactions, modifyAndSignTransactions, signAndSendTransactions και
signMessages δέχονται όλες το { abortSignal } ως δεύτερο όρισμα. Η ακύρωση
σταματά την αναμονή· δεν αναιρεί εργασία που έχει ήδη αποδεχτεί ο πάροχος.
Στο Crossmint και στη native auto λειτουργία του Fordefi, μια αποτυχία δεν σημαίνει ότι δεν
πραγματοποιήθηκε τίποτα. Όταν ο πάροχος ενδέχεται να έχει αποδεχτεί τη συναλλαγή, ο κωδικός σφάλματος είναι
SignerErrorCode.BROADCAST_UNCONFIRMED ("SIGNER_BROADCAST_UNCONFIRMED").
Το context.providerTransactionId ορίζεται όταν η δημιουργία έγινε αποδεκτή, και το
context.idempotencyKey φέρει το κλειδί που προκύπτει από το μήνυμα. Η επαναποστολή της
απόλυτα ίδιας συναλλαγής (byte-identical) είναι ασφαλής· μια συναλλαγή που έχει ξαναχτιστεί (για παράδειγμα με νέο
blockhash) αποτελεί νέα μεταφορά. Οι providerMayHaveAccepted(error) και
providerStatus(error) από το @solana/keychain-core βοηθούν στην ταξινόμηση του σφάλματος.
Συμφιλιώστε την κατάσταση με τον πάροχο πριν επαναλάβετε την προσπάθεια.
Διαμόρφωση Backend
Μνήμη
Παρέχετε ακριβώς ένα από τα keyPair, privateKey, privateKeyString ή
privateKeyPath:
import { createMemorySigner } from "@solana/keychain-memory";const signer = await createMemorySigner({privateKeyPath: "/path/to/id.json"});
HashiCorp Vault
import { createVaultSigner } from "@solana/keychain-vault";const signer = createVaultSigner({vaultAddr: "https://vault.example.com:8200",vaultToken: "hvs.xxxxx",keyName: "my-solana-key",publicKey: "base58_public_key"});
AWS KMS
import { createAwsKmsSigner } from "@solana/keychain-aws-kms";const signer = createAwsKmsSigner({keyId: "alias/my-solana-key",publicKey: "base58_public_key",region: "us-east-1" // optional});
GCP KMS
import { createGcpKmsSigner } from "@solana/keychain-gcp-kms";const signer = createGcpKmsSigner({keyName:"projects/my-project/locations/us-east1/keyRings/my-ring/cryptoKeys/my-key/cryptoKeyVersions/1",publicKey: "base58_public_key"});
Privy
import { createPrivySigner } from "@solana/keychain-privy";const signer = await createPrivySigner({appId: "app_id",appSecret: "app_secret",walletId: "wallet_id"});
Turnkey
import { createTurnkeySigner } from "@solana/keychain-turnkey";const signer = createTurnkeySigner({apiPublicKey: "api_public_key",apiPrivateKey: "api_private_key",organizationId: "org_id",privateKeyId: "private_key_id",publicKey: "base58_public_key"});
Fireblocks
import { createFireblocksSigner } from "@solana/keychain-fireblocks";const signer = await createFireblocksSigner({apiKey: "api_key",privateKeyPem: "-----BEGIN RSA PRIVATE KEY-----\n...",vaultAccountId: "0",assetId: "SOL" // or "SOL_TEST" for devnet});
CDP (Coinbase Developer Platform)
import { createCdpSigner } from "@solana/keychain-cdp";const signer = await createCdpSigner({cdpApiKeyId: "api_key_id",cdpApiKeySecret: "api_key_secret",cdpWalletSecret: "wallet_secret",address: "base58_address",network: "solana" // or "solana-devnet"; required for address lookup tables});
Crossmint
import { createCrossmintSigner } from "@solana/keychain-crossmint";const signer = await createCrossmintSigner({apiKey: "api_key",walletLocator: "wallet_locator"});
Το Crossmint υποστηρίζει μόνο αποστολή. Το API του εκτελεί πάντα μια εγκεκριμένη συναλλαγή
στην πλευρά του διακομιστή και χρηματοδοτεί το gas, γι' αυτό ο signer εκθέτει μόνο τη
signAndSendTransactions(): δεν διαθέτει signTransactions() ή signMessages(),
και δεν μπορεί να εγκατασταθεί με το @solana/keychain-kit-plugin. Η υπογραφή που
επιστρέφεται προσδιορίζει τη συναλλαγή που κατέγραψε το Crossmint.
const [signature] = await signer.signAndSendTransactions([transaction]);// or: await signAndSendTransactionMessageWithSigners(transactionMessage);
Dfns
import { createDfnsSigner } from "@solana/keychain-dfns";const signer = await createDfnsSigner({authToken: "auth_token",credId: "cred_id",privateKeyPem: "-----BEGIN EC PRIVATE KEY-----\n...",walletId: "wallet_id"});
Openfort
import { createOpenfortSigner } from "@solana/keychain-openfort";const signer = await createOpenfortSigner({secretKey: "sk_...",walletSecret: "wallet_secret",accountId: "account_id"});
Παράγραφος
import { createParaSigner } from "@solana/keychain-para";const signer = await createParaSigner({apiKey: "api_key",walletId: "wallet_id"});
Utila
Το Utila υπογράφει μόνο συναλλαγές· δεν διαθέτει signMessages().
import { createUtilaSigner } from "@solana/keychain-utila";const signer = await createUtilaSigner({serviceAccountEmail: "sa@example.com",serviceAccountPrivateKeyPem: "-----BEGIN PRIVATE KEY-----\n...",vaultId: "vault_id",walletId: "wallet_id",network: "networks/solana-devnet"});
Fordefi
Το Fordefi έχει τρεις λειτουργίες υπογραφής, που καθορίζονται κατά την κατασκευή από τα chain και
pushMode. Κάθε λειτουργία εκθέτει ακριβώς μία μέθοδο συναλλαγής, και και οι τρεις υπογράφουν
μηνύματα:
| Λειτουργία | Διαμόρφωση | Τύπος | Μέθοδος |
|---|---|---|---|
| Black box | chain μη ορισμένο | FordefiBlackBoxSigner | signTransactions() |
| Native auto | chain ορισμένο, pushMode παραλείπεται ή "auto" | FordefiNativeSigner | signAndSendTransactions() |
| Native manual | chain ορισμένο, pushMode: "manual" | FordefiNativeManualSigner | modifyAndSignTransactions() |
Τα αιτήματα API ταυτοποιούνται με υπογραφή αιτήματος ECDSA P-256: δώστε το
κλειδί υπογραφής ως privateKeyPem, ή κρατήστε το σε KMS/HSM περνώντας έναν
requestSigner.
Λειτουργία Native auto (συνιστάται για χρήση on-chain): ορίστε το chain, και το Fordefi
υπογράφει και μεταδίδει το ίδιο τη συναλλαγή. Επειδή το Fordefi μπορεί να αντικαταστήσει το
blockhash ή τις χρεώσεις πριν από την υπογραφή, ο signer είναι ένας TransactionSendingSigner
του Kit: χρησιμοποιήστε τον με το
signAndSendTransactionMessageWithSigners, όχι με τη ροή partial-signer που εμφανίζεται
παραπάνω. Η λειτουργία Native auto δέχεται μόνο μη υπογεγραμμένη συναλλαγή της οποίας ο μοναδικός απαιτούμενος
signer είναι το θησαυροφυλάκιο (vault), και δεν μπορεί να χρησιμοποιηθεί με το @solana/keychain-kit-plugin.
import { createFordefiSigner } from "@solana/keychain-fordefi";import { signAndSendTransactionMessageWithSigners } from "@solana/signers";import { readFileSync } from "node:fs";const signer = await createFordefiSigner({accessToken: process.env.FORDEFI_ACCESS_TOKEN!,vaultId: process.env.FORDEFI_VAULT_ID!,publicKey: process.env.FORDEFI_PUBLIC_KEY!, // Solana vault address (base58)privateKeyPem: readFileSync("./secret/private.pem", "utf8"),chain: "solana_devnet", // or "solana_mainnet"fee: { type: "custom", priority_fee: "1000" } // optional});const signature =await signAndSendTransactionMessageWithSigners(transactionMessage);
Λειτουργία Native manual: ορίστε το chain και pushMode: "manual". Το Fordefi ξαναγράφει
το μήνυμα (πρόσφατο blockhash, εντολές χρέωσης Compute Budget) και το υπογράφει,
αλλά δεν το μεταδίδει. Η modifyAndSignTransactions() επιστρέφει τη συναλλαγή που
υπέγραψε το Fordefi, η οποία αντικαθιστά αυτήν που υποβάλατε: συνεχίζετε πάντα από τη
συναλλαγή που επιστρέφεται. Το Fordefi πρέπει να είναι ο πληρωτής των χρεώσεων και πρέπει να υπογράφει πριν από οποιονδήποτε
άλλο απαιτούμενο signer. Η αναδιατύπωση δεν παρουσιάζεται ως diff, γι' αυτό ελέγξτε το αποτέλεσμα πριν από
τη μετάδοση.
import { createFordefiSigner } from "@solana/keychain-fordefi";import { readFileSync } from "node:fs";const signer = await createFordefiSigner({accessToken: process.env.FORDEFI_ACCESS_TOKEN!,vaultId: process.env.FORDEFI_VAULT_ID!,publicKey: process.env.FORDEFI_PUBLIC_KEY!,privateKeyPem: readFileSync("./secret/private.pem", "utf8"),chain: "solana_devnet",pushMode: "manual"});const [signedTransaction] = await signer.modifyAndSignTransactions([transaction]);
Λειτουργία Black Box: παραλείψτε το chain. Το Fordefi υπογράφει ανεπεξέργαστα bytes και δεν μεταδίδει· εσείς συναρμολογείτε και υποβάλλετε τη συναλλαγή μόνοι σας. Χρησιμοποιήστε το με ένα θησαυροφυλάκιο black box του Fordefi.
import { createFordefiSigner } from "@solana/keychain-fordefi";import { readFileSync } from "node:fs";const signer = await createFordefiSigner({accessToken: process.env.FORDEFI_ACCESS_TOKEN!,vaultId: process.env.FORDEFI_BB_VAULT_ID!,publicKey: process.env.FORDEFI_BB_PUBLIC_KEY!,privateKeyPem: readFileSync("./secret/private.pem", "utf8")});
Δυνατότητες Signer
Το @solana/keychain-core ορίζει μία διεπαφή για κάθε μορφή signer του Kit. Καθεμία προσθέτει
το isAvailable(): Promise<boolean> στην αντίστοιχη διεπαφή του @solana/signers:
SolanaTransactionSigner(TransactionPartialSignerτου Kit): επιστρέφει υπογραφές για μια συναλλαγή που κατέχετε εσείς.SolanaModifyingSigner(TransactionModifyingSignerτου Kit): ξαναγράφει τη συναλλαγή, την υπογράφει και επιστρέφει τη νέα συναλλαγή χωρίς να τη μεταδώσει.SolanaSendingSigner(TransactionSendingSignerτου Kit): υπογράφει και μεταδίδει μέσω του παρόχου του.SolanaMessageSigner(MessagePartialSignerτου Kit): υπογράφει μηνύματα off-chain. Αυτό είναι ξεχωριστό από τις μορφές συναλλαγών.
Το SolanaSigner είναι η ένωση (union) των τριών μορφών συναλλαγών. Ο τύπος επιστροφής κάθε factory
ονομάζει την ακριβή μορφή του backend του. Όταν η διαμόρφωση είναι γνωστή μόνο κατά την
εκτέλεση, περιορίστε τον τύπο με isSolanaTransactionSigner, isSolanaModifyingSigner,
isSolanaSendingSigner ή isSolanaMessageSigner. Η signerCapabilities(signer)
αναφέρει και τις τέσσερις ταυτόχρονα.
| Backend | Μορφή |
|---|---|
| memory, vault, aws-kms, gcp-kms, privy, turnkey, fireblocks, cdp, dfns, para, openfort, fordefi (black box) | SolanaTransactionSigner & SolanaMessageSigner |
| utila | SolanaTransactionSigner (χωρίς υπογραφή μηνυμάτων) |
| fordefi (native manual) | SolanaModifyingSigner & SolanaMessageSigner |
| fordefi (native auto) | SolanaSendingSigner & SolanaMessageSigner |
| crossmint | SolanaSendingSigner (χωρίς υπογραφή μηνυμάτων) |
import {isSolanaSendingSigner,isSolanaTransactionSigner} from "@solana/keychain-core";if (isSolanaSendingSigner(signer)) {await signer.signAndSendTransactions([transaction]);} else if (isSolanaTransactionSigner(signer)) {await signer.signTransactions([transaction]);}
Δημιουργία Προσαρμοσμένων Signers
Υλοποιήστε τις διεπαφές δυνατοτήτων που υποστηρίζει το backend σας:
import type {SolanaMessageSigner,SolanaTransactionSigner} from "@solana/keychain-core";import type { Address } from "@solana/addresses";import type {MessagePartialSignerConfig,SignableMessage,TransactionPartialSignerConfig} from "@solana/signers";import type { Transaction } from "@solana/transactions";class MyCustomSigner implements SolanaTransactionSigner, SolanaMessageSigner {constructor(readonly address: Address) {}async isAvailable(): Promise<boolean> {return await myBackend.healthCheck();}async signMessages(messages: readonly SignableMessage[],config?: MessagePartialSignerConfig) {return await myBackend.signMessages(messages, config?.abortSignal);}async signTransactions(transactions: readonly Transaction[],config?: TransactionPartialSignerConfig) {return await myBackend.signTransactions(transactions, config?.abortSignal);}}
Υλοποιήστε μόνο ό,τι υποστηρίζει το backend σας. Το Kit ταξινομεί τους signers ανάλογα με το ποιες μέθοδοι υπάρχουν, γι' αυτό μην προσθέτετε ποτέ μέθοδο που απλώς πετάει σφάλμα.
Δείτε τον οδηγό Adding Signers για να ενσωματώσετε πρόσθετες υπηρεσίες διαχείρισης κλειδιών.
Is this page helpful?