Skip to content

SDK Overview

The Flowsta SDK provides multiple packages for integrating "Sign in with Flowsta" into your application - whether you use npm, vanilla JavaScript, or just want to download button assets.

Available Packages

@flowsta/auth - Core SDK ⭐

OAuth 2.0 authentication with PKCE for modern web apps.

bash
npm install @flowsta/auth

Features:

  • ✅ OAuth 2.0 + PKCE - No client secrets needed
  • ✅ TypeScript-first - Full type safety
  • ✅ React bindings - import from '@flowsta/auth/react'
  • ✅ Zero-knowledge - User data stays private
  • ✅ Zero dependencies - Lightweight (< 10kb)

@flowsta/login-button - Pre-built Buttons

Official "Sign in with Flowsta" button components.

bash
npm install @flowsta/login-button

Supports:

  • ✅ React, Vue, Qwik
  • ✅ Vanilla JavaScript
  • ✅ Multiple button variants
  • ✅ Automatic PKCE generation

View button downloads - Use without npm

@flowsta/holochain - Holochain Integration

Sign Holochain actions with your Flowsta identity.

bash
npm install @flowsta/holochain

Integration Methods

Choose the method that fits your project:

MethodBest ForSetup Time
@flowsta/authModern web apps (React, Vue, etc.)10 min
@flowsta/login-buttonQuick integration with pre-built UI5 min
Vanilla JSStatic HTML, no build tools15 min
Button DownloadsMaximum flexibility, custom implementationVariable

Core SDK: @flowsta/auth

Installation

bash
npm install @flowsta/auth

Basic Usage

typescript
import { FlowstaAuth } from '@flowsta/auth';

const auth = new FlowstaAuth({
  clientId: 'your_client_id',
  redirectUri: 'https://yourapp.com/auth/callback'
});

// Redirect to login
auth.login();

// On callback page
const user = await auth.handleCallback();

Pre-built Buttons: @flowsta/login-button

Installation

bash
npm install @flowsta/login-button

Quick Start

tsx
import { FlowstaLoginButton } from '@flowsta/login-button/react';

<FlowstaLoginButton
  clientId="your_client_id"
  redirectUri="https://yourapp.com/callback"
  variant="dark-pill"
/>
vue
<script setup>
import { FlowstaLoginButtonVue } from '@flowsta/login-button/vue';
</script>

<template>
  <FlowstaLoginButtonVue
    client-id="your_client_id"
    redirect-uri="https://yourapp.com/callback"
    variant="dark-pill"
  />
</template>
html
<div id="login"></div>

<script type="module">
  import { FlowstaLoginButton } from '@flowsta/login-button/vanilla';
  
  const button = new FlowstaLoginButton({
    clientId: 'your_client_id',
    redirectUri: 'https://yourapp.com/callback',
    variant: 'dark-pill'
  });
  
  button.mount('#login');
</script>

Button Variants

  • dark-pill - Dark background, rounded (recommended for light backgrounds)
  • dark-rectangle - Dark background, square corners
  • light-pill - Light background, rounded (for dark backgrounds)
  • light-rectangle - Light background, square corners
  • neutral-pill - Neutral colors, works anywhere
  • neutral-rectangle - Neutral colors, square corners

View all button styles and download

Without npm

You can also use the buttons without installing via npm:

html
<!-- Hotlink to button image -->
<a href="YOUR_OAUTH_URL">
  <img src="https://docs.flowsta.com/buttons/svg/flowsta_signin_web_dark_pill.svg" 
       alt="Sign in with Flowsta" 
       width="175" height="40">
</a>

Complete vanilla JS guide


Flowsta Auth - Core SDK Details

Configuration Options

FlowstaAuthConfig

PropertyTypeRequiredDefaultDescription
clientIdstring✅ Yes-Your application's client ID
redirectUristring✅ Yes-OAuth callback URL
scopesstring[]❌ No['profile', 'email']OAuth scopes to request
loginUrlstring❌ Nohttps://login.flowsta.comFlowsta login URL
apiUrlstring❌ Nohttps://auth-api.flowsta.comFlowsta API URL
typescript
interface FlowstaAuthConfig {
  clientId: string;
  redirectUri: string;
  scopes?: string[];
  loginUrl?: string;
  apiUrl?: string;
}

No Client Secret Required

Unlike traditional OAuth, Flowsta uses PKCE (Proof Key for Code Exchange) which provides the same security as a client secret but works safely in browsers and mobile apps.

Core Methods

login()

Redirect user to Flowsta login page.

typescript
auth.login();
// User is redirected to login.flowsta.com
// After authentication, they're redirected back to your redirectUri

handleCallback()

Handle OAuth callback and retrieve user data. Call this on your redirect URI page.

typescript
const user = await auth.handleCallback();

// user contains:
// - id: string
// - email?: string
// - username?: string
// - displayName?: string
// - profilePicture?: string
// - agentPubKey?: string
// - did?: string

isAuthenticated()

Check if user is logged in.

typescript
if (auth.isAuthenticated()) {
  console.log('User is logged in');
}

getUser()

Get the current user.

typescript
const user = auth.getUser();
if (user) {
  console.log('Hello,', user.displayName);
  console.log('Username:', user.username);
}

getAccessToken()

Get the current access token for API calls.

typescript
const token = auth.getAccessToken();

// Use for API requests
fetch('/api/data', {
  headers: { 'Authorization': `Bearer ${token}` }
});

logout()

Log out the current user.

typescript
auth.logout();
// Clears local session storage

getState()

Get the full authentication state.

typescript
const state = auth.getState();
// {
//   isAuthenticated: boolean,
//   user: FlowstaUser | null,
//   accessToken: string | null,
//   isLoading: boolean,
//   error: string | null
// }

Type Definitions

typescript
interface FlowstaUser {
  /** User's unique ID */
  id: string;
  /** Email address (if 'email' scope granted) */
  email?: string;
  /** Username (if set by user) */
  username?: string;
  /** Display name */
  displayName?: string;
  /** Profile picture URL */
  profilePicture?: string;
  /** Holochain agent public key */
  agentPubKey?: string;
  /** W3C Decentralized Identifier */
  did?: string;
}

interface AuthState {
  isAuthenticated: boolean;
  user: FlowstaUser | null;
  accessToken: string | null;
  isLoading: boolean;
  error: string | null;
}

React Integration

The SDK includes React hooks for easy integration:

tsx
import { FlowstaAuthProvider, useFlowstaAuth } from '@flowsta/auth/react';

// Wrap your app
function App() {
  return (
    <FlowstaAuthProvider
      clientId="your_client_id"
      redirectUri="https://yourapp.com/auth/callback"
    >
      <MyApp />
    </FlowstaAuthProvider>
  );
}

// Use in components
function LoginButton() {
  const { isAuthenticated, user, login, logout } = useFlowstaAuth();

  if (isAuthenticated) {
    return (
      <div>
        <span>Hello, {user.displayName}!</span>
        {user.username && <span> (@{user.username})</span>}
        <button onClick={logout}>Logout</button>
      </div>
    );
  }

  return <button onClick={login}>Sign in with Flowsta</button>;
}

Error Handling

The SDK throws errors for various scenarios:

typescript
try {
  const user = await auth.handleCallback();
} catch (error) {
  if (error.message.includes('Invalid state')) {
    // CSRF attack or expired session
    console.error('Security error - please try again');
  } else if (error.message.includes('No authorization code')) {
    // User cancelled or error from Flowsta
    console.error('Authentication was cancelled');
  } else {
    console.error('Authentication failed:', error.message);
  }
}

Security Features

PKCE (Proof Key for Code Exchange)

The SDK automatically handles PKCE:

  1. Generates a random code_verifier (128 characters)
  2. Creates a code_challenge (SHA-256 hash)
  3. Sends code_challenge with authorization request
  4. Sends code_verifier with token exchange

This prevents authorization code interception attacks without needing a client secret.

State Parameter

The SDK automatically:

  • Generates a random state parameter
  • Stores it in sessionStorage
  • Verifies it on callback

This prevents CSRF attacks.

Secure Storage

  • Access tokens stored in localStorage
  • PKCE verifiers stored in sessionStorage (cleared after use)
  • State parameter stored in sessionStorage (cleared after use)

Best Practices

1. Handle Errors Gracefully

typescript
try {
  const user = await auth.handleCallback();
  // Success - redirect to app
  window.location.href = '/dashboard';
} catch (error) {
  // Show user-friendly error
  showError('Login failed. Please try again.');
  // Redirect to login page
  window.location.href = '/login';
}

2. Check Authentication on Page Load

typescript
// On protected pages
if (!auth.isAuthenticated()) {
  // Redirect to login
  window.location.href = '/login';
}

3. Handle Token Expiration

typescript
// Access tokens expire - check before API calls
const token = auth.getAccessToken();
if (!token) {
  // Session expired, re-authenticate
  auth.login();
}

Migrating from SDK 1.x

SDK 2.0 removes direct email/password authentication. All users now authenticate through Flowsta's hosted login page.

Before (SDK 1.x - Deprecated):

typescript
// ❌ No longer supported
await auth.login(email, password);
await auth.register(email, password);

After (SDK 2.0):

typescript
// ✅ OAuth redirect
auth.login(); // Redirects to login.flowsta.com
const user = await auth.handleCallback();

Next Steps

Documentation licensed under CC BY-SA 4.0.