🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@flow-industries/auth

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install
Package was removed
Sorry, it seems this package was removed from the registry

@flow-industries/auth

Passkey-first authentication for Flow applications. One passkey bound to `id.flow.industries`, usable across all Flow apps, with optional Tempo chain support.

latest
npmnpm
Version
0.1.0
Version published
Maintainers
1
Created
Source

Flow Auth

Passkey-first authentication for Flow applications. One passkey bound to id.flow.industries, usable across all Flow apps, with optional Tempo chain support.

Integration

There are two ways to integrate Flow Auth into your app:

Option 1: Wagmi connector

Best for apps that use wagmi/viem and want standard React hooks (useAccount, useConnect, useSendTransaction).

Install dependencies:

bun add wagmi viem @tanstack/react-query

Set up the config:

// config.ts
import { createConfig, http, createStorage } from "wagmi"
import { tempo } from "viem/chains"
import { flow } from "@flow/auth/client"

export const config = createConfig({
  chains: [tempo],
  connectors: [
    flow({
      host: "https://id.flow.industries/dialog",
      rpId: "id.flow.industries",
    }),
  ],
  storage: createStorage({ storage: localStorage }),
  transports: {
    [tempo.id]: http(),
  },
})

Wrap your app:

// main.tsx
import { WagmiProvider } from "wagmi"
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { config } from "./config"

const queryClient = new QueryClient()

createRoot(document.getElementById("root")!).render(
  <WagmiProvider config={config}>
    <QueryClientProvider client={queryClient}>
      <App />
    </QueryClientProvider>
  </WagmiProvider>
)

Use in components:

import { useAccount, useConnect, useConnectors, useDisconnect } from "wagmi"

function Auth() {
  const { connect, isPending, error } = useConnect()
  const [connector] = useConnectors()
  const account = useAccount()
  const { disconnect } = useDisconnect()

  if (account.isConnected) {
    return (
      <div>
        <p>Connected: {account.address}</p>
        <button onClick={() => disconnect()}>Sign out</button>
      </div>
    )
  }

  return (
    <div>
      {/* Sign up — opens dialog with username + passkey creation */}
      <button onClick={() => connect({
        connector,
        capabilities: { type: "sign-up" },
      } as any)}>
        Sign up
      </button>

      {/* Sign in — opens dialog, passkey prompt immediately */}
      <button onClick={() => connect({
        connector,
        capabilities: { type: "sign-in" },
      } as any)}>
        Sign in
      </button>

      {/* Welcome screen — opens dialog, user chooses */}
      <button onClick={() => connect({ connector })}>
        Sign in with Flow
      </button>

      {error && <p>{error.message}</p>}
    </div>
  )
}

After connecting, the user's Tempo address is available via useAccount(). The passkey credential is persisted in localStorage — useAccount() returns the address on page reload without re-prompting.

Option 2: Direct dialog host

Best for apps that don't use wagmi, or want full control over the dialog lifecycle.

import { createDialogHost } from "@flow/auth/client"

const dialog = createDialogHost({
  host: "https://id.flow.industries/dialog",
})

Sign up:

const result = await dialog.request("wallet_connect", [
  { capabilities: { createAccount: true } },
])
// result: { user: { id, username }, credential: { id, publicKey } }

Sign in:

const result = await dialog.request("wallet_connect", [
  { capabilities: { signIn: true } },
])
// result: { user: { id, username }, credential: { id, publicKey } }

Welcome screen (user chooses sign up or sign in):

const result = await dialog.request("wallet_connect", [
  { capabilities: {} },
])

Check session:

const res = await fetch("https://id.flow.industries/api/me", {
  credentials: "include",
})
const { session } = await res.json()
// session.user.username, session.user.id, etc.

Close the dialog:

dialog.close()   // close the iframe
dialog.destroy() // remove from DOM entirely

How it works

  • Your app opens the Flow Auth dialog (iframe at id.flow.industries)
  • The dialog handles passkey creation/authentication + username onboarding
  • A session cookie is set on id.flow.industries
  • The credential (id + publicKey) is returned to your app
  • For Tempo chain apps: Account.fromWebAuthnP256(credential, { rpId }) reconstructs a signing account from the stored passkey

The passkey is bound to id.flow.industries via WebAuthn's rpId, so the same passkey works across all Flow apps (flow.game, flow.talk, etc.) through the shared dialog.

Server endpoints

EndpointDescription
GET /api/configReturns { rpId, rpName }
GET /api/meReturns current session/user (requires session cookie)
GET /api/account/username/:nameCheck username availability
GET /api/account/account/:addressLook up username by address
GET /keys/challengeGenerate WebAuthn challenge
GET /keys/:credentialIdGet stored public key
POST /keys/:credentialIdStore public key (with attestation verification)
POST /api/auth/passkey/registerCreate user + passkey + session
POST /api/auth/passkey/challengeGenerate sign-in challenge
POST /api/auth/passkey/verifyVerify passkey signature + create session

Development

bun install
bun run db:push    # create/update database tables
bun run dev        # starts server (:3000) + dialog (:5175) + playground (:5176)

Playground at http://localhost:5176 — has both Wagmi and Direct integration demos.

FAQs

Package last updated on 05 Apr 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts