JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 24
  • Score
    100M100P100Q46032F
  • License CC-BY-1.0

Turn-key library for using Nostr with React.

Package Exports

  • @cmdcode/use-nostr

Readme

useNostr

This project is designed to be a turn-key library for using Nostr with React.

  • Login with pubkey, npub, seckey, nsec, extension, or generate a new key.
  • Nostr client API with get, list, sub, and publish.
  • Configure a list of relays for your client to use.
  • Uses a simple reducer store with update method.
  • Helper boolean, status and error messages for reactive components.

Coming soon:

  • Sign / verify custom messages and challenges using the Signer API.
  • Receive a Taproot HD wallet derived from your nostr signing device.

This project is fully typed and designed to work with intellisense.

More documentation coming soon!

Import

To make useNostr available across your entire react app, wrap your root component with the included NostrProvider component:

// Example entrypoint for react / nextjs.
// Your project may look slightly different.
import { NostrProvider } from '@cmdcode/useNostr'

export default function App ({ Component, pageProps }) {
  return (
    <NostrProvider>
      <Component {...pageProps} />
    </NostrProvider>
  )
}

Basic Usage

With the NostrProvider configured, importing the library and store is relatively simple.

Here is a basic example of reading and updating your relay list:

import { useState } from 'react'
import { useNostr } from '@cmdcode/useNostr'

export default function Relays () {
  const { store, update }   = useNostr()
  const [ input, setInput ] = useState('')

  function handleSubmit() {
    update({ relays: [ ...store.relays, input ] })
  }

  return (
    <div>
      <p>Relays</p>
      { store.relays && <pre>{JSON.stringify(store.relays, null, 2)}</pre> }
      <input onChange={(e) => { setInput(e.target.value) }} value={input} />
      <button onClick={handleSubmit}>Add Relay</button>
    </div>
  )
}

Here is an example login flow that covers all methods of signing in:

import { useState } from 'react'
import { useNostr } from '@cmdcode/useNostr'

export default function Login () {
  const [ pubkey, setPubKey ] = useState('')
  const [ seckey, setSecKey ] = useState('')

  const { hasExtension, login, store } = useNostr()

  return (
    <div className='container'>
      <div className='card'>
        <label>Login Via Extention:</label>
        <button disabled={!hasExtension} onClick={login.withExt}>Login</button>
      </div>
      <div className='card'>
        <label>Login with your Public Key or npub:</label>
        <input value={pubkey} onChange={(e) => setPubKey(e.target.value)}></input>
        <button onClick={() => login.withPubKey(pubkey)}>Login</button>
      </div>
      <div className='card'>
        <label>Login with your Secret Key or nsec:</label>
        <input value={seckey} onChange={(e) => setSecKey(e.target.value)}></input>
        <div className='field'>
          <button onClick={() => login.withSecKey(seckey)}>Login</button>
          <button onClick={login.generateKey}>Generate</button>
        </div>
      </div>
    </div>
  )
}

Library API

The library is split into several modules that plug into the main store.

Store API

const { store, update, reset, setError } = useNostr()

// The main data store.
store : NostrStore
// Update the data store using a JSON object.
update   = (store : Partial<NostrStore>) => void
// Resets the data store. Provide an 
// optional JSON object for defaults.
reset    = (store : Partial<NostrStore>) => void
// Sets an error message in the store, 
// plus print to console.
setError = (err : Error) => void

interface NostrStore {
  // Schema for the data store.
  client      ?: Client
  connection   : 'none' | 'conn' | 'ok' | 'error'
  hasExtension : boolean
  isConnected  : boolean
  isLoading    : boolean
  error       ?: string
  pubkey      ?: string
  profile     ?: Profile
  relays       : string[]
  signer      ?: Signer
}

Login API

const { login, logout } = useNostr()

login = {
  // Login with NIP-07 extension (if available).
  withExt     : () => void,
  // Login with npub or pubkey hex (read only).
  withPub     : (string) => void,
  // Login with nsec or seckey hex.
  withSec     : (string) => void,
  // Generate a new (ephemeral) keypair.
  generateKey : () => void
}

// Removes all user data from the store.
logout = () => void

Client API

const { client } = useNostr()

client = {
  // Checks pool connection and returns a boolean result.
  connected : () => Promise<boolean>,
  // Publish an event from a partial JSON template.
  publish   : (event : Partial<Event>) => Promise<Event>,
  // Fetch the top event using the provided filter.
  get  : async (filter  : Filter)      => Promise<Event>,
  // Fetch a list of events using the provided filters.
  list : async (filters : Filter[])    => Promise<Event[]>,
  // Publish a signed event and receive a Pub emitter.
  pub  : async (event   : Event)       => Promise<Pub>,
  // Subscribe to a list of filters and receive a Sub emitter.
  sub  : async (filters : Filter[])    => Promise<Sub>
}

Profile API

const { getProfile, setProfile } = useNostr()

// Fetch your profile from the relays.
getProfile = () => Promise<Profile | undefined>
// Update your profile using a partial JSON template.
setprofile = (updates : Partial<Profile>) => Promise<void>

Signer API

Coming soon!

Development / Testing

This library uses yarn for package management and vite for a development / demo server.

## Start the vite development server:
yarn dev
## Build a new release of the package:
yarn release

Bugs / Issues

If you run into any bugs or have any questions, please submit an issue ticket.

Contribution

Feel free to fork and make contributions. Suggestions are welcome!

Dependencies

This library contains minimal dependencies.

React
React library for hooks and JSX.
https://github.com/facebook/react

nostr-tools
Nostr utility library for all nostr stuff.
https://github.com/nbd-wtf/nostr-tools

Resources

Nostr Implementation Possibilities
This site is an index of current and draft NIPs. https://nips.be

License

Use this library however you want!

Contact

You can find me on nostr at: npub1gg5uy8cpqx4u8wj9yvlpwm5ht757vudmrzn8y27lwunt5f2ytlusklulq3