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

@flow-industries/id

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@flow-industries/id

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

npmnpm
Version
0.2.0
Version published
Weekly downloads
205
485.71%
Maintainers
1
Weekly downloads
 
Created
Source

Flow ID

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

npm: @flow-industries/id

Installation

bun add @flow-industries/id wagmi viem @tanstack/react-query

Integration

Option 1: Wagmi connector

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

Set up the config:

// config.ts
import { createConfig, http, createStorage, webSocket } from "wagmi"
import { tempoModerato } from "viem/chains"
import { withFeePayer } from "viem/tempo"
import { flow } from "@flow-industries/id"

const alphaUsd = "0x20c0000000000000000000000000000000000001"

export const config = createConfig({
  chains: [tempoModerato.extend({ feeToken: alphaUsd })],
  connectors: [
    flow({
      host: "https://id.flow.industries/dialog",
      rpId: "id.flow.industries",
      accessKey: true, // enables in-page tx signing without passkey prompts
    }),
  ],
  storage: createStorage({ storage: localStorage }),
  transports: {
    [tempoModerato.id]: withFeePayer(
      webSocket(),          // regular transactions
      http("/fee-payer"),   // sponsored transactions
    ),
  },
})

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>
)

Authentication:

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 — passkey prompt, no dialog UI */}
      <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>
  )
}

Transactions (Tempo):

import { Hooks } from "wagmi/tempo"
import { Value } from "ox"

const alphaUsd = "0x20c0000000000000000000000000000000000001"

function Transfer() {
  const transfer = Hooks.token.useTransferSync()

  return (
    <button onClick={() => transfer.mutate({
      to: "0x...",
      token: alphaUsd,
      amount: Value.from("10", 6),
    })}>
      Send 10 AlphaUSD
    </button>
  )
}

With accessKey: true, transactions sign with an in-page access key — no passkey prompt per transaction. The access key is provisioned automatically during sign-up/sign-in.

Sponsored transactions:

transfer.mutate({
  to: "0x...",
  token: alphaUsd,
  amount: Value.from("10", 6),
  feePayer: true, // routes through fee payer relay
})

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-industries/id"

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()

How it works

  • Your app opens the Flow ID 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: an access key is provisioned for in-page transaction signing

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.

API

flow(options)

Creates a wagmi connector.

OptionTypeDescription
hoststringDialog URL (e.g. https://id.flow.industries/dialog)
rpIdstring?WebAuthn relying party ID (e.g. id.flow.industries)
accessKeyboolean | { expiry?: number; strict?: boolean }Enable Tempo access key for in-page signing. Default expiry: 24h.

createDialogHost(options)

Creates a direct dialog interface.

OptionTypeDescription
hoststringDialog URL
containerHTMLElement?DOM element to attach iframe to (default: document.body)

Returns: { open, close, destroy, request, messenger }

Server endpoints

EndpointDescription
GET /api/configReturns { rpId, rpName }
GET /api/meCurrent session/user
POST /fee-payerTempo fee sponsorship relay
GET /keys/challengeGenerate WebAuthn challenge
GET /keys/:credentialIdGet stored public key
POST /keys/:credentialIdStore public key
POST /api/auth/passkey/registerCreate user + passkey + session
POST /api/auth/passkey/challengeGenerate sign-in challenge
POST /api/auth/passkey/verifyVerify passkey + 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 Wagmi and Direct integration demos with Tempo testnet support (faucet, transfers, fee sponsorship).

FAQs

Package last updated on 26 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