Authentication

The ARN Client is a tool used for authentication-related operations in the context of the Arianee blockchain platform. It provides several functionalities, including wallet connection, checking/listening for connection state, wallet disconnection, and signing.

To use the ARN Client, you can initialize it and access its ArnAuthService through the following code:

arnClient.auth

Concepts

The ARN auth service manages authentication contexts (ArnAuthContext): represents a user session. The user must:

  • Connect: identify a wallet address
  • Sign: authenticate the wallet ownership.

As a result, an authentication context can bear the following statuses:

  1. disconnected
  2. connecting
  3. connected
  4. signing
  5. authenticated (i.e. connected + signed)

The configuration of the authentication service is specified in the auth section of the ARN Client configuration. The properties of the configuration are as follows:

  • connectorType: This property determines the type of wallet connection allowed. It can be one of the following options:
    • Web3ModalV2: Allows wallet connection through WalletConnect v2 Web3Modal.
    • ArianeeCore: Acts as a bridge between a connector and Arianee SDK's Wallet API.
  • options: This property allows customization of the selected connector. It combines standard Web3Modal options with Arianee-specific options. The available options include:
    • desktopBehavior:
      • mode: Describes the display mode of the customized Web3Modal interface. It can be set to 'WalletConnectOnly', 'ArianeeOnly', or 'ArianeeOrWalletConnect'.
      • universalLink: The URL to redirect to if the user doesn't have a wallet yet.
      • primaryLogoUrl: The URL of the logo to display in the middle of the QR code (non-WalletConnect).
      • primaryText: The text to display alongside the main logo.
      • secondaryText: The text to display alongside the secondary logo, if applicable (in case of 'ArianeeOrWalletConnect' mode).
    • wcVersion: The version of the Wallet Connect protocol to use. It can be 1 or 2.
    • delegateAuth (only for ArianeeCore type): Contains the options for the connector that Arianee SDK's Wallet API will delegate signing to.
  • signMessage: The message to display when asking the user to sign the connection transaction.
  • trySwitchChainNumber: The number of the blockchain to attempt to switch to.
  • autoConnect: Determines whether the service should try to reconnect from the cache. It is true by default.
  • persist (since 2.0.0): Storing user connections within a persistent cache is a feature to consider for the documentation. This cache can be implemented using various methods such as localStorage, sessionStorage, or a combination of both (e.g., sessionStorage followed by localStorage) to serve as a fallback. Alternatively, a boolean value can be utilized to control this behavior. By default, the value is set to true, signifying that localStorage is employed for maintaining compatibility with previous versions. Conversely, setting the value to false will result in no persistence of user connections, requiring a fresh wallet connection upon the next reload.
  • beforeSign (since 2.2.1): An optional asynchronous function can be employed as a preparatory step before initiating a signature request. This function presents an opportunity to display user interface notifications and prompts for signature approval through a dedicated button. This feature is particularly advantageous for enhancing the user experience on mobile platforms like iOS. The function should return a Promise containing a boolean value, which signifies the user's approval. When the value returned is true, the sign request will seamlessly progress within the user's wallet. Conversely, if the value is false, the sign request will be immediately terminated.
  • retrySign (since 2.3.0): A custom function that prompts the user to decide whether to retry a failed signature attempt. Typically, it displays a popup to the end user, featuring an approval button. This user interaction serves to assure the (i)OS that the request is initiated by the user and not a programmatic action, allowing the relevant app or app popup to open safely.
    The function takes the authentication context as a parameter and should return true if the user agrees to retry. Employing this option is highly recommended to ensure a seamless and user-friendly experience.
  • retryCount (since 2.3.0): The number of sign attempts if retrySign is defined.

These configurations allow you to customize the behavior of the ARN Client's authentication service according to your specific requirements.

Connecting a Wallet

Wallet connection can be performed in several ways:

  • Through Wallet Connect, depending on your ARN Client auth configuration through Web3Modal ;
  • From the cache, by reading the previous connection state from the browser’s localstorage ;
  • Through a URL containing an Arianee Access Token (AAT).

Each connection will create an ArnAuthContext. This allows having parallel/different connection contexts.

Interactive wallet connection

To establish an interactive wallet connection, you can use the following example code:

await arnClient.auth.connect();
console.log("User is connected now");

πŸ’‘

If the connection request is consecutive to clicking some HTML element, you might find it easier to use the <arn-connect> component than handling the events yourself.

If you want to manage different authentication contexts, you can save the created context as the result of the connect() call:

const myContext: ArnAuthContext = await arnClient.auth.connect();

or, similarly:

await arnClient.auth.connect();  // Set the new currentContext
const myContext: ArnAuthContext = arnClient.auth.currentContext;

Connecting from cache

By default, connections are saved in the local storage of your browser, allowing you to stay connected even after a page reload. To restore a connected state from the cache, you can use the following code:

try {
  arnClient.auth.connectFromCache();
} catch (e) {
  // Absorb "already connected" error
  if (e.message !== 'Already connected') {
    throw e;
  }
}

πŸ’‘

  • This process is performed automatically unless you set autoConnect to false in the client auth configuration.
  • ARN uses an arianee-auth-prefixed key in your localstorage per connector. For example, if your configuration uses a Web3Modal connector, it will store the relevant authentication status under an arianee-auth-Web3Modal key.
    Other keys may be stored by third-party libraries such as WalletConnect or Web3Modal (WEB3_CONNECT_CACHED_PROVIDER).

Connecting using an Arianee Access Token (AAT)

Apart from using the cache, connection can also be established implicitly through a hyperlink containing an Arianee Access Token (AAT).

For example:

const aat = "eyJ0eXAiOiJKV1QiLCJhbGciOiJFVEgifQ==..."; // Arianee Access Token
try {
  arnClient.auth.connectFromToken(aat);
} catch (e) {
  // Absorb error if AAT was omitted
  if (!(e instanceof ArnClientError) || !(e as ArnClientError).message.startsWith("No arianeeAccessToken value in")) {
     throw e;
  }
}

Typically, such an AAT could be provided through a link from an Arianee NFT (also known as Arianee Smart Assets), containing an ?arianeeAccessToken=*xxx* query parameter, where xxx is the AAT string value. In such cases, your app initialization code may attempt an automatic connection using the AAT parameter:

try {
  arnClient.auth.connectFromUrl(new URL(document.location.href));
} catch (e) {
  // Absorb error if AAT was omitted
  if (!(e instanceof ArnClientError) || !(e as ArnClientError).message.startsWith("No arianeeAccessToken value in")) {
     throw e;
  }
}

Checking connection state

Synchronous API

You can use the synchronous API to check the connection state:

if (arnClient.auth.isConnected()) {
  console.log("You are connected!");
}

Asynchronous API

Using a pub/sub scheme, you can listen to connection status changes. Here's an example using the asynchronous API:

arnClient.auth.status$
  .subscribe((status: ArnAuthStatus | undefined) => {
    switch (status?.connectionStatus) {
      case ArnConnectionStatus.authenticated:
        console.log("You are connected");
        break;
      case ArnConnectionStatus.disconnected:
        console.log("You are not connected");
        break;
    }
});

πŸ“Œ

If you want to display different HTML depending on the connection state, consider using the [arn-if-connected] custom tag.

Since ARN supports concurrent authentication contexts, if you want to be aware of the status change of any authentication context, nest this subscription within an authentication context listening:

arnClient.auth.currentContext$
	.subscribe(async (authContext) => {
	  authContext?.status$.subscribe((status) => {
	    switch (status?.connectionStatus) {
	      case ArnConnectionStatus.authenticated:
	        console.log("You are connected");
	        break;
	      case ArnConnectionStatus.disconnected:
	        console.log("You are not connected");
	        break;
	    }
	  });
});

This documentation explains how to connect a wallet using various methods, restore connections from cache, and check the connection state within your application.

Certainly! Here's the documentation for disconnecting a wallet and signing details using the ARN Client Authentication API:

Disconnecting a Wallet

To disconnect a wallet, you can use the following example code:

if (arnClient.auth.isConnected()) {
  await arnClient.auth.disconnect();
  console.log("You are now disconnected");
}

Make sure to check if the user is connected before attempting to disconnect to avoid any errors.

Signing Details

The ARN Client Authentication API provides methods for signing messages securely using the client/wallet side or the server side.

Client/Wallet Signing

Using the wallet, you can ask the user to sign different types of data.

Signing a Message

To ask the user to sign a text message, you can use the signMessage(textMessage) method available in the current authentication context:

const signature = await arnClient.auth.currentContext.signMessage(textMessage);

The method returns a Promise that resolves to the signature string.

Signing Typed Data

If you need the user to sign typed data following the EIP-712 standard, you can use the signTypedData(domain, types, record) method:

const signature = await arnClient.auth.currentContext.signTypedData(domain, types, record);

Provide the relevant domain, types, and record as parameters. The method returns a Promise that resolves to the signature string.

Signing a Transaction

If you want the user to sign a transaction, such as minting an NFT, you can use the signTransaction(ethersTx) method:

const signature = await arnClient.auth.currentContext.signTransaction(ethersTx);

Pass the Ethereum transaction object (ethersTx) as a parameter. The method returns a Promise that resolves to the signature string.

Signing an Access Token

Starting from version 1.45.4, you can ask the user to sign an Arianee JWT (AAT) using the signAAT(jwtPayload, message?, separator?) method:

const signature = await arnClient.auth.currentContext.signAAT(jwtPayload, message, separator);

Provide the jwtPayload and optional message and separator parameters. The method returns a Promise that resolves to the signature string.

Server-Side Signing

You can obtain a JWT signed using a project-specific key by calling the signJwt(jwt, keyName) method:

const signedJwt = await arnClient.auth.signJwt(jwt, keyName);

Pass the Json Web Token object (jwt) and the symbolic identifier (keyName) referring to a key pair stored in the server configuration. The method returns a Promise that resolves to the signed JWT.

This documentation explains how to disconnect a wallet and perform various types of signing using the ARN Client Authentication API.