After you have initialized your Tanker instance, you will be able to start a Tanker session for your user, using their Tanker identity.

Starting the session client-side

After getting a Tanker identity from your application server, you can call start() to start a Tanker session in the client-side application:

// Authenticate the user with your server
const user = await app.authenticateUser(id, password);

// Start a Tanker session for the user
const status = await tanker.start(user.tankerIdentity);
typedef void (^TKRStartHandler)(TKRStatus _Nullable status,
                                NSError* _Nullable err);

// Get the Tanker identity from your server before calling this function
- (void)startTanker:(NSString*)userId password(NSString*)password
{
  // Authenticate the user with your server
  User* user = [self.app authenticateUser:userID password:password];

  [self.tanker startWithIdentity:user.identity
          completionHandler:^(TKRStatus status, NSError* error) {
            if (error == nil) {
              // do something with status
            }
          }];
}
User user = app.authenticateUser(id, password);
Status status = getTanker().start(user.tankerIdentity).get();

The start() method returns a status, which tells you what to do next.

Status changes also trigger the statusChange event, and the current status can be read at any time using tanker.status.

Status values are defined in Tanker.statuses.

Status values are defined in the TKRStatus enum.

Status values are defined in the Status enum.

Ready

The READY status means that the Tanker session is started and ready to be used.

if (status === Tanker.statuses.READY) {
  // Let's encrypt, share and decrypt data!
}

The TKRStatusReady status means that the Tanker session is started and ready to be used.

if (status == TKRStatusReady) {
  // Let's encrypt, share and decrypt data!
}

The READY status means that the Tanker session is started and ready to be used.

if (status == Status.READY) {
  // Let's encrypt, share and decrypt data!
}

Identity registration needed

The IDENTITY_REGISTRATION_NEEDED status means that Tanker does not know this user yet. Their identity must be registered with the Tanker service, along with a method to verify it.

The TKRStatusIdentityRegistrationNeeded status means that Tanker does not know this user yet. Their identity must be registered with the Tanker service, along with a method to verify it.

The IDENTITY_REGISTRATION_NEEDED status means that Tanker does not know this user yet. Their identity must be registered with the Tanker service, along with a method to verify it.

In the scope of this guide, we will only consider verifying a user's identity by email. For other verification means, please refer to Alternative verification methods.

To register the user's identity, first ask Tanker to send them a verification email, then ask the user to input the verification code they received.

Use this code in the in the registerIdentity() method to complete the registration process.

if (status === Tanker.statuses.IDENTITY_REGISTRATION_NEEDED) {
  // Ask the application server to send a verification code via Tanker
  await app.sendVerificationCode('user@example.com');

  // Wait for the user to input the verification code
  const verificationCode = await app.promptUser('Enter your verification code:');

  // Register the identity on Tanker
  await tanker.registerIdentity({ email: 'user@example.com', verificationCode });
}
NSString* email = @"user@example.com";

if (status == TKRStatusIdentityRegistrationNeeded) {

  // Ask your application server to send a verification code via Tanker
  [self.app sendVerificationCode:email];
  // Wait for the user to input the verification code
  NSString* verificationCode = [self.app promptUser:@"Enter your verification code:"];
  // Convert the email and verificationCode into a TKRVerification.
  TKRVerification* verification = [TKRVerification verificationFromEmail:email code:verificationCode];
  // Register the email as the current identity verification method.
  [self.tanker registerIdentityWithVerification:verification
                              completionHandler:^(NSError* error) {
                              if (error == nil) {
                                // do something
                              }
                          }];
}
if (status == Status.IDENTITY_REGISTRATION_NEEDED) {
  // Ask the application server to send a verification code via Tanker
  app.sendVerificationCode("user@example.com");

  // Wait for the user to input the verification code
  String verificationCode = app.promptUser("Enter your verification code:");

  // Register the identity on Tanker
  tanker.registerIdentity(new EmailVerification(email, verificationCode)).get();
}

Once the identity is registered, the internal Tanker status changes to READY.

Identity verification needed

The IDENTITY_VERIFICATION_NEEDED status means that Tanker needs to verify the user's identity. It happens for instance when the user starts a Tanker session on a new device.

The TKRStatusIdentityVerificationNeeded status means that Tanker needs to verify the user's identity. It happens for instance when the user starts a Tanker session on a new device.

The IDENTITY_VERIFICATION_NEEDED status means that Tanker needs to verify the user's identity. It happens for instance when the user starts a Tanker session on a new device.

Similarly to the registration procedure, your user will need a verification code sent by email.

Ask Tanker to send the the verification email, then ask the user to input the verification code they received.

Use the received code in the in the verifyIdentity() method to complete the verification process.

if (status === Tanker.statuses.IDENTITY_VERIFICATION_NEEDED) {
  // Ask the application server to send a verification code via Tanker
  await app.sendVerificationCode('user@example.com');

  // Wait for the user to input the verification code
  const verificationCode = await app.promptUser('Enter your verification code:');

  // Verify the identity
  await tanker.verifyIdentity({ email: 'user@example.com', verificationCode });
}
NSString* email = @"user@example.com";

if (status == TKRStatusIdentityVerificationNeeded) {

  // Ask your application server to send a verification code via Tanker
  [self.app sendVerificationCode:email];
  // Wait for the user to input the verification code
  NSString* verificationCode = [self.app promptUser:@"Enter your verification code:"];
  // Convert the email and verificationCode into a TKRVerification.
  TKRVerification* verification = [TKRVerification verificationFromEmail:email code:verificationCode];
  // Verify the identity.
  [self.tanker verifyIdentityWithVerification:verification
                            completionHandler:^(NSError* error) {
                            if (error == nil) {
                              // do something
                            }
                        }];
}
if (status == Status.IDENTITY_VERIFICATION_NEEDED) {
  // Ask the application server to send a verification code via Tanker
  app.sendVerificationCode("user@example.com");

  // Wait for the user to input the verification code
  String verificationCode = app.promptUser("Enter your verification code:");

  // Verify the identity
  tanker.verifyIdentity(new EmailVerification(email, verificationCode)).get();
}

Once the identity is verified, the internal Tanker status changes to READY.

Updating verification methods

To update a user's verification methods, call setVerificationMethod().

This requires the Tanker object to be in the READY state.

This requires the Tanker object to be in the TKRStatusReady state.

This requires the Tanker object to be in the READY state.

Updating a user's verification email also requires them to provide a verification code.

function updateVerificationEmail(newEmail) {
  // Ask the application server to send a verification code via Tanker
  await app.sendVerificationCode(newEmail);

  // Wait for the user to input the verification code
  const verificationCode = await app.promptUser('Enter your verification code:');

  // Update the verification email
  await tanker.setVerificationMethod({ email: newEmail, verificationCode });
}
NSString* email = @"user@example.com";

// Ask your application server to send a verification code via Tanker
[self.app sendVerificationCode:email];
// Wait for the user to input the verification code
NSString* verificationCode = [self.app promptUser:@"Enter your verification code:"];
// Convert the email and verificationCode into a TKRVerification.
TKRVerification* verification = [TKRVerification verificationFromEmail:email code:verificationCode];

// Update the user's verification methods.
[self.tanker setVerificationMethod:verification
                 completionHandler:^(NSError* error) {
                 if (error == nil) {
                   // do something
                 }
              }];
// Ask the application server to send a verification code via Tanker
app.sendVerificationCode(newEmail);

// Wait for the user to input the verification code
String verificationCode = app.promptUser("Enter your verification code:");

// Update the verification email
tanker.setVerificationMethod(new EmailVerification(newEmail, verificationCode)).get();

Stopping the session

At some point you might want to stop your Tanker session. This changes the internal status back to STOPPED.

At some point you might want to stop your Tanker session. This changes the internal status back to TKRStatusStopped.

At some point you might want to stop your Tanker session. This changes the internal status back to STOPPED.

// Close a Tanker session
await tanker.stop();
private void logout() {
  // Get the Tanker instance from application or other activity
  mTanker.stop().then((closeFuture) -> {
      // Do something when Tanker is stopped (for example redirect to the home page).
      return null;
  });
}
[self.tanker stopWithCompletionHandler:^(NSError* error) {
                    if (error == nil) {
                      // do something when Tanker is stopped (for example redirect to the home page)
                    }
                  }];

Code summary

So far, we've seen how to initialize Tanker, start and stop a session. Let's sum up what your code should look like client-side:

import { Tanker } from '@tanker/client-browser';

const { READY, IDENTITY_REGISTRATION_NEEDED, IDENTITY_VERIFICATION_NEEDED } = Tanker.statuses

const config = { appId: 'your-app-id' };
const tanker = new Tanker(config);

const id = 'user-id';
const password = 'Tanker';
const email = 'user@example.com';

const startTanker = async () => {
  // Authenticate the user with your server
  const user = await app.authenticateUser(id, password);

  // Start a Tanker session for the user
  const status = await tanker.start(user.tankerIdentity);

  switch (status) {
    case IDENTITY_REGISTRATION_NEEDED:
      // Ask the application server to send a verification code via Tanker
      await app.sendVerificationCode(email);

      // Wait for the user to input the verification code
      const verificationCode = await app.promptUser('Enter your verification code:');

      // Register the identity
      await tanker.registerIdentity({ email, verificationCode });
      break;

    case IDENTITY_VERIFICATION_NEEDED:
      // Ask the application server to send a verification code via Tanker
      await app.sendVerificationCode(email);

      // Wait for the user to input the verification code
      const verificationCode = await app.promptUser('Enter your verification code:');

      // Verify the identity
      await tanker.verifyIdentity({ email, verificationCode });
      break;

    case READY:
      // Well... you're ready :)
      break;

    default:
      throw new Error(`Assertion error: unknown status ${tanker.status}`);
  }
}

const run = async() => {
  const tanker = await startTanker();

  // Let's encrypt, share and decrypt data!

  await tanker.stop();
}

NSString* email = @"user@example.com";

- (void)startTanker(TKRStartHandler startHandler)
{
  // Authenticate the user with your server
  User* user = [self.app authenticateUser:userID password:password];

  // Start a Tanker session for the user
  [self.tanker startWithIdentity:user.identity completionHandler:startHandler];
}


TKRStartHandler startHandler = ^(TKRStatus status, NSError* err) {
  if (err == nil) {
    if (status == TKRStatusIdentityRegistrationNeeded)
    {
      // Ask the application server to send a verification code via Tanker
      [self.app sendVerificationCode:email];
      // Wait for the user to input the verification code
      NSString* verificationCode = [self.app promptUser:@"Enter your verification code":];
      // Convert the email and verificationCode into a TKRVerification.
      TKRVerification* verification = [TKRVerification verificationFromEmail:email code:verificationCode];

      return [self.tanker registerIdentityWithVerification:verification completionHandler:^(NSError* err) {
        if (err == nil) {
          // do something
        }
      })];
    }
    else if (status == TKRStatusIdentityRegistrationNeeded)
    {
      // Ask the application server to send a verification code via Tanker
      [self.app sendVerificationCode:email];
      // Wait for the user to input the verification code
      NSString* verificationCode = [self.app promptUser:@"Enter your verification code":];
      // Convert the email and verificationCode into a TKRVerification.
      TKRVerification* verification = [TKRVerification verificationFromEmail:email code:verificationCode];

      return [self.tanker verifyIdentityWithVerification:verification completionHandler:^(NSError* err) {
        if (err == nil) {
          // do something
        }
      }];
    }
    else if (status == TKRStatusReady)
    {
      // Tanker is ready
    }
  }
};

- (void)stopTanker {
  return [self.tanker stopWithCompletionHandler:^(NSError* err) {
    if (err == nil) {
      // do something
    }
  }];
}
public class LoginActivity extends AppCompatActivity {
    private static final String TAG = "LoginActivity";
    private Tanker tanker;
    private String userId = "user-id";
    private String password = "Tanker";
    private String emailAddress = "user@example.com";

    protected void onCreate(Bundle savedInstanceState) {
        TankerOptions options = new TankerOptions();
        String writablePath = getApplicationContext().getFilesDir().getAbsolutePath();
        options.setWritablePath(writablePath);
        options.setAppId(appId);
        tanker = new Tanker(options);
    }

    public void startTanker() {
        // Authenticate the user with your server
        User user = authenticateUser(userId, password);

        // Start a Tanker session for the user
        Status status = tanker.start(user.tankerIdentity);

        switch (status) {
            case Status.IDENTITY_REGISTRATION_NEEDED:
                // Ask the application server to send a verification code via Tanker
                app.sendVerificationCode(emailAddress);

                // Wait for the user to input the verification code
                String verificationCode = app.promptUser("Enter your verification code:");

                // Register the identity
                tanker.registerIdentity(new EmailVerification(emailAddress, verificationCode)).get();
                break;

            case Status.IDENTITY_VERIFICATION_NEEDED:
                // Ask the application server to send a verification code via Tanker
                app.sendVerificationCode(emailAddress);

                // Wait for the user to input the verification code
                String verificationCode = app.promptUser("Enter your verification code:");

                // Verify the identity
                tanker.verifyIdentity(new EmailVerification(emailAddress, verificationCode)).get();
                break;

            case Status.READY:
                // Well... you're ready :)
                break;

            default:
                throw new RuntimeException("Unknown status " + status);
        }
    }
}

Next, we will see how to encrypt, decrypt, and share data using Tanker.