Overview
Karen can be imported as a TypeScript library into your Node.js application, giving you programmatic access to all wallet management, transaction execution, and DeFi capabilities.
This is ideal for:
Building custom AI agents with full control over the decision loop
Integrating Solana wallets into existing applications
Creating trading bots with custom strategies
Developing autonomous systems that need Solana blockchain interactions
Karen is built with TypeScript and provides full type definitions for all classes and methods.
Installation
Package name is tentative. For now, clone the repo and import directly: git clone https://github.com/Don-Vicks/karen.git
cd karen
npm install
npm run build
Then in your project: import { WalletManager , TransactionEngine } from '../path/to/karen/src'
Core Exports
Karen exports the following modules from src/index.ts:
// Agent runtime and orchestration
export * from './agent'
export { ApiServer } from './api/server'
// Core wallet and transaction infrastructure
export * from './core'
// MCP server
export { startMCPServer } from './mcp/server'
// DeFi protocol adapters
export * from './protocols'
Main Classes
WalletManager Create and manage Solana wallets, HD derivation, balance queries
TransactionEngine Execute transactions with guardrails, audit logging, history
AgentRuntime Autonomous agent loop with LLM integration and skill execution
Orchestrator Manage multiple agents, create/start/stop, chat interface
ApiServer REST API server for HTTP access to all Karen features
Guardrails Security policies for spending limits, rate limiting, program whitelist
Quick Start
Basic Wallet Operations
import { WalletManager , TransactionEngine , Guardrails , AuditLogger } from 'karen'
// Initialize services
const password = 'your-secure-password'
const walletManager = new WalletManager ( password )
const logger = new AuditLogger ()
const guardrails = new Guardrails ( undefined , logger )
const txEngine = new TransactionEngine ( walletManager , guardrails , logger )
// Create a wallet
const wallet = await walletManager . createWallet ( 'my-bot' , [ 'trading' , 'automated' ])
console . log ( 'Wallet created:' , wallet . publicKey )
// Check balance
const balance = await walletManager . getBalances ( wallet . id )
console . log ( 'SOL balance:' , balance . sol )
console . log ( 'Tokens:' , balance . tokens )
// Request devnet airdrop
const airdropRecord = await txEngine . airdrop ( wallet . id , 2 )
if ( airdropRecord . status === 'confirmed' ) {
console . log ( 'Airdrop successful:' , airdropRecord . signature )
}
// Transfer SOL
const transferRecord = await txEngine . transferSol (
wallet . id ,
'7xKKzD8qHa...' , // recipient address
0.5 // amount
)
if ( transferRecord . status === 'confirmed' ) {
console . log ( 'Transfer successful:' , transferRecord . signature )
} else if ( transferRecord . status === 'blocked' ) {
console . error ( 'Blocked by guardrails:' , transferRecord . error )
}
WalletManager
Manages encrypted keystores, wallet creation, and balance queries.
Constructor
import { WalletManager } from 'karen'
const walletManager = new WalletManager (
password : string , // Keystore encryption password
keystorePath ?: string // Optional custom path (default: ~/.karen/keystore.enc)
)
Methods
Create a new standalone wallet. async createWallet (
name : string ,
tags ?: string []
): Promise < WalletInfo >
Example: const wallet = await walletManager . createWallet ( 'trading-bot' , [ 'automated' ])
console . log ( 'Wallet ID:' , wallet . id )
console . log ( 'Address:' , wallet . publicKey )
Create an HD-derived wallet from a mnemonic. async createDerivedWallet (
name : string ,
mnemonic : string ,
index : number
): Promise < WalletInfo >
Example: const mnemonic = WalletManager . generateMnemonic ()
const wallet = await walletManager . createDerivedWallet (
'agent-1' ,
mnemonic ,
0 // derivation index
)
Get SOL and SPL token balances. async getBalances ( walletId : string ): Promise <{
sol : number
tokens : Array <{
mint : string
symbol ?: string
uiBalance : string
rawBalance : string
}>
}>
Example: const { sol , tokens } = await walletManager . getBalances ( wallet . id )
console . log ( `Balance: ${ sol } SOL` )
tokens . forEach ( t => console . log ( ` ${ t . symbol } : ${ t . uiBalance } ` ))
List all managed wallets. listWallets (): WalletInfo []
Get wallet by ID. getWallet ( walletId : string ): WalletInfo | undefined
Find wallet by name. findWalletByName ( name : string ): WalletInfo | undefined
Get Solana keypair for signing (internal use). getKeypair ( walletId : string ): Keypair
TransactionEngine
Executes transactions with guardrails, audit logging, and transaction history.
Constructor
import { TransactionEngine , Guardrails , AuditLogger } from 'karen'
const txEngine = new TransactionEngine (
walletManager : WalletManager ,
guardrails : Guardrails ,
logger : AuditLogger
)
Methods
Send SOL to another address. async transferSol (
walletId : string ,
to : string ,
amount : number ,
source ?: string // Optional context (e.g., 'api', 'agent')
): Promise < TransactionRecord >
Example: const record = await txEngine . transferSol (
wallet . id ,
'7xKKzD8qHa...' ,
0.5 ,
'my-app'
)
if ( record . status === 'confirmed' ) {
console . log ( 'Tx signature:' , record . signature )
} else if ( record . status === 'blocked' ) {
console . error ( 'Blocked:' , record . error )
}
Request devnet SOL airdrop. async airdrop (
walletId : string ,
amount : number ,
source ?: string
): Promise < TransactionRecord >
Get transaction history. getTransactionHistory (
walletId ?: string , // Optional: filter by wallet
limit : number = 20
): TransactionRecord []
Example: const txs = txEngine . getTransactionHistory ( wallet . id , 50 )
txs . forEach ( tx => {
console . log ( ` ${ tx . type } - ${ tx . status } - ${ tx . timestamp } ` )
})
DeFi Protocol Adapters
Karen includes adapters for common Solana DeFi operations.
JupiterAdapter - Token Swaps
import { JupiterAdapter , KNOWN_TOKENS } from 'karen'
const jupiter = new JupiterAdapter ()
// Execute swap
const result = await jupiter . executeSwap (
walletManager ,
wallet . id ,
'SOL' , // input token
'USDC' , // output token
0.5 , // amount
50 // slippage in bps (0.5%)
)
console . log ( 'Swapped:' , result . inputAmount , '→' , result . outputAmount )
console . log ( 'Signature:' , result . signature )
// Known token addresses
console . log ( KNOWN_TOKENS . USDC ) // EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
TokenLauncherAdapter - Create SPL Tokens
import { TokenLauncherAdapter } from 'karen'
const launcher = new TokenLauncherAdapter ()
// Create a new token
const token = await launcher . createToken (
walletManager ,
wallet . id ,
'Agent Coin' , // name
'AGT' , // symbol
9 , // decimals
1_000_000 // initial supply
)
console . log ( 'Mint address:' , token . mint )
console . log ( 'Supply:' , token . supply )
// Mint additional supply
const mintResult = await launcher . mintAdditionalSupply (
walletManager ,
wallet . id ,
token . mint ,
500_000 , // amount
9 // decimals
)
// Revoke mint authority (irreversible!)
const sig = await launcher . revokeMintAuthority (
walletManager ,
wallet . id ,
token . mint
)
StakingAdapter - Native Staking
import { StakingAdapter } from 'karen'
const staking = new StakingAdapter ()
// Stake SOL
const stakeResult = await staking . stakeSOL (
walletManager ,
wallet . id ,
1.0 , // amount
'BeachiopjxQxL7CaHNSZsynRdj6vY5vCeaTXGKqfCZTP' // validator (optional)
)
console . log ( 'Stake account:' , stakeResult . stakeAccount )
// List stake accounts
const stakes = await staking . getStakeAccounts ( wallet . publicKey )
stakes . forEach ( s => {
console . log ( ` ${ s . address } : ${ s . solBalance } SOL ( ${ s . state } )` )
})
// Unstake
await staking . unstakeSOL ( walletManager , wallet . id , stakeResult . stakeAccount )
// Withdraw (after 1 epoch)
await staking . withdrawStake ( walletManager , wallet . id , stakeResult . stakeAccount )
WrappedSolAdapter - wSOL Operations
import { WrappedSolAdapter } from 'karen'
const wsol = new WrappedSolAdapter ()
// Wrap SOL
const wrapResult = await wsol . wrapSOL ( walletManager , wallet . id , 1.0 )
console . log ( 'Wrapped:' , wrapResult . amount , 'SOL' )
// Unwrap all wSOL
const unwrapResult = await wsol . unwrapSOL ( walletManager , wallet . id )
console . log ( 'Unwrapped:' , unwrapResult . amount , 'wSOL' )
SplTokenAdapter - Token Account Management
import { SplTokenAdapter } from 'karen'
const spl = new SplTokenAdapter ()
// Burn tokens
const burnResult = await spl . burnTokens (
walletManager ,
wallet . id ,
'7xKKzD8qHa...' , // mint address
100 // amount
)
// Close empty token account (reclaim rent)
const closeResult = await spl . closeTokenAccount (
walletManager ,
wallet . id ,
'7xKKzD8qHa...'
)
console . log ( 'Rent reclaimed:' , closeResult . rentReclaimed , 'SOL' )
Building Custom Agents
Using AgentRuntime
import { AgentRuntime , createDefaultSkillRegistry , MemoryStore } from 'karen'
const config = {
id: 'agent-1' ,
name: 'Trading Bot' ,
walletId: wallet . id ,
strategy: 'Buy low, sell high on SOL/USDC' ,
llmProvider: 'openai' as const ,
llmModel: 'gpt-4' ,
loopIntervalMs: 30000 ,
maxSolPerTransaction: 2 ,
dailySpendingLimitSol: 10
}
const skillRegistry = createDefaultSkillRegistry ( walletManager , txEngine )
const memory = new MemoryStore ()
const agent = new AgentRuntime (
config ,
skillRegistry ,
walletManager ,
txEngine ,
guardrails ,
logger ,
memory
)
// Start autonomous loop
agent . start ()
// Chat with agent
const response = await agent . chat ( 'What is your current balance?' )
console . log ( 'Agent:' , response )
// Stop agent
agent . stop ()
Using Orchestrator (Multiple Agents)
import { Orchestrator } from 'karen'
const orchestrator = new Orchestrator (
walletManager ,
txEngine ,
guardrails ,
logger
)
// Create agent
const agentConfig = await orchestrator . createAgent ({
name: 'trader-1' ,
strategy: 'Momentum trading on SOL/USDC' ,
llmProvider: 'anthropic' ,
llmModel: 'claude-3-5-sonnet-20241022' ,
loopIntervalMs: 60000
})
// Start agent
orchestrator . startAgent ( agentConfig . id )
// List all agents
const agents = orchestrator . listAgents ()
console . log ( 'Running agents:' , agents . filter ( a => a . status === 'running' ))
// Stop all
orchestrator . stopAll ()
Guardrails Configuration
import { Guardrails , AuditLogger } from 'karen'
const customGuardrails = new Guardrails (
{
maxSolPerTransaction: 5 ,
maxTransactionsPerMinute: 10 ,
dailySpendingLimitSol: 50 ,
allowedPrograms: [
'11111111111111111111111111111111' , // System
'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' , // Token Program
'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4' // Jupiter
]
},
new AuditLogger ()
)
API Server Integration
import { ApiServer } from 'karen'
const apiServer = new ApiServer (
walletManager ,
txEngine ,
guardrails ,
logger ,
orchestrator
)
apiServer . start ( 3001 )
// Server running on http://localhost:3001
Type Definitions
WalletInfo
type WalletInfo = {
id : string
name : string
publicKey : string
tags : string []
createdAt : string
metadata ?: Record < string , any >
}
TransactionRecord
type TransactionRecord = {
id : string
type : string
walletId : string
status : 'pending' | 'confirmed' | 'failed' | 'blocked'
signature ?: string
error ?: string
metadata ?: Record < string , any >
guardrailsApplied ?: string []
timestamp : string
}
AgentConfig
type AgentConfig = {
id : string
name : string
walletId : string
strategy : string
llmProvider : 'openai' | 'anthropic' | 'grok' | 'gemini'
llmModel ?: string
loopIntervalMs : number
maxSolPerTransaction : number
dailySpendingLimitSol : number
status : 'idle' | 'running' | 'stopped' | 'error'
createdAt : string
}
Complete Example: Trading Bot
import {
WalletManager ,
TransactionEngine ,
Guardrails ,
AuditLogger ,
JupiterAdapter
} from 'karen'
async function main () {
// Setup
const walletManager = new WalletManager ( 'secure-password' )
const logger = new AuditLogger ()
const guardrails = new Guardrails ( undefined , logger )
const txEngine = new TransactionEngine ( walletManager , guardrails , logger )
const jupiter = new JupiterAdapter ()
// Create wallet
const wallet = await walletManager . createWallet ( 'trading-bot' )
console . log ( 'Wallet:' , wallet . publicKey )
// Fund with devnet SOL
await txEngine . airdrop ( wallet . id , 2 )
console . log ( 'Funded with 2 SOL' )
// Trading loop
setInterval ( async () => {
const { sol , tokens } = await walletManager . getBalances ( wallet . id )
const usdc = tokens . find ( t => t . symbol === 'USDC' )
console . log ( `Balance: ${ sol } SOL, ${ usdc ?. uiBalance || 0 } USDC` )
// Simple strategy: buy USDC if SOL > 1, sell if USDC > 20
if ( sol > 1 ) {
const result = await jupiter . executeSwap (
walletManager ,
wallet . id ,
'SOL' ,
'USDC' ,
0.5 ,
50
)
console . log ( 'Bought USDC:' , result . outputAmount )
} else if ( parseFloat ( usdc ?. uiBalance || '0' ) > 20 ) {
const result = await jupiter . executeSwap (
walletManager ,
wallet . id ,
'USDC' ,
'SOL' ,
10 ,
50
)
console . log ( 'Bought SOL:' , result . outputAmount )
}
}, 60000 ) // Every minute
}
main (). catch ( console . error )
Next Steps
API Reference Detailed class and method documentation
CLI Command-line interface reference
MCP Server Integrate with Claude Desktop
Build Agents Create autonomous AI agents