@solana-keychain/vault
v0.1.0
Published
HashiCorp Vault signer for Solana transactions
Maintainers
Readme
@solana-keychain/vault
HashiCorp Vault-based signer for Solana transactions using Vault's transit engine.
Installation
npm install @solana-keychain/vaultPrerequisites
- A HashiCorp Vault instance with the transit engine enabled
- An ED25519 key created in the transit engine
- A Vault token with sign permissions for the key
Creating a Transit Key in Vault
# Enable the transit engine
vault secrets enable transit
# Create an ED25519 key
vault write transit/keys/my-solana-key type=ed25519
# Export the public key to get your Solana address
vault read -field=keys transit/export/signing-key/my-solana-key/1Usage
Basic Setup
import { VaultSigner } from '@solana-keychain/vault';
const signer = new VaultSigner({
vaultAddr: 'https://vault.example.com',
vaultToken: 'hvs.your-vault-token',
keyName: 'my-solana-key',
publicKey: 'your-solana-public-key-base58', // Must match the Vault key
});
// Check if the signer is available
const isAvailable = await signer.isAvailable();
console.log('Vault signer available:', isAvailable);Signing Transactions
import { pipe } from '@solana/functional';
import { createTransaction } from '@solana/transactions';
import { signTransaction } from '@solana/signers';
// Create your transaction
const transaction = pipe(
createTransaction({ version: 0 }),
// ... add instructions
);
// Sign the transaction
const signedTransaction = await signTransaction([signer], transaction);Signing Messages
import { signMessage } from '@solana/signers';
const message = new TextEncoder().encode('Hello, Solana!');
const signature = await signMessage([signer], message);With Rate Limiting
If you're signing multiple transactions/messages concurrently and want to avoid rate limits:
const signer = new VaultSigner({
vaultAddr: 'https://vault.example.com',
vaultToken: 'hvs.your-vault-token',
keyName: 'my-solana-key',
publicKey: 'your-solana-public-key',
requestDelayMs: 100, // 100ms delay between concurrent requests
});Configuration
VaultSignerConfig
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| vaultAddr | string | Yes | Vault server address (e.g., https://vault.example.com) |
| vaultToken | string | Yes | Vault authentication token |
| keyName | string | Yes | Name of the transit key in Vault |
| publicKey | string | Yes | Solana public key (base58) corresponding to the Vault key |
| requestDelayMs | number | No | Delay in ms between concurrent signing requests (default: 0) |
Vault Permissions
The Vault token must have the following permissions on the transit key:
path "transit/sign/my-solana-key" {
capabilities = ["update"]
}
path "transit/keys/my-solana-key" {
capabilities = ["read"]
}Error Handling
The signer will throw errors with specific codes from @solana-keychain/core:
CONFIG_ERROR- Invalid configurationHTTP_ERROR- Network request failedREMOTE_API_ERROR- Vault API returned an errorPARSING_ERROR- Failed to parse Vault response
import { SignerErrorCode } from '@solana-keychain/core';
try {
await signer.signMessages([message]);
} catch (error) {
if (error.code === SignerErrorCode.REMOTE_API_ERROR) {
console.error('Vault API error:', error.message);
}
}Security Considerations
- Token Security: Never hardcode Vault tokens. Use environment variables or secure secret management.
- TLS: Always use HTTPS when connecting to Vault.
- Token Rotation: Implement token rotation and use short-lived tokens when possible.
- Audit Logging: Enable Vault audit logging to track signing operations.
License
MIT
