cashcn
v0.0.0-alpha.0
Published
Smart `npm fund`: resolve an OSS maintainer/repo/package and open the right funding checkout, pre-filled with amount + recurrence. Routes money, never custodies it.
Maintainers
Readme
cashcn
Ultra-simple payments to OSS maintainers via the CLI — a smarter
npm fund.
cashcn resolves a maintainer / repo / package to its funding destinations and
opens the right hosted checkout, pre-filled with your amount and recurrence.
npx cashcn <verb> <destination> <amount>[/{m,y}]It is a discovery + deep-link tool. Money never touches cashcn — it routes
you to GitHub Sponsors / Open Collective / Liberapay / etc. with the amount and
recurrence already filled in. That is the one shape of this idea that is
shippable today with zero PCI/KYC burden (see cashcn.md research for why
actually moving the money requires becoming a regulated payment platform).
Why a POC, and what it proves
The research found that reading funding data is easy everywhere but
initiating a payment via API is gated on every fiat platform (GitHub
createSponsorship is recurring-only and charges the caller's card; Open
Collective blocks external Stripe/PayPal charges; thanks.dev / Liberapay have no
payment API). What is fully feasible is deep-linking into the hosted checkout
with the recipient, amount and recurrence prefilled. This POC demonstrates that
end-to-end.
Usage
# verbs are all synonyms (read it like a sentence):
# pay donate sponsor gift send tip back fund thank support
npx cashcn pay gh://franky47 100 # one-time $100
npx cashcn sponsor 47ng/nuqs 10/m # $10 / month
npx cashcn donate oc://antfu 25/y # $25 / year
npx cashcn tip npm://nuqs 5/m # resolve npm pkg fundingThe
$prefix is intentionally dropped — it triggers shell variable expansion. Amounts are plain numbers with an optional/mor/ysuffix.
Add --print (or --dry-run) to resolve and build the link without opening
a browser — handy for scripting and for seeing what got resolved.
Destinations
| Form | Meaning |
|---|---|
| gh://<user> | GitHub user → GitHub Sponsors (+ their profile FUNDING.yml) |
| gh://<owner>/<repo> | GitHub repo → reads .github/FUNDING.yml |
| npm://<pkg> | npm package → reads its funding field, then the repo's FUNDING.yml |
| oc://<slug> | Open Collective collective |
| <user> | shorthand for gh://<user> |
| <owner>/<repo> | shorthand for gh://<owner>/<repo> |
Scoped npm packages need the explicit scheme: npm://@scope/pkg.
How it works
- Parse the destination (
src/destination.js) and amount (src/amount.js). - Resolve funding targets (
src/resolve.js) by unioning:- the npm registry
fundingfield, .github/FUNDING.yml(src/funding-yml.js, a minimal parser),- GitHub Sponsors directly for a bare user.
- the npm registry
- Rank targets by how well each can be pre-filled (
src/platforms.js):Open Collective > Liberapay > GitHub Sponsors > profile-only. Liberapay is recurring-only, so it's demoted for one-time payments. - Build the deep-link with
amount/interval/frequencyinjected where the platform supports it, and open it (src/open-url.js).
GitHub Sponsors tier resolution
GitHub has no free-form amount query param — you can only deep-link to a
specific tier, identified by a numeric tier_id. cashcn resolves the tier
whose price exactly matches your amount (src/github-tiers.js), trying in order:
ghCLI —gh api graphqllists every tier with its node id (decoded to the numerictier_id). Authoritative; used whenghis installed + authed. An exact match deep-links to that tier (so the sponsor lands on its rewards).- Public-page crawl — scrapes
github.com/sponsors/<login>for thetier_id↔ price pairs. Token-free fallback whenghisn't available. - Custom amount — if no exact tier matches, pre-fill a free-form
amounton the/sponsorshipscheckout (?frequency=…&amount=…). GitHub honours this as long as the maintainer has custom amounts enabled.
One-time and monthly tiers have different ids, so pay … 10 and sponsor … 10/m
resolve to different tiers. GitHub has no yearly tier, so /y skips the lookup.
Pre-fill capability (per research)
| Platform | Amount | Recurrence | Notes |
|---|---|---|---|
| Open Collective | ✅ | ✅ | ?amount=&interval=month\|year |
| Liberapay | ✅ | ✅ | recurring-only; currency required or amount is dropped |
| GitHub Sponsors | ✅ | ✅ | exact-amount tier → tier_id, else custom amount (see below) |
| Patreon / Ko-fi / Buy Me a Coffee / Polar | ❌ | ❌ | opens the profile page only |
Limitations (it's a POC)
FUNDING.ymlparser handles the flatkey: value/key: [a, b]shape only — not arbitrary YAML. Swap in a real parser for production.- No ecosyste.ms aggregator backstop, no
funding.json(floss.fund) source yet — both are noted in the research as worthwhile additions. - GitHub tier resolution matches the amount exactly; it doesn't snap to the
nearest tier (that would silently change what you pay). Tier lookups aren't
cached, so each GitHub deep-link makes one
gh/HTTP call. - Zero runtime dependencies on purpose, so
npx-from-source has no install step. (The tier lookup shells out toghonly if it's already on your PATH.)
Run from source
node bin/cashcn.js sponsor 47ng/nuqs 10/m --print