coinscan 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +157 -2
- package/dist/index.cjs +614 -0
- package/dist/index.d.cts +704 -0
- package/dist/index.d.ts +704 -0
- package/dist/index.js +563 -0
- package/package.json +32 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PIRB
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,158 @@
|
|
|
1
|
-
#
|
|
1
|
+
# coinscan
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Official TypeScript/JavaScript client for the [CoinScan API](https://coinscan.tech): scan any token on Solana, Ethereum, BSC, Base and more for price, liquidity, holders, snipers, bundles, LP lock, honeypot and tax checks, dev history and an AI rug estimate; map holders and bubble clusters; read wallet PnL; render charts; pull market and launchpad data.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install coinscan
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Zero dependencies. Node 18+, Bun, Deno and edge runtimes (anything with `fetch`). ESM and CommonJS, full TypeScript types, automatic retries on rate limits, and your remaining credits after every call.
|
|
10
|
+
|
|
11
|
+
## Quickstart
|
|
12
|
+
|
|
13
|
+
Get a free key (25 scans a day) at [coinscan.tech/signup](https://coinscan.tech/signup), or:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { CoinScan } from "coinscan";
|
|
17
|
+
|
|
18
|
+
const { api_key } = await CoinScan.signup({ email: "you@example.com" }); // shown once
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { CoinScan } from "coinscan";
|
|
23
|
+
|
|
24
|
+
const cs = new CoinScan({ apiKey: process.env.COINSCAN_API_KEY }); // the default, too
|
|
25
|
+
const scan = await cs.scan("6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN");
|
|
26
|
+
|
|
27
|
+
console.log(scan.name, scan.market?.mcap, scan.market?.liquidity);
|
|
28
|
+
console.log("bundles", scan.holders?.bundle_pct, "snipers", scan.holders?.sniper_pct);
|
|
29
|
+
console.log("rug probability", scan.ai_predictions?.p_rug);
|
|
30
|
+
console.log(cs.lastUsage?.remaining, "credits left today");
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
CommonJS: `const { CoinScan } = require("coinscan");`
|
|
34
|
+
|
|
35
|
+
Keep the key on a server. A key shipped in browser or app code is public.
|
|
36
|
+
|
|
37
|
+
## What you can call
|
|
38
|
+
|
|
39
|
+
| method | returns | credits |
|
|
40
|
+
|-|-|-|
|
|
41
|
+
| `cs.scan(address, { chain })` | full token scan | 10 |
|
|
42
|
+
| `cs.scanLpLock(address)` | finishes a scan made with `lpDefer: true` | 6 |
|
|
43
|
+
| `cs.detect(address)` | `{ address, chain }` from the address shape | 0 |
|
|
44
|
+
| `cs.resolveTicker("PEPE")` | candidate contracts ranked by liquidity | 2 |
|
|
45
|
+
| `cs.resolvePair(chain, pair)` | the token behind a pool | 0 |
|
|
46
|
+
| `cs.major("BTC")` | price, cap, supply, ATH of a major coin | 0 |
|
|
47
|
+
| `cs.mcapBatch([addr, ...])` | `{ [address]: mcap }` for up to 500 tokens | 1 |
|
|
48
|
+
| `cs.maxMcapBatch(items)` | highest cap since a timestamp | 3 |
|
|
49
|
+
| `cs.lore(address)`, `cs.community(address)` | backstory; X community stats | 4 |
|
|
50
|
+
| `cs.search("cat")` | DexScreener pairs | 0 |
|
|
51
|
+
| `cs.chart(network, pool, { plotType: "ta" })` | PNG `Uint8Array` | 3 |
|
|
52
|
+
| `cs.subscan.holders(token, { chain })` | top holders report | 1 |
|
|
53
|
+
| `cs.subscan.holdersMap(token, { chain })` | holders by behaviour | 1 |
|
|
54
|
+
| `cs.subscan.whaleMap(token, { chain })` | holders by size | 2 |
|
|
55
|
+
| `cs.subscan.bubbleMap(token, { chain })` | `{ messages, image }` (PNG bytes) | 5 |
|
|
56
|
+
| `cs.subscan.earlyBuyers(token, { chain })` | first 50 buyers and what they did | 2 |
|
|
57
|
+
| `cs.subscan.walletMap(token, { chain })` | holders labelled bot, insider, smart money | 1 |
|
|
58
|
+
| `cs.subscan.kolHolders(token)` | influencer wallets holding (Solana) | 1 |
|
|
59
|
+
| `cs.subscan.topHolderBags(token)` | top holders' other pump.fun bags | 1 |
|
|
60
|
+
| `cs.subscan.overlap(token1, token2)` | wallets holding both (Solana) | 2 |
|
|
61
|
+
| `cs.subscan.dev(address, { chain })` | deployer launch history | 4 |
|
|
62
|
+
| `cs.subscan.topTraders(token, { chain })` | traders by realized PnL | 1 |
|
|
63
|
+
| `cs.subscan.walletStats(wallet)` | 30-day stats across chains | 3 |
|
|
64
|
+
| `cs.wallet.pnl(wallet, { chain })` | PnL report | 5 |
|
|
65
|
+
| `cs.wallet.floor(token, { chain })` | holders' entry caps, supply in loss | 1 |
|
|
66
|
+
| `cs.wallet.tokenBalance(wallet, token, { chain })` | number | 1 |
|
|
67
|
+
| `cs.wallet.tokenBalances(token, wallets, { chain })` | `{ [wallet]: balance }` | 1 |
|
|
68
|
+
| `cs.wallet.tx(hash, { chain })` | `{ from, to, value_wei, block_number }` | 1 |
|
|
69
|
+
| `cs.market.macro()`, `.news()`, `.calendar()`, `.gas()` | market data | 0 |
|
|
70
|
+
| `cs.market.dexPaid()`, `.dexTrending()`, `.dexPaidStatus(token)` | DexScreener signals | 0 |
|
|
71
|
+
| `cs.market.pumpfunGraduates()`, `.pumpfunSearch(q)` | pump.fun | 0 |
|
|
72
|
+
| `cs.market.treemap()`, `.topCoinsCard()`, `.fearGreedImage()`, `.pnlCard({...})` | PNG bytes | 0 |
|
|
73
|
+
| `cs.launchpads.summary()`, `.stats()`, `.chart()`, `.heat()` | launchpad volume and heat | 0 |
|
|
74
|
+
| `cs.account.me()`, `.usage()`, `.rotateKey()` | your plan, usage, keys | 0 |
|
|
75
|
+
| `cs.billing.plans()`, `.createInvoice({...})`, `.waitForPayment(id)` | plans and USDT/USDC invoices | 0 |
|
|
76
|
+
|
|
77
|
+
Field-by-field documentation: [coinscan.tech/docs](https://coinscan.tech/docs).
|
|
78
|
+
|
|
79
|
+
## Text reports
|
|
80
|
+
|
|
81
|
+
Holder, wallet and deployer routes return formatted reports (Telegram-style HTML), ready to post in a bot. `toText` makes them plain:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import { CoinScan, toText } from "coinscan";
|
|
85
|
+
|
|
86
|
+
const cs = new CoinScan();
|
|
87
|
+
console.log(toText(await cs.subscan.dev("6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN")));
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Images
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import { writeFile } from "node:fs/promises";
|
|
94
|
+
|
|
95
|
+
await writeFile("chart.png", await cs.chart("solana", "PAIR_ADDRESS", { timeframe: "hour", plotType: "ta" }));
|
|
96
|
+
|
|
97
|
+
const bubble = await cs.subscan.bubbleMap("6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN");
|
|
98
|
+
if (bubble.image) await writeFile("bubble.png", bubble.image);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Credits, limits and errors
|
|
102
|
+
|
|
103
|
+
`cs.lastUsage` holds the usage headers of the last metered call: `cost`, `limit`, `remaining`, `reset` (next 00:00 UTC), `rateLimit`, `rateRemaining`.
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { CoinScan, NotFoundError, QuotaExceededError, UpstreamTimeoutError } from "coinscan";
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
await cs.scan("So11111111111111111111111111111111111111112");
|
|
110
|
+
} catch (e) {
|
|
111
|
+
if (e instanceof NotFoundError) console.log("no such token");
|
|
112
|
+
else if (e instanceof QuotaExceededError) console.log("out of credits until", e.resetAt, e.upgradeUrl);
|
|
113
|
+
else if (e instanceof UpstreamTimeoutError) console.log("a provider was slow; try again");
|
|
114
|
+
else throw e;
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
| error | when |
|
|
119
|
+
|-|-|
|
|
120
|
+
| `AuthenticationError` | 401: missing or unknown key |
|
|
121
|
+
| `NotFoundError` | 404: token, pair or data not found |
|
|
122
|
+
| `ValidationError` | 422: bad input |
|
|
123
|
+
| `RateLimitError` | 429 per-minute limit (retried, then thrown; has `retryAfter`) |
|
|
124
|
+
| `QuotaExceededError` | 429 daily credits spent (`resetAt`, `upgradeUrl`) |
|
|
125
|
+
| `UpstreamTimeoutError` | a 45 s upstream deadline passed |
|
|
126
|
+
| `InternalServerError` | 5xx (502/503/504 retried; credits are refunded) |
|
|
127
|
+
| `APIConnectionError`, `APITimeoutError` | network problems |
|
|
128
|
+
|
|
129
|
+
All extend `CoinScanError`. `new CoinScan({ maxRetries: 0 })` turns retries off. The default timeout is 90 s per attempt because a scan can take up to 60.
|
|
130
|
+
|
|
131
|
+
## Paying from code
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
const inv = await cs.billing.createInvoice({ plan: "starter", chain: "solana", token: "USDC" });
|
|
135
|
+
console.log(`send exactly ${inv.amount} ${inv.token} to ${inv.pay_to}`);
|
|
136
|
+
console.log(inv.payment_uri); // Solana Pay / EIP-681 link
|
|
137
|
+
const paid = await cs.billing.waitForPayment(inv.id);
|
|
138
|
+
console.log(paid.status, paid.plan_expires_at);
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Configuration
|
|
142
|
+
|
|
143
|
+
| option | environment variable | default |
|
|
144
|
+
|-|-|-|
|
|
145
|
+
| `apiKey` | `COINSCAN_API_KEY` | none |
|
|
146
|
+
| `baseURL` | `COINSCAN_BASE_URL` | `https://api.coinscan.tech` |
|
|
147
|
+
| `timeout` (ms) | | 90 000 |
|
|
148
|
+
| `maxRetries` | | 2 |
|
|
149
|
+
| `fetch` | | `globalThis.fetch` |
|
|
150
|
+
|
|
151
|
+
## Links
|
|
152
|
+
|
|
153
|
+
- Docs: https://coinscan.tech/docs
|
|
154
|
+
- Pricing: https://coinscan.tech/pricing (free 25 scans a day; from $50 a month, paid in USDT or USDC)
|
|
155
|
+
- MCP server for Claude and Cursor: https://coinscan.tech/docs/mcp
|
|
156
|
+
- Support: contact@pirb.tech
|
|
157
|
+
|
|
158
|
+
MIT licensed.
|