Migrating to Version 1.0+

Overview

To simplify your application logic and integration with the Knot React Native SDK, Version 1.0 includes a number of breaking changes that may affect the way your integration works or behaves.

The new version includes a number of significant improvements:

  1. Enhanced speed and stability in loading merchant flows.
  2. More streamlined initialization of the SDK.
  3. Simplified event handling, more informative event messaging, and uniform naming conventions for easier debugging.
  4. Improved maintainability and foundations for new feature compatibility.

Breaking Changes

Configuring and opening a Knot SDK has changed significantly in React Native Version 1.0 and will requires some refactoring in order to initialize the SDK with a session, receive (KnotEvent) events, and handle errors. Errors are now encapsulated in a KnotError object which provides an enumerated value to debug with.

Session Initialization

Changes

  • openCardOnFileSwitcher, addCardSwitcherListener, and eventNames from "react-native-knotapi" are replaced with Knot and addKnotListener.
  • The product type is now defined by Product enum values .card_switcher and .transaction_link.
  • The new interface allows configuration of additional properties such as useCategoriesuseSearch, and merchantIds .
  • The open action now requires configuration values that are required to initialize with a session.

Before

import { openCardOnFileSwitcher, addCardSwitcherListener, eventNames } from "react-native-knotapi";

openCardOnFileSwitcher({
  sessionId: SESSION_ID,
  clientId: CLIENT_ID,
  environment: "development",
})

After

import {
  Knot,
  addKnotListener,
 } from "react-native-knotapi";

 Knot.open({
      sessionId: 'session_12345', // Current session ID
      clientId: 'client_67890', // Your client ID
      environment: 'development', // 'development' | 'production'
      product: 'card_switcher', // 'card_switcher' | 'transaction_link'
      entryPoint: 'onboarding', // Defined by you
      useCategories: true, // Recommend true
      useSearch: true, // Recommend true
      merchantIds: [52], // It is not recommended that you provide a long list of merchants
      domainUrls: ["https://domain1.com", "https://domain2.com"], // Only applicable for Android. 
    });
import {
  Knot,
  addKnotListener,
  type KnotError,
  type KnotEvent,
  type KnotExit,
  type KnotSuccess,
 } from "react-native-knotapi";
 
  Knot.open({
      sessionId: 'session_12345', // Current session ID
      clientId: 'client_67890', // Your client ID
      environment: 'development', // 'development' | 'production'
      product: 'card_switcher', // 'card_switcher' | 'transaction_link'
      entryPoint: 'onboarding', // Defined by you
      useCategories: true, // Recommend true
      useSearch: true, // Recommend true
      merchantIds: [52], // It is not recommended that you provide a long list of merchants
      domainUrls: ["https://domain1.com", "https://domain2.com"], // Only applicable for Android. 
   });

Event Handling

Changes

  • Event handling is now managed through addKnotListener instead of closures.
  • Events like onSuccessonError, and onExit are now product agnostic.
  • The onEvent method introduces the KnotEvent object to better handle Knot emitted events.
  • The KnotError type provides improved error descriptions.
  • The sendCard parameter is deprecated and its functionality incorporated into the metaData dictionary within KnotEvent when KnotEvent.event equals AUTHENTICATED.

Before

let listener = addCardSwitcherListener(eventNames.onSuccess, merchant => {
  console.log(merchant);
});

let listener = addCardSwitcherListener(eventNames.onError, (errorCode, errorMessage) => {
  console.log(`Error ${errorCode}: ${errorMessage}`);
});

let listener = addCardSwitcherListener(eventNames.onExit, () => {
  console.log("onExit");
});

let listener = addCardSwitcherListener(eventNames.onEvent, (e) => {
  console.log('Event: ', e.event);
  console.log('taskId: ', e.taskId);
  console.log('merchant:', e.merchant);
});

After

const onKnotSuccess = addKnotListener('onSuccess', (event) => {
  console.log('onSuccess', 'event', event);
});

const onKnotEvent = addKnotListener('onEvent', (event) => {
  console.log('onEvent', 'event', event);
});

const onKnotError = addKnotListener('onError', (event) => {
  console.log('onError', 'event', event);
});

const onKnotExit = addKnotListener('onExit', (event) => {
  console.log('onExit', 'event', event);
});
const onKnotSuccess = addKnotListener('onSuccess', (event: KnotSuccess) => {
  console.log('onSuccess', 'event', event);
});

const onKnotEvent = addKnotListener('onEvent', (event: KnotEvent) => {
  console.log('onEvent', 'event', event);
});

const onKnotError = addKnotListener('onError', (event: KnotError) => {
  console.log('onError', 'event', event);
});

const onKnotExit = addKnotListener('onExit', (event: KnotExit) => {
  console.log('onExit', 'event', event);
});

sendCard

🚧

Note

Most apps do not use the explicit sendCard method, as it is rarely applicable to the integration with the Knot SDK.

The sendCard parameter has been deprecated and its functionality is incorporated into the metaData dictionary within KnotEvent when the KnotEvent.event equals AUTHENTICATED. This change enhances flexibility by allowing additional contextual data to be included in events without requiring separate parameters. Previously, sendCard was accessed as a standalone value, but now developers can retrieve it from the metaData dictionary in the event callback. This approach ensures better extensibility and consistency across different event types. To access the sendCard value, simply extract it from the event’s metaData dictionary.

...
const onKnotEvent = addKnotListener('onEvent', (event: KnotEvent) => {
  console.log('onEvent', 'sendCard', event.metaData.sendCard);
});

Event Names

The SDK now maps raw event names to standardized event names for easier handling.

Event Name Prior to 1.01.0 Event Name
refresh session requestREFRESH_SESSION_REQUEST
merchant clickedMERCHANT_CLICKED
login startedLOGIN_STARTED
authenticatedAUTHENTICATED
otp requiredOTP_REQUIRED
security questions requiredSECURITY_QUESTIONS_REQUIRED
approval requiredAPPROVAL_REQUIRED

Error Handling

Error handling has been improved with more structured and meaningful error messages.

Changes

  • Errors are now encapsulated in the KnotError enum.
  • Each error has a human-readable description (errorDescription) and a unique error code (errorCode).
  • Improved clarity and consistency across error messages.

Before

let listener = addCardSwitcherListener(eventNames.onError, (errorCode, errorMessage) => {
  console.log(`Error ${errorCode}: ${errorMessage}`);
});

After

const onError = (error) => {
    switch (error) {
        case "invalidSession":
            console.warn("Error: Session is invalid. Please check your session ID.");
            break;
        case "expiredSession":
            console.warn("Error: Session has expired. Please start a new session.");
            break;
        case "invalidClientId":
            console.warn("Error: Invalid client ID. Ensure your credentials are correct.");
            break;
        case "internalError":
            console.warn("Error: An internal error occurred. Try again later.");
            break;
        default:
            console.warn("Error: An unknown error occurred.");
    }
};

Error Types

The Knot SDK provides predefined error cases for you to handle based on your own needs.

Error CaseDescription
.invalidSessionThe session is invalid.
.expiredSessionThe session has expired.
.invalidClientIdThe client ID is invalid.
.internalErrorAn internal error occurred.

Closing the SDK

🚧

Note

Most apps do not use the explicit close method, as it is infrequently applicable to the integration with the Knot SDK.

Changes

  • Closing the SDK is now statically accessed via Knot.close() as opposed to being bound to the session object.

Before

import { closeKnotSDK } from "react-native-knotapi";

closeKnotSDK();

After

Knot.close()