@elisedd/solana-sdk
v1.0.11
Published
Light unofficial Solana SDK for wallets, balances, and swaps.
Readme
@elisedd/solana-sdk
A lightweight TypeScript toolkit for common Solana tasks:
- Balance and portfolio: SOL and SPL token balances by address.
- Wallet management: Multiple local wallets in
wallet.json. - Transfers: Send SOL from a wallet.
- Swaps: Buy/sell tokens via Pump.fun or Jupiter.
Exports:
- getBalanceByAddress()
- getPortfolioByAddress()
- buyToken(), sellToken()
- walletManager()
Installation
- Node.js 18+ (required for global
fetch) - Install from npm:
npm install @elisedd/solana-sdkQuick Start
import {
getBalanceByAddress,
getPortfolioByAddress,
buyToken,
sellToken,
walletManager,
} from "@elisedd/solana-sdk";
const sol = await getBalanceByAddress("YourPublicKeyHere");
console.log(sol);
const portfolio = await getPortfolioByAddress(
"YourPublicKeyHere",
"https://api.mainnet-beta.solana.com",
"confirmed",
{
includeZeroBalances: false,
tryTokenList: true,
}
);
console.log(portfolio);
const wm = walletManager();
const { name, keypair } = wm.addNew("trader");
console.log(name, keypair.publicKey.toBase58());
const txBuy = await buyToken(
"https://api.mainnet-beta.solana.com",
"BASE58_PRIVATE_KEY",
"MintAddress",
0.05,
0.05
);
console.log("Buy sig", txBuy);
const txSell = await sellToken(
"https://api.mainnet-beta.solana.com",
"BASE58_PRIVATE_KEY",
"MintAddress",
10,
0.05
);
console.log("Sell sig", txSell);CommonJS:
const {
getBalanceByAddress,
getPortfolioByAddress,
buyToken,
sellToken,
walletManager,
} = require("@elisedd/solana-sdk");
(async () => {
const sol = await getBalanceByAddress("YourPublicKeyHere");
console.log(sol);
})();Runtime and Network
- Default RPC:
https://api.mainnet-beta.solana.com - Commitment defaults to
"confirmed"where applicable. - For best reliability use your own RPC endpoint.
API Reference
Balance
- getBalanceByAddress(address, rpc?, commitment?) => Promise
- Returns SOL balance in SOL units.
- Parameters:
address: stringbase58 wallet address.rpc?: stringdefault mainnet RPC.commitment?: Commitmentdefaults to"confirmed".
- Throws on invalid address or RPC error.
Example:
import { getBalanceByAddress } from "@elisedd/solana-sdk";
const balance = await getBalanceByAddress("8F...abc");
console.log(`Balance: ${balance} SOL`);Portfolio
Types:
TokenPositiontokenAccount: stringmint: stringamount: stringuiAmount: number | nulldecimals: number | nullisNFT: boolean(heuristic: decimals === 0 and uiAmount === 1)name?: stringsymbol?: string
Portfolioaddress: stringsol: numbertokens: TokenPosition[]message?: string
getPortfolioByAddress(address, rpc?, commitment?, opts?) => Promise
- Fetches SOL balance and all SPL token accounts (parsed).
- Parameters:
address: stringrpc?: stringdefault mainnet RPC.commitment?: Commitmentdefault"confirmed".opts?: { includeZeroBalances?: boolean; tryTokenList?: boolean }includeZeroBalancesdefaultfalseto omit zero uiAmount tokens.tryTokenListdefaulttrue, attempts to enrich with name/symbol via@solana/spl-token-registry.- Loaded dynamically; if unavailable or fails, names will be omitted.
Example:
import { getPortfolioByAddress } from "@elisedd/solana-sdk";
const portfolio = await getPortfolioByAddress(
"8F...abc",
undefined,
"confirmed",
{
includeZeroBalances: false,
tryTokenList: true,
}
);
console.log("SOL", portfolio.sol);
for (const t of portfolio.tokens) {
console.log(t.mint, t.uiAmount, t.symbol ?? "");
}Notes:
- Malformed token accounts are skipped, not fatal.
- The token list uses chainId 101 (mainnet). On devnet, disable
tryTokenList.
Wallets
- Local multi-wallet management stored in
wallet.jsonat the current working directory. - Format:
{
"wallet 1": {
"publicKey": "Base58Pubkey",
"privateKey": "Base58SecretKey"
},
"trader": {
"publicKey": "Base58Pubkey",
"privateKey": "Base58SecretKey"
}
}Migration is automatic from several older formats:
{ wallet: { publicKey, privateKey } }with privateKey either base58 or number array.{ secretKey: number[] }.
walletManager()
- Methods:
- readFile(): MultiWalletsFile
- writeFile(data: MultiWalletsFile): void
- getAll(): Map<string, Keypair>
- get(name: string): Keypair | undefined
- addNew(name?: string): { name: string; keypair: Keypair }
- Creates a new random Keypair and persists it. Returns final unique name.
- addFromSecret(secret: string | Uint8Array | number[], name?: string): string
- Imports an existing secret. Secret can be base58 string,
Uint8Array, or legacy number array. Returns final unique name.
- Imports an existing secret. Secret can be base58 string,
- remove(name: string): boolean
- save(mapLike: Map<string, Keypair> | MultiWalletsFile): void
- printInfo(connection?: Connection): Promise
- Without
connection, prints wallet names and addresses. - With a
Connection, prints each balance and total.
- Without
- Methods:
Examples:
import { walletManager } from "@elisedd/solana-sdk";
import { Connection } from "@solana/web3.js";
const wm = walletManager();
const { name, keypair } = wm.addNew("trader");
console.log(name, keypair.publicKey.toBase58());
const importedName = wm.addFromSecret("BASE58_SECRET", "cold");
console.log(importedName);
for (const [n, kp] of wm.getAll()) {
console.log(n, kp.publicKey.toBase58());
}
const conn = new Connection("https://api.mainnet-beta.solana.com", "confirmed");
await wm.printInfo(conn);
wm.remove("trader");Security:
wallet.jsonis written with mode0o600where supported. Keep it private.- Do not commit
wallet.jsonto version control.
Send SOL
Use the exported functions in your app. There is no CLI in the package. For example, to transfer SOL you can build a small script using @solana/web3.js and a Keypair from walletManager().
Swap
Exports:
buyToken(rpc, secret, mint, solAmount, maxSlippage?) => Promise
- Buys
mintusing SOL. Returns transaction signature. - Parameters:
rpc: stringsecret: stringbase58 private keymint: stringtoken mint addresssolAmount: numberamount of SOL to spendmaxSlippage?: numberdefault0.05(5%)
- Flow:
- If token is on Pump.fun, executes a Pump.fun buy.
- Otherwise, falls back to Jupiter swap (SOL -> token).
- Buys
sellToken(rpc, secret, mint, tokenAmount, maxSlippage?) => Promise
- Sells
tokenAmountofmintinto SOL. Returns transaction signature. - Parameters:
rpc: stringsecret: stringbase58 private keymint: stringtokenAmount: numberamount in UI unitsmaxSlippage?: numberdefault0.05
- Flow:
- Tries Pump.fun sell first.
- If it fails (not a Pump.fun token or on-chain mismatch), falls back to Jupiter swap (token -> SOL).
- Sells
Under the hood:
- Pump.fun integration:
- Checks bonding curve account discriminator.
- Creates ATA if needed.
- Adds compute budget instructions.
- Sends legacy transaction with
sendAndConfirmTransaction.
- Jupiter integration:
- Uses
/quoteto find a route. - Uses
/swapto get a serialized v0 transaction. - Signs as a
VersionedTransactionwhen possible, otherwise legacy. - Sends raw transaction, confirms at
"confirmed".
- Uses
Examples:
import { buyToken, sellToken } from "@elisedd/solana-sdk";
const rpc = "https://api.mainnet-beta.solana.com";
const secret = "BASE58_PRIVATE_KEY";
const mint = "TokenMintAddress";
const buySig = await buyToken(rpc, secret, mint, 0.02, 0.03);
console.log("Buy sig:", buySig);
const sellSig = await sellToken(rpc, secret, mint, 100, 0.03);
console.log("Sell sig:", sellSig);Notes:
- Node 18+ recommended for global
fetch. - Jupiter endpoints:
https://lite-api.jup.agare used. If they rate limit or change, adjust accordingly. tokenAmountconversion for Pump.fun assumes 6 decimals in this implementation. Verify mint decimals if you need exact raw amounts.- For Pump.fun buy, the program uses a fee recipient
FEE_RECIPIENT. Ensure you understand fees and risks.
Error Handling
- Functions throw
Errorwith helpful messages on RPC failures or invalid inputs. - Wrap calls in try/catch in production code.
- Network hiccups are common on public RPCs; prefer a stable provider.
Example:
try {
const sol = await getBalanceByAddress("8F...abc");
console.log(sol);
} catch (e) {
console.error("Could not fetch balance:", (e as Error).message);
}Security
- Never commit
wallet.jsonor private keys. - Use environment variables or secure secret managers for keys.
- Consider hardware wallets or custodial solutions for significant funds.
- Always verify mint addresses and slippage settings.
Testing on Devnet
- Many features are oriented to mainnet (
token-registrychainId 101). - For devnet:
- Use a devnet RPC.
- Disable
tryTokenList. - Fund wallets with airdrops where applicable.
Example:
import { getPortfolioByAddress } from "@elisedd/solana-sdk";
const devnetRPC = "https://api.devnet.solana.com";
const portfolio = await getPortfolioByAddress(
"DevnetPubkey",
devnetRPC,
"confirmed",
{
includeZeroBalances: true,
tryTokenList: false,
}
);
console.log(portfolio);Connect
Support the Project
If you like this SDK and want to support further development:
Solana Address:EnG5LZ3SAuYSz9CRXMAePQPXnqS3fFUR45GNyVLsZh5W
