Read any blockchain from your terminal.
One tool for Ethereum, Solana, Bitcoin and Cosmos. Check what is in a wallet, look up what a transaction did, see what fees cost right now — and get the answer in the same shape no matter which chain it came from.
The idea
One tool instead of four
A blockchain is a public ledger. Anyone can read it — you do not need an account, a password, or anyone's permission. What you normally do need is the right tool for the right chain: one for Ethereum, a different one for Solana, another for Bitcoin. Each has its own address format, its own vocabulary, and its own way of telling you the same thing.
Singularity-Agent is one tool for all of them. You ask a question, it goes and reads the ledger, and it answers in a consistent format. A Bitcoin balance and a Cosmos balance come back with the same field names, so you only have to learn them once.
It works in two places: as a command you type in a terminal, and as a plugin for Claude, so you can ask questions in plain English instead. Both run exactly the same code.
Safety
What it can and can't do
Every crypto wallet is controlled by a private key — a long secret that acts like the password to your money. Anyone who has it can spend everything. The single most important thing to know about this tool is that it never touches yours.
It can read
- Balances of any public address
- What a past transaction did
- Current network fees
- Data stored in smart contracts
- Prepare an unsigned payment for you
It cannot
- Ask for, store, or read a private key
- Sign a transaction
- Send or broadcast anything
- Move a single coin, in any circumstance
The practical consequence: the worst thing a bug in this tool can do is give you a wrong answer. It cannot lose your funds, because it was never able to reach them.
Setup
Install it
This takes about two minutes. You'll be typing into a terminal — Terminal on macOS, PowerShell or Git Bash on Windows, or any shell on Linux.
-
Install Node.js
Singularity runs on Node.js version 20.10 or newer. Get it from nodejs.org if you don't have it, then check it worked:
v22.19.0Any number 20.10 or higher is fine.
-
Download the code
Cloning into 'Singularity-Agent'... -
Install and build
The first command downloads the libraries it depends on. The second turns the source code into something runnable.
added 214 packages in 18s -
Make
singularityavailable everywhereThis lets you type
singularityfrom any folder instead of the full path.added 1 package -
Check that it works
This lists every network it knows about. No lookup, no account, no API key — if you see a table, you're ready.
ID NAME FAMILY CHAIN ID ASSET ALIASES ethereum Ethereum evm 1 ETH eth, mainnet, l1 base Base evm 8453 ETH arbitrum Arbitrum One evm 42161 ETH arb, arbitrum-one solana Solana svm — SOL sol bitcoin Bitcoin utxo — BTC btc cosmoshub Cosmos Hub cosmos cosmoshub-4 ATOM cosmos, atom, gaia … 32 chain(s).
Getting started
Your first real command
Let's look inside a wallet. This one belongs to Vitalik Buterin, a co-founder of Ethereum — it's public, like every address on a blockchain.
ethereum
────────
6.71259795 ETH (native)
37.192124 USDC 0xA0b86991…06eB48
290.368219 USDT 0xdAC17F95…831ec7
4.57207827 DAI 0x6B175474…271d0F
1.46189817 WETH 0xC02aaA39…756Cc2
EVM chains cannot be enumerated without an indexer, so this covers a curated
list of major tokens only. Pass `tokens` with contract addresses to check others.
https://etherscan.io/address/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
Reading the command
| Part | What it is |
|---|---|
singularity | The tool itself. |
balance | What you want — the question you're asking. |
vitalik.eth | Who you're asking about. A name, an address, or a nickname you've saved. |
--chain ethereum | Which network to look on. -c is the short form. |
Add --json to any command to get machine-readable output instead of a table.
Try it here
Run it without installing it
A working terminal, with the real answers. Every response below was captured from an actual run against live networks — nothing here is mocked up to look good, including the two that refuse to answer.
help lists everything the
demo knows; clear wipes the screen.
The other way to use it
Ask Claude instead of typing commands
MCP (Model Context Protocol) is a standard way to give an AI assistant real tools. Without it, an assistant answering “what's in this wallet?” is recalling something from training data — possibly years stale, possibly invented. With it, Claude runs the same commands you would and reads the actual, current answer off the chain.
The quickest way
One command, run from anywhere. Use the full path to wherever you cloned the repo,
and make sure you've run npm run build first.
✓ Added stdio MCP server singularity
Or install it as a proper plugin
The repo doubles as its own single-plugin marketplace, so this is two steps. Run the
first one from the folder containing Singularity-Agent — the path has to be in
./name or absolute form, and a bare . is rejected.
✓ Successfully added marketplace: singularity
✓ Successfully installed plugin: singularity-agent@singularity (scope: user)
/plugin install does not take a folder path
It expects a plugin-name@marketplace-name id. Handing it a path fails
with “Marketplace not found” — add the marketplace first, as above. Both commands
also work inside a session as /plugin marketplace add and
/plugin install.
Check it landed with claude plugin list.
Then just ask
- “What's in vitalik.eth right now?”
- “What did transaction 0xc29d744… actually do?”
- “Is it cheap to send Bitcoin at the moment?”
- “Prepare a transfer of 25 USDC on Base to this address.”
The eighteen tools Claude gets
| Tool | What it does |
|---|---|
chains | List every supported network. |
resolve | Identify what a piece of text is and which chains it belongs to. |
balance | Holdings for one address on one chain. |
portfolio | One address across many chains at once. |
transaction | Look up and explain a transaction. |
block | Fetch a block by height, hash, or latest. |
fees | What a transfer costs right now. |
read_contract | Read data out of a smart contract. |
decode | Turn raw transaction data into a readable function call. |
history | What an address has been doing, newest first. |
mint_audit | What a Solana mint can still do to you — who can mint more, who can freeze. |
token_identity | Whether a token is the one it claims to be. |
verify_burn | Confirm a burn from its signature, at finalized commitment. |
build_transfer | Prepare an unsigned payment. |
build_burn | Prepare an unsigned burn. |
chain_liveness | Whether a chain is still producing blocks, rather than merely answering. |
inspect_exit | Before you buy: what could stop you selling it again. |
receipt_art | What a payment receipt looks like, and whether an image is genuinely it. |
Every one of them is marked read-only, and build_transfer returns a payload
plus a list of warnings that Claude is instructed to show you before you sign anything.
history on an Ethereum-style chain needs an indexer key; without one it says
so rather than returning an empty list that reads as "nothing ever happened here".
Recipes
What you can ask it
Each of these is a real command with real output. Copy any of them and run it.
“What even is this thing I pasted?”
You have a string of characters and no idea whether it's a wallet, a transaction, or
a typo. resolve works it out — and if it's a name, looks up the address
behind it.
Input vitalik.eth
Kind name
Address 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
Name vitalik.eth
Family evm
Chains ethereum
Resolves through ENS on Ethereum mainnet; the resulting address works on
every EVM chain.
“Show me everything, everywhere”
portfolio checks one address across many chains at once. It only queries
chains where that address format is actually valid, so an Ethereum address doesn't
produce a pile of Solana errors.
Portfolio for 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
──────────────────────────────────────────────────────
Queried 5 chain(s).
ethereum
────────
6.71259795 ETH (native)
37.192124 USDC
base
────
0.04182 ETH (native)
Empty on: arbitrum, optimism, polygon
“What did this transaction do?”
Paste a transaction hash with no chain and it searches the likely ones in parallel. It also decodes the raw data into a readable function call where it recognises it.
base success
─────────────
Hash 0xc29d74412da1bec4e662a7978c3ef993beed7833219d3362a2abca09700fdaa5
From 0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001
To 0x4200000000000000000000000000000000000015
Value 0 ETH
Block 51344342
Time 2026-09-15T13:13:51.000Z
0xdead…0001 -> 0x4200…0015 on Base.
https://basescan.org/tx/0xc29d744…
“Is it expensive to send right now?”
Fees work completely differently on each chain. fees normalises them to
one comparable number, then shows you the chain's own units underneath.
Fees on bitcoin
───────────────
Simple transfer ~0.00000054 BTC
nextBlock 1.1 sat/vB
within6Blocks 0.4 sat/vB
within24Hours 0.3 sat/vB
assumedTxSize 141 vB (1 input, 2 outputs, P2WPKH)
Bitcoin fees are per-vbyte, so cost depends on how many UTXOs you spend,
not on the amount sent.
“What is this wall of hex?”
When a wallet asks you to approve something, it often shows an unreadable blob.
decode tells you what it actually calls and with what arguments — worth
doing before you approve, not after.
{
"selector": "0xa9059cbb",
"signature": "function transfer(address to, uint256 amount) returns (bool)",
"name": "transfer",
"args": [
{ "name": "to", "type": "address", "value": "0xd8dA6BF2…aA96045" },
{ "name": "amount", "type": "uint256", "value": "1000000" }
]
}
“Prepare a payment for me”
This is the one command that produces something you could eventually sign. Note that nothing is sent, and no key is involved.
Unsigned transaction — base
───────────────────────────
Send 25.5 USDC (0x8335…2913) to 0xd8dA…6045 on Base.
Payload
{
"to": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"value": "0x0",
"data": "0xa9059cbb000000000000000000000000d8da…01851960",
"chainId": 8453
}
How to sign
This calls transfer() on the token contract. `to` is the TOKEN address, not
the recipient — the recipient is encoded in `data`. Sign with your own wallet.
Warnings
! This transaction is unsigned. Review every field before signing.
! Verify the token address belongs to the asset you mean. Fake tokens
reuse real symbols.
Singularity holds no keys and has not signed or broadcast anything.
“Why is everything slow?”
Singularity talks to public servers that are free and therefore heavily rate-limited.
doctor tells you which ones are actually responding.
Endpoint health
───────────────
ok ethereum 440ms
ok base 216ms
ok arbitrum 212ms
ok solana 190ms
ok bitcoin 21403ms
ok cosmoshub 516ms
ok osmosis 513ms
ok celestia 723ms
All endpoints reachable.
“Tell me when this changes”
watch keeps asking and prints only what moved. It works on a balance, a
chain's head, one transaction until it's confirmed, or the health of several chains
at once.
Watching solana
───────────────
Polling. Ctrl-C to stop.
18:44:23 #448546031 (first reading)
18:44:25 #448546039 +8
18:44:27 #448546047 +8
-i is seconds between checks; add -n 3 to stop after three changes.singularity watch --help rather than
left for you to discover.
New in v0.2.0
Getting paid, and proving it
Every payment tool answers one question — did a transaction land — and hands
back paid: true. That single word hides three things you need to know
before you ship anything, so Singularity Pay keeps them apart.
How settled is it?
Four answers, not two. Confirmed and finalized are different claims on Solana, and only one of them cannot be reversed. A tool that calls both of those "paid" is asking you to hand over goods against a transaction that can still vanish.
Were you paid what you asked?
A transaction that lands is not a transaction that paid you, in that token, for that amount. Anyone can make a token called USDC, and a payment in the fake one arrives just as smoothly. Every mismatch is named.
Can it be taken back?
Some tokens let whoever issued them freeze your balance, or move it out of your wallet without you signing anything. That gets checked before the payment link is ever shown to anybody.
✓ Payment request for 0.25 SOL
To 7xKX...gAsU
Sender 9WzD...AWWM — balance 1.84 SOL, enough
Reference 695xPtsS... — how this payment is found on chain
[ a QR code image follows, in this payment's own colours ]
Scan it with Phantom. Singularity holds no keys and cannot sign.
The code is a picture of that one payment
Every payment carries a reference — a one-off value attached to the transfer so it can be found on chain. The artwork is calculated from it. Nothing is stored, which is the whole point: two payments can never look alike, the same payment always looks identical, and anyone holding the reference can redraw it and compare.
Colour varies. Contrast does not. Every palette is measured against the background and darkened until it clears the threshold a scanner needs — because lightness is not brightness, and a sweep of 400 colour schemes found one that looked perfectly good and sat well below what a cheap camera can read.
A receipt you can check, not just keep
Once a payment is finalized it can be minted as an NFT of that same picture. It refuses to mint for a payment that is merely confirmed, or that does not match what was asked for — a receipt is evidence, and evidence built from a request rather than a result is just a nicely formatted claim.
The image is not stored on the blockchain, and we are not going to pretend it is. There is room for 200 characters; the picture is about 30,000. So the seed goes on chain instead, and the picture is calculated from it. If whoever hosts the image swaps it for a different one, the swap simply fails to verify — ask Claude, or the bot, and it will tell you.
Receipt 695xPtsS
Palette moss/indigo
Modules dot
Finders rounded
Contrast 12.6:1 ink, 8.9:1 accent
Derived from the reference alone, so anyone holding it gets this
same answer without trusting a server.
One honest footnote. Creating any new token on Solana requires that token's own key to sign for its creation — there is no way around it. So a throwaway key is made, used for that one signature, and thrown away. It never holds funds, and once the receipt exists it can do nothing at all. Your wallet is still the only thing that signs for anything of value, and it is still the only thing holding your money.
For developers
Build something on it — the SDK
Everything above asks one question and reads one answer. An application is different: it runs for weeks, asks the same question hundreds of times an hour, and sooner or later has to write. singularity-sdk is the package for that — a separate install, versioned separately, built on the same engine as the commands on this page.
✓ Created my-app from the "reader" template.
cd my-app
npm install
npm start
It reads public endpoints and needs no key to run.
reader, monitor, agent. All of them run on the first try.The same answers, in code
Set your defaults once, then ask. The result carries the same honesty the terminal output does — including the note about what a token list covers.
import { createSingularity } from 'singularity-sdk';
const sdk = createSingularity({ chain: 'ethereum', budget: { maxItems: 8 } });
const balance = await sdk.balance({ address: 'vitalik.eth', includeTokens: true });
balance.native.amount.formatted // '6.71259795'
balance.tokenCompleteness.kind // 'curated' — read this before the list
Watching, rather than asking again
Poll a balance, a chain's head, or one transaction until it's confirmed. These are polling loops and the SDK says so plainly — there's no push feed hiding underneath.
sdk.watch.balance({ address: 'vitalik.eth' }, ({ value, previous }) => {
if (!previous) return; // the first reading isn't a change
notify(previous.native.amount.formatted, value.native.amount.formatted);
}, { intervalMs: 15_000 });
Your keys stay yours — still
The tool on this page cannot sign, and neither can the SDK. But an app that can only read isn't much of an app, so the SDK defines the shape of a signer and ships none: you plug in the browser wallet, hardware device or key service you already use, and it never hands a secret to the library.
Until you do, the write methods don't exist — and your editor says so before you ever run anything.
const sdk = createSingularity({ chain: 'ethereum' });
await sdk.build.transfer({ to: 'vitalik.eth', amount: '0.1' }); // fine
await sdk.write.transfer({ to: 'vitalik.eth', amount: '0.1' });
~~~~~
Property 'transfer' does not exist on type 'SignerRequired'.
Full documentation, the signer guide and four runnable examples: singularity-sdk on GitHub.
Coverage
32 chains, four families
A family is a group of chains that work the same way underneath. Learn one member and you have effectively learned the rest. You can add any chain that isn't listed here yourself — see Configuration.
Ethereum & friends
Addresses start 0x. Hundreds of chains share this design.
- ethereum
- base
- arbitrum
- optimism
- polygon
- bsc
- avalanche
- gnosis
- scroll
- linea
- zksync
- sepolia
- base-sepolia
Solana
Addresses are base58 text with no prefix. Token holdings can be listed in full.
- solana
- solana-devnet
Bitcoin & kin
Addresses start bc1, 1 or 3. No tokens — just coins.
- bitcoin
- bitcoin-testnet
- litecoin
Cosmos
Each chain has its own address prefix, which makes them self-identifying.
- cosmoshub
- osmosis
- celestia
- injective
- dydx
You can refer to a chain by its id, a nickname, or its numeric id — eth,
ethereum, mainnet and 1 all mean the same thing.
Get it wrong and it suggests what you probably meant.
Plain English
Words you'll see
Crypto has a lot of jargon. Here is the subset you actually need to use this tool.
- Address
- A public account identifier — like a bank account number. Safe to share; that is what it is for. Every chain family writes them differently.
- Private key
- The secret that controls an address. Never share it, never type it into anything. Singularity never asks for one.
- Transaction hash txid · signature
- The receipt number for something that happened on-chain. Paste one into
txto see what it did. - Native token
- The coin a chain runs on, used to pay fees — ETH on Ethereum, SOL on Solana, BTC on Bitcoin, ATOM on Cosmos Hub.
- Token
- Anything else living on that chain, like USDC. Identified by a contract address, which differs on every chain — the same-named token has a different address on Ethereum and Base.
- Base units wei · satoshi · lamport
- Chains store whole numbers only, so amounts are held in tiny units. 1 ETH is 1018 wei; 1 BTC is 100,000,000 satoshi. Singularity shows you both, and refuses to quietly round.
- Gas / fee gwei · sat/vB
- What you pay the network to process your transaction. It fluctuates with demand, which is why
feesexists. - RPC endpoint
- The server Singularity asks for data. Free public ones are included; they are slow and rate-limited. See Configuration.
- ENS name
- A human-readable name for an Ethereum address, like
vitalik.eth. Use it anywhere an address is accepted. - Unsigned transaction
- A prepared but unsigned instruction. Harmless on its own — it does nothing until a private key signs it, which happens in your wallet, not here.
- Smart contract
- A program stored on a chain.
read_contractreads data out of one; it never writes to one.
Going further
Configuration
Faster connections
The bundled public servers need no signup, which is why they're the default — but they are throttled and sometimes just disappear. Providers like Alchemy and Infura give free API keys with far better limits. Point Singularity at one:
# The name is SINGULARITY_RPC_ + the chain id, uppercased, with - becoming _
# So base-sepolia becomes SINGULARITY_RPC_BASE_SEPOLIA
# Comma-separate several for automatic failover.
Nicknames and custom chains
Create ~/.singularity/config.json to save addresses under names you'll remember, and to add chains that aren't built in:
{
"addressBook": {
"savings": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
},
"portfolioChains": ["ethereum", "base", "solana"],
"chains": [
{
"id": "my-rollup",
"family": "evm",
"chainId": 123456,
"nativeCurrency": { "name": "Ether", "symbol": "ETH", "decimals": 18 },
"rpc": ["https://rpc.my-rollup.example"]
}
]
}
Now singularity balance savings -c base works, and my-rollup is a chain like any other.
Troubleshooting
If something goes wrong
Errors from this tool carry a code and a hint. The hint is usually the fix.
“singularity: command not found”
Step 4 of the install didn't take. Run npm link again inside the project folder. If that fails, you can always run it directly:
“RPC call failed”, or everything is very slow
A public server is rate-limiting you. Check which ones are alive with singularity doctor, then set your own endpoint — see Configuration. This is the single most common problem, and the fix is free.
“is not a valid address on Osmosis”
Cosmos chains each use their own address prefix, but they're all the same underlying account. The tool does the conversion for you rather than just complaining:
INVALID_ADDRESS "cosmos1qypqx…lzv7xu" is not a valid address on Osmosis.
That is a "cosmos" address. It is the same account on Osmosis, re-encoded:
osmo1qypqxpq9qcrsszg2pvxq6rs0zqg3yyc5helwsw
Copy the address it gives you. singularity resolve on any Cosmos address lists every equivalent at once.
“Transaction was not found”
Three likely reasons. It might be on a chain outside the default search set — name it with --chain. It might be too new and still pending. Or, on Solana, it might simply be too old: public Solana servers delete old history, and retrieving it needs an archival endpoint.
A token I own isn't showing up
Expected on Ethereum-style chains — see Limits. Name the token explicitly by its contract address:
“Unknown chain”
Check the spelling against singularity chains. The error also guesses what you meant — typing etherium suggests ethereum.
Honesty
What it deliberately won't do
These are real boundaries, not bugs. They're listed here, and in the tool's own output, because a confident wrong answer is worse than a clear “I can't”.
- Ethereum token lists aren't complete. Listing every token an address holds requires a paid indexing service. Without one, the tool checks a curated set of major tokens and says so. Solana and Cosmos can list everything, and do.
- No prices. It reports quantities, not dollar values.
- IBC tokens show as hashes. On Cosmos, a transferred token appears as
ibc/3EF74C…. Identifying it needs a per-token lookup, so it shows the hash rather than guessing. - Cosmos fees are an estimate. Gas prices there are set by individual validators, not the chain. Your wallet will usually re-quote.
- No CosmWasm contract queries. Contract reads cover Ethereum-style chains and Solana.
- It cannot send anything. By design, permanently.