nimimo Logonimimo

Developer Docs

Resolve nimimo handles to blockchain addresses from any app, website, or service. One endpoint, three chains, zero authentication required.

How it works

Every nimimo user has a human-readable handle like @neat-gecko. Behind that handle are receiving addresses for Bitcoin, Ethereum, and Solana. The resolution API lets you look up those addresses programmatically so your users can send to a name instead of a raw address.

Public

No API key or auth required

Cross-origin

CORS enabled for browser use

Rate limited

30 requests per 60 seconds

Base URL

https://nimimo.com/api/v1

All endpoints are versioned. The current version is v1.

Endpoints

Handle Resolution
GET
/resolve?handle={handle}

Resolve a handle to all registered addresses

GET
/resolve?handle={handle}&chain={chain}

Resolve a handle to a specific chain address

Supported chains: bitcoin, ethereum, solana

Try it

Test the API right here. The default handle neat-gecko is a real nimimo identity — hit send and see the live response.

GET/api/v1/resolve
https://nimimo.com/api/v1/resolve?handle=neat-gecko

Resolve all chains

Request
GET https://nimimo.com/api/v1/resolve?handle=neat-gecko
Response 200
{
  "handle": "neat-gecko",
  "addresses": {
    "bitcoin": "bc1qz3yaratxc9z6wz2pj2k97nzl00l4cucpvcquq9",
    "ethereum": "0x874a40B1857B006d46b80c9e6badCEF3BA3B705C",
    "solana": "9rhN3eug2LbqZKCtbkGRKjRq9BVa4Y5VE4Puf2p4HCRk"
  }
}

Resolve a single chain

Request
GET https://nimimo.com/api/v1/resolve?handle=neat-gecko&chain=bitcoin
Response 200
{
  "handle": "neat-gecko",
  "chain": "bitcoin",
  "address": "bc1qz3yaratxc9z6wz2pj2k97nzl00l4cucpvcquq9"
}

Quick start

JavaScript / TypeScript
async function resolveHandle(handle) {
  const res = await fetch(
    `https://nimimo.com/api/v1/resolve?handle=${handle}`
  )
  if (!res.ok) throw new Error("Resolution failed")
  return res.json()
}

const { addresses } = await resolveHandle("neat-gecko")
console.log(addresses.bitcoin)
// "bc1qz3yaratxc9z6wz2pj2k97nzl00l4cucpvcquq9"
Python
import requests

def resolve_handle(handle, chain=None):
    params = {"handle": handle}
    if chain:
        params["chain"] = chain
    r = requests.get("https://nimimo.com/api/v1/resolve", params=params)
    r.raise_for_status()
    return r.json()

result = resolve_handle("neat-gecko")
print(result["addresses"]["ethereum"])
# "0x874a40B1857B006d46b80c9e6badCEF3BA3B705C"
cURL
curl "https://nimimo.com/api/v1/resolve?handle=neat-gecko"

# Single chain
curl "https://nimimo.com/api/v1/resolve?handle=neat-gecko&chain=solana"

Error responses

All errors return a JSON object with error and message fields.

StatusErrorMeaning
400invalid_handleHandle is malformed or empty
400invalid_chainChain not supported (use bitcoin, ethereum, or solana)
404not_foundHandle does not exist
404no_addressHandle exists but has no address for the requested chain
429Rate limit exceeded (30 req / 60s)
Example error response
{
  "error": "not_found",
  "message": "Handle not found"
}

Handle format

Handles are lowercase alphanumeric strings with optional hyphens. They always start with a letter. When displayed to users, prefix with @.

Validneat-gecko
Validlucky-mountain-42
Invalid123-bad
InvalidCool-Water

Rate limiting

The resolution API allows 30 requests per 60 seconds per IP address. Rate limit headers are included in every response:

X-RateLimit-Limit: 30
X-RateLimit-Remaining: 28
X-RateLimit-Reset: 1712073600000

If you need higher limits for production integrations, reach out to us.

TypeScript SDK

The official SDK wraps the resolution API with typed responses, automatic retries, caching, and payment helpers. Zero dependencies, ~3KB gzipped, dual ESM/CJS.

Install
npm install @nimimo/resolve

Initialize

Setup
import { NimimoClient } from "@nimimo/resolve"

const nimimo = new NimimoClient()

// Optional: custom config
const nimimo = new NimimoClient({
  baseUrl: "https://nimimo.com/api/v1",  // default
  cacheTtl: 30_000,  // 30s in-memory cache (default)
})

Resolve handles

Single handle — all chains
const { handle, addresses } = await nimimo.resolve("neat-gecko")

console.log(addresses.bitcoin)
// "bc1qz3yaratxc9z6wz2pj2k97nzl00l4cucpvcquq9"

console.log(addresses.ethereum)
// "0x874a40B1857B006d46b80c9e6badCEF3BA3B705C"

console.log(addresses.solana)
// "9rhN3eug2LbqZKCtbkGRKjRq9BVa4Y5VE4Puf2p4HCRk"
Single handle — specific chain
const { address } = await nimimo.resolve("neat-gecko", "bitcoin")
// "bc1qz3yaratxc9z6wz2pj2k97nzl00l4cucpvcquq9"
Batch resolve
const results = await nimimo.resolveMany(["neat-gecko", "lucky-mountain"])
// [
//   { handle: "neat-gecko", addresses: { bitcoin: "bc1q...", ... } },
//   { handle: "lucky-mountain", addresses: { bitcoin: "bc1q...", ... } }
// ]
Check if a handle exists
const exists = await nimimo.exists("neat-gecko")  // true
const nope = await nimimo.exists("nonexistent")   // false

Payment intents

Generate wallet-ready payment objects from a handle. The SDK resolves the address and converts the amount to the chain's native unit (wei, satoshis, lamports). You sign with whatever wallet you already use.

Create a payment intent
const intent = await nimimo.paymentIntent("neat-gecko", {
  chain: "ethereum",
  amount: "0.05",  // ETH
})

// intent = {
//   to: "0x874a40B1857B006d46b80c9e6badCEF3BA3B705C",
//   value: "50000000000000000",  // wei
//   chain: "ethereum",
//   handle: "neat-gecko",
// }

// Use with ethers.js
await signer.sendTransaction({ to: intent.to, value: intent.value })

// Use with wagmi/viem
await sendTransaction({ to: intent.to, value: intent.value })
Bitcoin payment intent
const intent = await nimimo.paymentIntent("neat-gecko", {
  chain: "bitcoin",
  amount: "0.001",  // BTC
})
// intent.to    → "bc1qz3yaratxc9z6wz2pj2k97nzl00l4cucpvcquq9"
// intent.value → "100000" (satoshis)

Pay URLs

Generate shareable payment links. No SDK needed on the receiving end — the link opens the nimimo profile with a pre-filled payment flow.

Generate a pay URL
const url = nimimo.payUrl("neat-gecko", {
  chain: "ethereum",
  amount: "0.05",
})
// "https://nimimo.com/@neat-gecko?pay=0.05&chain=ethereum"

// Drop it in an invoice, a bio, or a chat message.
// Anyone who clicks it can pay from any wallet.

Error handling

Typed errors
import { NimimoClient, HandleNotFound, NoAddress, RateLimited } from "@nimimo/resolve"

try {
  const result = await nimimo.resolve("nonexistent-handle")
} catch (err) {
  if (err instanceof HandleNotFound) {
    console.log("Handle doesn't exist")
  } else if (err instanceof NoAddress) {
    console.log("No address for this chain")
  } else if (err instanceof RateLimited) {
    console.log("Too many requests — SDK auto-retries with backoff")
  }
}

SDK features

  • Full TypeScript types for all responses and errors
  • Automatic retry with exponential backoff on 429
  • In-memory cache with configurable TTL (default 30s)
  • Batch resolution for multiple handles in one call
  • Payment intents with unit conversion (ETH to wei, BTC to sat, SOL to lamports)
  • Pay URL generation for zero-code payment links
  • Typed error classes: HandleNotFound, NoAddress, InvalidHandle, InvalidChain, RateLimited
  • ~3KB gzipped, zero dependencies, dual ESM/CJS

Use cases

Payment integrations

Let users pay to a @handle instead of copying a raw address. Resolve the handle, show the address, and initiate the transaction.

Contact books

Store nimimo handles as contacts and resolve addresses on demand. Addresses update automatically when users rotate keys.

Verification

Verify that a given blockchain address belongs to a specific nimimo identity via reverse lookup.

Multi-chain apps

Resolve a single handle to Bitcoin, Ethereum, and Solana addresses simultaneously. No chain selection needed from the user.

This API is provided as-is. nimimo reserves the right to adjust rate limits or deprecate endpoints with reasonable notice.