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

mars-plugged

v0.2.0

Published

Raw Solana + x402 toolkit: talk to Anchor programs with no IDL, decode accounts from a byte-offset table, and build x402 payment envelopes by hand.

Readme

plugged

Hackathon toolkit for the estate rooms. Two tracks: Solana (rooms 01, 04) — query the chain, decode raw account bytes, derive PDAs, call Anchor programs; and x402 (rooms 02, 03, 05) — read 402 terms in full, build signed payment envelopes by hand, follow paid trails.

Setup

cd ~/mars-dev/plugged
bun install
bun test          # 62 tests, all offline

.env:

OPERATIVE_ID=OPERATIVE-07     # required for x402; every clause value derives from it
SOLANA_RPC=https://api.devnet.solana.com  # optional; falls back to the Solana CLI's config, then devnet
SOLANA_KEYPAIR=~/.config/solana/id.json   # optional; the event box sets this at login
BRIEF_URL=http://10.61.0.20:8700          # optional; the live-parameters endpoint
OPENAI_API_KEY=***            # for the agent
MODEL=gpt-4o

The event runs on Solana devnet. RPC resolves as SOLANA_RPC → the Solana CLI's own json_rpc_url → devnet, so a preconfigured box is used automatically. The websocket endpoint is derived as RPC port + 1; don't pin it.

CLI

bun run scripts/cli.ts <command> [args...]

Read

| Command | What | |---|---| | balance [ADDRESS] | SOL balance | | account <ADDRESS> | Raw account bytes, owner, lamports | | tokens [OWNER] | SPL token accounts and balances | | ata <WALLET> <MINT> | Derive Associated Token Account address | | decode <ADDRESS> '<JSON>' | Decode account using offset field table | | pda <PROGRAM> <SEED...> | Derive PDA address | | pda-fetch <PROGRAM> <SEED...> | Derive PDA and fetch its account data |

Seed encodings for pda/pda-fetch — a pubkey seed is its 32 raw bytes, never its base58 text:

| Form | Bytes | |---|---| | claim | UTF-8 | | pk:<base58> | 32 raw bytes | | hex:<hex> | decoded hex | | u64:<n> | 8 little-endian bytes |

Field types for decode: pubkey, u8, u16, u32, u64, i64, bool, anchor_string, and — with a length — bytes (hex) and utf8 (text, for an 8-char code held as [u8; 8]).

Hash / Encode

| Command | What | |---|---| | hash sha256 <HEX> | SHA256 of raw bytes | | hash xor <HEX_A> <HEX_B> | Byte-wise XOR (equal lengths) | | hash xor-key <HEX> <KEY> | Repeating-key XOR (short key) | | hash ctr <HEX> <KEY> | SHA-256 counter-mode XOR (symmetric) | | hash crc32 <HEX> | CRC-32, to verify a decryption worked | | hash disc <INSTRUCTION> | Anchor instruction discriminator | | borsh '<JSON>' | Borsh-encode args to hex | | borsh-disc <NAME> | Same as hash disc |

Write

| Command | What | |---|---| | transfer <SRC_ATA> <DST_ATA> <AMT> [MEMO] | Send SPL tokens, with optional memo in same tx | | anchor <PROG> <IX> '<ARGS>' '<ACCTS>' [MEMO] | Build and send a raw Anchor instruction | | confirm <SIGNATURE> | Check transaction status |

x402 / Network

| Command | What | |---|---| | brief <room> | Live parameters for your operative ID | | operative | Your ID in both capitalisations | | fetch <URL> | Status + every header + raw body | | x402 get <URL> | Same, with ?operative= appended | | x402 pay <URL> <B64> | Retry with the envelope in the X-PAYMENT header | | envelope transfer <SRC> <DST> <AMT> [MEMO] | Sign without sending → base64 | | envelope anchor <PROG> <IX> '<ARGS>' '<ACCTS>' [MEMO] | Same, for a program call |

fetch deliberately prints status, headers and raw body rather than parsed JSON: a decryption key can arrive in a response header, and a green 200 can carry a failure in its body.

LLM Agent

Natural language interface to read and write:

bun run scripts/agent.ts "check my balance and token accounts"
bun run scripts/agent.ts "decode account ABC with fields: authority at offset 8 as pubkey, amount at offset 40 as u64"
bun run scripts/agent.ts "transfer 1000000 base units from my SCRIP ATA to tribute ATA with memo 'the exact memo string'"

Script Modules

Import directly for room scripts that need precise control:

| Module | Exports | |---|---| | scripts/decode.ts | decodeAccount(data, fields) — offset table decoder, bounds-checked by field name | | scripts/pda.ts | findPDA(programId, seeds), parseSeed(s), pkSeed(pk), printPDA() | | scripts/tx.ts | buildAnchorTx(), signAndSerialize(), sendTransferWithMemo(), sendTransfer() | | scripts/anchor.ts | buildAnchorInstruction(), discriminator(), borshEncode() | | scripts/hash.ts | sha256(), sha256FirstN(), nonceBytes(), xor(), fromHex()/toHex(), fromBase64()/toBase64() | | scripts/x402.ts | request(), get(), pay(), withOperative(), idCases(), operativeId() | | scripts/config.ts | ESTATE_RPC, resolveRpcUrl(), getConnection(), loadKeypair() | | scripts/bootstrap.ts | me (Keypair), conn (Connection) |

Room Pattern

A typical room script:

import { me, conn } from "./scripts/bootstrap";
import { decodeAccount } from "./scripts/decode";
import { sendTransferWithMemo } from "./scripts/tx";

// 1. Fetch clause
const clause = await (await fetch("http://10.61.0.20:3000/clause/4")).json();

// 2. Fetch and decode the target account
const info = await conn.getAccountInfo(new PublicKey(clause.account));
const decoded = decodeAccount(info!.data, clause.fields);

// 3. Derive your ATA
import { getAssociatedTokenAddress } from "@solana/spl-token";
const myAta = await getAssociatedTokenAddress(new PublicKey(clause.mint), me.publicKey);

// 4. Build and send (transfer + memo in ONE transaction)
await sendTransferWithMemo(conn, me, {
  sourceAta: myAta,
  destAta: new PublicKey(decoded.tribute_ata),
  amount: decoded.amount,
  memo: clause.memo,
});

Key Addresses

| Program | Address | |---|---| | SPL Token | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA | | Associated Token Account | ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL | | SPL Memo | MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr | | Instructions Sysvar | Sysvar1nstructions1111111111111111111111111 |

Pitfalls

  • Endianness. Multi-byte ints are little-endian. readBigUInt64LE, never BE.
  • Raw bytes, not hex strings. sha256(bytes), not sha256(hexString).
  • Base units, not decimals. Send the integer the clause states; never multiply by 10^decimals.
  • Memo in same transaction. The SDK transfer helper omits it. Build the tx yourself with both instructions.
  • ATA is already a token account. A tribute_ata from a decoded record is the destination — don't derive an ATA on top of it.
  • PDA seeds. Exact order, case, and encoding. Empty getAccountInfo usually means wrong seeds.
  • Decode fields in order. Wrong width on an early field shifts everything after it.
  • Read the body, not the status code. A green 200 and a payment that really left your wallet can still come back SEALED, with the fee kept.
  • Headers carry values. A key to unscramble a piece can be in a response header, not the body.
  • ?operative= on every request, or endpoints return nothing useful.
  • ID capitalisation varies per endpoint. Some want it exactly as issued, some lowercase. That is not a typo in the brief — use operative to see both.
  • Never hardcode. Every value is live and belongs to you; re-read it rather than pasting it forward.