tchain-api (v1.2.5) was published to npm by the account hallisaacpna555. It presents itself as a Turborepo and Next.js monorepo, with apps/docs, apps/web, and packages/ui filled out with the scaffolded boilerplate that create-next-app and create-turbo generate. Under that cover it ships two files, apps/docs/app/rsa.db and apps/docs/app/des.db, whose contents are CryptoJS-encrypted blobs. A single module reads both files and re-exports their bytes. The package neither decrypts nor runs the material, and no exfiltration is present in this version.
The carrier structure here matches the encrypted-payload tradecraft this research program documented earlier in the thedata package, which read rsa.db and des.db the same way. That gives moderate confidence that tchain-api belongs to the same operation or reuses its toolkit.
The artifact
tchain-api is a single package under the account hallisaacpna555, its only publication. It was released in four versions within roughly 2.5 hours on the same day, a release velocity consistent with active iteration on a work in progress.
The root package.json declares a Turborepo workspace over apps/* and packages/* with the standard turbo build, turbo dev, and turbo lint scripts. The apps/docs and apps/web trees hold the default Next.js README and the stock next.svg and vercel.svg assets, plus an eslint config lifted from the Turborepo template. None of that scaffolding does anything. It exists so the package looks like an ordinary monorepo when a reviewer skims the file list.
The README embeds a “Chain Hero Image” pulled from raw.githubusercontent[.]com/b-bot/chain/main/chain.jpg and links every badge to an npm package named chain. The published artifact is tchain-api while the README markets a package called chain, so the visible advertising names something other than what a reader installs. The gap between the README name and the registry name is the same lure pattern seen across this class of package, where the visible marketing points at a plausible-sounding project the reader is expected to trust.
The apps/docs/package.json is named thetachain-docs, sets "main": "./app/theta.ts", and its files array lists app/theta.ts and app/data.db. The package does not ship app/data.db. It ships rsa.db and des.db instead. The manifest describes one payload file while the tree carries two under different names.
What it does
The two .db files hold ciphertext. rsa.db begins with the base64 text U2FsdGVkX18q77TIYtph... and des.db begins with U2FsdGVkX18IXFVhY9Ht.... Decoding the shared eight-character prefix U2FsdGVkX18 from base64 yields the ASCII bytes Salted__, the header CryptoJS and OpenSSL write in front of an encrypted blob. The .db extension and the key-sounding variable names are cover for encrypted payload storage.
The read-and-export lives in apps/docs/app/theta.ts. It is eight lines:
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
const rsaPath = fileURLToPath(new URL("./rsa.db", import.meta.url));
const desPath = fileURLToPath(new URL("./des.db", import.meta.url));
export const rsaKey = readFileSync(rsaPath, "utf8");
export const desKey = readFileSync(desPath, "utf8");
The module resolves each .db file relative to itself, reads it as UTF-8 text, and exports the raw contents as rsaKey and desKey. The root index.js is a single line that re-exports the module:
export { theta } from "./apps/docs/app/theta.ts";
There is no CryptoJS.decrypt, no child_process, no spawn, no fetch, no writeFileSync to a temp path, and no outbound address anywhere in the package. The encrypted blobs are read and handed to whatever imports the module. What decrypts them and what runs the result is not shipped here.
The string 3.5.7.9 appears inside apps/docs/public/next.svg, where it is SVG path-coordinate data in the stock Next.js logo. No command-and-control endpoint was recovered from this version, and none exists in it. The package carries the capability in encrypted form without the code to activate it.
Shared tradecraft with a documented operation
The rsaKey and desKey pair, read out of .db files that hold base64 Salted__ blobs, is a distinctive carrier. This research program documented the same carrier in the thedata package, part of the encrypted-dropper operation whose lure imported a DES-encrypted blob from a sibling package, then decrypted and spawned it as a detached process. In that case thedata exposed rsaKey and desKey from encrypted .db files exactly as tchain-api does here.
tchain-api shares that encrypted-payload-carrier tradecraft. The supporting evidence is the identical file layout and export surface, the same Salted__ blob encoding, the shared monorepo dressing used as cover, and a compressed release cadence on a single day. That is enough to place the two artifacts together at moderate confidence. Whether tchain-api is the same operation or a separate actor reusing its toolkit stays an open question, and this analysis does not close it.
Staging without execution
Reading and re-exporting two files does nothing overtly hostile at rest. It installs cleanly and passes a lint, and importing it raises no error. Scanners looking for decrypt calls or spawned processes find neither, and no outbound connection is present because none is here yet. The malicious capability is staged one delivery away, in the ciphertext of rsa.db and des.db and in whatever later version or consumer supplies the key and the runner.
The carrier structure, the Salted__ blobs behind key-named files, the README pointing at a different package, and the four-versions-in-hours cadence are all observable now.
What a defender can do
Search your lockfiles for tchain-api. If it resolved, treat the encrypted .db files as an untrusted payload and preserve them for analysis rather than importing the module. Any consumer that imports theta and passes rsaKey or desKey into a decrypt-and-execute path is the completion of the chain, so audit for code that does so.
Be skeptical of packages whose README advertises a different package name than the one on the registry, and of .db or data files whose first bytes decode to Salted__. Static review tells you it carries encrypted material and surfaces it. Proving that material is hostile requires knowing what decrypts it, and package-by-package review cannot answer that.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| npm package | tchain-api (v1.2.5, four versions in ~2.5 hours) | Staging precursor posing as a Turborepo monorepo |
| npm account | hallisaacpna555 | Sole publisher of tchain-api |
| File | apps/docs/app/rsa.db | base64 Salted__ header, CryptoJS-encrypted blob holding ciphertext |
| File | apps/docs/app/des.db | base64 Salted__ header, CryptoJS-encrypted blob holding ciphertext |
| Source | apps/docs/app/theta.ts | Reads both .db files with readFileSync, exports rsaKey and desKey |
| Source | index.js | Re-exports theta |
| Manifest mismatch | thetachain-docs files lists app/data.db | Tree ships rsa.db and des.db instead |
| README lure | github[.]com/b-bot/chain hero image, links to npm package chain | Marketing points at a different package name than tchain-api |
| Cover scaffolding | apps/web, packages/ui, stock Next.js assets | Boilerplate filler, no functional role |
| Not an indicator | 3.5.7.9 in apps/docs/public/next.svg | SVG path-coordinate data in the stock Next.js logo |
| Absent | Command-and-control endpoint | None present or recovered in this version |
Where Aephix fits
Catching a staging precursor before it activates requires seeing the operation, not just the package. Aephix Sleuth links a carrier like tchain-api to the wider operation, so future packages from the same source are flagged before any payload activates. Aephix Vantage gives you a free cross-ecosystem check before you install.