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

relayshield-snap

v0.1.0

Published

Screens the counterparty address of every MetaMask transaction against RelayShield before you sign.

Readme

RelayShield Counterparty Screening (MetaMask Snap)

Screens the counterparty address of every transaction against RelayShield's criminal intelligence corpus, in the MetaMask confirmation window, before the user signs.

What it does

onTransaction takes the to address, calls POST /v1/metered/wallet-risk, and renders one of three things: a flagged verdict, a no-known-risk verdict, or an explicit not screened panel.

The rule this snap is built around

A failed check is never rendered as a clean result.

Every path that cannot produce a verdict returns the "Not screened" panel, which says in as many words that this is the absence of a result rather than a clean one. That covers a network failure, a rejected key, an empty balance, a non-200, an unparseable body, and an ok: false.

It also covers degraded: true. The API sets that when it assembled an answer from an upstream that did not respond, which makes an empty risk_flags list an absence of data rather than an absence of risk. Rendering that as "no known risk" would reproduce, inside a wallet at the moment of signing, the same false-clean defect that shipped in three separate live billing endpoints in August 2026. That is the single most important behaviour in src/index.tsx, and it is why Screening has screened: false as a first-class variant rather than an error thrown away in a catch.

Funding: the user pays for their own screens

Founder decision, and the reason for the endpoint choice. The snap holds the user's own RelayShield API key in snap_manageState and every call is billed to them at $0.05. We bundle no allowance.

The originally planned endpoint was /v1/payg/wallet-risk, which does not work here:

  • Bare /v1/wallet-risk is keyless and unbilled, so a key sent to it funds nothing.
  • /v1/payg/wallet-risk is x402, and paying it from inside a snap requires signing a payment, which needs a key-management permission, which triggers the mandatory third-party audit this snap is deliberately scoped to avoid.

So /v1/metered/wallet-risk was added to relayshield_api.py on 2026-08-09: same handler, same $0.05, reachable with the caller's own API key.

Permissions, and what is deliberately absent

endowment:transaction-insight   read the pending transaction
endowment:network-access        call api.relayshield.net
endowment:page-home             configuration screen
snap_dialog                     key entry
snap_manageState                store the user's key

allowTransactionOrigin is not requested: the snap does not need to know which dapp initiated the transaction, and asking for less is both better for the user and better at review time.

There is no endowment:keyring, no snap_getBip44Entropy and no snap_getEntropy. The snap never touches a key, a seed or a signature. That is what keeps it outside the mandatory audit requirement.

Build

npm install
npm run build

The build must run from a path with no spaces in it. mm-snap build URL-encodes the project path when it launches its eval worker and then fails to resolve it, so building from /Users/.../Side SaaS Hustle/relayshield-snap dies with Cannot find module '.../Side%20SaaS%20Hustle/.../eval-worker.cjs'. The bundle itself is fine; it is only the post-build evaluation that breaks. Copy the package to a space-free directory, build there, and copy dist/ and snap.manifest.json back.

Key entry

onHomePage renders a form when no key is set and a "Remove key" button when one is. onUserInput handles both and re-renders the page in place with a success or failure banner.

The key is validated locally against rs_live_ plus 32 hex characters before it is stored. That format comes from f"rs_live_{uuid.uuid4().hex}" in relayshield_developer_signup.py. Catching a paste error here matters: without it the first sign the user hears about it is a 401 rendered over a pending transaction, which is the worst possible moment.

Removing a key uses snap_manageState clear rather than writing an empty string, so nothing is left behind.

Where users find us

Three links to api.relayshield.net/developers?source=metamask-snap: the unconfigured transaction panel, the home page when no key is set, and the home page footer. The metamask-snap source key is registered in _SOURCE_BANNERS so those arrivals get an answer to the question they arrived with. That registration went in at the same time as the link on purpose, because rsscan shipped its link first, was silently aliased to the generic GitHub banner, and spent months sending arrivals to a paragraph about client libraries.

Not done yet

  • Not published to npm, so the manifest packageName and repository point at a repo that does not exist yet.
  • EVM only, which matches MetaMask. The underlying endpoint also handles Solana, TON and Bitcoin.
  • No local caching, so one screen per transaction. Worth revisiting alongside the freshness work.