npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lykta/core

v0.3.0

Published

Transaction decode engine, CPI graph builder, account diff, compute unit analyzer, and error explainer for Solana.

Readme

@lykta/core

Solana transaction decoder. Fetches a transaction by signature and runs it through a full analysis pipeline: CPI tree reconstruction, account/token diffs, compute unit breakdown, and error resolution.

What it does

Given a transaction signature and an RPC connection, @lykta/core produces a structured LyktaTransaction containing:

  • CPI tree — nested call graph built from innerInstructions, with program names resolved from the registry
  • Decoded instructions — Anchor instruction names and Borsh-decoded args when an on-chain IDL is available
  • Account diffs — lamport balance changes per account (pre/post)
  • Token diffs — BigInt-precise SPL token balance changes per mint/account
  • Compute units — consumed/limit per top-level frame, with isOverBudget flag
  • Error — 3-tier resolution: runtime string errors → Anchor custom codes → SPL Token error codes

Installation

pnpm add @lykta/core

Main entry points

decodeTransaction(signature, connection)

The primary entry point. Fetches the raw RPC response and runs the full 9-step analysis pipeline.

import { Connection } from '@solana/web3.js'
import { decodeTransaction } from '@lykta/core'

const connection = new Connection('https://api.mainnet-beta.solana.com')
const tx = await decodeTransaction(
  '5KtP4R8dg1a7HmcP5Q9wJtMWwVBwmhHsDQdqNP7PbmEm',
  connection,
)

console.log(tx.success)              // true
console.log(tx.totalCu)             // 150
console.log(tx.cpiTree[0].programId) // '11111111111111111111111111111111'

parseCpiTree(logMessages)

Reconstructs the CPI call tree from meta.logMessages alone — no innerInstructions required. Each node includes computeUnits, failed, and logsTruncated when the validator cut logs short.

import { parseCpiTree } from '@lykta/core'

const tree = parseCpiTree(tx.raw.meta!.logMessages!)
// tree[0].programId, tree[0].children, tree[0].computeUnits.consumed …

resolveError(raw)

3-tier error lookup against the built-in registry:

  1. Named runtime errors ('MissingRequiredSignature', 'ComputationalBudgetExceeded', …)
  2. Anchor custom error codes (2000–2999 range + full Anchor error table)
  3. SPL Token program error codes
import { resolveError } from '@lykta/core'

const err = resolveError(raw)
if (err) {
  console.log(err.code)    // 2000 or 'MissingRequiredSignature'
  console.log(err.name)    // 'ConstraintMut'
  console.log(err.message) // 'A mut constraint was violated.'
  console.log(err.programId)
}

computeTokenDiffs(raw)

BigInt-precise SPL token balance deltas. Avoids float rounding on large token amounts.

import { computeTokenDiffs } from '@lykta/core'

const diffs = computeTokenDiffs(raw)
for (const d of diffs) {
  console.log(d.mint, d.delta, d.uiDelta)
  // 'EPjFWdd5...', -5000000n, '-5.000000'
}

Splitting fetch from decode

decodeTransactionFromRaw runs the same pipeline on a pre-fetched VersionedTransactionResponse. Useful for injecting fixture data in tests without hitting the network.

import { fetchRawTransaction, decodeTransactionFromRaw } from '@lykta/core'

const raw = await fetchRawTransaction(signature, connection)
const tx  = await decodeTransactionFromRaw(raw, connection)

Output shape (LyktaTransaction)

interface LyktaTransaction {
  signature:           string
  slot:                number
  blockTime:           number | null
  success:             boolean
  fee:                 number
  cpiTree:             CpiNode[]
  decodedInstructions: DecodedInstruction[]
  accountDiffs:        AccountDiff[]
  tokenDiffs:          TokenDiff[]
  cuUsage:             CuUsage[]
  totalCu:             number
  error?:              LyktaError
  raw:                 VersionedTransactionResponse
}

Graceful degradation

  • No on-chain IDL → instructions are returned with matched: false and name: null; raw hex is always present
  • ALT lookup fails → ALT slots fall back to PublicKey.default; static keys are unaffected
  • Log truncation → affected CpiNodes are marked logsTruncated: true and the tree is flushed to preserve structure