npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@coinhero/sdk

v0.1.0

Published

SDK for building apps that run inside the CoinHero platform. Provides a postMessage bridge between embedded apps (iframes) and a CoinHero host, including wallet proxying, authentication, and a wagmi connector.

Readme

@coinhero/sdk

SDK for building apps that run inside the CoinHero platform. Provides a postMessage bridge between embedded apps (iframes) and a CoinHero host, including wallet proxying, authentication, and a wagmi connector.

Architecture

CoinHero Host (parent window)
├── Connected wallet (MetaMask, Coinbase, etc.)
├── SIWE auth session (JWT)
└── CoinHeroHost ← manages iframe communication
        │
        │  postMessage (JSON-RPC 2.0)
        │
        ▼
Embedded App (iframe)
├── CoinHeroSDK ← talks to host
├── CoinHeroEthProvider ← EIP-1193 provider
└── coinHeroConnector ← wagmi connector

The SDK has three entry points for different contexts:

| Entry point | Import | Environment | Purpose | |---|---|---|---| | App | @coinhero/sdk | Browser (iframe) | SDK for mini apps running inside CoinHero | | Host | @coinhero/sdk/host | Browser (parent) | SDK for the CoinHero launcher | | Server | @coinhero/sdk/server | Node.js | JWT verification for app backends |

Installation

npm install @coinhero/sdk

App SDK (mini apps)

Used by apps running inside a CoinHero iframe.

Detecting the CoinHero environment

import { CoinHeroSDK } from '@coinhero/sdk'

const sdk = new CoinHeroSDK()

if (await sdk.isInCoinHero()) {
  console.log('Running inside CoinHero')
  console.log('Wallet:', sdk.context?.address)
  console.log('Chain:', sdk.context?.chainId)
}

Using with wagmi

The SDK includes a wagmi connector that routes all wallet operations through the host:

import { coinHeroConnector } from '@coinhero/sdk/connector'
import { createConfig, http } from 'wagmi'
import { base } from 'wagmi/chains'

const config = createConfig({
  chains: [base],
  connectors: [coinHeroConnector()],
  transports: { [base.id]: http() },
})

Using the EIP-1193 provider directly

If you're not using wagmi, you can use the provider directly with viem or ethers:

const sdk = new CoinHeroSDK()
await sdk.isInCoinHero()

// EIP-1193 compatible
const accounts = await sdk.provider.request({ method: 'eth_requestAccounts' })
const balance = await sdk.provider.request({
  method: 'eth_getBalance',
  params: [accounts[0], 'latest'],
})

Authentication

Request a CoinHero auth token to exchange for an app-specific session:

const auth = await sdk.getAuthToken()
// auth = { token, approvalMessage, approvalSignature }

// Exchange with your backend
const res = await fetch('/api/auth/coinhero', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(auth),
})
const { token: sessionToken } = await res.json()

Lifecycle actions

// Signal that the app has loaded
await sdk.actions.ready()

// Request the host to close this app
await sdk.actions.close()

Events

The SDK emits wallet events from the host:

sdk.provider.on('accountsChanged', (accounts) => { ... })
sdk.provider.on('chainChanged', (chainId) => { ... })
sdk.provider.on('disconnect', () => { ... })

Host SDK (CoinHero launcher)

Used by the CoinHero app to manage communication with embedded mini apps.

import { CoinHeroHost } from '@coinhero/sdk/host'

const host = new CoinHeroHost({
  iframe: document.getElementById('app-frame') as HTMLIFrameElement,

  context: {
    address: '0x1234...', // connected wallet
    chainId: 8453,        // Base
    hostVersion: '1.0.0',
  },

  // Proxy wallet requests to the real wallet
  onWalletRequest: async (method, params) => {
    return walletClient.request({ method, params })
  },

  // Provide auth token when the app requests it
  onAuthTokenRequest: async () => {
    return {
      token: sessionStorage.getItem('coinhero-auth-token'),
      approvalMessage: localStorage.getItem(`approval:${appName}:message`),
      approvalSignature: localStorage.getItem(`approval:${appName}:signature`),
    }
  },

  onReady: () => console.log('App loaded'),
  onClose: () => console.log('App wants to close'),
})

host.listen()

// Notify app of wallet changes
host.emitAccountsChanged([newAddress])
host.emitChainChanged(8453)
host.emitDisconnect()

// Clean up
host.destroy()

Server SDK (app backends)

Used by app backends to verify CoinHero JWTs during the token exchange flow.

# jose is a peer dependency for the server module
npm install jose
import { verifyCoinHeroToken } from '@coinhero/sdk/server'

// Verify a CoinHero JWT against the JWKS endpoint
const { walletAddress, payload } = await verifyCoinHeroToken(token)

The JWKS URL defaults to https://coinhero.fun/api/auth/jwks. Override for local development:

// Via options
const result = await verifyCoinHeroToken(token, {
  jwksUrl: 'http://localhost:4000/api/auth/jwks',
})

// Or via environment variable
// COINHERO_JWKS_URL=http://localhost:4000/api/auth/jwks

JWKS responses are cached for 1 hour automatically.

Example: token exchange endpoint

A typical app backend exchange endpoint verifies the CoinHero JWT and the user's per-app approval signature, then issues an app-specific session:

import { verifyCoinHeroToken } from '@coinhero/sdk/server'

export async function POST(request: Request) {
  const { token, approvalMessage, approvalSignature } = await request.json()

  // 1. Verify the CoinHero JWT
  const { walletAddress } = await verifyCoinHeroToken(token)

  // 2. Verify the approval signature (EIP-191)
  const isValid = await publicClient.verifyMessage({
    address: walletAddress,
    message: approvalMessage,
    signature: approvalSignature,
  })

  // 3. Check approval is for this app
  if (!approvalMessage.includes('myapp')) throw new Error('Wrong app')

  // 4. Issue app-specific session
  const sessionToken = await signSessionJwt({ walletAddress })
  return Response.json({ token: sessionToken })
}

Wire Protocol

All communication uses JSON-RPC 2.0 payloads wrapped in a CoinHero envelope:

{
  "__coinhero": true,
  "version": 1,
  "direction": "request" | "response" | "event",
  "payload": {
    "jsonrpc": "2.0",
    "id": "uuid",
    "method": "eth_sendTransaction",
    "params": [...]
  }
}

The __coinhero: true flag distinguishes SDK messages from other postMessage traffic (e.g., Farcaster SDK).

Methods

| Method | Direction | Description | |---|---|---| | coinhero_ping | app -> host | Detection/handshake, returns context | | coinhero_context | app -> host | Refresh context | | coinhero_ready | app -> host | App signals it has loaded | | coinhero_close | app -> host | App requests to be closed | | coinhero_getAuthToken | app -> host | Request JWT + approval for auth | | eth_* | app -> host | All Ethereum JSON-RPC methods |

Events (host -> app)

| Event | Description | |---|---| | coinhero_accountsChanged | Wallet account changed | | coinhero_chainChanged | Network changed | | coinhero_disconnect | Wallet disconnected |

Auth Flow

User                CoinHero          App (iframe)        App Backend
 │                     │                    │                   │
 │  1. SIWE sign-in    │                    │                   │
 │────────────────────>│                    │                   │
 │                     │  2. JWT issued     │                   │
 │                     │  (sessionStorage)  │                   │
 │                     │                    │                   │
 │                     │  3. Opens app      │                   │
 │                     │───────────────────>│                   │
 │                     │                    │                   │
 │                     │  4. getAuthToken() │                   │
 │                     │<───────────────────│                   │
 │                     │                    │                   │
 │  5. Sign approval   │                    │                   │
 │     (first time)    │                    │                   │
 │<────────────────────│                    │                   │
 │────────────────────>│                    │                   │
 │                     │                    │                   │
 │                     │  6. {token,        │                   │
 │                     │   approval*}       │                   │
 │                     │───────────────────>│                   │
 │                     │                    │                   │
 │                     │                    │  7. POST /api/    │
 │                     │                    │  auth/coinhero     │
 │                     │                    │─────────────────>│
 │                     │                    │                   │
 │                     │                    │                   │ 8. Verify JWT
 │                     │                    │                   │    (JWKS)
 │                     │                    │                   │ 9. Verify
 │                     │                    │                   │    approval sig
 │                     │                    │                   │
 │                     │                    │  10. App session  │
 │                     │                    │<─────────────────│

License

Copyright (c) 2026 CoinHero

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.