TypeScript

Päivitätkö versiosta 1.x? Katso 2.0-siirtymäopas.

Asennus

Asenna kattopaketti tai yksittäiset allekirjoittajat tarpeen mukaan:

# 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

Vaatii @solana/kit-kirjaston version 8.1 tai uudemman. v1-transaktiot (createTransactionMessage({ version: 1 })) ovat tuettuja, paitsi Fireblocksissa asetuksella useProgramCall: true, joka hyväksyy vain legacy- ja v0-transaktiot.

Peruskäyttö

Yhtenäinen Factory (Suositeltu sovelluksille, jotka haluavat tukea useita allekirjoittajia)

Käytä createKeychainSigner -metodia erottelevalla konfiguraatiolla luodaksesi minkä tahansa backendin:

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
);

Tai asenna yksittäinen allekirjoittajapaketti pienemmän riippuvuusjalanjäljen saamiseksi:

import { createPrivySigner } from "@solana/keychain-privy";
const signer = await createPrivySigner({
appId: "your-app-id",
appSecret: "your-app-secret",
walletId: "your-wallet-id"
});

Käyttö transaktiviestien kanssa

Jokainen backend paitsi Crossmint ja Fordefin natiivitila palauttaa SolanaTransactionSigner-allekirjoittajan, joka on Kitin TransactionPartialSigner ja toimii alla olevien @solana/signers-kirjaston osittaisten allekirjoittajien apufunktioiden kanssa. Hallitun lähetyksen backendit käsitellään osiossa Allekirjoittajan ominaisuudet.

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;
}

Allekirjoita ja lähetä millä tahansa allekirjoittajalla

@solana/keychain-core-kirjaston signAndSendTransaction vie transaktion ketjuun allekirjoittajan tyypistä riippumatta. Lähettävät allekirjoittajat lähettävät omien palveluntarjoajiensa kautta; kaikki muut tyypit käyttävät antamaasi sendTransaction-funktiota (core ei riipu RPC:stä):

import { signAndSendTransaction } from "@solana/keychain-core";
const signature = await signAndSendTransaction(signer, transaction, {
sendTransaction: (tx) =>
sendAndConfirmTransaction(tx, { commitment: "confirmed" })
});

Käyttö Kit-asiakkaan kanssa (keychainSigner-laajennus)

@solana/keychain-kit-plugin asentaa avainnimiketun allekirjoittajan suoraan Kit-asiakkaaseen ja kytkee sen payer- ja identity-rooleiksi, joten voit ohittaa yllä näytetyn manuaalisen pipe-määrityksen:

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 hyväksyy saman backend-tunnisteisen konfiguraation kuin createKeychainSigner, paitsi Crossmintin ja Fordefin natiivitilan (chain asetettu). Nämä backendit muokkaavat transaktiota palvelinpuolella, joten ne eivät voi toimia asiakkaan payer- tai identity-roolissa; plugin hylkää ne sekä käännösaikana että ajon aikana. Vain se backend, johon ohjataan, sisällytetään pakettiin (backend-paketit ladataan dynaamisella import()-kutsulla).

Käytä keychainPayer- tai keychainIdentity-toimintoa asettaaksesi vain yhden roolin ja yhdistääksesi useita taustapalveluita yhdellä asiakkaalla:

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 }));

Onko sinulla jo SolanaTransactionSigner? Se on kelvollinen Kitin TransactionPartialSigner, joten voit asentaa sen myös @solana/kit-plugin-signer-pluginilla (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));

Peruutus ja vahvistamattomat lähetykset

signTransactions, modifyAndSignTransactions, signAndSendTransactions ja signMessages hyväksyvät kaikki { abortSignal }-arvon toisena argumenttinaan. Keskeytys lopettaa odottamisen, mutta se ei kumoa työtä, jonka palveluntarjoaja on jo hyväksynyt.

Crossmintin ja Fordefin natiivissa auto-tilassa virhe ei tarkoita, ettei mitään tapahtunut ketjussa. Kun palveluntarjoaja on voinut hyväksyä transaktion, virhekoodi on SignerErrorCode.BROADCAST_UNCONFIRMED ("SIGNER_BROADCAST_UNCONFIRMED"). context.providerTransactionId asetetaan, kun luonti hyväksyttiin, ja context.idempotencyKey sisältää viestistä johdetun avaimen. Tavu tavulta identtisen transaktion uudelleenlähetys on turvallista; uudelleenrakennettu (esimerkiksi uudella blockhashilla) on uusi siirto. @solana/keychain-core-kirjaston providerMayHaveAccepted(error) ja providerStatus(error) auttavat virheen luokittelussa. Täsmäytä tila palveluntarjoajan kanssa ennen uudelleenyritystä.

Taustapalvelun konfiguraatio

Muisti

Anna täsmälleen yksi seuraavista: keyPair, privateKey, privateKeyString tai 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 on vain lähettävä. Sen API suorittaa hyväksytyn transaktion aina palvelinpuolella ja sponsoroi gas-maksut, joten allekirjoittaja tarjoaa vain signAndSendTransactions()-metodin: siinä ei ole signTransactions()- eikä signMessages()-metodia, eikä sitä voi asentaa @solana/keychain-kit-plugin-pluginilla. Palautettu allekirjoitus tunnistaa transaktion, jonka Crossmint vei ketjuun.

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"
});

Para

import { createParaSigner } from "@solana/keychain-para";
const signer = await createParaSigner({
apiKey: "api_key",
walletId: "wallet_id"
});

Utila

Utila allekirjoittaa vain transaktioita; siinä ei ole signMessages()-metodia.

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

Fordefissa on kolme allekirjoitustilaa, jotka määräytyvät luontihetkellä arvojen chain ja pushMode mukaan. Jokainen tila tarjoaa täsmälleen yhden transaktiometodin, ja kaikki kolme allekirjoittavat viestejä:

TilaKonfiguraatioTyyppiMetodi
Musta laatikkochain asettamattaFordefiBlackBoxSignersignTransactions()
Natiivi autochain asetettu, pushMode jätetty pois tai "auto"FordefiNativeSignersignAndSendTransactions()
Natiivi manuaalinenchain asetettu, pushMode: "manual"FordefiNativeManualSignermodifyAndSignTransactions()

API-pyynnöt todennetaan ECDSA P-256 -pyyntöallekirjoituksella: anna allekirjoitusavain arvona privateKeyPem tai säilytä se KMS:ssä/HSM:ssä antamalla requestSigner.

Natiivi auto -tila (suositeltu ketjussa käyttöön): aseta chain, jolloin Fordefi allekirjoittaa ja lähettää transaktion itse. Koska Fordefi voi vaihtaa blockhashin tai maksut ennen allekirjoitusta, allekirjoittaja on Kitin TransactionSendingSigner: käytä sitä signAndSendTransactionMessageWithSigners-funktion kanssa, älä yllä esitetyllä osittaisen allekirjoittajan menettelyllä. Natiivi auto -tila hyväksyy vain allekirjoittamattoman transaktion, jonka ainoa vaadittu allekirjoittaja on holvi, eikä sitä voi käyttää @solana/keychain-kit-plugin-pluginin kanssa.

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);

Natiivi manuaalinen tila: aseta chain ja pushMode: "manual". Fordefi kirjoittaa viestin uudelleen (tuore blockhash, Compute Budget -maksuinstruktiot) ja allekirjoittaa sen, mutta ei lähetä sitä. modifyAndSignTransactions() palauttaa transaktion, jonka Fordefi allekirjoitti ja joka korvaa lähettämäsi: jatka aina palautetusta transaktiosta. Fordefin täytyy olla maksun maksaja ja sen täytyy allekirjoittaa ennen muita vaadittuja allekirjoittajia. Uudelleenkirjoituksesta ei muodosteta diffiä, joten tarkista tulos ennen lähettämistä.

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
]);

Musta laatikko -tila: jätä chain pois. Fordefi allekirjoittaa raakatavut eikä lähetä transaktiota; kokoa ja lähetä transaktio itse. Käytä tätä Fordefin musta laatikko -holvin kanssa.

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")
});

Allekirjoittajan ominaisuudet

@solana/keychain-core määrittelee yhden rajapinnan jokaiselle Kitin allekirjoittajatyypille. Jokainen lisää isAvailable(): Promise<boolean> vastaavaan @solana/signers-rajapintaan:

  • SolanaTransactionSigner (Kitin TransactionPartialSigner): palauttaa allekirjoitukset omistamallesi transaktiolle.
  • SolanaModifyingSigner (Kitin TransactionModifyingSigner): kirjoittaa transaktion uudelleen, allekirjoittaa sen ja palauttaa uuden transaktion lähettämättä sitä.
  • SolanaSendingSigner (Kitin TransactionSendingSigner): allekirjoittaa ja lähettää palveluntarjoajansa kautta.
  • SolanaMessageSigner (Kitin MessagePartialSigner): allekirjoittaa ketjun ulkopuolisia viestejä. Tämä on erillinen transaktiotyypeistä.

SolanaSigner on kolmen transaktiotyypin unioni. Jokaisen factoryn paluutyyppi nimeää sen backendin tarkan tyypin. Kun konfiguraatio tiedetään vasta ajon aikana, rajaa tyyppi funktioilla isSolanaTransactionSigner, isSolanaModifyingSigner, isSolanaSendingSigner tai isSolanaMessageSigner. signerCapabilities(signer) raportoi kaikki neljä kerralla.

BackendTyyppi
memory, vault, aws-kms, gcp-kms, privy, turnkey, fireblocks, cdp, dfns, para, openfort, fordefi (musta laatikko)SolanaTransactionSigner & SolanaMessageSigner
utilaSolanaTransactionSigner (ei viestien allekirjoitusta)
fordefi (natiivi manuaalinen)SolanaModifyingSigner & SolanaMessageSigner
fordefi (natiivi auto)SolanaSendingSigner & SolanaMessageSigner
crossmintSolanaSendingSigner (ei viestien allekirjoitusta)
import {
isSolanaSendingSigner,
isSolanaTransactionSigner
} from "@solana/keychain-core";
if (isSolanaSendingSigner(signer)) {
await signer.signAndSendTransactions([transaction]);
} else if (isSolanaTransactionSigner(signer)) {
await signer.signTransactions([transaction]);
}

Mukautettujen allekirjoittajien rakentaminen

Toteuta ne ominaisuusrajapinnat, joita backendisi tukee:

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);
}
}

Toteuta vain se, mitä backendisi tukee. Kit luokittelee allekirjoittajat sen mukaan, mitkä metodit ovat olemassa, joten älä koskaan lisää metodia, joka vain heittää virheen.

Katso Allekirjoittajien lisääminen -opas lisätäksesi uusia avainten hallintapalveluita.

Is this page helpful?

© 2026 Solana Foundation. Kaikki oikeudet pidätetään.