> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reown.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SIWX Custom Usage

The Sign In With X feature enables decentralized applications to authenticate users seamlessly across multiple blockchain networks, such as Ethereum, Polygon or Solana.
The user can connect and then sign a message with their account to prove ownership of the account.

## SIWX Custom Implementation

**SIWX** is developed to work as a plugin system for AppKit and to enable correctly it you need to fulfill the expected interface within the `createAppKit` function.

### SIWXConfig interface

This is the interface that you need to implement to create your own **SIWX** feature.

```ts theme={null}
interface SIWXConfig {
  createMessage: (input: SIWXMessage.Input) => Promise<SIWXMessage>
  addSession: (session: SIWXSession) => Promise<void>
  revokeSession: (chainId: CaipNetworkId, address: string) => Promise<void>
  setSessions: (sessions: SIWXSession[]) => Promise<void>
  getSessions: (chainId: CaipNetworkId, address: string) => Promise<SIWXSession[]>
  getRequired?: () => boolean
  signOutOnDisconnect?: boolean
}
```

All the typings used are exposed by `@reown/appkit-react-native` package. You may check the source code [here](https://github.com/reown-com/appkit-react-native/tree/main/packages/common/src/types/siwx).

<Accordion title="Full Detailed Interfaces">
  ```typescript theme={null}
  /**
   * This interface represents the SIWX configuration plugin, which is used to create and manage SIWX messages and sessions.
   * You may use it to create a custom implementation following your needs, but watch close for the methods requirements.
   */
  export interface SIWXConfig {
    /**
     * This method will be called to create a new message to be signed by the user.
     *
     * Constraints:
     * - The message MUST be unique and contain all the necessary information to verify the user's identity.
     * - SIWXMessage.toString() method MUST be implemented to return the message string.
     *
     * @param input SIWXMessage.Input
     * @returns SIWXMessage
     */
    createMessage: (input: SIWXMessage.Input) => Promise<SIWXMessage>

    /**
     * This method will be called to store a new single session.
     *
     * Constraints:
     * - This method MUST verify if the session is valid and store it in the storage successfully.
     *
     * @param session SIWXSession
     */
    addSession: (session: SIWXSession) => Promise<void>

    /**
     * This method will be called to revoke all the sessions stored for a specific chain and address.
     *
     * Constraints:
     * - This method MUST delete all the sessions stored for the specific chain and address successfully.
     *
     * @param chainId CaipNetworkId
     * @param address string
     */
    revokeSession: (chainId: CaipNetworkId, address: string) => Promise<void>

    /**
     * This method will be called to replace all the sessions in the storage with the new ones.
     *
     * Constraints:
     * - This method MUST verify all the sessions before storing them in the storage;
     * - This method MUST replace all the sessions in the storage with the new ones succesfully otherwise it MUST throw an error.
     *
     * @param sessions SIWXSession[]
     */
    setSessions: (sessions: SIWXSession[]) => Promise<void>

    /**
     * This method will be called to get all the sessions stored for a specific chain and address.
     *
     * Constraints:
     * - This method MUST return only sessions that are verified and valid;
     * - This method MUST NOT return expired sessions.
     *
     * @param chainId CaipNetworkId
     * @param address string
     * @returns
     */
    getSessions: (chainId: CaipNetworkId, address: string) => Promise<SIWXSession[]>

    /**
     * This method determines whether the wallet stays connected when the user denies the signature request.
     *
     * @returns {boolean}
     */
    getRequired?: () => boolean

    /**
     * This method determines whether the session should be cleared when the user disconnects.
     *
     * @default true
     * @returns {boolean}
     */
    signOutOnDisconnect?: boolean
  }

  /**
   * This interface represents a SIWX session, which is used to store the user's identity information.
   */
  export interface SIWXSession {
    data: SIWXMessage.Data
    message: string
    signature: string
    cacao?: Cacao
  }

  /**
   * This interface represents a SIWX message, which is used to create a message to be signed by the user.
   * This must contain the necessary information to verify the user's identity and how to generate the string message.
   */
  export interface SIWXMessage extends SIWXMessage.Data, SIWXMessage.Methods {}

  export namespace SIWXMessage {
    /**
     * This interface represents the SIWX message data, which is used to create a message to be signed by the user.
     */
    export interface Data extends Input, Metadata, Identifier {}

    /**
     * This interface represents the SIWX message input.
     * Here must contain what is different for each user of the application.
     */
    export interface Input {
      accountAddress: string
      chainId: CaipNetworkId
      notBefore?: Timestamp
    }

    /**
     * This interface represents the SIWX message metadata.
     * Here must contain the main data related to the app.
     */
    export interface Metadata {
      domain: string
      uri: string
      version: string
      nonce: string
      statement?: string
      resources?: string[]
    }

    /**
     * This interface represents the SIWX message identifier.
     * Here must contain the request id and the timestamps.
     */
    export interface Identifier {
      requestId?: string
      issuedAt?: Timestamp
      expirationTime?: Timestamp
    }

    /**
     * This interface represents the SIWX message methods.
     * Here must contain the method to generate the message string and any other method performed by the SIWX message.
     */
    export interface Methods {
      toString: () => string
    }

    /**
     * The timestamp is a UTC string representing the time in ISO 8601 format.
     */
    export type Timestamp = string
  }

  /**
   * The Cacao interface is a reference of CAIP-74 and represents a chain-agnostic Object Capability (OCAP).
   * https://chainagnostic.org/CAIPs/caip-74
   */
  export interface Cacao {
    h: Cacao.Header
    p: Cacao.Payload
    s: {
      t: 'eip191' | 'eip1271'
      s: string
      m?: string
    }
  }

  export namespace Cacao {
    export interface Header {
      t: 'caip122'
    }

    export interface Payload {
      domain: string
      aud: string
      nonce: string
      iss: string
      version?: string
      iat?: string
      nbf?: string
      exp?: string
      statement?: string
      requestId?: string
      resources?: string[]
      type?: string
    }
  }
  ```
</Accordion>

### Constraints

You are able to implement the `SIWXConfig` in the way you would like, but some constraints MUST be followed to make sure that AppKit can interact with it correctly and it will work as expected:

#### `createMessage`

This method will be called to create a new message to be signed by the user.

* The message MUST be unique and contain all the necessary information to verify the user's identity.

#### `addSession`

This method will be called to store a new single session.

* This method MUST verify if the session is valid and store it in the storage successfully.

#### `revokeSession`

This method will be called to revoke all the sessions stored for a specific chain and address.

* This method MUST delete all the sessions stored for the specific chain and address successfully.

#### `setSessions`

This method will be called to replace all the sessions in the storage with the new ones.

* This method MUST verify all the sessions before storing them in the storage;
* This method MUST replace all the sessions in the storage with the new ones successfully otherwise it MUST throw an error.

#### `getSessions`

This method will be called to get all the sessions stored for a specific chain and address.

* This method MUST return only sessions that are verified and valid;
* This method MUST NOT return expired sessions.

### Example

Here is an example of how you can implement use your `SIWXConfig` interface:

```typescript theme={null}
import { createAppKit, type SIWXConfig } from '@reown/appkit-react-native'

const siwx: SIWXConfig = {
  createMessage: async (input) => {
    // Implement your logic to create a message
    return 'my message'
  },
  addSession: async (session) => {
    // Implement your logic to add a session
  },
  revokeSession: async (chainId, address) => {
    // Implement your logic to revoke a session
  },
  setSessions: async (sessions) => {
    // Implement your logic to set sessions
  },
  getSessions: async (chainId, address) => {
    // Implement your logic to get sessions
    return []
  },
  getRequired: () => {
    // Return whether the wallet should stay connected when user denies signature
    return false
  },
  signOutOnDisconnect: true // Whether to clear sessions when user disconnects
}

createAppKit({
  // ... your configuration
  siwx
})
```
