Skip to main content

Quick Start Video

Setup Instructions

1

Create Next.js Project

npx create-next-app@latest my-next-app
cd my-next-app
2

Install Dependencies

npm install
npm install @frankieone/one-sdk
3

Configure Environment

Create a .env.local file with your OneSDK credentials:
NEXT_PUBLIC_CUSTOMER_ID=your_customer_id
NEXT_PUBLIC_API_KEY=your_api_key
NEXT_PUBLIC_CHILD_ID=your_child_id  # Optional

Implementation Guide

Create a new file hooks/useOneSDK.js:
"use client";
import OneSdk from "@frankieone/one-sdk";
import { useEffect, useRef, useState } from "react";

const useOneSDK = ({ config }) => {
  const [oneSDKInstance, setOneSDKInstance] = useState(null);
  const [error, setError] = useState(null);
  const [loading, setLoading] = useState(false);
  const initializedRef = useRef(false);

  const generateToken = async () => {
    try {
      const credentials = btoa(
        `${process.env.NEXT_PUBLIC_CUSTOMER_ID}:${process.env.NEXT_PUBLIC_API_KEY}`
      );
      
      const response = await fetch(
        "https://backend.latest.frankiefinancial.io/auth/v2/machine-session",
        {
          method: "POST",
          headers: {
            authorization: `machine ${credentials}`,
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            permissions: {
              preset: "one-sdk",
              reference: `demo-${new Date().toISOString()}`,
            },
          }),
        }
      );
      
      return await response.json();
    } catch (error) {
      setError(error.message);
      return null;
    }
  };

  const initializeSDK = async () => {
    setLoading(true);
    try {
      const token = await generateToken();
      if (!token) return;

      const instance = await OneSdk({
        session: token,
        ...config,
      });
      
      setOneSDKInstance(instance);
    } catch (error) {
      setError(error.message);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    if (!initializedRef.current) {
      initializeSDK();
      initializedRef.current = true;
    }
  }, [config]);

  return { oneSDKInstance, error, loading };
};

export default useOneSDK;
Create a new component file components/EndToEnd.js:
"use client";
import { useEffect } from "react";
import useOneSDK from "../hooks/useOneSDK";

const EndToEnd = () => {
  const config = {
    mode: "development",
    recipe: {
      form: {
        provider: {
          name: "react",
        },
      },
    },
  };

  const { oneSDKInstance, error, loading } = useOneSdk({ config });

  const initializeComponents = () => {
    if (!oneSDKInstance) return;

    // Initialize Components
    const components = {
      welcome: oneSDKInstance.component("form", {
        name: "WELCOME",
        type: "manual",
      }),
      consent: oneSDKInstance.component("form", {
        name: "CONSENT"
      }),
      document: oneSDKInstance.component("form", {
        name: "DOCUMENT",
        showPreps: true,
      }),
      biometrics: oneSDKInstance.component("biometrics"),
    };

    // Mount Welcome Component
    components.welcome.mount("#form-container");

    // Setup Event Handlers
    setupEventHandlers(components);
  };

  const setupEventHandlers = (components) => {
    const { welcome, consent, document, biometrics } = components;

    welcome.on("form:welcome:ready", () => {
      consent.mount("#form-container");
    });

    consent.on("form:consent:ready", () => {
      document.mount("#form-container");
    });

    // Add more event handlers as needed
  };

  useEffect(() => {
    if (oneSDKInstance) {
      initializeComponents();
    }
  }, [oneSDKInstance]);

  if (loading) {
    return <div>Loading OneSDK...</div>;
  }

  if (error) {
    return <div>Error: {error}</div>;
  }

  return <div id="form-container" />;
};

export default EndToEnd;
Update your page file (e.g., app/page.js):
import EndToEnd from '../components/EndToEnd';

export default function Home() {
  return (
    <main>
      <EndToEnd />
    </main>
  );
}

Component Configuration

const welcome = oneSDKInstance.component("form", {
  name: "WELCOME",
  type: "manual",
  descriptions: [
    { label: 'Welcome to our KYC process', style: {} },
    { label: 'Please follow the steps to verify your identity', style: {} },
  ],
});

Event Handling

// Welcome Form Events
welcome.on("form:welcome:ready", () => {
  // Handle welcome form ready
});

welcome.on("form:welcome:failed", () => {
  // Handle welcome form failure
});

// Document Form Events
document.on("form:document:ready", async ({ inputInfo }) => {
  // Handle document form ready
  const docType = inputInfo.documentType;
  // Initialize OCR component
});
biometrics.on("detection_failed", () => {
  // Handle failed detection
});

biometrics.on("processing", () => {
  // Handle processing state
});

biometrics.on("results", (result) => {
  // Handle biometrics results
});

Best Practices

Error Handling

Always implement proper error handling for both SDK initialization and component events.

Loading States

Show appropriate loading states during initialization and between component transitions.

Event Cleanup

Properly clean up event listeners when components unmount to prevent memory leaks.

Security

Never expose credentials in client-side code. Use environment variables and server-side token generation.
Remember to handle cleanup in your components by implementing proper unmounting logic and removing event listeners when components are destroyed.

Troubleshooting

  • SDK Initialization Failed: Check your credentials and network connection
  • Component Mount Errors: Ensure the container element exists in the DOM
  • Event Handler Issues: Verify event names and handler implementations
// Enable debug logging
const config = {
  mode: "development",
  debug: true,
  // ... other config options
};

// Listen to all events
oneSDKInstance.on("*", (event) => {
  console.log("Event:", event);
});