Singularity-Agent
Singularity-Agent — agentic blockchain, made practical

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.

It never asks for your keys. Singularity can read the blockchain and prepare a payment for you, but it cannot sign or send one. There is no code in it that can move your money.

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
What "unsigned" means Singularity can fill out the paperwork for a payment — who is sending, who is receiving, how much, what it will cost. It hands that form to you. You sign it in your own wallet, where your key lives. Think of it as a very well-informed assistant who prepares the cheque but can never sign it.

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.

  1. 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:

    $ node --version
    v22.19.0

    Any number 20.10 or higher is fine.

  2. Download the code

    $ git clone https://github.com/DarkStarMatters/Singularity-Agent.git && cd Singularity-Agent
    Cloning into 'Singularity-Agent'...
  3. Install and build

    The first command downloads the libraries it depends on. The second turns the source code into something runnable.

    $ npm install && npm run build
    added 214 packages in 18s
  4. Make singularity available everywhere

    This lets you type singularity from any folder instead of the full path.

    $ npm link
    added 1 package
  5. 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.

    $ singularity chains
      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
    
    
      23 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.

$ singularity balance vitalik.eth --chain ethereum
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
Real output from a live run. Balances change constantly, so yours will differ.

Reading the command

PartWhat it is
singularityThe tool itself.
balanceWhat you want — the question you're asking.
vitalik.ethWho you're asking about. A name, an address, or a nickname you've saved.
--chain ethereumWhich network to look on. -c is the short form.
Notice what it told you The grey note at the bottom is deliberate. On Ethereum there is no way to list every token a wallet holds without a paid indexing service, so the tool checks a curated list of major ones and says so. It would rather tell you the shape of the answer than let you assume it found everything.

Add --json to any command to get machine-readable output instead of a table.


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.

$ claude mcp add singularity -- node /path/to/Singularity-Agent/dist/mcp/server.js
 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.

$ claude plugin marketplace add ./Singularity-Agent
 Successfully added marketplace: singularity
$ claude plugin install singularity-agent@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 ten tools Claude gets

ToolWhat it does
chainsList every supported network.
resolveIdentify what a piece of text is and which chains it belongs to.
balanceHoldings for one address on one chain.
portfolioOne address across many chains at once.
transactionLook up and explain a transaction.
blockFetch a block by height, hash, or latest.
feesWhat a transfer costs right now.
read_contractRead data out of a smart contract.
decodeTurn raw transaction data into a readable function call.
build_transferPrepare an unsigned payment.

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.


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.

$ singularity resolve vitalik.eth
  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.

$ singularity portfolio vitalik.eth
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.

$ singularity tx 0xc29d74412da1bec4e662a7978c3ef993beed7833219d3362a2abca09700fdaa5
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…
You never told it this was on Base — it found it.

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.

$ singularity fees --chain bitcoin
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.

$ singularity decode 0xa9059cbb000000000000000000000000d8da…0f4240
{
  "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" }
  ]
}
Translation: send 1,000,000 base units — 1 USDC, which has 6 decimals — to that address.

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.

$ singularity build --chain base --to vitalik.eth --amount 25.5 --token USDC
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.
Read the warnings, every time That second warning is not boilerplate. Anyone can create a token called “USDC”. The only thing that identifies a real one is its contract address — which is why the tool prints it and asks you to check.

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.

$ singularity doctor
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.
That 21-second Bitcoin result is a slow public server, not a broken one. Configuration shows how to use a faster one.

Coverage

23 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.

evm

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
svm

Solana

Addresses are base58 text with no prefix. Token holdings can be listed in full.

  • solana
  • solana-devnet
utxo

Bitcoin & kin

Addresses start bc1, 1 or 3. No tokens — just coins.

  • bitcoin
  • bitcoin-testnet
  • litecoin
cosmos

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 tx to 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 fees exists.
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_contract reads 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:

$ export SINGULARITY_RPC_ETHEREUM=https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY
# 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:

{} ~/.singularity/config.json
{
  "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:

$ node dist/cli/index.js chains
“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:

$ singularity balance cosmos1qypqx…lzv7xu -c osmosis
  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:

$ singularity balance 0xYourAddress -c base --token 0xTokenContractAddress
“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.