
Research
/Security News
Miasma Mini Shai-Hulud Hits ImmobiliareLabs npm Packages
Miasma Mini Shai-Hulud hits @immobiliarelabs Backstage plugins, targeting GitLab and LDAP auth packages on npm.
@flow-industries/id
Advanced tools
Passkey-first identity for Flow applications. One passkey bound to `id.flow.industries`, usable across all Flow apps, with optional Tempo chain support.
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
bun add @flow-industries/id wagmi viem @tanstack/react-query
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
})
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()
id.flow.industries)id.flow.industriesThe 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.
flow(options)Creates a wagmi connector.
| Option | Type | Description |
|---|---|---|
host | string | Dialog URL (e.g. https://id.flow.industries/dialog) |
rpId | string? | WebAuthn relying party ID (e.g. id.flow.industries) |
accessKey | boolean | { expiry?: number; strict?: boolean } | Enable Tempo access key for in-page signing. Default expiry: 24h. |
createDialogHost(options)Creates a direct dialog interface.
| Option | Type | Description |
|---|---|---|
host | string | Dialog URL |
container | HTMLElement? | DOM element to attach iframe to (default: document.body) |
Returns: { open, close, destroy, request, messenger }
| Endpoint | Description |
|---|---|
GET /api/config | Returns { rpId, rpName } |
GET /api/me | Current session/user |
POST /fee-payer | Tempo fee sponsorship relay |
GET /keys/challenge | Generate WebAuthn challenge |
GET /keys/:credentialId | Get stored public key |
POST /keys/:credentialId | Store public key |
POST /api/auth/passkey/register | Create user + passkey + session |
POST /api/auth/passkey/challenge | Generate sign-in challenge |
POST /api/auth/passkey/verify | Verify passkey + create session |
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
Passkey-first identity for Flow applications. One passkey bound to `id.flow.industries`, usable across Flow apps with audience-bound JWTs and optional Tempo signing.
The npm package @flow-industries/id receives a total of 205 weekly downloads. As such, @flow-industries/id popularity was classified as not popular.
We found that @flow-industries/id demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

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.

Research
/Security News
Miasma Mini Shai-Hulud hits @immobiliarelabs Backstage plugins, targeting GitLab and LDAP auth packages on npm.

Security News
Rolldown paused Rust React Compiler integration after a 5MB binary size increase raised concerns about shipping React-specific code to all Vite users.

Security News
/Research
Mini Shai-Hulud expands into the Go ecosystem after hitting LeoPlatform npm packages and targeting GitHub Actions workflows.