TypeScript

Αναβαθμίζετε από την 1.x; Δείτε τον οδηγό μετάβασης στην 2.0.

Εγκατάσταση

Εγκαταστήστε το ενιαίο πακέτο ή μεμονωμένους υπογράφοντες ανάλογα με τις ανάγκες σας:

# Umbrella package (includes all signers)
pnpm add @solana/keychain
# Or install individual packages
pnpm add @solana/keychain-core # Core interfaces (required for custom signers)
pnpm add @solana/keychain-memory # Local keypair signer
pnpm add @solana/keychain-vault # HashiCorp Vault
pnpm add @solana/keychain-aws-kms # AWS KMS
pnpm add @solana/keychain-gcp-kms # GCP KMS
pnpm add @solana/keychain-privy # Privy
pnpm add @solana/keychain-turnkey # Turnkey
pnpm add @solana/keychain-fireblocks # Fireblocks
pnpm add @solana/keychain-cdp # Coinbase Developer Platform
pnpm add @solana/keychain-crossmint # Crossmint
pnpm add @solana/keychain-dfns # Dfns
pnpm add @solana/keychain-openfort # Openfort
pnpm add @solana/keychain-para # Para
pnpm add @solana/keychain-utila # Utila
pnpm 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.1
const signer = await createKeychainSigner({
backend: "privy",
appId: "your-app-id",
appSecret: "your-app-secret",
walletId: "your-wallet-id"
});
// Sign an already-compiled transaction
const 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 builder
const transaction = pipe(
createTransactionMessage({ version: 0 }),
(tx) => setTransactionMessageFeePayerSigner(signer, tx)
// ... set a lifetime and add instructions
);
// Sign with the standard signers API
const 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 TransactionPartialSigner
client.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 boxchain μη ορισμένοFordefiBlackBoxSignersignTransactions()
Native autochain ορισμένο, pushMode παραλείπεται ή "auto"FordefiNativeSignersignAndSendTransactions()
Native manualchain ορισμένο, pushMode: "manual"FordefiNativeManualSignermodifyAndSignTransactions()

Τα αιτήματα 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
utilaSolanaTransactionSigner (χωρίς υπογραφή μηνυμάτων)
fordefi (native manual)SolanaModifyingSigner & SolanaMessageSigner
fordefi (native auto)SolanaSendingSigner & SolanaMessageSigner
crossmintSolanaSendingSigner (χωρίς υπογραφή μηνυμάτων)
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?

© 2026 Ίδρυμα Solana. Με επιφύλαξη παντός δικαιώματος.