# Initialize

Using the SDK requires two preliminary steps (for every execution of your application):

1. **Initialize the SDK**: Call the [`initFordefiSDK`](https://documentation.fordefi.com/react-native/functions/initFordefiSDK.html) function. This function should be called exactly once (for every execution of your application) and before calling any other SDK functions.


React Native

```
async function initSdk() {
    try {
        await initFordefiSDK();
            console.log('SDK was initiated successfully!');
    } catch (e) {
        const error = e as FordefiSdkErrorResult;
        console.log(`Init Failed. code :${error.code}, message: ${error.message}`);
    }
}
```

Kotlin

```
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import com.fordefi.fordefi.Fordefi
import com.fordefi.fordefi.FordefiConfiguration

class MainActivity: ComponentActivity() {
    private
    var fordefi: Fordefi ? = null

    override fun onCreate(savedInstanceState: Bundle ? ) {
      super.onCreate(savedInstanceState)

      fordefi = Fordefi.getInstance(applicationContext, null)
      setupLifecycleObserver()
    }

    private fun setupLifecycleObserver() {
      ProcessLifecycleOwner.get().lifecycle.addObserver(
        object: DefaultLifecycleObserver {
          override fun onStart(owner: LifecycleOwner) {
            fordefi!!.notifyAppStateChanged(FordefiAppState.Foreground)
          }

          override fun onStop(owner: LifecycleOwner) {
            fordefi!!.notifyAppStateChanged(FordefiAppState.Background)
          }
        })
    }
```

Swift

```swift
import FordefiSdk

class ViewController: UIViewController {
  private var fordefi: Fordefi?
  override func viewDidAppear(_ animated: Bool) {
    do {
      self.fordefi = try Fordefi.getInstance(
        configuration: FordefiConfiguration()
    } catch let error {
      print("Failed to initialize Fordefi. Error: \(error.localizedDescription)")
      return
    }
  }

  @objc func appWillEnterForeground() {
    self.fordefi?.notifyAppStateChanged(appState: .foreground)
  }

  @objc func appDidEnterBackground() {
    self.fordefi?.notifyAppStateChanged(appState: .background)
  }
}
```

Web (JS)

```javascript
const fordefiApiBaseUrl = "https://api.fordefi.com";
const fordefi = fordefiWebSDK.Fordefi.getInstance({
  baseURL: fordefiApiBaseUrl,
});

class SDKLogger {
  log(logLevel, message) {
    console.log(`[Fordefi SDK][${logLevel}] ${message}.`);
  }
}
fordefi.setLogger(new SDKLogger());

class ErrorHandler {
  handleError(error: fordefiWebSDK.FordefiError) {
    console.log(`Error on Fordefi SDK: ${error.description()} `);

    switch (error.errorCode) {
      case fordefiWebSDK.FordefiErrorCode.InvalidKeysetIDFormat:
        // do something...
      case fordefiWebSDK.FordefiErrorCode.ExpiredAuthToken:
        // do something else...
    }
  }
}
fordefi.setErrorHandler(new ErrorHandler());

// user auth token issued by API user
const userId = await fordefi.login(userAuthToken);
```

1. **Authenticate the SDK to the Fordefi backend**: Call the [login](https://documentation.fordefi.com/react-native/functions/login.html) function and pass in an end-user authentication token. This function should be called after calling [initFordefiSDK](https://documentation.fordefi.com/react-native/functions/initFordefiSDK.html) and before calling any other function. When the authentication token expires (as indicated by errors returned from other functions), the [login](https://documentation.fordefi.com/react-native/functions/login.html) function must be called again with a fresh authentication token.


React Native

```
async function Login() {
  try {
    const res = await login('my-auth-token');
    console.log(`Successful login. userId ${res.userId}, deviceState ${res.deviceState}!`);
  } catch (e) {
    const error = e as FordefiSdkErrorResult;
    console.log(`Login error. code :${error.code}, message: ${error.message}`);
  }
}
```

Kotlin

```
import com.fordefi.fordefi.Fordefi
import com.fordefi.fordefi.FordefiError

class MainActivity: ComponentActivity() {
  private
  var fordefi: Fordefi ? = null
  private val authToken = "<AUTH_TOKEN>"

  override fun onCreate(savedInstanceState: Bundle ? ) {
    super.onCreate(savedInstanceState)
      ...
      fordefi!!.login(authToken) {
        deviceState: FordefiDeviceState,
        userId: String ? ,
        error: FordefiError ? ->
          handleLogin(deviceState, userId, error)
      }
  }

  private fun handleLogin(deviceState: FordefiDeviceState , userId: String ? , error: FordefiError ? ) {
    if (error == null) {
      Log.i("FordefiSDK", "Successful login. userId: ${userId!!} deviceState: ${deviceState!!}")
    } else {
      Log.i("FordefiSDK", String.format("Login Error: %s", error.description()))
    }
  }
}
```

Swift

```
import FordefiSdk

class ViewController: UIViewController {
  private var fordefi: Fordefi?
  private let authToken = "<AUTH_TOKEN>"

  override func viewDidAppear(_ animated: Bool) {
    //...
    self.fordefi!.login(authToken: authToken) { deviceState, userId, error in
      self.handleLogin(deviceState: deviceState, userId: userId, error: error)
    }
  }

  private func handleLogin(deviceState: FordefiDeviceState, userId: String?, error: FordefiError?) {
    if error != nil {
      print("Login Error. \(error!.errorDescription!)")
      return
    }
    print("Successful login. userId: \(userID!) ")
  }
}
```

Web (JS)

```
// user auth token issued by API user
const userId = await fordefi.login(userAuthToken);
```

The [login](https://documentation.fordefi.com/react-native/functions/login.html) function validates the authorization token and checks the state of the user's MPC shares. On the user's first login, this function also runs the MPC key generation protocol. The `login` function then returns a `DeviceState`:

- `BACKUP_REQUIRED`: For a new end user, before any further operation can be conducted, it is required to complete the keys backup. [Learn more](/waas/end-user-backup-and-recovery).
- `RECOVERY_REQUIRED`: This is returned when logging in on a new device, which does not yet have a copy of the user's MPC shares. In this case, you need to use the `recover Key` method to retrieve the previously generated MPC shares. [Learn more](/waas/end-user-backup-and-recovery).
- `NO_OPERATION_REQUIRED`: Keys are in sync. You can proceed.
- `ERROR`: See the list of possible [errors](/waas/logging-and-errors#general-errors).