ui-keyring

A component to simplify the next generation of web3.storage Auth.

Simple UCAN based authentication. Includes registration and email verification, key creation and secure storage, as well as tools to switch between accounts and delegate abilities to other parties allowing you to build multi-tenant apps that allow your users to upload data to web3.storage without registration or a shared API key!

Supported frameworks: React, Solid, Vue

Simple Registration

UCAN based registration and email verification is fast and easy even for switching accounts

Secure Account Delegation

Secure key creation and storage allows you to build multi-tenant apps without a shared API key

import React, { useEffect, useState } from 'react'
import { useKeyring } from '@w3ui/react-keyring'

export default function Component () {
  const [{ account }, { loadAgent, unloadAgent, authorize, cancelAuthorize }] = useKeyring()
  const [email, setEmail] = useState('')
  const [submitted, setSubmitted] = useState(false)

  useEffect(() => { loadAgent() }, []) // load the agent - once.

  if (account) {
    return (
      <div>
        <h1>Welcome!</h1>
        <p>You are logged in as {account}!</p>
        <form onSubmit={e => { e.preventDefault(); unloadAgent() }}>
          <button type='submit'>Sign Out</button>
        </form>
      </div>
    )
  }

  if (submitted) {
    return (
      <div>
        <h1>Verify your email address!</h1>
        <p>Click the link in the email we sent to {email} to sign in.</p>
        <form onSubmit={e => { e.preventDefault(); cancelAuthorize() }}>
          <button type='submit'>Cancel</button>
        </form>
      </div>
    )
  }

  const handleAuthorizeSubmit = async e => {
    e.preventDefault()
    setSubmitted(true)
    try {
      await authorize(email)
    } catch (err) {
      throw new Error('failed to authorize', { cause: err })
    } finally {
      setSubmitted(false)
    }
  }

  return (
    <form onSubmit={handleAuthorizeSubmit}>
      <div>
        <label htmlFor='email'>Email address:</label>
        <input id='email' type='email' value={email} onChange={e => setEmail(e.target.value)} required />
      </div>
      <button type='submit' disabled={submitted}>Authorize</button>
    </form>
  )
}

View on codesandbox.io