React

Here’s how to create a React starter project and integrate OneSDK package modules. This will give you a solid foundation to build with OneSDK and React.

1. Initialize Project

Create react boilerplate with Vite bundler using this command:

npm create vite@latest my-react-app --template react

To create using Webpack, we can use react-script or create-react-app

npx create-react-app my-app

Once the setup is complete, go to your project and run the following command:

npm i

Install oneSDK package into your project:

npm i @frankieone/one-sdk

Run npm start to run your project.


Additional Config

for Vite build, please add this to the vite.config.js

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  define: {
    'process.env': {}
  }
})

Code Examples

To use OneSDK, we use hooks to initialize oneSDK instance with the correct credentials (Customer ID and API key). Retrieve the token with the correct credentials and then pass the initialized instance

  1. useOneSDK
    This is an example of using hooks to pass an initialised instance of OneSDK so that it can be used in separate components.
"use client"
import OneSDK from "@frankieone/one-sdk"
import { useEffect, useRef, useState } from "react"

const CUSTOMER_ID = process.env.REACT_APP_CUSTOMER_ID
const API_KEY = process.env.REACT_APP_API_KEY
const CHILD_ID = ''

const CUSTOMER_ID2 = process.env.REACT_APP_CUSTOMER_ID2
const API_KEY2 = process.env.REACT_APP_API_KEY2
const CHILD_ID2 = process.env.REACT_APP_CHILD_ID2

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 () => {
    const parseURL = () => {
      return btoa(`${CUSTOMER_ID}:${API_KEY}`)
    }
    try {

      const tokenRawAsync = await fetch("https://backend.latest.frankiefinancial.io/auth/v2/machine-session", {
          method: "POST",
          headers: {
              "authorization": "machine " + parseURL(),
              "Content-Type": "application/json"
          },
          body: JSON.stringify({
              permissions: {
                  "preset": "one-sdk",
                  "reference": `demo-${new Date().toISOString()}`//"<YOUR_UNIQUE_CUSTOMER_REF>"
              }
          })
      });
      return await tokenRawAsync.json()
    } catch (error) {
      setError(error.message)
      return null
    }
  }

  const generateOneSDKInstance = async () => {
    setLoading(true)
    const tokenSessionFromBackEnd = await generateToken()
    if(!tokenSessionFromBackEnd) return
    const SDKConfig = config || {
      mode: "development",
      recipe: {
        form: {
          provider: {
            name: 'react'
          },
        }
      }
    }
    try {

      const oneSDKInit = await OneSDK({
        session: tokenSessionFromBackEnd,
        ...SDKConfig
      })
      setOneSDKInstance(oneSDKInit)
    } catch(error) {
      setError(error.message)
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    if(!initializedRef.current) {

      generateOneSDKInstance()
      initializedRef.current = true
    }
  }, [config])

  return {
    oneSDKInstance,
    error,
    loading
  }
}

export default useOneSDK
  1. call useOneSDK in component using this sample-code as an example:

    "use client"
    import { useEffect } from "react";
    import useOneSDK from "../useOneSDK";
    
    const End2End = () => {
      const config = {
        mode: "development",
        recipe: {
          form: {
            provider: {
              name: "react",
            },
          },
        },
      };
      const { oneSDKInstance, error: errorOneSDK, loading } = useOneSDK({ config })
      
        const initOneSDK = () => {
          const welcome = oneSDKInstance.component('form', {
          name: 'WELCOME',
          type: 'manual',
          /*descriptions: [
                  { label: ‘This is a sample dynamic page.’, style: {} },
                  { label: ‘It can contain multiple paragraphs.’, style: {} },
                ], */
          //cta: {style: {‘ff-button’:{backgroundColor: “red”}}}
        });
        const form_consent = oneSDKInstance.component("form", {name: "CONSENT"});
        const form_loading1 = oneSDKInstance.component("form", {name: "LOADING", title: {label: "Loading..."}, descriptions: [{label: ""}]});
        const form_loading2 = oneSDKInstance.component("form", {name: "LOADING", title: {label: "Extracting data..."}, descriptions: [{label: "Hold tight, this can take up to 30 seconds. Please do not referesh this page or click the 'back' button on your browser."}]});
        const form_loading3 = oneSDKInstance.component("form", {name: "LOADING", title: {label: "Hold on..."}, descriptions: [{label: ""}]});
        const form_document = oneSDKInstance.component("form", {
          name: "DOCUMENT",
          showPreps: true,
        });
        const form_review = oneSDKInstance.component("form", {
          name: "REVIEW",
          type: "ocr",
        });
        
        const biometrics = oneSDKInstance.component('biometrics');
    
        welcome.mount("#form-container");
        welcome.on("form:welcome:ready", () => {
          form_consent.mount("#form-container");
        });
    
        form_consent.on("form:consent:ready", async () => {
    
          form_document.mount("#form-container");
        });
    
        welcome.on("form:welcome:failed", () => {
          // display error message
        });
    
        welcome.on("*", (message) => {
          console.log(message);
        });
    
        let docType;
    
        form_document.on("form:document:ready", async ({inputInfo}) => {
    
          form_loading1.mount("#form-container");
          docType = inputInfo.documentType;
          
          const ocr = oneSDKInstance.component("ocr", {
            documents: [{ type: docType, countries: ["AUS"] }],
          });
    
          ocr.mount("#form-container");
          ocr.on("ready", () => form_loading1.unmount())
    
          ocr.on("*", (message) => {
            console.log(message);
          });
    
          ocr.on("results", ({ document }) => {   
            doSomethingAfterOcr({ document })
          });
    
          ocr.on("loading", (display)=>{
            if(display){
              form_loading2.mount("#form-container");
            }else{
              form_loading2.unmount() 
            }
          });
        });
    
        function doSomethingAfterOcr({ document }) {
          // Present the details of the document that were detected from the uploaded image or images.
          // Decide whether to proceed to the next stage of the onboarding process
          // depending on whether document verification was successful.
          if (document) {
            console.log(document);
            console.log(document.ocrResult.dateOfBirth);
            console.log("trying to load review screen");
            
            form_review.mount("#form-container");
            
          } else {
            console.log("No document returned");
          }
        }
    
        form_review.on("form:review:ready", async () => {
          biometrics.mount("#form-container");
        });
    
        biometrics.on("*", (message) => {
          console.log(message);
        });
    
        biometrics.on('error', console.error);
    
        let error = false;
        biometrics.on('detection_failed', () => (error = true));
        biometrics.on('session_closed', () => {
          // If the session was closed due to an error, try running the biometrics component again.
          if (error) biometrics.mount("#form-container");
          error = false;
        });
    
        biometrics.on("loading", (display)=>{
          if(display){
            //alert("loading, show now")
            form_loading3.mount("#form-container");
          }else{
            form_loading3.unmount() 
          }
        });
    
        biometrics.on('processing', () => alert('We will get back to you with results soon'));
        biometrics.on('results', (result) => {
          // Decide whether to proceed to the next stage of the onboarding process
          // depending on whether biometrics verification was successful.
          console.log(result);
        });
        // oneSdkReact.on('*', console.log('oke'));
        }
        
      useEffect(() => {
        if(oneSDKInstance) {
    
          initOneSDK()
        }
      }, [oneSDKInstance])
    
      return loading ? <div>Loading...</div> : <div id='form-container' ></div>
    }
    
    export default End2End
    
    
  2. Run the project using npm start.