# Introduction

<figure><img src="/files/jQGwWWkhNvQO1JWZxLjk" alt="" width="563"><figcaption></figcaption></figure>

CSPR.click is a unified SDK that simplifies Web3 application onboarding by offering seamless integration with all wallets, facilitating easy user transitions between Web3 apps, and providing developers and users a consistent and secure interface for managing Web3 assets and interactions.

This documentation compiles important guidelines on how to use the CSPR.click SDKs.

## Components

* **Wallet Aggregator**. One integration for seamless compatibility with every Casper wallet.
* **Social Logins**. Simplify onboarding with instant access via Google, Apple, and more.
* **Fiat On-Ramps**. Purchase CSPR instantly using your card or wire transfer.
* **CSPR.cloud Proxy**. Connect directly to CSPR.cloud APIs — no backend required.

## Reference

To get familiar with CSPR.click, we recommend that you read these documents:

* [Overview](/documentation/overview)\
  Learn about the general technical aspects of CSPR.click SDK, and how it works.
* [Getting started](/documentation/getting-started)\
  Learn the basic concepts while creating a dApp from zero with CSPR.click React template.

## Support

If you have any questions or run into any issues while using the CSPR.click SDKs, you can find help in the [CSPR.click Developer Community](https://t.me/CSPRDevelopers). Here you can connect and get help from other developers.

## Legal

By using CSPR.click, you agree to our [Developer Terms of Service](https://cspr.click/terms-of-service/) and acknowledge that you have read our [Privacy Policy](https://cspr.click/privacy-policy/).


# Overview

In any web application that integrates CSPR.click you'll be using the Core JS SDK. It provides the essential functionality to interact with wallets and the CSPR.click servers. Through it, you'll request a connection with a wallet to start a user session, and ask the user to sign a transaction or a message. You'll get a complete graphical interface that manages for you the interactions with the user to perform the account management and the signature requests operations.

## Get your application Id

To initialize CSPR.click library, you need an `appId` for your application. By default, our examples use the `csprclick-template` identifier. You may use this value to try CSPR.click out and start developing your application.

Note, though, that this identifier is *only valid for development on `localhost`*. Before you push your application to a server, you must get your own `appId` on [console.cspr.build](https://console.cspr.build).

## Supported wallets

CSPR.click supports every wallet built for the Casper ecosystem.

<table><thead><tr><th width="120">Wallet</th><th>Provider key</th><th>Name</th></tr></thead><tbody><tr><td><img src="/files/qu93DIXmBspuBIyhZeUu" alt="Casper Wallet logo" data-size="original"></td><td><code>casper-wallet</code></td><td>Casper Wallet</td></tr><tr><td><img src="/files/c9Cy2JpMacoF6AfFz7Uz" alt="Ledger logo" data-size="original"></td><td><code>ledger</code></td><td>Ledger</td></tr><tr><td><img src="/files/pZxPDveJjXA4LJWL0boo" alt="WalletConnect logo" data-size="original"></td><td><code>walletconnect</code></td><td>WalletConnect</td></tr><tr><td><img src="/files/DwueGNda18fnWiLXjXJ4" alt="Metamask logo" data-size="original"></td><td><code>metamask-snap</code></td><td>Metamask (Snap)</td></tr><tr><td><img src="/files/DrJ6386bvbc9sMRSmjHc" alt="CSPR.click web wallet logo" data-size="original"></td><td><code>csprclick-w3a-google</code> and <code>csprclick-w3a-apple</code></td><td>CSPR.click wallet (Social logins)</td></tr></tbody></table>

In your application, you can decide which wallets you want to enable. To do so, set accordingly the array of providers in the [CsprClickInitOptions ](/cspr.click-sdk/reference/types#csprclickinitoptions)initialization object.

```javascript
const clickOptions: CsprClickInitOptions = {
    appName: 'CSPR.playground',
    appId: 'csprclick-template',
    contentMode: CONTENT_MODE.IFRAME,
    providers: [
        WALLET_KEYS.CASPER_WALLET,
        WALLET_KEYS.LEDGER,
        WALLET_KEYS.METAMASK_SNAP,
        WALLET_KEYS.CSPRCLICK_W3A_GOOGLE,
        WALLET_KEYS.CSPRCLICK_W3A_APPLE,
    ],
};
```

### WalletConnect

WalletConnect is a protocol that provides a secure and convenient way for users to interact with decentralized applications. CSPR.click supports WalletConnect as a provider, allowing users to connect their WalletConnect-compatible wallets to your application.

To use WalletConnect with CSPR.click, you need to have a WalletConnect project ID. You can get one by creating a project on the [WalletConnect Cloud](https://dashboard.reown.com/).

Once you have your project ID, you can add it to your CSPR.click initialization options like this:

```javascript
const clickOptions: CsprClickInitOptions = {
    appName: 'CSPR.playground',
    appId: 'csprclick-template',
    contentMode: CONTENT_MODE.IFRAME,
    providers: [
        WALLET_KEYS.CASPER_WALLET,
        WALLET_KEYS.LEDGER,
        WALLET_KEYS.METAMASK_SNAP,
        WALLET_KEYS.WALLET_CONNECT,
    ],
    walletConnect: {
        relayUrl: 'wss://relay.walletconnect.com',
        projectId: '6cdf3...9cc4d'
    }
};
```


# Getting started

This page guides you through the steps to create a new React application for your project with CSPR.click UI SDK integrated and ready to use.

{% hint style="info" %}
If you want to integrate CSPR.click SDK into an existing React application, go to the [React Context Provider](/cspr.click-sdk/integration/react-context-provider) section. If you are not using React, or you want to control the runtime loading yourself, follow [Downloading and initializing the SDK](https://github.com/make-software/casper-click-websdk/blob/master/docs/public/csprclick-sdk/downdload-and-initialize.md).
{% endhint %}

## Create a new React project

To create a new React project with CSPR.click ready to use, write the following command in a terminal session:

```
npx tiged make-software/csprclick-examples/csprclick-react my-casper-app
```

Next, go to the newly created project directory and run the app:

```
cd my-casper-app
pnpm install
pnpm run dev
```

Your new app will open in your browser. If it doesn't, browse to the URL: <http://localhost:5173>.

<figure><img src="/files/F4poS6qGUl8FIPNfiCTd" alt=""><figcaption><p>Your new application</p></figcaption></figure>

## Adjust the initialization options

Your new project comes with some default initialization options. You'll need to review them and adjust some.

Open the file `src/ClickContext.tsx` and locate the definition of the `clickSDKOptions` variable. It'll look similar to this:

```typescript
import { CONTENT_MODE } from '@make-software/csprclick-core-types';

window.clickSDKOptions = {
  appName: 'CSPR.click React template',
  appId: 'csprclick-template',
  providers: ['casper-wallet', 'ledger', 'metamask-snap'],
  contentMode: CONTENT_MODE.IFRAME
};
```

You can use the default `csprclick-template` application identifier while you're working locally on your application. But to upload your new project to a server, you'll need to [get your own application id](/documentation/overview).

Update the properties according to your needs. Read more about the [CsprClickInitOptions ](/cspr.click-sdk/reference/types#csprclickinitoptions)type in the Core JS SDK reference.

## What's next

You're almost ready to start developing the next web3 killer app. Before you get cracking on your project, get familiar with some crucial aspects of CSPR.click that are demonstrated in the template:

#### Responding to CSPR.click events

The `App` component sets handlers to listen and respond to events triggered by CSPR.click when the user connects an account, switches to a different one, or closes the session.

Refer to the [Handling events](/cspr.click-sdk/integration/handling-events) page for information on how to add your listener functions.

#### Customize the top navigation bar

The template displays some settings selectors in the top navigation bar. Find the `ClickTopBar` component in `src/components/ClickTopBar/index.tsx` and see how these settings are defined.

Refer to the [Customizing the top bar](/cspr.click-sdk/integration/customizing-the-top-bar) section for complete reference on how to work with each of the setting elements in the top bar.

#### Request transaction approvals

At some point, your application will need to interact with the Casper network by sending a transaction (aka deploy).\
CSPR.click manages this process communicating with the active wallet to request the user to approve or reject the transaction. The UI depends on the wallet.

The template includes the `BuyMeACoffee` components to demonstrate how to request a transaction signature and send the approved deploy to the network.

Refer to the [Signing transactions](/cspr.click-sdk/integration/signing-transactions) page for information on how to request the user a transaction approval. Also, look at [Processing status updates](/cspr.click-sdk/integration/processing-status-updates) for information on how to listen for real-time status updates.

#### Leverage CSPR.cloud Proxy

CSPR.click provides a proxy to interact with the CSPR.cloud REST and Streaming APIs, as well as to set up a Node RPC client with `casper-js-sdk`. This is helpful when you want to interact with the CSPR.cloud APIs from the frontend of your application, as CSPR.cloud APIs require authentication and you must not expose your API keys in the frontend.

Refer to the [CSPR.cloud API proxies](/cspr.click-sdk/reference/cloud-proxies) page for information on how to use the proxy.


# AI Agent Skills

An agent skill is available for the CSPR.click Web SDK. Once installed, your AI coding assistant will automatically know how to integrate CSPR.click into dApps — including wallet connection, transaction signing, event handling, theming, and CSPR.cloud API access — across React (< 19 and 19+), Next.js, and Vanilla JS.

**Skill source:** [`make-software/csprclick-examples › csprclick-skill`](https://github.com/make-software/csprclick-examples/tree/master/csprclick-skill)

***

## Installation

### Option 1 - Ask your agent to install the skill

```
Install this skill: https://cspr.click/SKILL.md
```

### Option 2 — `skills` CLI

The [`skills` CLI](https://github.com/vercel-labs/skills) auto-detects installed coding agents and places the skill in the right location.

```bash
npx skills add https://github.com/make-software/csprclick-examples/tree/master/csprclick-skill
```

The CLI will prompt you to select which agents to install to and whether to install project-wide or globally. To skip prompts:

```bash
# Install globally to all detected agents
npx skills add https://github.com/make-software/csprclick-examples/tree/master/csprclick-skill --global --yes

# Install to a specific agent (e.g. Augment, Claude Code, Cursor …)
npx skills add https://github.com/make-software/csprclick-examples/tree/master/csprclick-skill --agent opencode --yes
```

> Supported agents include Augment, Claude Code, Cursor, Windsurf, GitHub Copilot, Cline, and [many more](https://github.com/vercel-labs/skills?tab=readme-ov-file#supported-agents).

***

### Option 3 — Manual installation

The skill consists of two parts that must be kept together:

| Path in repo                          | Contents                                                |
| ------------------------------------- | ------------------------------------------------------- |
| `csprclick-skill/SKILL.md`            | Skill definition and instructions                       |
| `csprclick-skill/references/llms.txt` | Full API reference, type definitions, and code examples |

**Steps:**

1. Download or clone the examples repository:

   ```bash
   git clone --depth 1 --filter=blob:none --sparse \
     https://github.com/make-software/csprclick-examples.git
   cd csprclick-examples
   git sparse-checkout set csprclick-skill
   ```
2. Copy the `csprclick-skill/` folder into the skills directory for your agent:

   \| Agent | Project scope | Global scope | |----------------|---------------------|-------------------------------------| | Opencode | `.opencode/skills/` | `~/.config/opencode/skills/` | | Claude Code | `.claude/skills/` | `~/.claude/skills/` | | Cursor | `.agents/skills/` | `~/.cursor/skills/` | | Windsurf | `.windsurf/skills/` | `~/.codeium/windsurf/skills/` | | GitHub Copilot | `.agents/skills/` | `~/.copilot/skills/` | | Cline / Warp | `.agents/skills/` | `~/.agents/skills/` |

   Example for Augment (project scope):

   ```bash
   mkdir -p .opencode/skills
   cp -r csprclick-skill .augment/skills/
   ```
3. Verify the layout looks like this:

   ```
   .opencode/skills/
   └── csprclick-skill/
       ├── SKILL.md
       └── references/
           └── llms.txt
   ```

***

## What the skill covers

Once installed, your agent will know how to:

* **Initialize the SDK** — For React, Next.JS and other stacks applications
* **Connect wallets** — `signIn()`, `connect(provider)`, provider detection
* **Handle account events** — sign-in, account switch, sign-out, disconnect
* **Sign and send transactions** — `send()`, `sign()` with `casper-js-sdk` TransactionV1
* **Sign messages** — off-chain authentication flows
* **Customize themes** — `buildTheme`, `DefaultThemes`, light/dark switching (React < 19)
* **Access CSPR.cloud APIs** — REST proxy, WebSocket streaming, Node RPC
* **Show the Buy CSPR widget** — fiat on-ramp integration


# Changelog

*Note: patch versions are not released as npm packages if interfaces haven't changed with respect to the previous version.*

## v2.1.0 - June 3rd, 2026

* Added new method `signTypedData()` to the SDK for EIP-712 typed structured data signing. Returns a [SignTypedDataResult](/cspr.click-sdk/reference/types#signtypeddataresult) with the signature and digest.

## v2.0.0 - March 11th, 2026

* New wallet providers added to sign in with Google and Apple Id accounts and get a new Casper wallet.
* CSPR.click web wallet for managing wallets connected to a Google or Apple Id accounts.

## v1.13.0 - January 28th, 2026

* Added new methods `decryptMessage()` and `encryptMessage()` to the SDK. These methods are supported by Casper Wallet. Other wallets will return an error.

## v1.12.0 - November 7th, 2025

* New CSPR.cloud proxy client. Use the proxy client to interact with CSPR.cloud REST and Streaming APIs, , or set up a Node RPC client with `casper-js-sdk` directly from your frontend application when you don't operate a separate backend. For more info, see the new article [CSPR.cloud API proxies](/cspr.click-sdk/reference/cloud-proxies) in the reference section.
* Moved all types to the package `@make-software/csprclick-core-types`. Now you don't need to install `@make-software/csprclick-core-client`.
* Added the method `showBuyCsprUi()` to display the Buy CSPR widget. It replaces previous SDK method `showByCsprUi()` which is now deprecated and will be removed in a future version.

{% hint style="info" %}

## Migration guide

Upgrading to `v1.12.0` from a previous version may require some changes in your code.

1. Remove `@make-software/csprclick-core-client` from your dependencies.
2. Change all types imported from `@make-software/csprclick-core-client` to be imported from `@make-software/csprclick-core-types`.
3. Use the interface `ICSPRClickSDK` to keep instances of the SDK instead of the class `CSPRClickSDK`.
4. Change calls to `showByCsprUi()` to `showBuyCsprUi()`. The first method will be removed in a future version.
   {% endhint %}

## v1.11.0 - October 13th, 2025

* Enhanced WalletConnect sign in flows for a better user experience with Casper Wallet Mobile.

## v1.10.0 - September 12th, 2025

* new `<AccountCardMenuItem>` component to display account information in the account dropdown menu (includes account name, public key and liquid/total balances). Replaces `<ViewAccountOnExplorerMenuItem>`.

## v1.9.0 - July 22th, 2025

* new `onStatusUpdate` in the `send()` methods arguments. When used, CSPR.click opens a websockets connection with CSPR.cloud backend to receive processing status updates for the deployed transaction.
* Integration with Google Sign in and Apple Id for CSPR.click web wallet.

## v1.8.0 - Apr 30th, 2025

* new `providerSupports` property in the account object to indicate if the connected wallet supports signing with the `TransactionV1` transaction model.
* CSPR.name enhanced support.

## v1.7.0 - Dec 23rd, 2024

* Support for the new transaction model `TransactionV1`.
* Updated Casper Wallet, Ledger, and Metamask Snap integrations to newest versions (all support now Casper 2.0).
* Deprecation notice for CasperDash wallet.

## v1.6.0 - Oct 16th, 2024

* Enhanced colors customization for the CSPR.click top bar UI elements.

## v1.5.0 - July 18th, 2024

* Torus and Casper Signer deprecation notices. These wallets will be removed in the next minor version.
* Added CSPR.name names to accounts in the UI overlays.

## v1.4.0 - Mar 5th, 2024

* Added Casper Wallet mobile universal links to enhance the user experience on mobile applications.
* New JWT provider for CSPR.click web wallet.
* New identicon component available to developers.

## v1.3.0 - Jan 19th, 2024

{% hint style="info" %}
**Important note if you're upgrading your app to `1.3.0` from a previous version.** `<ClickTopBar>` component has been replaced with new `<ClickUI>` component. The latter permits a more granular configuration for the elements that the developer wants to display in their application. For example, to not include the top navigtaion bar.

Check [this](https://docs.cspr.click/ui-sdk/integrating-the-ui-sdk-into-your-application#add-less-than-clickui-greater-than-component-to-your-app) section for `<ClickUI>` component reference.
{% endhint %}

* New Buy CSPR UI to select between different onramp platforms.
* Integration with Ramp.
* CSPR.click navigation bar is now optional. Applications that have their own controls for signing in and displaying connected accounts, can exclude this component.

## v1.2.1 - Jan 8th, 2024

* fixed a bug that caused people using different Ledger devices to not be able to sign in with the second device without signing out and reloading the web page.
* fixed a bug that might cause transaction signature rejection when the user had different accounts in different tabs for the same application.
* UI fixes

## v1.2.0 - Dec 12th, 2023

* new API csprclick.switchAccount() to trigger the UI that permits to connect to another account.
* Previously used accounts are now shown in most recently used order.
* UI fixes.
* new API csprclick.switchAccount() to trigger the UI that permits to connect to another account.
* Previously used accounts are now shown in most recently used order.
* UI fixes.

## v1.1.4 - Dec 1st, 2023

* CSPR.click now detects if it's running within a mobile wallet in-app browser to skip wallet selection UI in sign-in flow.
* Ledger now works on Android devices.
* UI now shows an animation in account widget during loading.
* CSPR.click now display a warning if Casper app version in the Ledger device is outdated.

## v1.1.0 - Nov 1st, 2023

* Added Buy CSPR menu item to account dropdown menu.
* UI/UX improvements.

## v1.0.0 - Oct 10th, 2023

* Initial release.


# Integration

This section explains how to integrate the CSPR.click SDK into a web application, initialize the runtime, connect wallets, handle SDK events, request transaction approvals, and customize the optional top bar.

Start with [Downloading and initializing the SDK](https://github.com/make-software/casper-click-websdk/blob/master/docs/public/csprclick-sdk/downdload-and-initialize.md). If you are building a React application, you can wrap the same setup in the [React Context Provider](/cspr.click-sdk/integration/react-context-provider).

After initialization, continue with the integration steps that apply to your application:

* [Handling events](/cspr.click-sdk/integration/handling-events)
* [Connecting a wallet](/cspr.click-sdk/integration/connecting-a-wallet)
* [Signing transactions](/cspr.click-sdk/integration/signing-transactions)
* [Tracking your transactions in real time](/cspr.click-sdk/integration/processing-status-updates)
* [Customizing the top bar](/cspr.click-sdk/integration/customizing-the-top-bar)
* [Identicons](/cspr.click-sdk/integration/identicons)


# Downloading and initializing the SDK

This page explains how to download the CSPR.click runtime library and provide the initialization options it needs to start. These steps are the same for any browser application, whether it is built with React, another framework, or plain JavaScript.

React applications can use the [React Context Provider](/cspr.click-sdk/integration/react-context-provider) to wrap this setup in a provider component. Use the lower-level setup below when you want to control the runtime loading yourself.

## Add a container for CSPR.click UI

Add a container element where CSPR.click can render the top bar and modal windows. The `id` must match the `uiContainer` value used during initialization.

```html
<body>
  <div id="csprclick-ui-wrapper"> <!-- CSPR.click UI container -->
    <div id="csprclick-ui"></div>
  </div>
  <div id="root">
    <!-- your application goes here -->
  </div>
```

The `rootAppElement` option should point to the root element of your application. CSPR.click uses it when displaying modal windows and pop-ups.

A `csprclick-ui-wrapper` div is normally used with fixed-with layouts to center the top bar and display an homogeneous background color.

## Define the initialization options

Define the UI and SDK options before downloading the runtime script. The CDN library reads `window.clickUIOptions` and `window.clickSDKOptions` when it starts.

```typescript
import type { ClickUIOptions } from '@make-software/csprclick-core-types/clickui';
import type { CsprClickInitOptions } from '@make-software/csprclick-core-types';
import { CONTENT_MODE, WALLET_KEYS } from '@make-software/csprclick-core-types';

declare global {
  interface Window {
    clickUIOptions: ClickUIOptions;
    clickSDKOptions: CsprClickInitOptions;
  }
}

const clickUIOptions: ClickUIOptions = {
  uiContainer: 'csprclick-ui',
  rootAppElement: '#root',
  defaultTheme: 'light',
  accountMenuItems: [
    'AccountCardMenuItem',
    'CopyHashMenuItem',
    'BuyCSPRMenuItem',
  ],
};

window.clickUIOptions = clickUIOptions;

const clickSDKOptions: CsprClickInitOptions = {
  appName: 'CSPR.click demo',
  appId: 'csprclick-template',
  contentMode: CONTENT_MODE.IFRAME,
  providers: [
    WALLET_KEYS.CASPER_WALLET,
    WALLET_KEYS.LEDGER,
    WALLET_KEYS.METAMASK_SNAP,
  ],
};

window.clickSDKOptions = clickSDKOptions;
```

{% hint style="info" %}
You can use the default `csprclick-template` application identifier while working locally. Before publishing your application, create and configure your own application id.
{% endhint %}

Read more about the available options in the [Types](/cspr.click-sdk/reference/types#csprclickinitoptions) and [Properties](/cspr.click-sdk/reference/properties) reference pages.

## Download the runtime library

After the initialization options are available on `window`, add the CSPR.click CDN script to the page.

```typescript
if (!document.querySelector('script#csprclick-client')) {
  const script = document.createElement('script');
  script.src = 'https://cdn.cspr.click/ui/v2.1.0/csprclick-client-2.1.0.js';
  script.id = 'csprclick-client';
  script.async = true;
  document.head.appendChild(script);
}
```

CSPR.click emits the `csprclick:loaded` browser event after the runtime has loaded and initialized. Use that event when your application needs to run code only after the SDK is ready.

```typescript
window.addEventListener('csprclick:loaded', () => {
  console.log('CSPR.click SDK loaded');
});
```

## What's next

Once the SDK is loaded, your application can listen to CSPR.click events, connect wallets, request transaction approvals, and customize the top bar.

* [Handling events](/cspr.click-sdk/integration/handling-events)
* [Connecting a wallet](/cspr.click-sdk/integration/connecting-a-wallet)
* [Signing transactions](/cspr.click-sdk/integration/signing-transactions)
* [Customizing the top bar](/cspr.click-sdk/integration/customizing-the-top-bar)


# React Context Provider

In React applications, you can wrap the SDK download and initialization flow in a context provider. This keeps the CSPR.click runtime reference and connected account state available to any component through a custom hook.

Use this approach when your application loads CSPR.click from the CDN but still wants React-friendly access to the SDK. If you are not using React, follow the lower-level [Downloading and initializing the SDK](https://github.com/make-software/casper-click-websdk/blob/master/docs/public/csprclick-sdk/downdload-and-initialize.md) guide instead.

## Create the provider

Create a `ClickContext.tsx` file and define the SDK options before the runtime script is loaded. The provider listens for the `csprclick:loaded` event, stores the SDK reference, and keeps the active account state synchronized with CSPR.click events.

```tsx
import { createContext, useContext, useEffect, useState } from 'react';
import type { ReactNode } from 'react';
import {
  CONTENT_MODE,
  WALLET_KEYS,
} from '@make-software/csprclick-core-types';
import type {
  AccountType,
  CsprClickInitOptions,
  ICSPRClickSDK,
} from '@make-software/csprclick-core-types';
import type { ClickUIOptions } from '@make-software/csprclick-core-types/clickui';

declare global {
  interface Window {
    clickUIOptions: ClickUIOptions;
    clickSDKOptions: CsprClickInitOptions;
    csprclick?: ICSPRClickSDK;
  }
}

window.clickUIOptions = {
  uiContainer: 'csprclick-ui',
  rootAppElement: '#root',
  show1ClickModal: true,
  showTopBar: true,
  accountMenuItems: [
    'AccountCardMenuItem',
    'CopyHashMenuItem',
    'BuyCSPRMenuItem',
  ],
  defaultTheme: 'light',
};

window.clickSDKOptions = {
  appName: 'CSPR.click React template',
  appId: 'csprclick-template',
  providers: [
    WALLET_KEYS.CASPER_WALLET,
    WALLET_KEYS.LEDGER,
    WALLET_KEYS.METAMASK_SNAP,
  ],
  contentMode: CONTENT_MODE.IFRAME,
};

type ClickContextState = {
  publicKey: string | undefined;
  provider: string | undefined;
  clickRef: ICSPRClickSDK | undefined;
};

type AccountChangedEvent = {
  account?: AccountType;
};

const ClickContext = createContext<ClickContextState | undefined>(undefined);

type ClickProviderProps = {
  children: ReactNode;
};

export const ClickProvider = ({ children }: ClickProviderProps) => {
  const [connectedAccount, setConnectedAccount] = useState<AccountType | undefined>();
  const [clickRef, setClickRef] = useState<ICSPRClickSDK | undefined>();

  useEffect(() => {
    const checkActiveAccount = async (ref: ICSPRClickSDK) => {
      try {
        const account = await ref.getActiveAccountAsync({
          withBalance: true,
          withFiatCurrency: 'USD',
        });

        setConnectedAccount(account?.public_key ? account : undefined);
      } catch (error) {
        console.error('Failed to get active account', error);
        setConnectedAccount(undefined);
      }
    };

    const handleAccountChanged = (event: AccountChangedEvent) => {
      const account = event.account;
      setConnectedAccount(account?.public_key ? account : undefined);
    };

    const handleSdkLoaded = () => {
      const ref = window.csprclick;

      if (!ref) {
        return;
      }

      setClickRef(ref);
      ref.on('csprclick:signed_in', handleAccountChanged);
      ref.on('csprclick:switched_account', handleAccountChanged);
      ref.on('csprclick:unsolicited_account_change', handleAccountChanged);
      ref.on('csprclick:signed_out', () => setConnectedAccount(undefined));
      checkActiveAccount(ref);
    };

    window.addEventListener('csprclick:loaded', handleSdkLoaded);

    if (window.csprclick) {
      handleSdkLoaded();
    }

    if (!document.querySelector('script#csprclick-client')) {
      const script = document.createElement('script');
      script.src = 'https://cdn.cspr.click/ui/v2.1.0/csprclick-client-2.1.0.js';
      script.id = 'csprclick-client';
      script.async = true;
      document.head.appendChild(script);
    }

    return () => {
      window.removeEventListener('csprclick:loaded', handleSdkLoaded);
    };
  }, []);

  return (
    <ClickContext.Provider
      value={{
        publicKey: connectedAccount?.public_key,
        provider: connectedAccount?.provider,
        clickRef,
      }}
    >
      {children}
    </ClickContext.Provider>
  );
};

export const useClickRef = (): ClickContextState => {
  const context = useContext(ClickContext);

  if (!context) {
    throw new Error('useClickRef must be used within a ClickProvider');
  }

  return context;
};
```

## Add the UI container

The CDN runtime still needs a DOM element where it can mount the CSPR.click top bar and modal UI. Add this container to your `index.html`, before the React root element.

```html
<body>
  <div id="csprclick-ui-wrapper">
    <div id="csprclick-ui"></div>
  </div>
  <div id="root">
    <!-- your React application goes here -->
  </div>
</body>
```

The container `id` must match the `uiContainer` value configured in `window.clickUIOptions`.

## Wrap your application

Wrap your application with `ClickProvider` so components can access the SDK reference and account state.

```tsx
import { ClickProvider } from './ClickContext';

createRoot(document.getElementById('root')!).render(
  <ClickProvider>
    <App />
  </ClickProvider>
);
```

## Use the SDK from a component

Call `useClickRef()` from any component rendered inside the provider. The `clickRef` value is available after the CDN runtime has loaded.

```tsx
import { useClickRef } from './ClickContext';

const ConnectButton = () => {
  const { clickRef, publicKey } = useClickRef();

  return (
    <button onClick={() => clickRef?.signIn()}>
      {publicKey ? 'Connected' : 'Connect wallet'}
    </button>
  );
};
```

## What's next

After the provider is in place, continue with the shared integration steps:

* [Handling events](/cspr.click-sdk/integration/handling-events)
* [Connecting a wallet](/cspr.click-sdk/integration/connecting-a-wallet)
* [Signing transactions](/cspr.click-sdk/integration/signing-transactions)


# Handling events

CSPR.click emits events when the SDK is ready, when the user connects or switches accounts, and when the current session ends. Your application should listen to these events to keep its own state in sync with the wallet session.

This page covers the events most applications need during integration. Check the [Events](/cspr.click-sdk/reference/events) page for the complete reference.

## Register event handlers

CSPR.click emits the `csprclick:loaded` browser event after the runtime has loaded and initialized. Register your SDK event handlers inside this callback so `window.csprclick` is available.

```typescript
window.addEventListener('csprclick:loaded', () => {
  window.csprclick.on('csprclick:signed_in', async (evt) => {
    console.log('csprclick:signed_in', evt);
    // Start or refresh the user session in your application.
  });

  window.csprclick.on('csprclick:switched_account', async (evt) => {
    console.log('csprclick:switched_account', evt);
    // Update your application state for the new active account.
  });

  window.csprclick.on('csprclick:signed_out', async (evt) => {
    console.log('csprclick:signed_out', evt);
    // Clear the current user session in your application.
  });

  window.csprclick.on('csprclick:disconnected', async (evt) => {
    console.log('csprclick:disconnected', evt);
    // Close the session because the connected wallet disconnected.
  });
});
```

### csprclick:signed\_in

This event is emitted when CSPR.click connects to an account. Use it to store the connected account and enable account-specific parts of your UI.

[csprclick:signed\_in](/cspr.click-sdk/reference/events#csprclick-signed_in) reference.

### csprclick:switched\_account

This event is emitted when the user switches to a different account in the same wallet or another wallet. Use it to replace the current account in your application state.

[csprclick:switched\_account](/cspr.click-sdk/reference/events#csprclick-switched_account) reference.

### csprclick:signed\_out

This event is emitted after the application calls the `signOut()` SDK method. Use it to clear session state while leaving the wallet connection available for future sign-ins.

[csprclick:signed\_out](/cspr.click-sdk/reference/events#csprclick-signed_out) reference.

### csprclick:disconnected

This event is emitted when CSPR.click receives a disconnect request or event from the connected wallet. The application should close the current session as a consequence of this event.

It receives in the event object the provider that has been disconnected.

[csprclick:disconnected](/cspr.click-sdk/reference/events#csprclick-disconnected) reference.


# Connecting a wallet

If your application does not use the CSPR.click top bar, you need to provide your own controls for wallet connection and session management. A typical application has buttons or menu items to connect a wallet, show the connected account, switch to another account, and disconnect.

This page explains which wallets are available to users and how to trigger the most common wallet session actions from your UI.

## Available wallets

The wallets shown to the user are defined by the `providers` array in your SDK initialization options. CSPR.click uses this list when it opens the wallet selector, so only the wallets enabled by your application can be selected.

```typescript
const clickSDKOptions: CsprClickInitOptions = {
  appName: 'CSPR.click demo',
  appId: 'csprclick-template',
  contentMode: CONTENT_MODE.IFRAME,
  providers: [
    WALLET_KEYS.CASPER_WALLET,
    WALLET_KEYS.LEDGER,
    WALLET_KEYS.METAMASK_SNAP,
  ],
};
```

Read more about the [CsprClickInitOptions](/cspr.click-sdk/reference/types#csprclickinitoptions) type and the available wallet provider values in the reference.

## Sign in

When the user clicks your Sign in or Connect wallet button, call `signIn()` to open the CSPR.click wallet selector.

```tsx
clickRef.signIn()
```

This method returns immediately. Listen for the `csprclick:signed_in` event to update your application after the user connects an account.

## Switch account

Call `switchAccount()` when the user wants to change to another account. Depending on the selected wallet, this may let the user choose another account in the same wallet or connect through a different provider.

```tsx
clickRef.switchAccount()
```

This method returns immediately. Listen for the `csprclick:switched_account` event to update your session state with the new account.

## Disconnect

Call `signOut()` to close the current CSPR.click session in your application.

```tsx
clickRef.signOut()
```

This does not request the connected wallet to disconnect from your site. The next time the user signs in, the wallet may be able to reconnect without asking for permission again.

If you want to remove the wallet connection completely, call `disconnect()` instead:

```tsx
clickRef.disconnect()
```

Listen for `csprclick:signed_out` and `csprclick:disconnected` to clear the current account from your application state.


# Signing transactions

Applications that interact with the Casper Network often need to submit transactions. Before a transaction can be processed, the user must review and approve it by signing it with their wallet.

Your frontend application is not always responsible for creating the transaction. Depending on your architecture, the transaction may be built by your frontend, by a backend service, or by a third party before it is sent to the user for approval.

In all cases, CSPR.click helps with the approval step: it asks the active wallet to show the transaction to the user, collects the signature if the user approves, and then either returns the signature or submits the signed transaction.

The CSPR.click SDK provides two ways to obtain this approval:

1. [`send()`](/cspr.click-sdk/reference/methods#send).

* Requests the active wallet to prompt the user for approval (signature).
* Automatically submits the signed transaction to a Casper node for processing.
* Optionally accepts a callback function to receive live status updates during execution (e.g., pending, confirmed, rejected).

This is the most common method. In most applications, you can call `send()` and use its result or status updates to tell the user whether the transaction is being processed, confirmed, rejected by the user, or rejected by the network.

2. [`sign()`](/cspr.click-sdk/reference/methods#sign).

* Requests the active wallet to prompt the user for approval.
* Returns the signature value to your application, without submitting the transaction.

Use this method for advanced workflows where your application needs the raw signature, such as off-chain processing, server-side validation, or multi-step transaction orchestration.

## Buy Alice a Coffee on testnet

The [React template](https://github.com/make-software/csprclick-examples/tree/master/csprclick-react) includes an example that asks the user to approve a transaction sending testnet CSPR to Alice, an imaginary teammate.

<figure><img src="/files/mKMblaxbUYnGsKHQbiRS" alt=""><figcaption><p>Example in the template project</p></figcaption></figure>

The example lives in the `<BuyMeACoffee>` component. These are the key steps:

1. **Build the transaction**

First, construct a transfer transaction. The `casper-js-sdk` package is included in the template to help with this step. Refer to the official Casper SDK documentation for more detailed usage and examples.

2. **Send the transaction**

Next, call `clickRef.send()`. CSPR.click will:

* Prompt the user in the active wallet to review and sign the transaction.
* Forward the signed transaction to a Casper node for processing.

3. **Handle responses**

Your application should be prepared to handle all possible outcomes:

* Success: The transaction was sent and you receive a transaction hash.
* User rejection: The user declined to sign the transaction.
* Network rejection: The Casper node rejected the transaction.

You can handle the final response with `.then()` and `.catch()`, and you can also use live status updates while the transaction is being processed.

4. **(Optional) Track transaction status**

The `.send()` method accepts an optional callback function as its second argument. This callback receives status updates while the transaction is being executed, so your UI can:

* Show progress indicators in your UI (e.g., “Transaction pending…”)
* Update users when the transaction is confirmed or fails
* Provide richer feedback beyond just the final outcome

```tsx
function BuyMeACoffee() {
  const { clickRef } = useClickRef();
  const activeAccount = clickRef?.getActiveAccount();
  const [transactionHash, setTransactionHash] = useState<string>('');
  const [waitingResponse, setWaitingResponse] = useState<boolean>(false);

  const signAndSend = (transactionObj: object, sender: string) => {
          const onStatusUpdate = (status: string, data: any) => {
            console.log('STATUS UPDATE', status, data);
            if(status === TransactionStatus.SENT)
              setWaitingResponse(true);
          };
      
          clickRef
            ?.send(transactionObj, sender, onStatusUpdate)
            .then((res: SendResult | undefined) => {
                setWaitingResponse(false);
                if (res?.transactionHash) {
                    setTransactionHash(res.transactionHash);
                    alert('Transaction sent successfully: ' + res.transactionHash +
                        '\n Status: ' +
                        res.status +
                        '\n Timestamp: ' +
                        res.csprCloudTransaction.timestamp);
              } else if (res?.cancelled) {
                alert('Sign cancelled');
              } else {
                alert('Error in send(): ' + res?.error + '\n' + res?.errorData);
              }
            })
            .catch((err: any) => {
              alert('Error: ' + err);
              throw err;
            });
  };

  const handleSignTransaction = (evt: any) => {
    evt.preventDefault();
    const senderPk = activeAccount?.public_key?.toLowerCase() || '';
    const transaction = new NativeTransferBuilder()
        .from(PublicKey.fromHex(senderPk))
        .target(PublicKey.fromHex(recipientPk))
        .amount('6' + '000000000')
        .id(Date.now())
        .chainName(clickRef.chainName!)
        .payment(100_000_000)
        .build();
    signAndSend(transaction.toJSON() as object, senderPk);
  };
	
  return (
    ...
    <button onClick={() => handleSignTransaction()} />Sign and send transaction</button>
    ...
  )
}
```


# Tracking your transactions in real time

When you use `send()` to request transaction approval and deploy the signed transaction to the network, the SDK can open a websocket connection to the CSPR.click backend and receive real-time execution updates.

Without real-time updates, applications usually need to poll a backend service or query a Casper node to know whether a transaction has been processed, confirmed, rejected, or expired. Polling adds complexity and often leaves users waiting without clear feedback.

With CSPR.click status updates, your application can:

* Receive status notifications during the transaction lifecycle.
* Update your UI with progress states (e.g., pending, processed, failed).
* Access processed transaction data without making extra API calls.

This makes it easier to build responsive applications that keep users informed while their transactions move through the Casper Network.

<figure><img src="/files/fwEvmY0vXqwxr7aqQKs3" alt="Waiting for transaction completion"><figcaption></figcaption></figure>

## Receive transaction updates

To receive updates, pass a callback function to the `send()` method. The SDK calls this function as the transaction is signed, submitted, processed, or stopped by an error or timeout.

```javascript
const onStatusUpdate = (status, data) => {
    console.log('STATUS UPDATE', status, data);
    if (status === TransactionStatus.SENT)
        setWaitingIndicator();
    if (status === TransactionStatus.PROCESSED)
        parseProcessedTransaction();
    // Handle other status updates (cancel, timeout, error, etc.)
};

await clickRef.send(transaction, sender, onStatusUpdate);
```

### Status values

The `status` argument passed to the callback function can have these values:

| Value       | Description                                                                                                                           |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `sent`      | The transaction has been signed and successfully deployed to a Casper node.                                                           |
| `processed` | The transaction has been executed by the network. The execution may have succeeded or failed.                                         |
| `expired`   | The transaction’s time-to-live (TTL) elapsed before execution.                                                                        |
| `cancelled` | The user rejected the signature request.                                                                                              |
| `timeout`   | The SDK stopped listening for updates before the transaction was finalized. A custom timeout can be specified (default: 120 seconds). |
| `error`     | An unexpected error occurred while submitting or monitoring the transaction.                                                          |
| `ping`      | A heartbeat event sent periodically to indicate that the connection is still active.                                                  |

### Processed transaction data

When the transaction reaches the `processed` state, the callback function receives an additional `data` argument.

This object contains the full `Deploy` entity, as defined in the [CSPR.cloud REST API documentation](https://docs.cspr.cloud/rest-api/deploy#properties).

Your application can use this information to:

* Show whether the transaction succeeded or failed.
* Provide more detailed feedback, such as execution cost or error messages.


# Customizing the top bar

CSPR.click displays a navigation bar at the top of your application. It includes the CSPR products menu on the left, the connected account menu on the right, and optional selectors that your application can enable during initialization.

<figure><img src="/files/1seET90p34RaRJyPkO5k" alt=""><figcaption><p>CSPR.click navigation bar</p></figcaption></figure>

The top bar is configured through `window.clickUIOptions`. The main customizable areas are:

* [Account dropdown menu](/cspr.click-sdk/integration/customizing-the-top-bar/account-dropdown-menu): add account information, copy actions, buy CSPR, or custom application menu items.
* [Theme selector](/cspr.click-sdk/integration/customizing-the-top-bar/theme-selector): let users switch between light and dark mode and notify your application when the selected theme changes.
* [Network selector](/cspr.click-sdk/integration/customizing-the-top-bar/network-selector): let users choose between the networks supported by your application.

## Hide the top bar

If your application has its own sign-in, account, and session controls, you can hide the CSPR.click top bar with the `showTopBar` field in `ClickUIOptions`.

```typescript
const clickUIOptions = {
  uiContainer: 'csprclick-ui',
  rootAppElement: '#app',
  showTopBar: false,
};
```

When `showTopBar` is `false`, CSPR.click still uses the UI container for modal windows and wallet interactions, but it does not render the navigation bar.


# Account dropdown menu

The account dropdown menu is displayed on the right side of the CSPR.click top bar after the user connects a wallet. CSPR.click always includes the session actions needed to switch account and sign out. You can add prebuilt menu items and custom application actions before those session actions.

<figure><img src="/files/r1xacFl1JiWLiv2YvLzg" alt=""><figcaption></figcaption></figure>

## Account dropdown menu setup

Configure the account dropdown menu with the `accountMenuItems` property in `window.clickUIOptions`. The array can contain prebuilt item literals and custom menu item objects.

```typescript
import type {
  ClickUIOptions,
  CustomMenuItem,
} from '@make-software/csprclick-core-types/clickui';

const csprClickDocsMenuItem = {
  label: 'CSPR.click docs',
  icon: './csprclick-icon.svg',
  badge: { title: 'New', variation: 'green' },
  onClick: () => {
    window.open('https://docs.cspr.click', '_blank');
  },
} as CustomMenuItem;

window.clickUIOptions = {
  uiContainer: 'csprclick-ui',
  rootAppElement: '#root',
  show1ClickModal: true,
  showTopBar: true,
  accountMenuItems: [
    'AccountCardMenuItem',
    'CopyHashMenuItem',
    csprClickDocsMenuItem,
    'BuyCSPRMenuItem',
  ],
  defaultTheme: 'light',
} as ClickUIOptions;
```

## Prebuilt menu items

CSPR.click provides these prebuilt account menu item literals:

| Literal               | Description                                                                    |
| --------------------- | ------------------------------------------------------------------------------ |
| `AccountCardMenuItem` | Displays account information, including account name, public key, and balance. |
| `CopyHashMenuItem`    | Copies the connected account hash to the clipboard.                            |
| `BuyCSPRMenuItem`     | Opens the [Topper by Uphold](https://www.topperpay.com/) widget in a new tab.  |

### Account card

Add `AccountCardMenuItem` to render a card with connected account information at the top of the dropdown menu. The card includes the account name, public key, and balances.

```typescript
accountMenuItems: ['AccountCardMenuItem']
```

### Copy public key

Add `CopyHashMenuItem` to render a menu item that copies the connected account hash to the clipboard.

```typescript
accountMenuItems: ['CopyHashMenuItem']
```

### Buy CSPR

Add `BuyCSPRMenuItem` to render a menu item that opens the Topper by Uphold widget in a new tab. This lets users top up their account with a card payment.

```typescript
accountMenuItems: ['BuyCSPRMenuItem']
```

## Custom menu item

Use a custom menu item object when you want to add an application-specific action. A custom item has a label, an icon, and an `onClick` handler. You can also add a small badge next to the label.

```typescript
const csprClickDocsMenuItem = {
  label: 'CSPR.click docs',
  icon: './csprclick-icon.svg',
  badge: { title: 'New', variation: 'green' },
  onClick: () => {
    window.open('https://docs.cspr.click', '_blank');
  },
} as CustomMenuItem;
```

Valid badge variation values are `green`, `blue`, `violet`, and `gray`.


# Theme selector

<figure><img src="/files/ySdjriteiERUyDOzZvK6" alt=""><figcaption><p>Theme selector widget</p></figcaption></figure>

CSPR.click can display a theme selector in the top bar so users can switch between the light and dark themes.

During initialization, your application defines the initial theme with `defaultTheme`. The CSPR.click UI manages its own theme state internally. When the user asks to change the theme, CSPR.click calls your `onThemeChanged` callback so your application can update its own page styles.

## Theme selector setup

Define a default theme and an `onThemeChanged` callback in `window.clickUIOptions`.

```typescript
const onThemeChanged = (theme) => {
  const page = document.querySelector('body');

  if (theme === 'dark') {
    page?.classList.add('dark');
  } else {
    page?.classList.remove('dark');
  }

  console.log('Theme switched to', theme);
};

const defaultTheme = 'light';

const clickUIOptions = {
  uiContainer,
  rootAppElement: '#app',
  defaultTheme,
  onThemeChanged,
  accountMenuItems,
  networkSettings,
};
```

The `defaultTheme` value can be `light` or `dark`. Use `onThemeChanged` to synchronize your application shell, CSS classes, state store, or design system with the theme selected in the CSPR.click top bar.


# Network selector

<figure><img src="/files/ILBQaL5ECjeDTSwcuatw" alt=""><figcaption><p>Network selector widget</p></figcaption></figure>

If your application supports more than one Casper network, you can display a network selector in the CSPR.click top bar. The selector shows the available network labels and calls your application when the user selects a different one.

## Network selector setup

Configure the selector with the `networkSettings` property in `window.clickUIOptions`. The `networks` array defines the labels shown in the top bar, `currentNetwork` defines the initially selected value, and `onNetworkSwitch` handles user selection.

The following example displays a switch between Mainnet and Testnet:

```typescript
const NETWORKS = ['Mainnet', 'Testnet'];

const networkSettings = {
  networks: NETWORKS,
  currentNetwork: NETWORKS[0],
  onNetworkSwitch: (n) => {
    console.log('Network selected', n);
    window.csprclickUI.setNetwork(n);
  },
};

const clickUIOptions = {
  uiContainer,
  rootAppElement: '#app',
  defaultTheme,
  onThemeChanged,
  accountMenuItems,
  networkSettings,
};
```

Use `onNetworkSwitch` to update your application state, reload network-specific data, and reconfigure any services that depend on the selected network. Call `window.csprclickUI.setNetwork(n)` after handling the change so the CSPR.click top bar reflects the selected network.


# Identicons

CSPR.click can generate an identicon for a public key. Identicons are useful when you want to display a compact visual hint next to an account, recipient, sender, or connected wallet address.

Use the `getAccountIdenticon()` SDK method to generate an `HTMLCanvasElement`, then render it as an image with `toDataURL()`.

{% hint style="info" %}
**Recommended display guidelines:**

* Place the identicon to the **left** of the public key.
* Render it as a **square** with **no border** and **10% rounded corners**. Never display it as a circle.
* When truncating the public key, use **5 hex chars + `...` + 5 hex chars** — for example: `02026...9555c`.
  {% endhint %}

<figure><img src="/files/okxxMH7qxWP33LfEWQCL" alt="Account identicon example"><figcaption></figcaption></figure>

## React example

The following component receives a public key, generates its identicon, and renders it next to the public key.

```tsx
import { useMemo } from 'react';
import { useClickRef } from './ClickContext';

type IdenticonProps = {
  publicKey: string;
};

export const Identicon = ({ publicKey }: IdenticonProps) => {
  const { clickRef } = useClickRef();

  const identicon = useMemo(() => {
    if (!clickRef || !publicKey) {
      return undefined;
    }

    return clickRef.getAccountIdenticon(publicKey.toLowerCase());
  }, [clickRef, publicKey]);

  return (
    <FlexRow gap={8} align="center">
      <img
        src={identicon?.toDataURL()}
        width={20}
        height={20}
        alt="Account identicon"
      />
      <Span>{publicKey}</Span>
    </FlexRow>
  );
};
```

Read more about the [getAccountIdenticon](/cspr.click-sdk/reference/methods#getaccountidenticon) method in the SDK reference.


# Legacy csprclick-ui Package

{% hint style="warning" %}
This integration path is **no longer recommended** for new projects. The preferred way to integrate CSPR.click in React applications is described in [Integration](/cspr.click-sdk/integration).

This page is kept for existing applications that already use `@make-software/csprclick-ui` and for developers who need the additional flexibility it provides. The package is still supported and will continue to be maintained.
{% endhint %}

## When to use this approach

The `@make-software/csprclick-ui` package trades some integration simplicity for a higher degree of UI control. Consider it if your project requires:

* **Deep customization of the top bar** — you can add your own items, controls, and menu entries beyond what the standard integration exposes.
* **Tweak the CSPR.click styled-components theme** — most of the time, the default CSPR.click UI theme works well with the client application. Sometimes, though, the developer may want to tweak the top bar styles to match their application's design system.

For most new projects these trade-offs are unnecessary. If you are starting fresh, follow the [recommended integration path](/documentation/getting-started) instead.

***

This page guides you through the steps required to integrate the CSPR.click SDK into your existing React web application using the `@make-software/csprclick-ui` package.

## Install CSPR.click packages

Run the following command in a terminal window to install CSPR.click packages:

```bash
npm install --save-dev @make-software/csprclick-ui @make-software/csprclick-core-types
```

If you're using Typescript, the command above also installs type definitions for CSPR.click.

## ClickProvider context provider

First, define the initialization options for the CSPR.click library:

```typescript
import { CONTENT_MODE } from '@make-software/csprclick-core-types';

const clickOptions: CsprClickInitOptions = {
    appName: 'Casper dApp',
    appId: 'csprclick-template',
    contentMode: CONTENT_MODE.IFRAME,
    providers: ['casper-wallet', 'ledger', 'metamask-snap'],
};
```

Next, wrap your main application component with the `<ClickProvider>` context provider:

```tsx
<ClickProvider options={clickOptions}>
  <App />
</ClickProvider>
```

This component will manage the download and initialization of the CSPR.click runtime library.

Read more about the [CsprClickInitOptions ](/cspr.click-sdk/reference/types#csprclickinitoptions)type in the SDK reference section.

{% hint style="info" %}
You can use the default `csprclick-template` application identifier while you're working locally on your application. But to upload your new project to a server, you'll need to [get your own application id](https://github.com/make-software/casper-click-websdk/blob/master/docs/overview.md).
{% endhint %}

## Add \<ClickUI> component to your app

All the CSPR.click UI elements are managed from the `<ClickUI>` component. This component must be added to the very beginning of your main UI component and it's responsible for displaying the top bar and all the modal windows and pop-ups needed for connecting with wallets, showing information to the user, etc.

```tsx
const topBarSettings = {
    accountMenuItems: [<ViewAccountOnExplorerMenuItem key='0' />],
}

const App = () => {
    return (
        <!-- ... -->
        <ClickUI topBarSettings={topBarSettings}/>
        <!-- ... -->
    )
}
```

Refer to the [Customizing the top bar ](https://github.com/make-software/casper-click-websdk/blob/master/docs/public/csprclick-sdk/react/customizing-the-top-bar.md)section in this guide for complete reference on how to work with each of the setting elements in the top bar.

{% hint style="info" %}
While we recommend to include the CSPR.click top bar in your application, if you have your own Sign in and session management controls you can opt-out. To do so, do not include the `topBarSettings` prop to `ClickUI` and CSPR.click won't render the top bar.
{% endhint %}

## Add CSPR.click styles

### Option 1: your application uses styled-components

When your application already uses the \<ThemeProvider> component from styled-components library, you just need to add CSPR.click styles to your themes.

Considering as an example that your application has `light` and `dark` themes, you may merge the styles into your theme settings like this:

```typescript
import { CsprClickThemes } from '@make-software/csprclick-ui';

const YourAppThemes = {
	dark: {
		...CsprClickThemes.dark,
		// your styles for dark theme here
	},
	light: {
		...CsprClickThemes.light,
		// your styles for light theme here
	},
};
```

### Option 2: your application doesn't use styled-components

CSPR.click requires the `styled-components` library to work. Add it to your dependencies by running the command:

```
npm install --save styled-components@5.3.9
```

Next, add the theme provider to your application:

```tsx
import { CsprClickThemes } from '@make-software/csprclick-ui';

<ThemeProvider theme={CsprClickThemes.light}>
  <ClickProvider options={clickOptions}>
    <App />
  </ClickProvider>
</ThemeProvider>
```

Currently, you can choose between two themes: `light` and `dark`.

### Handling events

In your application, you'll need to listen and respond to different events emitted by the CSPR.click library. On this page, we're covering the most common. Check the [Events](https://github.com/make-software/casper-click-websdk/blob/master/docs/public/reference/events.md) page for a complete list of events.

The following code snippet shows an example of how to bind your handlers to the CSPR.click events with the React `useEffect()` hook:

```tsx
const clickRef = useClickRef();

useEffect(() => {
  clickRef?.on('csprclick:signed_in', async (evt) => {
    // update your app accordingly
  });
  clickRef?.on('csprclick:signed_out', async (evt) => {
    // update your app accordingly
  });
}, [clickRef?.on]);
```

### Import required fonts

In your main CSS file, import the Inter and Jetbrains mono fonts:

```
@import url('https://fonts.cdnfonts.com/css/inter');

@font-face {
    font-family: 'JetBrains Mono';
    src: url('https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff2/JetBrainsMono-Regular.woff2')
        format('woff2'),
      url('https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff/JetBrainsMono-Regular.woff')
        format('woff');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
  }
```


# Customizing the top bar

{% hint style="info" %}
While we recommend to include the CSPR.click top bar in your application, if you have your own Sign in and session management controls you can opt-out. To do so, do not include the `topBarSettings` prop to `ClickUI` and CSPR.click won't render the top bar.
{% endhint %}

CSPR.click includes a navigation bar that displays on the top of the web application. It's the same navigation bar you can find on CSPR.live and other applications that integrate CSPR.click.

<figure><img src="/files/1seET90p34RaRJyPkO5k" alt=""><figcaption><p>CSPR.click navigation bar</p></figcaption></figure>

In this top bar you always see the CSPR Products menu on the left side, and the Account menu on the right side. The rest are customizable selectors that you can choose to add or not. Most of them are customizable as we'll see in the next pages.

### TopBarSettings object

This object wraps all settings in the navigation bar and is included to `<ClickUI>` as a prop. More on each configuration in the following subpages.

```tsx
const topBarSettings: TopBarSettings = {
    accountMenuItems,
    onThemeSwitch: toggleTheme,
    languageSettings: languageSettings(lang, setLang),
    currencySettings: currencySettings(currency, setCurrency),
    networkSettings: networkSettings(network, setNetwork),
};

<ClickUI
    topBarSettings={topBarSettings}
    themeMode={themeMode}
/>
```


# Account dropdown menu

You can customize the account dropdown menu in our top bar with your own menu items. Options to switch to another account and sign out are always present at the end of the list. The rest, depends on your needs. We provide a couple of common menu item components you may add, and one component for you to include anything you need.

<figure><img src="/files/r1xacFl1JiWLiv2YvLzg" alt=""><figcaption></figcaption></figure>

## Account dropdown menu set up

To customize the account dropdown menu, add the menu items you want to display into an array:

```tsx
const accountMenuItems = [
  <AccountCardMenuItem key={0} />,
  <CopyHashMenuItem key={1} />,
  <AccountMenuItem
    key={2}
    onClick={() => {
        window.location.href = 'https://cspr.click';
    }}
    icon={CSPRClickIcon}
    label={'CSPR.click docs'}
    badge={{ title: 'new', variation: 'green' }}
  />,
];
```

Then, add the array to the `<ClickUI>` component:

```tsx
<ClickUI
    topBarSettings={{
        accountMenuItems
    }}
/>
```

## Prebuilt menu items

### Account card

```tsx
<AccountCardMenuItem />
```

Renders a card with account information at the top of the dropdown menu. The card includes the account name, public key and liquid/total balances. The account also links to CSPR.live.

By default, balances are shown in `USD` currency. If your application supports multiple currencies, you can pass the `currency` prop to the `<ClickUI>` component to display the balances in the selected currency:

```tsx
<ClickUI
    topBarSettings={topBarSettings}
    themeMode={themeMode}
    currencyCode={currency.code}
/>
```

See in the template project how to set up the currency selector connected to the account card.

### View account on CSPR.live

```tsx
<ViewAccountOnExplorerMenuItem />
```

Alternative to the account card. Renders a menu item in the account dropdown menu to open the CSPR.live account page in a new tab.

### Copy public key

```tsx
<CopyHashMenuItem />
```

Renders a menu item in the account dropdown menu to copy the connected public key to the clipboard.

### Buy CSPR

```tsx
<BuyCSPRMenuItem />
```

Renders a menu item in the account dropdown menu to open the [Topper by Uphold](https://www.topperpay.com/) widget on a new tab. This widget allows the user to top-up his account with a credit card payment.

### Custom menu item

```tsx
<AccountMenuItem
  onClick={() => {
    window.location.href = 'https://docs.cspr.click';
  }}
  icon={CSPRClickIcon}
  label={'CSPR.click docs'}
  badge={{ title: 'new', variation: 'green' }}
/>
```

Renders a menu item in the account dropdown menu with a custom text, icon, and handler action.

Optionally, you can add a small badge right to the menu item title. Valid variation values are `green`, `blue`, `violet`, and `gray`.


# Theme selector

CSPR.click navigation bar has two themes: **light** and **dark**. You can use one or the other. And if your application also has light and dark modes, you can add to the navigation bar a theme selector to let the user easily change between both.

## Theme selector set up

In your application, create a state value to store the current theme. For example, with `useState()` hook, but you can use any other method.

```tsx
const [themeMode, setThemeMode] = useState<ThemeModeType>(ThemeModeType.light);
```

Next, define a callback function that will be invoked when the theme selector is used to change the theme:

```tsx
const handleThemeSwitch = () => 
      setThemeMode(themeMode === ThemeModeType.light ?
            ThemeModeType.dark : 
            ThemeModeType.light);
```

Finally, indicate the current theme mode and the theme switch callback method to the `<ClickUI>` component:

```tsx
<ClickUI
    themeMode={themeMode}
    topBarSettings={{
        onThemeSwitch:handleThemeSwitch
    }}
/>
```


# Network selector

<figure><img src="/files/ILBQaL5ECjeDTSwcuatw" alt=""><figcaption><p>Network selector widget</p></figcaption></figure>

If your application can switch between Mainnet and Testnet networks you may want to add the network selector widget to the CSPR.click navigation bar.

## Network selector set up

Define an array with the list of networks your application supports:

```tsx
export const NETWORKS = ['Mainnet', 'Testnet'];
```

Create a state value to store the current network. For example, with `useState()` hook, but you can use any other method.

```tsx
const [network, setNetwork] = useState<string>(NETWORKS[1]);
```

Define a `networkSettings` object with the list of networks, the current network, and a callback method to handle network selection by the user. Add this object to the `topBarSettings` prop in the `<ClickUI>` component:

```typescript
const networkSettings = {
  networks: NETWORKS,
  currentNetwork: network,
  onNetworkSwitch: (n: string) => { setNetwork(n); },
}
```

```tsx
<ClickUI 
    topBarSettings={{
        networkSettings
    }}
/>
```

### Customize the network icons

You can also specify your custom icons for each of the networks:

```tsx
import mainnetIcon from './assets/ico-mainnet.svg'
import testnetIcon from './assets/ico-testnet.svg'

const NETWORKS = [
  { title: 'Mainnet', icon: mainnetIcon },
  { title: 'Testnet', icon: testnetIcon }
];
```


# Language selector

<figure><img src="/files/YHH6qmnkyUbDU1c2BzQ2" alt=""><figcaption><p>Language selector widget</p></figcaption></figure>

If your application supports multiple languages, you can add to the CSPR.click navigation bar a language selector.

## Language selector set up

Define an array with the list of languages your application supports:

```tsx
export const LANGUAGES: Lang[] = [
    Lang.EN,
    Lang.AZ,
    Lang.DE,
    Lang.ES,
    //...,
];
```

Create a state value to store the current language. For example, with `useState()` hook, but you can use any other method.

```tsx
const [language, setLanguage] = useState<Lang>(Lang.EN);
```

Define a `languageSettings` object with the list of languages, the current language, and a callback method to handle language selection by the user. Add this object to the `topBarSettings` prop in the `<ClickUI>` component:

```typescript
const languageSettings = {
    languages: LANGUAGES,
    creditsUrl: "/credits",
    contributeUrl: "/contribute",
    currentLanguage:  language,
    onChangeLanguage: (l: Lang) => { setLanguage(l); }
}
```

```tsx
<ClickUI
    topBarSettings={{
        languageSettings
    }}
/>
```

If you want to show a credits page to shout out your contributors, specify a URL in the `credits` field.

And if you want to ask your visitors to help you maintain the translations, specify a URL in the `contribute` field.

Note that both, `credits` and `contribute` links are optional. If you don't specify one or both, such options won't show in the language selector widget.


# Currency selector

<figure><img src="/files/1Fi6Mct4SeaiF5wre9m9" alt=""><figcaption><p>Currency selector widget</p></figcaption></figure>

If your application supports multiple currencies, you can add to the CSPR.click navigation bar a currency selector.

## Language selector set up

Define an array with the list of currencies your application supports:

```tsx
export const CURRENCIES: Currency[] = [
    {
        code: 'USD',
        title: 'US Dollar',
        type_id: CurrencyType.FIAT,
    },
    {
        code: 'EUR',
        title: 'Euro',
        type_id: CurrencyType.FIAT,
    },
    //...,
    {
        code: 'BTC',
        title: 'Bitcoin',
        type_id: CurrencyType.CRYPTO,
    },
    {
        code: 'ETH',
        title: 'Ethereum',
        type_id: CurrencyType.CRYPTO,
    },
];
```

Note in the image above how currencies are grouped in cryptocurrencies and fiat currencies. In your list of currencies, classify them using the `type_id` property in one of the groups.

Create a state value to store the current currency. For example, with `useState()` hook, but you can use any other method.

```tsx
	const [currency, setCurrency] = useState(CURRENCIES[0]);
```

Define a `currencySettings` object with the list of currencies, the selected currency, and a callback method to handle currency selection by the user. Add this object to the `topBarSettings` prop in the `<ClickUI>` component:

```typescript
const currencySettings= {
  currencies: CURRENCIES,
  currentCurrency: currency,
  onChangeCurrency: (c: any) => { setCurrency(c); },
}
```

```tsx
<ClickUI
    topBarSettings={{
        currencySettings
    }}
/>
```


# Custom selector

<figure><img src="/files/OmIlfeCzVpPUPr3hBk2F" alt=""><figcaption></figcaption></figure>

In addition to the standard settings selectors described in the previous pages, you can define your own dropdown menus with the options your application requires.

The code below shows an example with a menu that allows to choose between three different tokens:

```tsx
const TOKENS: CustomTopBarMenuItem[] = [
  {title:'Token 1', icon: <LogoGreen/>  },
  {title: 'Token 2', icon: <LogoYellow/>},
  {title: 'Token 3', icon: <LogoOrange/> }
];

const tokenSettings = {
    items: TOKENS,
    currentItem: currentToken,
    onItemSwitch: (t: string) => {
      // update your app upon item change
    },
};
```

```tsx
<ClickUI
    topBarSettings={{
        customTopBarMenuSettings:[tokenSettings]
    }}
/>
```


# Theme customization

CSPR.click provides set of different ui themes out of box, such as `red`, `green`, `blue` and `csprclick` as default theme. Each theme has its own set of `Dark` and `Light` version where all necessary colours are specified. Customer can easily use and modify set of colours for each theme and for its Dark or Light version.

### Default themes declaration

To use one of default theme, you need to export `DefaultThemes` object and `builtThemes` helper function from `@make-software/csprclick-ui`

DefaultThemes object consist of four properties which actually are themes itself. So by default we got four themes:

* `csprclick`
* `red`
* `green`
* `blue`

By default you'll get `csprclick` theme.

```tsx
import {DefaultThemes, buildTheme} from '@make-software/csprclick-ui';

export const AppTheme = buildTheme({
    ...DefaultThemes.csprclick,
});
```

You can easily change it to any of available themes from `DefaultThemes` object.

```tsx
export const AppTheme = buildTheme({
    ...DefaultThemes.red,
});
```

or

```tsx

export const AppTheme = buildTheme({
    ...DefaultThemes.blue,
});
```

### Default themes usage

To connect and apply theme you have selected all you need it just to pass it as a props to `ThemeProvider` which you can import from `styled-components` And wrap with it the whole application.

`ThemeModeType` enum which consist theme modes:

* `light`
* `dark`

```tsx
import { ThemeProvider } from 'styled-components';
import { AppTheme } from "./settings/theme";
import { ThemeModeType } from '@make-software/csprclick-ui';

<ThemeProvider theme={AppTheme[ThemeModeType.light]}>
    ...
    <App/>
    ...
</>
```

### Customise whole application alongside with `<ClickUI>` component

Besides customizing `<ClickUI>` component you can also customize the whole body of your application.

To do that, we have declared two properties:

* `appDarkTheme` - to customize application in dark mode
* `appLightTheme` - to customize application in light mode

Each of them has its own set of properties:

```tsx

export const AppTheme = buildTheme({
    ...DefaultThemes.csprclick,
    appDarkTheme: {
        topBarSectionBackgroundColor: DefaultThemes.csprclick.csprclickDarkTheme[clickStyleguide.backgroundTopBarColor],
        [clickStyleguide.textColor]: '#DADCE5',
        bodyBackgroundColor: '#0f1429'
    },
    appLightTheme: {
        topBarSectionBackgroundColor: DefaultThemes.csprclick.csprclickLightTheme[clickStyleguide.backgroundTopBarColor],
        [clickStyleguide.textColor]: '#1A1919',
        bodyBackgroundColor: '#f2f3f5'
    },
});

```

* `topBarSectionBackgroundColor` - stands for wrapping `<ClickUI>` component and set appropriate color for this wrapper
* `[clickStyleguide.textColor]` - stands for changing text color. Applies to the part of application which is inside `<body>` tag
* `bodyBackgroundColor` - stands for changing background color. Applies to the part of application which is inside `<body>` tag


# Create your own custom theme

If you're not enough with default set of themes you can easily create the new one. To do that, all you need is to directly extend `AppTheme` object with new property which would be the title of new theme and add appropriate structure.

### Theme creation structure

First of all, from `@make-software/csprclick-ui` you need to import`clickStyleguide` object which consist all necessary colors constructors to cover you application with new theme. Also you'll need helper function to build your own theme `buildTheme`.

To create the new custom theme, please follow the signature:

**note: (instead of hardcoded hex, please use your own color values)**

```tsx
import { clickStyleguide, buildTheme } from '@make-software/csprclick-ui';

const newCustomTheme = {
        csprclickDarkTheme: {
            [clickStyleguide.backgroundTopBarColor]: '#6305a2',
            [clickStyleguide.backgroundMenuColor]: '#b6a3e5',
            [clickStyleguide.hoverProductMenu]: '#b193ec',
            [clickStyleguide.hoverAccountMenu]: '#b193ec',
            [clickStyleguide.textColor]: '#500383',
            [clickStyleguide.topBarTextColor]: '#9770ef',
            [clickStyleguide.menuIconAndLinkColor]: '#af05f3',
            [clickStyleguide.topBarIconHoverColor]: '#6a3be0',
        },
        csprclickLightTheme: {
            [clickStyleguide.backgroundTopBarColor]: '#9d13cb',
            [clickStyleguide.backgroundMenuColor]: '#a15fe0',
            [clickStyleguide.hoverProductMenu]: '#693388',
            [clickStyleguide.hoverAccountMenu]: '#693388',
            [clickStyleguide.textColor]: '#c9b6ea',
            [clickStyleguide.topBarTextColor]: '#d8cae8',
            [clickStyleguide.menuIconAndLinkColor]: '#ec06c5',
            [clickStyleguide.topBarIconHoverColor]: '#ec06c5',
        },
}
```

Then, you need to inject newly created theme object into `buildTheme` constructor function alongside with `appDarkTheme` and `appLightTheme` if needed.

```tsx
export const AppTheme = buildTheme({
    ...newCustomTheme,
    appDarkTheme: {
        topBarSectionBackgroundColor: newCustomTheme.csprclickDarkTheme[clickStyleguide.backgroundTopBarColor],
        [clickStyleguide.textColor]: '#DADCE5',
        bodyBackgroundColor: newCustomTheme.csprclickDarkTheme[clickStyleguide.backgroundTopBarColor],
    },
    appLightTheme: {
        topBarSectionBackgroundColor: newCustomTheme.csprclickLightTheme[clickStyleguide.backgroundTopBarColor],
        [clickStyleguide.textColor]: '#1A1919',
        bodyBackgroundColor: newCustomTheme.csprclickLightTheme[clickStyleguide.backgroundTopBarColor],
    },
});
```

### Colors matching examples

`clickStyleguide` has a set of colors. Each color from `clickStyleguide` has its own corresponding area of usage and responsibility.

Here you can find all matching with colors and its corresponding area of usage on `<ClickUI>` component

* `csprclickDarkTheme` - stands for customise `<ClickUI>` component and all child or relative components in Dark mode.
* `csprclickLightTheme` - stands for customise `<ClickUI>` component and all child or relative components in Light mode.

Each of above properties has the same set of colors:

* `[clickStyleguide.backgroundTopBarColor]: 'blue'` - stands for whole `<ClickUI>` background color

Example on the screen below:

<figure><img src="/files/Jvu3j3fJl2Q3FmeuJpnf" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.backgroundMenuColor]: 'blue'` - stands for all dropdown backgrounds Applies for the following components: `<ProductMenu>`, `<AccountMenu>`, `<Currencies>`, `<Languages>`, `<Network>` and `<CustomSelect>` component.

Example on the screen below:

<figure><img src="/files/cvcFVK0h40KaYa2Yv68t" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/7BQf3uqzxnwUyIdPFLVf" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/Hmmawo8KJs4Gcs1KVfEc" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/DcrZJqDW2HpYuuoe4HW2" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.hoverProductMenu]: 'blue'` - stands for changing colour when hovering on items inside `<ProductMenu>`

Example on the screen below:

<figure><img src="/files/Jjzj1GrQbRtlHtsFYua9" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.hoverAccountMenu]: 'blue'` - stands for changing colour when hovering on items inside `<AccountMenu>`, `<Currencies>`, `<Languages>`, `<Network>` and `<CustomSelect>` component.

Example on the screen below:

<figure><img src="/files/HmC190aNPBq00S7ihAiH" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/hNu7NWZ5FGVZgdFtS2QD" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.textColor]: 'blue'` - stands for text colour inside each dropdown which is under `<ClickUI>`

Example on the screen below:

<figure><img src="/files/qEVlN2gpKxojhe2NDcty" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/cV0ZKbLtH2HfeZqhm4y8" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.topBarTextColor]: 'blue'` - stands for text colour specific for `<ClickUI` and `ClickModals` components

Example on the screen below:

<figure><img src="/files/iKvcdWb6j8MaUKNQdLPs" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/ABRrRx73V85EnoAnyZK4" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.topBarIconHoverColor]: 'blue'` - stands for changing colour when hovering on items which are on `<ClickUI>` component

Example on the screen below:

<figure><img src="/files/f1U43m3V22wqaZpyEqtt" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.menuIconAndLinkColor]: 'blue'` - stands for links and icons colour

Example on the screen below:

<figure><img src="/files/4TuEnZKxL5TRoG1rZMQ4" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/RG4gWt3kWDkOvRlgNJH9" alt=""><figcaption></figcaption></figure>

It's really easy and fast to create you own color theme! Enjoy the process!


# Add custom information badge

In case you want to add some information badge on the ClickTopBar, you can use `useClickBadge()` hook to do it. You need to import it from csprclick library

```tsx
import { useClickBadge } from '@make-software/csprclick-ui';
```

### `useClickBadge` structure

useClickBadge hook returns two functions: `setLeftBadge` and `setRightBadge`. Both are responsible to add info badge on specific ClickTopBar side. Each of these functions accepts the same set of parameters.\
Here the list of props for badge customization.

```tsx
export type BadgeSettings = {
        title: string;
        link?: string;
        color?: string;
        background: string;
   };
```

Here the example of having one badge with custom color, link and title on the left side of ClickTopBar:

```tsx
const ClickTopBar = ({ themeMode, onThemeSwitch }) => {

  const { setLeftBadge } = useClickBadge();

  setLeftBadge({
      title: `📄 Go to CSPR.click docs`,
      background: 'blue',
      color:'white',
      link: 'https://docs.cspr.click/'
  });

}
```

Then you should see the result: one left side badge with your own color, link and title. Like on the screen below:

<figure><img src="/files/594SpWNJTZT5FV9Sh3qJ" alt=""><figcaption></figcaption></figure>

To remove the badge but keep it ready to use in codebase you can add `null` as parameter

```tsx
    setLeftBadge(null);
```

So, to create your own custom badge dynamically, all you need is to use `useClickBadge()` hook and call `setLeftBadge` or `setRightBadge` functions.


# Hooks and Components

### Hooks

#### useClickRef() hook

In your components, you'll often need to call the CSPR.click API to get data or request an operation. To get a reference to the CSPR.click SDK instance make use of the `useClickRef()` React hook:

```tsx
import { useClickRef } from '@make-software/csprclick-ui';

function MyComponent() {
  const clickRef = useClickRef();
  ...
}
```

Then, in your application you'll be able to request CSPR.click to perform some operations using the class [methods](/cspr.click-sdk/reference/methods), or get values reading the class [properties](/cspr.click-sdk/reference/properties).

### Components

#### \<AccountIdenticon>

Use the `AccountIdenticon` component to display the public key identicon (or avatar). It can be used also with an account hash string.

<figure><img src="/files/okxxMH7qxWP33LfEWQCL" alt="AccountIdenticon component example"><figcaption></figcaption></figure>

In addition to the public key or account hash, indicate the size of the resulting image: `'xs'` for `16px`; `'sm'` for `20px`; `'m'` for `32px`; or `'l'` for `40px`.

```tsx
<AccountIdenticon hex={publicKey} size={'l'} />
```

The size can be indicated with a number of pixels:

```tsx
<AccountIdenticon hex={accountHash} size={40}  />
```


# Reference


# Properties

The following properties are available in `csprclick` global object after initialization.

### appName

```typescript
appName: string
```

Returns the name of the application. This name is set during the library initialization.

### appId

```typescript
appId: string
```

Returns the id of the application.

### casperNode

```typescript
casperNode: string
```

Returns the URL of the RPC interface CSPR.click uses to get or send information from/to the Casper network.

### chainName

```typescript
chainName: string
```

Returns the name of the Casper network the application interacts with.

### csprclickHost

```
csprclickHost: string
```

Returns the CSPR.click server.


# Methods

### connect

```typescript
connect(provider: string, options: any): Promise<AccountType|undefined>
```

Call the `connect()` method using a provider name as the first parameter to request a connection using that wallet or login mechanism.

Some providers may need an options argument to indicate the connection behavior requested.

### decryptMessage

```typescript
decryptMessage(encryptedMessage: string, signingPublicKey: string): Promise<DecryptMessageResult | undefined>;
```

Triggers the mechanisms to request your user to decrypt a message with the active wallet.

`signingPublicKey` MUST be the public key for the active account. Otherwise, this method will return an error.

A [DecryptMessageResult ](/cspr.click-sdk/reference/types#decryptmessageresult)object is returned with the decrypted message or an `error`.

### disconnect

```typescript
 disconnect(fromWallet: string, options?: any): void
```

Usually you will call `signOut()` method to close a user session. Use `disconnect()` when you want to clear the connection between the wallet and your app. Next time the user signs in with that wallet, he'll must gran connection permission again.

Send empty arguments or empty string to disconnect from currently active account. Or call disconnect with a wallet provider key to force the disconnection of a specific wallet.

### encryptMessage

```typescript
encryptMessage(message: string, signingPublicKey: string): Promise<EncryptMessageResult | undefined>;
```

Triggers the mechanisms to request the active wallet to encrypt a message with the user's public key.

`signingPublicKey` MUST be the public key for the active account. Otherwise, this method will return an error.

A [EncryptMessageResult ](/cspr.click-sdk/reference/types#encryptmessageresult)object is returned with the encrypted message or an `error`.

### forgetAccount

```typescript
forgetAccount(account: AccountType): void
```

Removes an account from the list of known accounts in CSPR.click. It won’t be returned to the list of known accounts unless it’s connected again using the `connect()` method.

### getAccountIdenticon

`typescript` getAccountIdenticon(hex: string, size: number = 20): HTMLCanvasElement

````

This method generates a `<canvas>` HTML element to display the account identicon (aka avatar) of the public key.

It can be used with an account hash to display the hash ('#') symbol instead of a public key identicon.

On React, the `<AccountIdenticon>` component is available to wrap the call to this method.

### getActiveAccount

```typescript
getActiveAccount(): AccountType | null 
````

Gets the account for the current session (if any). Or `undefined` if there is no active session.

### getActiveAccountAsync

```typescript
getActiveAccountAsync(options?: GetActiveAccountOptions): Promise<AccountType | null> 
```

Gets the account for the current session (if any). Returns `undefined` if there is no active session.

Pass `options.withBalance = true` to include the balance of the account.

### getActivePublicKey

```typescript
getActivePublicKey(): Promise<string | undefined>
```

Gets the public key for the current session (if any). Or undefined if no active session.

### getCsprCloudProxy

```typescript
getCsprCloudProxy(): ICsprCloudProxy
```

Returns a CSPR.cloud proxy object that can be used to interact with the CSPR.cloud REST and Streaming APIs, as well to set up an Node RPC client with `casper-js-sdk`.

### getProviderInfo

```typescript
getProviderInfo(provider?: string): Promise<ProviderInfo|undefined>
```

Returns a [ProviderInfo](/cspr.click-sdk/reference/types#providerinfo) object containing the information of the connected wallet, or the specified in the `provider` argument. Keep in mind that some information is only available if the wallet is connected (e.g. Version of Ledger can only be recovered if the hardware device is connected).

### getSignInOptions

```typescript
getSignInOptions(refresh: boolean = false): Promise<any>
```

Returns an object with a list of providers enabled to use in the application and a list of known accounts that can be used to sign in automatically with `signInWithAccount()`.

### init

```typescript
init(options: CsprClickInitOptions): void
```

Call `init` to initialize CSPR.click in your web application. This MUST be the first method you call after the downloading of the library.

See [CsprClickInitOptions ](/cspr.click-sdk/reference/types#csprclickinitoptions)for reference on the `options` parameter.

### isConnected

```typescript
isConnected(provider: string): Promise<boolean | undefined>
```

Checks if the provider (not the account) indicated as the first argument is connected to the application. Note this check is independent of whether there's an active account on CSPR.click or not or even if that account belongs to the given provider.

### isProviderPresent

```typescript
isProviderPresent(provider: string): boolean
```

Checks if the provider indicated as the first argument is enabled in the application and installed (in case it’s a browser extension).

### isUnlocked

```typescript
isUnlocked(provider: string): Promise<boolean | undefined>
```

Returns `true` if the provider is unlocked. `false` if the provider is locked.

This method returns `undefined` when the provider does not offer this information.

### send

```typescript
send(transactionJSON: string | object, 
     signingPublicKey: string,
     onStatusUpdate: ((status: string, data: any) => void) | undefined = undefined,
     timeout: number = 120
  ): Promise<SendResult | undefined>
```

Triggers the mechanisms to request your user to sign a transaction with the active wallet.

When the user approves the signature, CSPR.click sends the transaction to the Casper network. A [SendResult ](/cspr.click-sdk/reference/types#sendresult)object is returned with status information.

The `transactionJSON` is a json object (or a string) containing either a `Deploy` or a `TransactionV1`.

**Note:** If you're working with `Transaction` objects from `casper-js-sdk`, use the `transaction.toJSON()` method to get the object to pass as the first argument.

`signingPublicKey` MUST be the public key for the active account. Otherwise, this method will return an error.

Use `onStatusUpdate` to establish a websockets communication with CSPR.click backend and receive updates on the processing of the transaction sent.

There's a default waiting time of `120sec`. If the transaction is not processed in that time, the caller receives a `timeout` status update and the websocket connection is closed.

Example (see full example in CSPR.click project template):

```typescript
/* build a transaction object using Casper JS SDK */
const senderPk = activeAccount?.public_key?.toLowerCase() || '';
const transaction = new NativeTransferBuilder()
    .from(PublicKey.fromHex(senderPk))
    .target(PublicKey.fromHex(recipientPk))
    .amount('6' + '000000000')
    .id(Date.now())
    .chainName(clickRef.chainName!)
    .payment(100_000_000)
    .build();

/* define a status callback method to get updates during the transaction processing. 
   use this callback to update your UI on each step of the processing
*/
const onStatusUpdate = (status: string, data: any) => {
    console.log('STATUS UPDATE', status, data);
    if(status === TransactionStatus.SENT)
      setWaitingIndicator();
    if(status === TransactionStatus.PROCESSED)
      parseProcessedTransaction();
  };    

/* request a transaction signature and deploy the transaction via a node proxy */  
window.csprclick
  .send(transaction.toJSON() as object, sender, onStatusUpdate)
  .then((res: SendResult) => {
    // check result and update UI accordingly
  })
  .catch((err: any) => {
    alert('Error: ' + err);
    throw err;
  });
```

Check a list with possible processing status in the [SendResult](/cspr.click-sdk/reference/types#sendresult) type reference.

### sign

```typescript
sign(transactionJSON: string | object, signingPublicKey: string): Promise<SignResult | undefined>
```

Triggers the mechanisms to request your user to sign a transaction with the active wallet.

A [SignResult ](/cspr.click-sdk/reference/types#signresult)object is returned with the signature value or an `error`.

The `transactionJSON` is a json object (or a string) containing either a `Deploy` or a `TransactionV1`.

**Note:** If you're working with `Transaction` objects from `casper-js-sdk`, use the `transaction.toJSON()` method to get the object to pass as the first argument.

`signingPublicKey` MUST be the public key for the active account. Otherwise, this method will return an error.

### signIn

```typescript
signIn(): void
```

Triggers a request to a UI library to show a sign-in dialog.

### signInWithAccount

```typescript
signInWithAccount(account: AccountType): Promise<AccountType | undefined>
```

Starts a session with the indicated account. This account must be one of the accounts returned in `getKnownAccounts` or `getSignInOptions`.

Note that no interaction with the account provider is required to sign-in. CSPR.click will check and restore the connection if needed when there's a transaction or message to sign.

### signMessage

```typescript
signMessage(message: string, signingPublicKey: string): Promise<SignResult|undefined>
```

Triggers the mechanisms to request your user to sign a text message with the active wallet.

`signingPublicKey` MUST be the public key for the active account. Otherwise, this method will return an error.

### signTypedData

```typescript
signTypedData(params: SignTypedDataParams, signingPublicKey: string): Promise<SignTypedDataResult | undefined>
```

Triggers the mechanisms to request your user to sign EIP-712 typed structured data with the active wallet.

`signingPublicKey` MUST be the public key for the active account. Otherwise, this method will return an error.

A [SignTypedDataResult](/cspr.click-sdk/reference/types#signtypeddataresult) object is returned with the signature and digest, or an `error`.

See [SignTypedDataParams](/cspr.click-sdk/reference/types#signtypeddataparams) for the full description of the `params` argument.

For detailed information on the EIP-712 hashing and signing mechanisms as implemented for Casper, refer to the [casper-eip-712](https://github.com/casper-ecosystem/casper-eip-712) repository.

### signOut

```typescript
signOut(): void
```

Closes an active session in your dApp.

Triggers the [`csprclick:signed_out`](/cspr.click-sdk/reference/events#csprclick-signed_out) event.

### showBuyCsprUi

```typescript
showBuyCsprUi(): void
```

Displays the Buy CSPR widget. This widget allows the user to top-up his account with a credit card payment.

### switchAccount

```typescript
switchAccount(withProvider: string | undefined, options?: any): Promise<void>
```

Call this method to request to the specified wallet to offer the user the selection of a different account. This is valid for providers with its own UI (like browser extenstions).

Call this method without any provider to request CSPR.click UI to show the Switch Account modal window.


# Types

### AccountType

```
type AccountType = {
    provider: string,
    providerSupports: string[]|undefined,
    cspr_name: string | null,
    public_key: string | null,
    connected_at: Number,
    token: string | null,
    custom?: any,
    balance?: string,
    liquid_balance?: string;
    logo?: string;
}
```

<table><thead><tr><th width="201.33333333333331">Property</th><th>Description</th></tr></thead><tbody><tr><td>provider</td><td>The provider to which the account belongs to.</td></tr><tr><td>providerSupports</td><td>An array of supported capabilities in the connected wallet. Possible values: "sign-deploy", "sign-transactionv1", "sign-message".</td></tr><tr><td>cspr_name</td><td>CSPR.name name</td></tr><tr><td>public_key</td><td>The public key.</td></tr><tr><td>connected_at</td><td>Timestamp for the initial connection of the account</td></tr><tr><td>token</td><td>n/a (for future use)</td></tr><tr><td>custom</td><td>Custom data. Depends on the provider.</td></tr><tr><td>balance</td><td>Total balance of the account in CSPR motes (includes liquid +staked balance)</td></tr><tr><td>liquid_balance</td><td>Liquid balance of the account in CSPR motes (includes liquid +staked balance)</td></tr><tr><td>logo</td><td>A URL to the account avatar or logo.</td></tr></tbody></table>

### CsprClickInitOptions

```
type CsprClickInitOptions = {
    appName: string,
    appId: string,
    contentMode: 'iframe' | 'popup',
    casperNode?: string,
    chainName?: string,
    providers: Array<string>,
}
```

<table><thead><tr><th width="201.33333333333331">Property</th><th>Description</th></tr></thead><tbody><tr><td>appName</td><td>The name of your app as it will be shown in the pop-up windows.</td></tr><tr><td>appId</td><td>An application identifier. Read more about it <a href="/pages/XE4wdI9S2eIeAIJpWLRE">here</a>.</td></tr><tr><td>contentMode</td><td>Defines whether the sign in interface is shown within an iframe in your application or in external pop-up windows.</td></tr><tr><td>casperNode</td><td>The RPC endpoint CSPR.click uses to get information from the Casper network and to send deploys.</td></tr><tr><td>chainName</td><td>Use <code>casper</code> or <code>casper-test</code> to interact with Casper Mainnet or Casper Testnet, respectively.</td></tr><tr><td>providers</td><td>The list of providers (wallets) you want to allow in your application</td></tr><tr><td></td><td></td></tr></tbody></table>

The wallets you can add to the `providers` array are:

* `casper-wallet`
* `ledger`
* `metamask-snap`

### DecryptMessageResult

```
export type DecryptMessageResult = {
    cancelled: boolean;
    decryptedMessage: string | null;
    error: string | null;
}
```

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td>cancelled</td><td><code>true</code> when the user has declined the decryption of a message. <code>false</code> otherwise</td></tr><tr><td>decryptedMessage</td><td>String with the decrypted message.</td></tr><tr><td>error</td><td><code>null</code> if the message has been successfully decrypted. It contains an error message otherwise..</td></tr></tbody></table>

### EncryptMessageResult

```
export type EncryptMessageResult = {
    cancelled: boolean;
    encryptedMessage: string | null;
    error: string | null;
}
```

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td>cancelled</td><td><code>true</code> when the user has declined the encryption of a message. <code>false</code> otherwise</td></tr><tr><td>encryptedMessage</td><td>Hexadecimal string with the encrypted message bytes.</td></tr><tr><td>error</td><td><code>null</code> if the message has been successfully encrypted. It contains an error message otherwise..</td></tr></tbody></table>

### ProviderInfo

```
type ProviderInfo = {
    key: string,
    name: string,
    version: string,
    supports: Array<string>,
}
```

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td>key</td><td>Internal name of the provider (wallet).</td></tr><tr><td>name</td><td>Friendly/Huma readable name of the provider.</td></tr><tr><td>version</td><td>Version of the provider. Only available for some wallets, when they're installed and/or connected.</td></tr><tr><td>supports</td><td><p>Array of keys of the features supported. The values returned may depend on the connected version of the provider.</p><p>Currently, the possible supported features are: <code>sign-deploy</code>, <code>sign-transactionv1</code>, and <code>sign-message</code>.</p></td></tr></tbody></table>

### SendResult

```
type SendResult = {
    cancelled: boolean,
    deployHash: string | null,
    transactionHash: string | null,
    error: string | null,
    errorData: object | null,
    status: string | null;
    csprCloudTransaction: any;
}
```

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td>cancelled</td><td><code>true</code> when the user has declined the signature of the transaction. <code>false</code> otherwise</td></tr><tr><td>deployHash</td><td>The hash of the deploy signed and sent to the Casper network. <code>null</code> when the deploy signature has been cancelled or there was an error sending it to the network</td></tr><tr><td>error</td><td><code>null</code> if the deploy has been successfully signed and sent to the network. It contains an error message when the network rejects the deploy.</td></tr><tr><td>errorData</td><td>extra information on the error. It's usually a json object.</td></tr><tr><td>status</td><td>Indicates the status of the transaction sent. This property is helpful when used in combination with the `waitProcessing` in the `send()` method. Possible values: "sent", "processed", "created", "cancelled", "error", "timeout".</td></tr><tr><td>csprCloudTransaction</td><td>Raw json object returned by CSPR.cloud streaming API for a processed transaction. Check CSPR.cloud docs for detailed info on the contents.</td></tr></tbody></table>

### SignResult

```
type SignResult = {
    cancelled: boolean,
    signatureHex: string | null,
    signature: Uint8Array | null,
    deploy: object | null,
    transaction: object | null,
    error: string | null,
}
```

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td>cancelled</td><td><code>true</code> when the user has declined the signature of the transaction. <code>false</code> otherwise</td></tr><tr><td>signatureHex</td><td>An hexadecimal string with the crytpographic signature of the deploy.</td></tr><tr><td>signature</td><td>A byte array with the cryptographic signature of the deploy.</td></tr><tr><td>deploy</td><td>A json object containing the deploy with the user approval entry (i.e., the new signature).</td></tr><tr><td>error</td><td><code>null</code> if the deploy has been successfully signed. It contains an error message otherwise.</td></tr></tbody></table>

### SignTypedDataParams

```
type SignTypedDataParams = {
    typedData: {
        domain: Record<string, unknown>;
        types: Record<string, Array<{ name: string; type: string }>>;
        primaryType: string;
        message: Record<string, unknown>;
    };
    options?: {
        domainTypes?: Array<{ name: string; type: string }>;
        returnHashArtifacts?: boolean;
        rejectUnknownFields?: boolean;
    };
}
```

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td>typedData.domain</td><td>EIP-712 domain object (e.g. <code>name</code>, <code>version</code>, <code>chain_name</code>, and <code>contract_package_hash</code>).</td></tr><tr><td>typedData.types</td><td>Map of type names to their field definitions, following EIP-712 conventions.</td></tr><tr><td>typedData.primaryType</td><td>The top-level type to sign (must be a key in <code>types</code>).</td></tr><tr><td>typedData.message</td><td>The structured data object to sign, matching the schema of <code>primaryType</code>.</td></tr><tr><td>options.domainTypes</td><td>Optional explicit domain field definitions for hashing. When omitted, the wallet uses <code>typedData.types.EIP712Domain</code> if present.</td></tr><tr><td>options.returnHashArtifacts</td><td>When <code>true</code>, the response includes intermediate hash artifacts (domain separator, struct hash, etc.) in the <code>hashArtifacts</code> field of <a href="#signtypeddataresult">SignTypedDataResult</a>.</td></tr><tr><td>options.rejectUnknownFields</td><td>When <code>true</code>, the wallet MUST reject the request if the message contains fields not declared in <code>types</code>.</td></tr></tbody></table>

Example:

```json
{
    "typedData": {
        "domain": {
            "name": "Wrapped CSPR",
            "version": "1",
            "chain_name": "casper:casper-test",
            "contract_package_hash": "3d80df21ba4ee4d66a2a1f60c32570dd5685e4b279f6538162a5fd1314847c1e"
        },
        "types": {
            "TransferWithAuthorization": [
                {
                    "name": "from",
                    "type": "address"
                },
                {
                    "name": "to",
                    "type": "address"
                },
                {
                    "name": "value",
                    "type": "uint256"
                },
                {
                    "name": "validAfter",
                    "type": "uint256"
                },
                {
                    "name": "validBefore",
                    "type": "uint256"
                },
                {
                    "name": "nonce",
                    "type": "bytes32"
                }
            ]
        },
        "primaryType": "TransferWithAuthorization",
        "message": {
            "from": "00a13d2ae9e961c0f8abfca595d330511aa2b82acd8df6d1642dc80d3c7ca22977",
            "to": "00aa35d1c9dcaadea97c34d79b55b6af07aa9d760e5dd1aabf78a45fb39e0723fa",
            "value": 7500000000,
            "validAfter": 1780556982,
            "validBefore": 1780560582,
            "nonce": "17a0406a474c8dc0ac00889901001fdec05f21a0e204f99c8c5005c416bfe910"
        }
    },
    "options": {
        "returnHashArtifacts": true
    }
}
```

### SignTypedDataResult

```
type SignTypedDataResult = {
    cancelled: boolean;
    signatureHex: string | null;
    digest: string | null;
    publicKey: string | null;
    error: string | null;
    errorCode?: SignTypedDataErrorCode;
    hashArtifacts?: EIP712HashArtifacts;
}
```

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td>cancelled</td><td><code>true</code> when the user has declined the signing operation. <code>false</code> otherwise.</td></tr><tr><td>signatureHex</td><td>Prefixed signature hex (01 for ed25519, 02 for secp256k1) followed by the signature bytes, or <code>null</code> if cancelled or failed.</td></tr><tr><td>digest</td><td>0x-prefixed 32-byte hex digest that was signed, or <code>null</code> if cancelled or failed.</td></tr><tr><td>publicKey</td><td>Prefixed public key used for signing, or <code>null</code> if cancelled or failed.</td></tr><tr><td>error</td><td><code>null</code> if the operation succeeded. Contains an error message otherwise.</td></tr><tr><td>errorCode</td><td>Machine-readable error code. See <a href="#signtypeddataerrorcode">SignTypedDataErrorCode</a> for possible values.</td></tr><tr><td>hashArtifacts</td><td>Intermediate hash artifacts for debugging. Only present when <code>returnHashArtifacts</code> was <code>true</code> in the request options. See <a href="#eip712hashartifacts">EIP712HashArtifacts</a>.</td></tr></tbody></table>

### SignTypedDataErrorCode

A string union of machine-readable error codes returned in [SignTypedDataResult](#signtypeddataresult).

| Value                            | Description                                                       |
| -------------------------------- | ----------------------------------------------------------------- |
| `USER_REJECTED`                  | The user declined the signing request.                            |
| `INVALID_PARAMS`                 | The request parameters are malformed or missing required fields.  |
| `UNSUPPORTED_TYPE`               | The wallet does not support the requested type definition.        |
| `DOMAIN_TYPES_REQUIRED`          | Domain type definitions are required but were not provided.       |
| `SIGNATURE_SCHEME_NOT_SUPPORTED` | The account's key scheme is not supported for typed data signing. |
| `ACCOUNT_NOT_FOUND`              | The requested account could not be found in the wallet.           |
| `NOT_AUTHORIZED`                 | The wallet rejected the request due to an authorization failure.  |

### EIP712HashArtifacts

Intermediate hashing artifacts returned in [SignTypedDataResult](#signtypeddataresult) when `options.returnHashArtifacts` is `true`.

```
type EIP712HashArtifacts = {
    domainTypeString?: string;
    domain?: Record<string, unknown>;
    domainSeparator?: string;
    canonicalTypeString?: string;
    typeHash?: string;
    structHash?: string;
}
```

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td>domainTypeString</td><td>The encoded EIP-712 domain type string used for hashing.</td></tr><tr><td>domain</td><td>The domain object as used during hashing.</td></tr><tr><td>domainSeparator</td><td>0x-prefixed domain separator hash.</td></tr><tr><td>canonicalTypeString</td><td>Canonical type string for the primary type.</td></tr><tr><td>typeHash</td><td>0x-prefixed type hash.</td></tr><tr><td>structHash</td><td>0x-prefixed struct hash of the message.</td></tr></tbody></table>


# Events

The CSPR.click library emits several events you may need to handle to update your app accordingly.

Listen to these events calling the `on()` method with a callback handler. For example:

```typescript
csprclick.on('csprclick:signed_in', async (evt) => {
  //update your app content for the new session
  console.log("Connected account: " + evt.account.public_key)
});
```

### csprclick:loaded

This event is emitted when the CSPR.click library initialization is complete. Usually, you shouldn’t call any method in the library (apart from init()) before this event occurs.

Use `once()` to bind the callback handler instead of `on()` for this event since it’s triggered only once.

### csprclick:signed\_in

This event is emitted when the CSPR.click library connects to a new account. Previously, either `csprclick.connect()` or `csprclick.signInWithAccount()` methods must have been called by the application.

Receives an [AccountType](/cspr.click-sdk/reference/types#accounttype) object with data about the newly connected account.

### csprclick:switched\_account

This event is emitted when CSPR.click library switches connection from one account to another after the application has called `csprclick.switchAccount()` method.

Receives an [AccountType ](/cspr.click-sdk/reference/types#accounttype)object with data about the newly connected account.

### csprclick:unsolicited\_account\_change

This event is emitted when there's an account connected to the application and the user changes the active account in his wallet, but the application hasn't requested the change calling `connect()` or `switchAccount()` methods.

When CSPR.click UI SDK is being used, the application shows a pop up notice where the user can confirm if he wants to switch the current session to the new account or keep the current one.

If you're not using CSPR.click UI SDK, your application should define a handler for this event and confirm the account change by calling `signInWithAccount()` method. For example:

```typescript
csprclick.on('csprclick:unsolicited_account_change', async (evt) => {
  window.csprclick.signInWithAccount(evt.account);
});
```

When the new account is connected, the SDK will emit the event `csprclick:signed_in`.

### csprclick:signed\_out

This event is emitted when the CSPR.click library disconnects the active account due to a call to the `signOut()` SDK method.

### csprclick:disconnected

This event is emitted when CSPR.click library receives a disconnect request or event from the connected wallet. The app should close the current session as a consequence of this event.

Receives the provider that has been disconnected.

### csprclick:sign\_in

Indicates that the signIn() method has been called. In your app, you should typically respond to these event showing the sign-in options to the user (e.g. list of wallets, list of known accounts, etc.).


# CSPR.cloud proxies

CSPR.click provides a proxy to interact with the CSPR.cloud REST and Streaming APIs, as well as to set up a Node RPC client with `casper-js-sdk`. This is helpful when you want to interact with the CSPR.cloud APIs from the frontend of your application, as CSPR.cloud APIs require authentication and you must not expose your API keys in the frontend.

## Configuration of CSPR.cloud proxy on CSPR.build

The proxy functionality is disabled by default to protect your CSPR.cloud usage quota. To enable it, you need to edit your CSPR.click app configuration on [CSPR.build](https://console.cspr.build).

Enable only the proxies you need and only for the methods you require in your frontend application for better security.

## REST API proxy

The REST API proxy allows you to interact with the [CSPR.cloud REST APIs](https://docs.cspr.cloud/rest-api/reference) from the frontend of your application. The proxy will add the necessary authentication headers to your requests.

Use the `fetch()` method of the `ICsprCloudProxy` instance obtained from the `getCsprCloudProxy()` method. The method signature is the same as the `fetch()` method of the browser's `window` object.

Example of calculating the current APY:

```typescript
const getAPY = async () => {
  const cloudProxy = window.csprclick.getCsprCloudProxy();
  const metrics = await cloudProxy.fetch('/auction-metrics?includes=total_active_era_stake');
  const supply = await cloudProxy.fetch('/supply');
  
  const totalStakeInMotes = Big(metrics.data.total_active_era_stake).div(1000000000);
  
  return Big(supply.data.total)
    .mul(supply.data.annual_issuance)
    .div(totalStakeInMotes)
    .toString();
};
```

## Streaming API proxy

The Streaming API proxy allows you to interact with the [CSPR.cloud Streaming APIs](https://docs.cspr.cloud/streaming-api/reference) from the frontend of your application. The proxy will add the necessary authentication headers to your requests.

Use the `newWebSocket()` method of the `ICsprCloudProxy` instance obtained from the `getCsprCloudProxy()` method. The method returns a [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) instance.

Example of setting up a WebSocket connection to listen for native transfers:

```typescript
  const proxy = window.csprclick.getCsprCloudProxy();
  // @ts-ignore
  const ws = proxy.newWebSocket('/transfers');

  // Set up event listeners
  ws.onopen = (event) => {
    console.log('WebSocket connection opened:', event);
  };

  ws.onmessage = (event) => {
    console.log('WebSocket message received:', event.data);

    // Try to parse JSON if possible
    try {
      const parsedData = JSON.parse(event.data);
      console.log('Parsed WebSocket data:', parsedData);
    } catch (error) {
      console.log('WebSocket data (raw):', event.data);
    }
  };

  ws.onerror = (error) => {
    console.error('WebSocket error:', error);
  };

  ws.onclose = (event) => {
    console.log('WebSocket connection closed:', event.code, event.reason);
  };
```

### Node RPC client proxy

The Node RPC client proxy allows you to interact with the Casper node RPC interface from the frontend of your application. In this case, CSPR.click provides you with the proxy URL and a token to use with the `RpcClient` class from the `casper-js-sdk` library.

```typescript
  const proxy = window.csprclick.getCsprCloudProxy();
  const rpcHandler = new HttpHandler(proxy.RpcURL, 'fetch');
  rpcHandler.setCustomHeaders({ Authorization: proxy.RpcDigestToken });
  const rpcClient = new RpcClient(rpcHandler);

  const stateRootHash = await rpcClient.getStateRootHashLatest();
  console.log('State root hash:', stateRootHash.stateRootHash.toHex());
```


# Contact us

Should you have any questions about CSPR.click or need assistance with the integration, please join our telegram channel CSPR Developers Group with this link:

* CSPR Developers Group: <https://t.me/CSPRDevelopers>


# Introduction

<figure><img src="/files/mqnW7sgLBflO0JYe2oOc" alt="" width="563"><figcaption></figcaption></figure>

CSPR.click is a unified SDK that simplifies Web3 application onboarding by offering seamless integration with all wallets, facilitating easy user transitions between Web3 apps, and providing developers and users a consistent and secure interface for managing Web3 assets and interactions.

This documentation compiles important guidelines on how to use the CSPR.click SDKs.

## Components

* **Wallet Aggregator**. One integration for seamless compatibility with every Casper wallet.
* **Social Logins**. Simplify onboarding with instant access via Google, Apple, and more.
* **Fiat On-Ramps**. Purchase CSPR instantly using your card or wire transfer.
* **CSPR.cloud Proxy**. Connect directly to CSPR.cloud APIs — no backend required.

## Reference

To get familiar with CSPR.click, we recommend that you read these documents:

* [Overview](/cspr.click-v1.12/documentation/overview)\
  Learn about the general technical aspects of CSPR.click SDK, and how it works.
* [Getting started](/cspr.click-v1.12/documentation/getting-started)\
  Learn the basic concepts while creating a dApp from zero with CSPR.click React template.

## Support

If you have any questions or run into any issues while using the CSPR.click SDKs, you can find help in the [CSPR.click Developer Community](https://t.me/CSPRDevelopers). Here you can connect and get help from other developers.

## Legal

By using CSPR.click, you agree to our [Developer Terms of Service](https://cspr.click/terms-of-service/) and acknowledge that you have read our [Privacy Policy](https://cspr.click/privacy-policy/).


# Overview

In any web application that integrates CSPR.click you'll be using the Core JS SDK. It provides the essential functionality to interact with wallets and the CSPR.click servers. Through it, you'll request a connection with a wallet to start a user session, and ask the user to sign a transaction or a message. You'll get a complete graphical interface that manages for you the interactions with the user to perform the account management and the signature requests operations.

## Get your application Id

To initialize CSPR.click library, you need an `appId` for your application. By default, our examples use the `csprclick-template` identifier. You may use this value to try CSPR.click out and start developing your application.

Note, though, that this identifier is *only valid for development on `localhost`*. Before you push your application to a server, you must get your own `appId` on [console.cspr.build](https://console.cspr.build).

## Supported wallets

CSPR.click supports every wallet built for the Casper ecosystem.

<table><thead><tr><th width="120">Wallet</th><th>Provider key</th><th>Name</th></tr></thead><tbody><tr><td><img src="/files/8bhRvRprUFMeCRu3cBn7" alt="Casper Wallet logo"></td><td><code>casper-wallet</code></td><td>Casper Wallet</td></tr><tr><td><img src="/files/2WkfEWcF8hUtnHlSYWio" alt="Ledger logo"></td><td><code>ledger</code></td><td>Ledger</td></tr><tr><td><img src="/files/2K7AZPgLe4ITbM3LF4TK" alt="WalletConnect logo"></td><td><code>walletconnect</code></td><td>WalletConnect</td></tr><tr><td><img src="/files/bnyQ4O8IFLClIYCyHo6d" alt="Metamask logo"></td><td><code>metamask-snap</code></td><td>Metamask (Snap)</td></tr></tbody></table>

In your application, you can decide which wallets you want to enable. To do so, set accordingly the array of providers in the [CsprClickInitOptions ](https://github.com/make-software/casper-click-websdk/blob/documentation-v1.12/docs/csprclick-sdk/reference/types.md#csprclickinitoptions)initialization object.

```javascript
const clickOptions: CsprClickInitOptions = {
    appName: 'CSPR.playground',
    appId: 'csprclick-template',
    contentMode: CONTENT_MODE.IFRAME,
    providers: [
        WALLET_KEYS.CASPER_WALLET,
        WALLET_KEYS.LEDGER,
        WALLET_KEYS.METAMASK_SNAP,
    ],
};
```

### WalletConnect

WalletConnect is a protocol that provides a secure and convenient way for users to interact with decentralized applications. CSPR.click supports WalletConnect as a provider, allowing users to connect their WalletConnect-compatible wallets to your application.

To use WalletConnect with CSPR.click, you need to have a WalletConnect project ID. You can get one by creating a project on the [WalletConnect Cloud](https://dashboard.reown.com/).

Once you have your project ID, you can add it to your CSPR.click initialization options like this:

```javascript
const clickOptions: CsprClickInitOptions = {
    appName: 'CSPR.playground',
    appId: 'csprclick-template',
    contentMode: CONTENT_MODE.IFRAME,
    providers: [
        WALLET_KEYS.CASPER_WALLET,
        WALLET_KEYS.LEDGER,
        WALLET_KEYS.METAMASK_SNAP,
        WALLET_KEYS.WALLET_CONNECT,
    ],
    walletConnect: {
        relayUrl: 'wss://relay.walletconnect.com',
        projectId: '6cdf3...9cc4d'
    }
};
```


# Getting started

This page guides you through the steps to create a new React application for your project with CSPR.click UI SDK integrated and ready to use.

{% hint style="info" %}
If you want to integrate CSPR.click JS SDK into your existing React 18 application, go to the [React](/cspr.click-v1.12/cspr.click-sdk/react) section. If you're not using React 19, or you don't use React in your application, you can also integrate CSPR.click following the steps described in the [Javascript](/cspr.click-v1.12/cspr.click-sdk/javascript) section.
{% endhint %}

## Create a new React project

To create a new React project with CSPR.click ready to use, write the following command in a terminal session:

```
npx create-react-app my-casper-app --template @make-software/csprclick-react
```

Next, go to the newly created project directory and run the app:

```
cd my-casper-app
npm start
```

Your new app will open in your browser. If it doesn't, browse to the URL: <http://localhost:3000>.

<figure><img src="/files/COyvEVnG72vmhBtEdMjM" alt=""><figcaption><p>Your new application</p></figcaption></figure>

## Adjust the initialization options

Your new project comes with some default initialization options. You'll need to review them and adjust some.

Open the file `src/index.tsx` and locate the definition of the `clickOptions` variable. It'll look similar to this:

```typescript
import { CONTENT_MODE } from '@make-software/csprclick-core-types';

const clickOptions: CsprClickInitOptions = {
    appName: 'CSPR.app',
    appId: 'csprclick-template',
    contentMode: CONTENT_MODE.IFRAME,
    providers: [
        'casper-wallet',
        'ledger',
        'casper-signer',
    ]
};
```

You can use the default `csprclick-template` application identifier while you're working locally on your application. But to upload your new project to a server, you'll need to [get your own application id](/cspr.click-v1.12/documentation/overview).

Update the properties according to your needs. Read more about the [CsprClickInitOptions ](/cspr.click-v1.12/cspr.click-sdk/reference/types#csprclickinitoptions)type in the Core JS SDK reference.

These options are sent to CSPR.click through the `<ClickProvider>` component that wraps your main application component:

```tsx
<ClickProvider options={clickOptions}>
  <App/>
</ClickProvider>
```

## What's next

You're almost ready to start developing the next web3 killer app. Before you get cracking on your project, get familiar with some crucial aspects of CSPR.click that are demonstrated in the template:

#### Responding to CSPR.click events

The `App` component sets handlers to listen and respond to events triggered by CSPR.click when the user connects an account, switches to a different one, or closes the session.

Refer to the [Handling events](/cspr.click-v1.12/cspr.click-sdk/react/handling-events) page for information on how to add your listener functions.

#### Customize the top navigation bar

The template displays some settings selectors in the top navigation bar. Find the `ClickTopBar` component in `src/components/ClickTopBar/index.tsx` and see how these settings are defined.

Refer to the [Customizing the top bar](/cspr.click-v1.12/cspr.click-sdk/react/customizing-the-top-bar) section for complete reference on how to work with each of the setting elements in the top bar.

#### Request transaction approvals

At some point, your application will need to interact with the Casper network by sending a transaction (aka deploy).\
CSPR.click manages this process communicating with the active wallet to request the user to approve or reject the transaction. The UI depends on the wallet.

The template includes the `BuyMeACoffee` components to demonstrate how to request a transaction signature and send the approved deploy to the network.

Refer to the [Signing transactions](/cspr.click-v1.12/cspr.click-sdk/react/signing-transactions) page for information on how to request the user a transaction approval. Also, look at [Processing status updates](https://github.com/make-software/casper-click-websdk/blob/documentation-v1.12/docs/public/javascript/processing-status-updates.md) for information on how to listen for real-time status updates.

#### Leverage CSPR.cloud Proxy

CSPR.click provides a proxy to interact with the CSPR.cloud REST and Streaming APIs, as well as to set up a Node RPC client with `casper-js-sdk`. This is helpful when you want to interact with the CSPR.cloud APIs from the frontend of your application, as CSPR.cloud APIs require authentication and you must not expose your API keys in the frontend.

Refer to the [CSPR.cloud API proxies](/cspr.click-v1.12/cspr.click-sdk/reference/cloud-proxies) page for information on how to use the proxy.


# Changelog

*Note: patch versions are not released as npm packages if interfaces haven't changed with respect to the previous version.*

## v1.12.0 - November 7th, 2025

* New CSPR.cloud proxy client. Use the proxy client to interact with CSPR.cloud REST and Streaming APIs, , or set up a Node RPC client with `casper-js-sdk` directly from your frontend application when you don't operate a separate backend. For more info, see the new article [CSPR.cloud API proxies](/cspr.click-v1.12/cspr.click-sdk/reference/cloud-proxies) in the reference section.
* Moved all types to the package `@make-software/csprclick-core-types`. Now you don't need to install `@make-software/csprclick-core-client`.
* Added the method `showBuyCsprUi()` to display the Buy CSPR widget. It replaces previous SDK method `showByCsprUi()` which is now deprecated and will be removed in a future version.

{% hint style="info" %}

### Migration guide

Upgrading to `v1.12.0` from a previous version may require some changes in your code.

1. Remove `@make-software/csprclick-core-client` from your dependencies.
2. Change all types imported from `@make-software/csprclick-core-client` to be imported from `@make-software/csprclick-core-types`.
3. Use the interface `ICSPRClickSDK` to keep instances of the SDK instead of the class `CSPRClickSDK`.
4. Change calls to `showByCsprUi()` to `showBuyCsprUi()`. The first method will be removed in a future version.
   {% endhint %}

## v1.11.0 - October 13th, 2025

* Enhanced WalletConnect sign in flows for a better user experience with Casper Wallet Mobile.

## v1.10.0 - September 12th, 2025

* new `<AccountCardMenuItem>` component to display account information in the account dropdown menu (includes account name, public key and liquid/total balances). Replaces `<ViewAccountOnExplorerMenuItem>`.

## v1.9.0 - July 22th, 2025

* new `onStatusUpdate` in the `send()` methods arguments. When used, CSPR.click opens a websockets connection with CSPR.cloud backend to receive processing status updates for the deployed transaction.
* Integration with Google Sign in and Apple Id for CSPR.click web wallet.

## v1.8.0 - Apr 30th, 2025

* new `providerSupports` property in the account object to indicate if the connected wallet supports signing with the `TransactionV1` transaction model.
* CSPR.name enhanced support.

## v1.7.0 - Dec 23rd, 2024

* Support for the new transaction model `TransactionV1`.
* Updated Casper Wallet, Ledger, and Metamask Snap integrations to newest versions (all support now Casper 2.0).
* Deprecation notice for CasperDash wallet.

## v1.6.0 - Oct 16th, 2024

* Enhanced colors customization for the CSPR.click top bar UI elements.

## v1.5.0 - July 18th, 2024

* Torus and Casper Signer deprecation notices. These wallets will be removed in the next minor version.
* Added CSPR.name names to accounts in the UI overlays.

## v1.4.0 - Mar 5th, 2024

* Added Casper Wallet mobile universal links to enhance the user experience on mobile applications.
* New JWT provider for CSPR.click web wallet.
* New identicon component available to developers.

## v1.3.0 - Jan 19th, 2024

{% hint style="info" %}
**Important note if you're upgrading your app to `1.3.0` from a previous version.** `<ClickTopBar>` component has been replaced with new `<ClickUI>` component. The latter permits a more granular configuration for the elements that the developer wants to display in their application. For example, to not include the top navigtaion bar.

Check [this](https://docs.cspr.click/ui-sdk/integrating-the-ui-sdk-into-your-application#add-less-than-clickui-greater-than-component-to-your-app) section for `<ClickUI>` component reference.
{% endhint %}

* New Buy CSPR UI to select between different onramp platforms.
* Integration with Ramp.
* CSPR.click navigation bar is now optional. Applications that have their own controls for signing in and displaying connected accounts, can exclude this component.

## v1.2.1 - Jan 8th, 2024

* fixed a bug that caused people using different Ledger devices to not be able to sign in with the second device without signing out and reloading the web page.
* fixed a bug that might cause transaction signature rejection when the user had different accounts in different tabs for the same application.
* UI fixes

## v1.2.0 - Dec 12th, 2023

* new API csprclick.switchAccount() to trigger the UI that permits to connect to another account.
* Previously used accounts are now shown in most recently used order.
* UI fixes.
* new API csprclick.switchAccount() to trigger the UI that permits to connect to another account.
* Previously used accounts are now shown in most recently used order.
* UI fixes.

## v1.1.4 - Dec 1st, 2023

* CSPR.click now detects if it's running within a mobile wallet in-app browser to skip wallet selection UI in sign-in flow.
* Ledger now works on Android devices.
* UI now shows an animation in account widget during loading.
* CSPR.click now display a warning if Casper app version in the Ledger device is outdated.

## v1.1.0 - Nov 1st, 2023

* Added Buy CSPR menu item to account dropdown menu.
* UI/UX improvements.

## v1.0.0 - Oct 10th, 2023

* Initial release.


# React

{% hint style="info" %}
To create a new application with CSPR.click already integrated, we recommend you to use the `create-react-app` template as described in [Getting started](/cspr.click-v1.12/documentation/getting-started).
{% endhint %}

This page guides you through the steps required to integrate the CSPR.click SDK into your existing React web application.

## Install CSPR.click packages

Run the following command in a terminal window to install CSPR.click packages:

```bash
npm install --save-dev @make-software/csprclick-ui @make-software/csprclick-core-client @make-software/csprclick-core-types
```

If you're using Typescript, the command above also installs type definitions for CSPR.click.

## ClickProvider context provider

First, define the initialization options for the CSPR.click library:

```typescript
import { CONTENT_MODE } from '@make-software/csprclick-core-types';

const clickOptions: CsprClickInitOptions = {
    appName: 'Casper dApp',
    appId: 'csprclick-template',
    contentMode: CONTENT_MODE.IFRAME,
    providers: ['casper-wallet', 'ledger', 'metamask-snap', 'casperdash'],
};
```

Next, wrap your main application component with the `<ClickProvider>` context provider:

```tsx
<ClickProvider options={clickOptions}>
  <App />
</ClickProvider>
```

This component will manage the download and initialization of the CSPR.click runtime library.

Read more about the [CsprClickInitOptions ](/cspr.click-v1.12/cspr.click-sdk/reference/types#csprclickinitoptions)type in the SDK reference section.

{% hint style="info" %}
You can use the default `csprclick-template` application identifier while you're working locally on your application. But to upload your new project to a server, you'll need to [get your own application id](https://github.com/make-software/casper-click-websdk/blob/documentation-v1.12/docs/overview.md).
{% endhint %}

## Add \<ClickUI> component to your app

All the CSPR.click UI elements are managed from the `<ClickUI>` component. This component must be added to the very beginning of your main UI component and it's responsible for displaying the top bar and all the modal windows and pop-ups needed for connecting with wallets, showing information to the user, etc.

```tsx
const topBarSettings = {
    accountMenuItems: [<ViewAccountOnExplorerMenuItem key='0' />],
}

const App = () => {
    return (
        <!-- ... -->
        <ClickUI topBarSettings={topBarSettings}/>
        <!-- ... -->
    )
}
```

Refer to the [Customizing the top bar ](/cspr.click-v1.12/cspr.click-sdk/react/customizing-the-top-bar)section in this guide for complete reference on how to work with each of the setting elements in the top bar.

{% hint style="info" %}
While we recommend to include the CSPR.click top bar in your application, if you have your own Sign in and session management controls you can opt-out. To do so, do not include the `topBarSettings` prop to `ClickUI` and CSPR.click won't render the top bar.
{% endhint %}

## Add CSPR.click styles

### Option 1: your application uses styled-components

When your application already uses the \<ThemeProvider> component from styled-components library, you just need to add CSPR.click styles to your themes.

Considering as an example that your application has `light` and `dark` themes, you may merge the styles into your theme settings like this:

```typescript
import { CsprClickThemes } from '@make-software/csprclick-ui';

const YourAppThemes = {
	dark: {
		...CsprClickThemes.dark,
		// your styles for dark theme here
	},
	light: {
		...CsprClickThemes.light,
		// your styles for light theme here
	},
};
```

### Option 2: your application doesn't use styled-components

CSPR.click requires the `styled-components` library to work. Add it to your dependencies by running the command:

```
npm install --save styled-components@5.3.9
```

Next, add the theme provider to your application:

```tsx
import { CsprClickThemes } from '@make-software/csprclick-ui';

<ThemeProvider theme={CsprClickThemes.light}>
  <ClickProvider options={clickOptions}>
    <App />
  </ClickProvider>
</ThemeProvider>
```

Currently, you can choose between two themes: `light` and `dark`.

### Import required fonts

In your main CSS file, import the Inter and Jetbrains mono fonts:

```
@import url('https://fonts.cdnfonts.com/css/inter');

@font-face {
    font-family: 'JetBrains Mono';
    src: url('https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff2/JetBrainsMono-Regular.woff2')
        format('woff2'),
      url('https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff/JetBrainsMono-Regular.woff')
        format('woff');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
  }
```

## What's next

At this point, your application is prepared to display the CSPR.click UI to interact with the user and connect with wallets, switch to other accounts and approve transactions. Build and run your application, and take a look.

From here, your application needs to interact with CSPR.click library to, for example, respond to wallet connection and request transaction approvals. Go through the following sections as required to complete the integration:

#### Listen to CSPR.click events

You'll need to listen and respond to some events triggered when the user connects an account, switches to a different one, or closes the session.

Refer to the [Handling events](/cspr.click-v1.12/cspr.click-sdk/react/handling-events) page for information on how to add your listener functions.

#### Ask the user to connect a wallet

If you don't display the CSPR.click top navigation bar, you must have your own Sign in or Connect buttons and respond calling the CSPR.click library .

Refer to the [Connecting a wallet](/cspr.click-v1.12/cspr.click-sdk/react/connecting-a-wallet) page for information on how to trigger the wallet connection process.

#### Request transaction approvals

At some point, your application will need to interact with the Casper network by sending a transaction (aka deploy).\
CSPR.click manages this process communicating with the active wallet to request the user to approve or reject the transaction. The UI depends on the wallet.

Refer to the [Signing transactions](/cspr.click-v1.12/cspr.click-sdk/react/signing-transactions) page for information on how to request the user a transaction approval. Also, look at [Processing status updates](/cspr.click-v1.12/cspr.click-sdk/react/processing-status-updates) for information on how to listen for real-time status updates.

#### Customize the top navigation bar

You can add any of our predefined settings selectors or account menu items. And you can define your own.

Refer to the [Customizing the top bar](/cspr.click-v1.12/cspr.click-sdk/react/customizing-the-top-bar) section for complete reference on how to work with each of the setting elements in the top bar.


# Handling events

In your application, you'll need to listen and respond to different events emitted by the CSPR.click library. On this page, we're covering the most common. Check the [Events](/cspr.click-v1.12/cspr.click-sdk/reference/events) page for a complete list of events.

The following code snippet shows an example of how to bind your handlers to the CSPR.click events with the React `useEffect()` hook:

```tsx
const clickRef = useClickRef();

useEffect(() => {
  clickRef?.on('csprclick:signed_in', async (evt) => {
    // update your app accordingly
  });
  clickRef?.on('csprclick:signed_out', async (evt) => {
    // update your app accordingly
  });
}, [clickRef?.on]);
```

### csprclick:signed\_in

This event is emitted every time the CSPR.click library connects to an account.

[csprclick:signed\_in](/cspr.click-v1.12/cspr.click-sdk/reference/events#csprclick-signed_in) reference.

### csprclick:switched\_account

This event is emitted instead of `csprclick:signed_i` when the user has clicked on the Switch Account menu item and has switched to another account in the same or a different wallet.

[csprclick:switched\_account](/cspr.click-v1.12/cspr.click-sdk/reference/events#csprclick-switched_account) reference.

### csprclick:signed\_out

This event is emitted when the CSPR.click library disconnects the active account due to a call to the `signOut()` SDK method.

[csprclick:signed\_out](/cspr.click-v1.12/cspr.click-sdk/reference/events#csprclick-signed_out) reference.

### csprclick:disconnected

This event is emitted when CSPR.click library receives a disconnect request or event from the connected wallet. The app should close the current session as a consequence of this event.

It receives in the event object the provider that has been disconnected.

[csprclick:disconnected](/cspr.click-v1.12/cspr.click-sdk/reference/events#csprclick-disconnected) reference.


# Connecting a wallet

If you're not displaying the top navigation bar you'll need to have you own UI components to let the user connect a wallet, display the connected account, switch to another account, and disconnect. In this page we're describing how to use the CSPR.click library to perform these operations.

## Sign in

When the user clicks on your 'Sign in' or 'Connect wallet' button, call the `signIn()` method to display the wallet selector window:

```tsx
clickRef.signIn()
```

This method returns immediately. Listen to the library events to get a notification of connection.

## Switch account

To let the user to change to another account, call the `switchAccount()` method:

```tsx
clickRef.switchAccount()
```

This method returns immediately. Listen to the library events to get a notification of connection.

## Disconnect

To close the current user session, call the `signOut()` method:

```tsx
clickRef.signOut()
```

This call does not request the connected wallet to disconnect from your application, so next time the user wants to sign in he'll not need to go through the connection step. If you want to disconnect completely the wallet from your app, call the `disconnect()` method:

```tsx
clickRef.disconnect()
```


# Signing transactions

Applications interacting with the Casper Network must submit transactions. Every transaction requires explicit user approval, which is done by digitally signing it.

Your frontend application is not always responsible for creating the transaction. Depending on your architecture, a transaction may be constructed by your backend service, or even by a third party, before being sent to the user for approval.

Typically, you'll handle a transaction without approvals. And such approval is what you want to get from the user. Then, the transaction will be ready to be processed by a Casper node.

The CSPR.click SDK provides two ways to obtain this approval:

1. [`send()`](/cspr.click-v1.12/cspr.click-sdk/reference/methods#send).

* Requests the active wallet to prompt the user for approval (signature).
* Automatically submits the signed transaction to a Casper node for processing.
* Optionally accepts a callback function to receive live status updates during execution (e.g., pending, confirmed, rejected).

This is the most common method. In most applications, you can simply call send() and use its result or the status updates to inform the user whether their transaction is being processed, or if it was rejected (by either the user or the network).

2. [`sign()`](/cspr.click-v1.12/cspr.click-sdk/reference/methods#sign).

* Requests the active wallet to prompt the user for approval.
* Returns the signature value to your application, without submitting the transaction.

This method is intended for advanced scenarios, where you need the raw signature for custom workflows (e.g., off-chain processing, server-side validation, or multi-step transaction orchestration).

## Buy Alice a Coffee on testnet

In the React `create-react-app` [template ](/cspr.click-v1.12/documentation/getting-started#create-a-new-project)we've added an example that shows how to request the approval for a transaction that sends to Alice (an imaginary colleague in our team) 50 CSPR testnet tokens;

<figure><img src="/files/vrfw1V4JVGKPG82XO2ZB" alt=""><figcaption><p>Example in the template project</p></figcaption></figure>

Take a look into the `<BuyMeACoffee>` component. Here are the key parts:

1. **Build the transaction**

First, construct a transfer transaction. Thecasper-js-sdk is included in this template to help you with this step. Refer to the official Casper SDK documentation for more detailed usage and examples.

2. **Send the transaction**

Next, call the clickRef.send() method. CSPR.click will:

* Prompt the user in the active wallet to review and sign the transaction.
* Forward the signed transaction to a Casper node for processing.

3. **Handle responses**

Your application should be prepared to handle all possible outcomes:

* Success: The transaction was sent and you receive a transaction hash.
* User rejection: The user declined to sign the transaction.
* Network rejection: The Casper node rejected the transaction.

You can handle responses using the .then() and .catch() blocks, or use the status updates as explained in the next step.

4. **(Optional) Track transaction status**

The `.send()` method accepts an optional callback function as its second argument. This callback receives transaction status updates while the transaction is being executed, enabling you to:

* Show progress indicators in your UI (e.g., “Transaction pending…”)
* Update users when the transaction is confirmed or fails
* Provide richer feedback beyond just the final outcome

```tsx
function BuyMeACoffee() {
  const clickRef = useClickRef();
  const activeAccount = clickRef?.getActiveAccount();
  const [transactionHash, setTransactionHash] = useState<string>('');
  const [waitingResponse, setWaitingResponse] = useState<boolean>(false);

  const signAndSend = (transactionObj: object, sender: string) => {
          const onStatusUpdate = (status: string, data: any) => {
            console.log('STATUS UPDATE', status, data);
            if(status === TransactionStatus.SENT)
              setWaitingResponse(true);
          };
      
          clickRef
            ?.send(transactionObj, sender, onStatusUpdate)
            .then((res: SendResult | undefined) => {
                setWaitingResponse(false);
                if (res?.transactionHash) {
                    setTransactionHash(res.transactionHash);
                    alert('Transaction sent successfully: ' + res.transactionHash +
                        '\n Status: ' +
                        res.status +
                        '\n Timestamp: ' +
                        res.csprCloudTransaction.timestamp);
              } else if (res?.cancelled) {
                alert('Sign cancelled');
              } else {
                alert('Error in send(): ' + res?.error + '\n' + res?.errorData);
              }
            })
            .catch((err: any) => {
              alert('Error: ' + err);
              throw err;
            });
  };

  const handleSignTransaction = (evt: any) => {
    evt.preventDefault();
    const senderPk = activeAccount?.public_key?.toLowerCase() || '';
    const transaction = new NativeTransferBuilder()
        .from(PublicKey.fromHex(senderPk))
        .target(PublicKey.fromHex(recipientPk))
        .amount('6' + '000000000')
        .id(Date.now())
        .chainName(clickRef.chainName!)
        .payment(100_000_000)
        .build();
    signAndSend(transaction.toJSON() as object, senderPk);
  };
	
  return (
    ...
    <button onClick={() => handleSignTransaction()} />Sign and send transaction</button>
    ...
  )
}
```


# Tracking your transactions in real time

When using the `send()`method to request a transaction approval and deploy it to the network, the SDK can, optionally, establish a websocket connection with CSPR.click backend and receive real-time updates about the transaction execution.

Traditionally, applications had to rely on polling a backend service or querying a Casper node to know whether a transaction had been processed, confirmed, or rejected. This approach added complexity, increased latency, and delayed the user experience.

Using a websockets connection to listen for real-time updates, your application can:

* Receive immediate status notifications during the full transaction lifecycle.
* Update your UI with progress states (e.g., pending, processed, failed).
* Access result data without the need for extra API calls.

This makes it easier to build responsive, user-friendly applications that keep users informed in real time as their transactions move through the Casper Network.

<figure><img src="/files/lFnLNlWEuPb8yXQd6Dzl" alt="Waiting for transaction completion"><figcaption></figcaption></figure>

## Receive transaction updates

To wait for transaction execution and receive status updates, pass a callback function to the `send()` method. This function will be called with status updates as the transaction is approved and processed.

```javascript
const onStatusUpdate = (status, data) => {
    console.log('STATUS UPDATE', status, data);
    if (status === TransactionStatus.SENT)
        setWaitingIndicator();
    if (status === TransactionStatus.PROCESSED)
        parseProcessedTransaction();
};

clickRef
    .send(transaction, sender, onStatusUpdate)
    .then((res) => {
        // check result and update UI accordingly
    })
    .catch((err) => {
        alert('Error: ' + err);
        throw err;
    });
```

### Status values

The `status` argument passed to the callback function can have the following values:

| Value       | Description                                                                                                                           |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `sent`      | The transaction has been signed and successfully deployed to a Casper node.                                                           |
| `processed` | The transaction has been executed by the network. May result in success or failure.                                                   |
| `expired`   | The transaction’s time-to-live (TTL) elapsed before execution.                                                                        |
| `cancelled` | The user rejected the signature request.                                                                                              |
| `timeout`   | The SDK stopped listening for updates before the transaction was finalized. A custom timeout can be specified (default: 120 seconds). |
| `error`     | An unexpected error occurred while submitting or monitoring the transaction.                                                          |
| `ping`      | A heartbeat event sent periodically to indicate that the connection is still active..                                                 |

### Data with processed Status

When the transaction reaches the processed state, the callback function receives an additional data argument.

This object contains the full `Deploy` entity, as defined in the [CSPR.cloud REST API documentation](https://docs.cspr.cloud/rest-api/deploy#properties).

Your application can use this information to:

* Show whether the transaction succeeded or failed.
* Provide more detailed feedback (e.g., execution cost, error messages).


# Customizing the top bar

{% hint style="info" %}
While we recommend to include the CSPR.click top bar in your application, if you have your own Sign in and session management controls you can opt-out. To do so, do not include the `topBarSettings` prop to `ClickUI` and CSPR.click won't render the top bar.
{% endhint %}

CSPR.click includes a navigation bar that displays on the top of the web application. It's the same navigation bar you can find on CSPR.live and other applications that integrate CSPR.click.

<figure><img src="/files/JVuzSOKM00sFOxwKvjFu" alt=""><figcaption><p>CSPR.click navigation bar</p></figcaption></figure>

In this top bar you always see the CSPR Products menu on the left side, and the Account menu on the right side. The rest are customizable selectors that you can choose to add or not. Most of them are customizable as we'll see in the next pages.

### TopBarSettings object

This object wraps all settings in the navigation bar and is included to `<ClickUI>` as a prop. More on each configuration in the following subpages.

```tsx
const topBarSettings: TopBarSettings = {
    accountMenuItems,
    onThemeSwitch: toggleTheme,
    languageSettings: languageSettings(lang, setLang),
    currencySettings: currencySettings(currency, setCurrency),
    networkSettings: networkSettings(network, setNetwork),
};

<ClickUI
    topBarSettings={topBarSettings}
    themeMode={themeMode}
/>
```


# Account dropdown menu

You can customize the account dropdown menu in our top bar with your own menu items. Options to switch to another account and sign out are always present at the end of the list. The rest, depends on your needs. We provide a couple of common menu item components you may add, and one component for you to include anything you need.

<figure><img src="/files/HhdropnVqmhm6MKSt0qs" alt=""><figcaption></figcaption></figure>

## Account dropdown menu set up

To customize the account dropdown menu, add the menu items you want to display into an array:

```tsx
const accountMenuItems = [
  <AccountCardMenuItem key={0} />,
  <CopyHashMenuItem key={1} />,
  <AccountMenuItem
    key={2}
    onClick={() => {
        window.location.href = 'https://cspr.click';
    }}
    icon={CSPRClickIcon}
    label={'CSPR.click docs'}
    badge={{ title: 'new', variation: 'green' }}
  />,
];
```

Then, add the array to the `<ClickUI>` component:

```tsx
<ClickUI
    topBarSettings={{
        accountMenuItems
    }}
/>
```

## Prebuilt menu items

### Account card

```tsx
<AccountCardMenuItem />
```

Renders a card with account information at the top of the dropdown menu. The card includes the account name, public key and liquid/total balances. The account also links to CSPR.live.

By default, balances are shown in `USD` currency. If your application supports multiple currencies, you can pass the `currency` prop to the `<ClickUI>` component to display the balances in the selected currency:

```tsx
<ClickUI
    topBarSettings={topBarSettings}
    themeMode={themeMode}
    currencyCode={currency.code}
/>
```

See in the template project how to set up the currency selector connected to the account card.

### View account on CSPR.live

```tsx
<ViewAccountOnExplorerMenuItem />
```

Alternative to the account card. Renders a menu item in the account dropdown menu to open the CSPR.live account page in a new tab.

### Copy public key

```tsx
<CopyHashMenuItem />
```

Renders a menu item in the account dropdown menu to copy the connected public key to the clipboard.

### Buy CSPR

```tsx
<BuyCSPRMenuItem />
```

Renders a menu item in the account dropdown menu to open the [Topper by Uphold](https://www.topperpay.com/) widget on a new tab. This widget allows the user to top-up his account with a credit card payment.

### Custom menu item

```tsx
<AccountMenuItem
  onClick={() => {
    window.location.href = 'https://docs.cspr.click';
  }}
  icon={CSPRClickIcon}
  label={'CSPR.click docs'}
  badge={{ title: 'new', variation: 'green' }}
/>
```

Renders a menu item in the account dropdown menu with a custom text, icon, and handler action.

Optionally, you can add a small badge right to the menu item title. Valid variation values are `green`, `blue`, `violet`, and `gray`.


# Theme selector

<figure><img src="/files/RwM5KDwuNBPNY34ZuIxw" alt=""><figcaption><p>Theme selector widget</p></figcaption></figure>

CSPR.click navigation bar has two themes: **light** and **dark**. You can use one or the other. And if your application also has light and dark modes, you can add to the navigation bar a theme selector to let the user easily change between both.

## Theme selector set up

In your application, create a state value to store the current theme. For example, with `useState()` hook, but you can use any other method.

```tsx
const [themeMode, setThemeMode] = useState<ThemeModeType>(ThemeModeType.light);
```

Next, define a callback function that will be invoked when the theme selector is used to change the theme:

```tsx
const handleThemeSwitch = () => 
      setThemeMode(themeMode === ThemeModeType.light ?
            ThemeModeType.dark : 
            ThemeModeType.light);
```

Finally, indicate the current theme mode and the theme switch callback method to the `<ClickUI>` component:

```tsx
<ClickUI
    themeMode={themeMode}
    topBarSettings={{
        onThemeSwitch:handleThemeSwitch
    }}
/>
```


# Network selector

<figure><img src="/files/6CZuAGFieSStmi8sYwk7" alt=""><figcaption><p>Network selector widget</p></figcaption></figure>

If your application can switch between Mainnet and Testnet networks you may want to add the network selector widget to the CSPR.click navigation bar.

## Network selector set up

Define an array with the list of networks your application supports:

```tsx
export const NETWORKS = ['Mainnet', 'Testnet'];
```

Create a state value to store the current network. For example, with `useState()` hook, but you can use any other method.

```tsx
const [network, setNetwork] = useState<string>(NETWORKS[1]);
```

Define a `networkSettings` object with the list of networks, the current network, and a callback method to handle network selection by the user. Add this object to the `topBarSettings` prop in the `<ClickUI>` component:

```typescript
const networkSettings = {
  networks: NETWORKS,
  currentNetwork: network,
  onNetworkSwitch: (n: string) => { setNetwork(n); },
}
```

```tsx
<ClickUI 
    topBarSettings={{
        networkSettings
    }}
/>
```

### Customize the network icons

You can also specify your custom icons for each of the networks:

```tsx
import mainnetIcon from './assets/ico-mainnet.svg'
import testnetIcon from './assets/ico-testnet.svg'

const NETWORKS = [
  { title: 'Mainnet', icon: mainnetIcon },
  { title: 'Testnet', icon: testnetIcon }
];
```


# Language selector

<figure><img src="/files/lB68VZ9Je3RIJL5H4Hgg" alt=""><figcaption><p>Language selector widget</p></figcaption></figure>

If your application supports multiple languages, you can add to the CSPR.click navigation bar a language selector.

## Language selector set up

Define an array with the list of languages your application supports:

```tsx
export const LANGUAGES: Lang[] = [
    Lang.EN,
    Lang.AZ,
    Lang.DE,
    Lang.ES,
    //...,
];
```

Create a state value to store the current language. For example, with `useState()` hook, but you can use any other method.

```tsx
const [language, setLanguage] = useState<Lang>(Lang.EN);
```

Define a `languageSettings` object with the list of languages, the current language, and a callback method to handle language selection by the user. Add this object to the `topBarSettings` prop in the `<ClickUI>` component:

```typescript
const languageSettings = {
    languages: LANGUAGES,
    creditsUrl: "/credits",
    contributeUrl: "/contribute",
    currentLanguage:  language,
    onChangeLanguage: (l: Lang) => { setLanguage(l); }
}
```

```tsx
<ClickUI
    topBarSettings={{
        languageSettings
    }}
/>
```

If you want to show a credits page to shout out your contributors, specify a URL in the `credits` field.

And if you want to ask your visitors to help you maintain the translations, specify a URL in the `contribute` field.

Note that both, `credits` and `contribute` links are optional. If you don't specify one or both, such options won't show in the language selector widget.


# Currency selector

<figure><img src="/files/rSQe30sp6KOKEYEOFyrO" alt=""><figcaption><p>Currency selector widget</p></figcaption></figure>

If your application supports multiple currencies, you can add to the CSPR.click navigation bar a currency selector.

## Language selector set up

Define an array with the list of currencies your application supports:

```tsx
export const CURRENCIES: Currency[] = [
    {
        code: 'USD',
        title: 'US Dollar',
        type_id: CurrencyType.FIAT,
    },
    {
        code: 'EUR',
        title: 'Euro',
        type_id: CurrencyType.FIAT,
    },
    //...,
    {
        code: 'BTC',
        title: 'Bitcoin',
        type_id: CurrencyType.CRYPTO,
    },
    {
        code: 'ETH',
        title: 'Ethereum',
        type_id: CurrencyType.CRYPTO,
    },
];
```

Note in the image above how currencies are grouped in cryptocurrencies and fiat currencies. In your list of currencies, classify them using the `type_id` property in one of the groups.

Create a state value to store the current currency. For example, with `useState()` hook, but you can use any other method.

```tsx
	const [currency, setCurrency] = useState(CURRENCIES[0]);
```

Define a `currencySettings` object with the list of currencies, the selected currency, and a callback method to handle currency selection by the user. Add this object to the `topBarSettings` prop in the `<ClickUI>` component:

```typescript
const currencySettings= {
  currencies: CURRENCIES,
  currentCurrency: currency,
  onChangeCurrency: (c: any) => { setCurrency(c); },
}
```

```tsx
<ClickUI
    topBarSettings={{
        currencySettings
    }}
/>
```


# Custom selector

<figure><img src="/files/Br0x0wVn9IbF1z0vNhs3" alt=""><figcaption></figcaption></figure>

In addition to the standard settings selectors described in the previous pages, you can define your own dropdown menus with the options your application requires.

The code below shows an example with a menu that allows to choose between three different tokens:

```tsx
const TOKENS: CustomTopBarMenuItem[] = [
  {title:'Token 1', icon: <LogoGreen/>  },
  {title: 'Token 2', icon: <LogoYellow/>},
  {title: 'Token 3', icon: <LogoOrange/> }
];

const tokenSettings = {
    items: TOKENS,
    currentItem: currentToken,
    onItemSwitch: (t: string) => {
      // update your app upon item change
    },
};
```

```tsx
<ClickUI
    topBarSettings={{
        customTopBarMenuSettings:[tokenSettings]
    }}
/>
```


# Theme customization

CSPR.click provides set of different ui themes out of box, such as `red`, `green`, `blue` and `csprclick` as default theme. Each theme has its own set of `Dark` and `Light` version where all necessary colours are specified. Customer can easily use and modify set of colours for each theme and for its Dark or Light version.

### Default themes declaration

To use one of default theme, you need to export `DefaultThemes` object and `builtThemes` helper function from `@make-software/csprclick-ui`

DefaultThemes object consist of four properties which actually are themes itself. So by default we got four themes:

* `csprclick`
* `red`
* `green`
* `blue`

By default you'll get `csprclick` theme.

```tsx
import {DefaultThemes, buildTheme} from '@make-software/csprclick-ui';

export const AppTheme = buildTheme({
    ...DefaultThemes.csprclick,
});
```

You can easily change it to any of available themes from `DefaultThemes` object.

```tsx
export const AppTheme = buildTheme({
    ...DefaultThemes.red,
});
```

or

```tsx

export const AppTheme = buildTheme({
    ...DefaultThemes.blue,
});
```

### Default themes usage

To connect and apply theme you have selected all you need it just to pass it as a props to `ThemeProvider` which you can import from `styled-components` And wrap with it the whole application.

`ThemeModeType` enum which consist theme modes:

* `light`
* `dark`

```tsx
import { ThemeProvider } from 'styled-components';
import { AppTheme } from "./settings/theme";
import { ThemeModeType } from '@make-software/csprclick-ui';

<ThemeProvider theme={AppTheme[ThemeModeType.light]}>
    ...
    <App/>
    ...
</>
```

### Customise whole application alongside with `<ClickUI>` component

Besides customizing `<ClickUI>` component you can also customize the whole body of your application.

To do that, we have declared two properties:

* `appDarkTheme` - to customize application in dark mode
* `appLightTheme` - to customize application in light mode

Each of them has its own set of properties:

```tsx

export const AppTheme = buildTheme({
    ...DefaultThemes.csprclick,
    appDarkTheme: {
        topBarSectionBackgroundColor: DefaultThemes.csprclick.csprclickDarkTheme[clickStyleguide.backgroundTopBarColor],
        [clickStyleguide.textColor]: '#DADCE5',
        bodyBackgroundColor: '#0f1429'
    },
    appLightTheme: {
        topBarSectionBackgroundColor: DefaultThemes.csprclick.csprclickLightTheme[clickStyleguide.backgroundTopBarColor],
        [clickStyleguide.textColor]: '#1A1919',
        bodyBackgroundColor: '#f2f3f5'
    },
});

```

* `topBarSectionBackgroundColor` - stands for wrapping `<ClickUI>` component and set appropriate color for this wrapper
* `[clickStyleguide.textColor]` - stands for changing text color. Applies to the part of application which is inside `<body>` tag
* `bodyBackgroundColor` - stands for changing background color. Applies to the part of application which is inside `<body>` tag


# Create your own custom theme

If you're not enough with default set of themes you can easily create the new one. To do that, all you need is to directly extend `AppTheme` object with new property which would be the title of new theme and add appropriate structure.

### Theme creation structure

First of all, from `@make-software/csprclick-ui` you need to import`clickStyleguide` object which consist all necessary colors constructors to cover you application with new theme. Also you'll need helper function to build your own theme `buildTheme`.

To create the new custom theme, please follow the signature:

**note: (instead of hardcoded hex, please use your own color values)**

```tsx
import { clickStyleguide, buildTheme } from '@make-software/csprclick-ui';

const newCustomTheme = {
        csprclickDarkTheme: {
            [clickStyleguide.backgroundTopBarColor]: '#6305a2',
            [clickStyleguide.backgroundMenuColor]: '#b6a3e5',
            [clickStyleguide.hoverProductMenu]: '#b193ec',
            [clickStyleguide.hoverAccountMenu]: '#b193ec',
            [clickStyleguide.textColor]: '#500383',
            [clickStyleguide.topBarTextColor]: '#9770ef',
            [clickStyleguide.menuIconAndLinkColor]: '#af05f3',
            [clickStyleguide.topBarIconHoverColor]: '#6a3be0',
        },
        csprclickLightTheme: {
            [clickStyleguide.backgroundTopBarColor]: '#9d13cb',
            [clickStyleguide.backgroundMenuColor]: '#a15fe0',
            [clickStyleguide.hoverProductMenu]: '#693388',
            [clickStyleguide.hoverAccountMenu]: '#693388',
            [clickStyleguide.textColor]: '#c9b6ea',
            [clickStyleguide.topBarTextColor]: '#d8cae8',
            [clickStyleguide.menuIconAndLinkColor]: '#ec06c5',
            [clickStyleguide.topBarIconHoverColor]: '#ec06c5',
        },
}
```

Then, you need to inject newly created theme object into `buildTheme` constructor function alongside with `appDarkTheme` and `appLightTheme` if needed.

```tsx
export const AppTheme = buildTheme({
    ...newCustomTheme,
    appDarkTheme: {
        topBarSectionBackgroundColor: newCustomTheme.csprclickDarkTheme[clickStyleguide.backgroundTopBarColor],
        [clickStyleguide.textColor]: '#DADCE5',
        bodyBackgroundColor: newCustomTheme.csprclickDarkTheme[clickStyleguide.backgroundTopBarColor],
    },
    appLightTheme: {
        topBarSectionBackgroundColor: newCustomTheme.csprclickLightTheme[clickStyleguide.backgroundTopBarColor],
        [clickStyleguide.textColor]: '#1A1919',
        bodyBackgroundColor: newCustomTheme.csprclickLightTheme[clickStyleguide.backgroundTopBarColor],
    },
});
```

### Colors matching examples

`clickStyleguide` has a set of colors. Each color from `clickStyleguide` has its own corresponding area of usage and responsibility.

Here you can find all matching with colors and its corresponding area of usage on `<ClickUI>` component

* `csprclickDarkTheme` - stands for customise `<ClickUI>` component and all child or relative components in Dark mode.
* `csprclickLightTheme` - stands for customise `<ClickUI>` component and all child or relative components in Light mode.

Each of above properties has the same set of colors:

* `[clickStyleguide.backgroundTopBarColor]: 'blue'` - stands for whole `<ClickUI>` background color

Example on the screen below:

<figure><img src="/files/3etkR0sE2CpP9A49V3TP" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.backgroundMenuColor]: 'blue'` - stands for all dropdown backgrounds Applies for the following components: `<ProductMenu>`, `<AccountMenu>`, `<Currencies>`, `<Languages>`, `<Network>` and `<CustomSelect>` component.

Example on the screen below:

<figure><img src="/files/VoF51jTpf5roMTruKnJG" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/nGbTHOoD59OlJsK7GCfG" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/ijoXDQ6b787FY3FowwsN" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/rConTlrvyXOH0FMUHexM" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.hoverProductMenu]: 'blue'` - stands for changing colour when hovering on items inside `<ProductMenu>`

Example on the screen below:

<figure><img src="/files/dZOfWn6p2NwCn9ac7INB" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.hoverAccountMenu]: 'blue'` - stands for changing colour when hovering on items inside `<AccountMenu>`, `<Currencies>`, `<Languages>`, `<Network>` and `<CustomSelect>` component.

Example on the screen below:

<figure><img src="/files/3DCPkXiANhyXg4SNX5kk" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/bAfvWiLKKO2CYvEF5UAD" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.textColor]: 'blue'` - stands for text colour inside each dropdown which is under `<ClickUI>`

Example on the screen below:

<figure><img src="/files/g9sfugamycynu8rNojpI" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/gvssGiyWUZe3gUp0RjPB" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.topBarTextColor]: 'blue'` - stands for text colour specific for `<ClickUI` and `ClickModals` components

Example on the screen below:

<figure><img src="/files/K0mJ1wQNN4et4Mc6HPs7" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/VU4xLQxEtYvTHjym3mdh" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.topBarIconHoverColor]: 'blue'` - stands for changing colour when hovering on items which are on `<ClickUI>` component

Example on the screen below:

<figure><img src="/files/E7E5hYSv564grrmh6AqC" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.menuIconAndLinkColor]: 'blue'` - stands for links and icons colour

Example on the screen below:

<figure><img src="/files/nBfCqQwUsnVujmmayhTV" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/r4vC3KClc4J4yGdSRGUx" alt=""><figcaption></figcaption></figure>

It's really easy and fast to create you own color theme! Enjoy the process!


# Add custom information badge

In case you want to add some information badge on the ClickTopBar, you can use `useClickBadge()` hook to do it. You need to import it from csprclick library

```tsx
import { useClickBadge } from '@make-software/csprclick-ui';
```

### `useClickBadge` structure

useClickBadge hook returns two functions: `setLeftBadge` and `setRightBadge`. Both are responsible to add info badge on specific ClickTopBar side. Each of these functions accepts the same set of parameters.\
Here the list of props for badge customization.

```tsx
export type BadgeSettings = {
        title: string;
        link?: string;
        color?: string;
        background: string;
   };
```

Here the example of having one badge with custom color, link and title on the left side of ClickTopBar:

```tsx
const ClickTopBar = ({ themeMode, onThemeSwitch }) => {

  const { setLeftBadge } = useClickBadge();

  setLeftBadge({
      title: `📄 Go to CSPR.click docs`,
      background: 'blue',
      color:'white',
      link: 'https://docs.cspr.click/'
  });

}
```

Then you should see the result: one left side badge with your own color, link and title. Like on the screen below:

<figure><img src="/files/ghJOteRwEjPMxO52Z9nw" alt=""><figcaption></figcaption></figure>

To remove the badge but keep it ready to use in codebase you can add `null` as parameter

```tsx
    setLeftBadge(null);
```

So, to create your own custom badge dynamically, all you need is to use `useClickBadge()` hook and call `setLeftBadge` or `setRightBadge` functions.


# Hooks and Components

### Hooks

#### useClickRef() hook

In your components, you'll often need to call the CSPR.click API to get data or request an operation. To get a reference to the CSPR.click SDK instance make use of the `useClickRef()` React hook:

```tsx
import { useClickRef } from '@make-software/csprclick-ui';

function MyComponent() {
  const clickRef = useClickRef();
  ...
}
```

Then, in your application you'll be able to request CSPR.click to perform some operations using the class [methods](/cspr.click-v1.12/cspr.click-sdk/reference/methods), or get values reading the class [properties](/cspr.click-v1.12/cspr.click-sdk/reference/properties).

### Components

#### \<AccountIdenticon>

Use the `AccountIdenticon` component to display the public key identicon (or avatar). It can be used also with an account hash string.

<figure><img src="/files/z5PUusnYUBlQWdI1f7Sz" alt="AccountIdenticon component example"><figcaption></figcaption></figure>

In addition to the public key or account hash, indicate the size of the resulting image: `'xs'` for `16px`; `'sm'` for `20px`; `'m'` for `32px`; or `'l'` for `40px`.

```tsx
<AccountIdenticon hex={publicKey} size={'l'} />
```

The size can be indicated with a number of pixels:

```tsx
<AccountIdenticon hex={accountHash} size={40}  />
```


# JavaScript

This page guides you through the steps required to integrate the UI SDK into a non-React application.

Check also the HTML/Javascript demo in the [csprclick-examples](https://github.com/make-software/csprclick-examples) repository to see the resulting application. In that repo you can find also examples or few other libraries/frameworks.

## Download the CSPR.click UI runtime library from the CDN:

Before the closing `head` tag, add a `script` element to download the CSPR.click scripts:

```html
  <!-- update to latest released version -->
  <script defer="defer" src="https://cdn.cspr.click/ui/v1.9.0/csprclick-client-1.9.0.js"></script>
</head>
```

## Add a container for the CSPR.click UI

In your main layout file, add a `<div>` container where CSPR.click will inject some UI components like the navigation top bar or the 1-click sign in modal. Set an `id`, you'll need it later during CSPR.click initialization.

```html
<body>
  <div id="app">
    <div id="csprclick-ui"></div>
    <div id="content">
     <!-- you rapplication goes here -->
    </div>
  </div>
</body>
```

Also, depending on the layout of your application and the grid system you're using, you'll need to add some CSS styles to this container to match the styles of the rest of the app (width, background color, etc).

## Configure the initialization of the CSPR.click SDK

In a javascript file, add the initialization options for the CSPR.click SDK. Make sure this script loads before CSPR.click is downloaded.

The minimal configuration for the UI just defines the container for the navigation top bar and the root container of your app. We'll see other options later in this document.

```javascript
const clickUIOptions = {
  uiContainer: 'csprclick-ui', 
  rootAppElement: '#app',
  showTopBar: true,  
};
```

Next, define Client SDK options:

```javascript
const clickSDKOptions = {
  appName: 'CSPR.click demo',
  appId: 'csprclick-template',
  providers: ['casper-wallet', 'casper-signer'],
};
```

You can read more about the [CsprClickInitOptions ](/cspr.click-v1.12/cspr.click-sdk/reference/types#csprclickinitoptions)object in the reference section.

## What's next

At this point, your application should show the CSPR.click top navigation bar and you can click on Sign in button to connect your favorite wallet.

<figure><img src="/files/JgO1W1itsavt6mCu7a72" alt=""><figcaption></figcaption></figure>

#### Listen to CSPR.click events

You'll need to listen and respond to some events triggered when the user connects an account, switches to a different one, or closes the session.

Refer to the [Handling events](/cspr.click-v1.12/cspr.click-sdk/javascript/handling-events) page for information on how to add your listener functions.

#### Ask the user to connect a wallet

If you don't display the CSPR.click top navigation bar, you must have your own Sign in or Connect buttons and respond calling the CSPR.click library .

Refer to the [Connecting a wallet](/cspr.click-v1.12/cspr.click-sdk/javascript/connecting-a-wallet) page for information on how to trigger the wallet connection process.

#### Request transaction approvals

At some point, your application will need to interact with the Casper network by sending a transaction (aka deploy).\
CSPR.click manages this process communicating with the active wallet to request the user to approve or reject the transaction. The UI depends on the wallet.

Refer to the [Signing transactions](/cspr.click-v1.12/cspr.click-sdk/javascript/signing-transactions) page for information on how to request the user a transaction approval. Also, look at [Processing status updates](/cspr.click-v1.12/cspr.click-sdk/javascript/processing-status-updates) for information on how to listen for real-time status updates.

#### Customize the top navigation bar

You can add any of our predefined settings selectors or account menu items. And you can define your own.

Refer to the [Customizing the top bar](/cspr.click-v1.12/cspr.click-sdk/javascript/customizing-the-top-bar) section for complete reference on how to work with each of the setting elements in the top bar.


# Handling events

In your application, you'll need to listen and respond to different events emitted by the CSPR.click library. On this page, we're covering the most common. Check the [Events](/cspr.click-v1.12/cspr.click-sdk/reference/events) page for a complete list of events.

For that purpose, add a listener for the `csprclick:loaded` message and register your callback functions for the different events triggered by the CSPR.click library.

```javascript
window.addEventListener('csprclick:loaded', () => {
  window.csprclick.on('csprclick:signed_in', async (evt) => {
    console.log("csprclick:signed_in", evt);
  });
  window.csprclick.on('csprclick:switched_account', async (evt) => {
    console.log("csprclick:switched_account", evt);
  });
  window.csprclick.on('csprclick:signed_out', async (evt) => {
    console.log("csprclick:signed_out", evt);
  });
  window.csprclick.on('csprclick:disconnected', async (evt) => {
    console.log("csprclick:disconnected", evt);
  });
});
```

### csprclick:signed\_in

This event is emitted every time the CSPR.click library connects to an account.

[csprclick:signed\_in](/cspr.click-v1.12/cspr.click-sdk/reference/events#csprclick-signed_in) reference.

### csprclick:switched\_account

This event is emitted instead of `csprclick:signed_i` when the user has clicked on the Switch Account menu item and has switched to another account in the same or a different wallet.

[csprclick:switched\_account](/cspr.click-v1.12/cspr.click-sdk/reference/events#csprclick-switched_account) reference.

### csprclick:signed\_out

This event is emitted when the CSPR.click library disconnects the active account due to a call to the `signOut()` SDK method.

[csprclick:signed\_out](/cspr.click-v1.12/cspr.click-sdk/reference/events#csprclick-signed_out) reference.

### csprclick:disconnected

This event is emitted when CSPR.click library receives a disconnect request or event from the connected wallet. The app should close the current session as a consequence of this event.

It receives in the event object the provider that has been disconnected.

[csprclick:disconnected](/cspr.click-v1.12/cspr.click-sdk/reference/events#csprclick-disconnected) reference.


# Connecting a wallet

If you're not displaying the top navigation bar you'll need to have you own UI components to let the user connect a wallet, display the connected account, switch to another account, and disconnect. In this page we're describing how to use the CSPR.click library to perform these operations.

## Sign in

When the user clicks on your 'Sign in' or 'Connect wallet' button, call the `signIn()` method to display the wallet selector window:

```tsx
window.csprclick.signIn()
```

This method returns immediately. Listen to the library events to get a notification of connection.

## Switch account

To let the user to change to another account, call the `switchAccount()` method:

```tsx
window.csprclick.switchAccount()
```

This method returns immediately. Listen to the library events to get a notification of connection.

## Disconnect

To close the current user session, call the `signOut()` method:

```tsx
window.csprclick.signOut()
```

This call does not request the connected wallet to disconnect from your application, so next time the user wants to sign in he'll not need to go through the connection step. If you want to disconnect completely the wallet from your app, call the `disconnect()` method:

```tsx
window.csprclick.disconnect()
```


# Signing transactions

Applications interacting with the Casper Network must submit transactions. Every transaction requires explicit user approval, which is done by digitally signing it.

Your frontend application is not always responsible for creating the transaction. Depending on your architecture, a transaction may be constructed by your backend service, or even by a third party, before being sent to the user for approval.

Typically, you'll handle a transaction without approvals. And such approval is what you want to get from the user. Then, the transaction will be ready to be processed by a Casper node.

The CSPR.click SDK provides two ways to obtain this approval:

1. [`send()`](/cspr.click-v1.12/cspr.click-sdk/reference/methods#send).

* Requests the active wallet to prompt the user for approval (signature).
* Automatically submits the signed transaction to a Casper node for processing.
* Optionally accepts a callback function to receive live status updates during execution (e.g., pending, confirmed, rejected).

This is the most common method. In most applications, you can simply call send() and use its result or the status updates to inform the user whether their transaction is being processed, or if it was rejected (by either the user or the network).

2. [`sign()`](/cspr.click-v1.12/cspr.click-sdk/reference/methods#sign).

* Requests the active wallet to prompt the user for approval.
* Returns the signature value to your application, without submitting the transaction.

This method is intended for advanced scenarios, where you need the raw signature for custom workflows (e.g., off-chain processing, server-side validation, or multi-step transaction orchestration).

## Buy Alice a Coffee on testnet

In the React `create-react-app` [template ](/cspr.click-v1.12/documentation/getting-started#create-a-new-project)we've added an example that shows how to request the approval for a transaction that sends to Alice (an imaginary colleague in our team) 50 CSPR testnet tokens;

<figure><img src="/files/vrfw1V4JVGKPG82XO2ZB" alt=""><figcaption><p>Example in the template project</p></figcaption></figure>

Take a look into the `<BuyMeACoffee>` component. Here are the key parts:

1. **Build the transaction**

First, construct a transfer transaction. Thecasper-js-sdk is included in this template to help you with this step. Refer to the official Casper SDK documentation for more detailed usage and examples.

2. **Send the transaction**

Next, call the clickRef.send() method. CSPR.click will:

* Prompt the user in the active wallet to review and sign the transaction.
* Forward the signed transaction to a Casper node for processing.

3. **Handle responses**

Your application should be prepared to handle all possible outcomes:

* Success: The transaction was sent and you receive a transaction hash.
* User rejection: The user declined to sign the transaction.
* Network rejection: The Casper node rejected the transaction.

You can handle responses using the .then() and .catch() blocks, or use the status updates as explained in the next step.

4. **(Optional) Track transaction status**

The `.send()` method accepts an optional callback function as its second argument. This callback receives transaction status updates while the transaction is being executed, enabling you to:

* Show progress indicators in your UI (e.g., “Transaction pending…”)
* Update users when the transaction is confirmed or fails
* Provide richer feedback beyond just the final outcome

```tsx
function BuyMeACoffee() {
  const clickRef = useClickRef();
  const activeAccount = clickRef?.getActiveAccount();
  const [transactionHash, setTransactionHash] = useState<string>('');
  const [waitingResponse, setWaitingResponse] = useState<boolean>(false);

  const signAndSend = (transactionObj: object, sender: string) => {
          const onStatusUpdate = (status: string, data: any) => {
            console.log('STATUS UPDATE', status, data);
            if(status === TransactionStatus.SENT)
              setWaitingResponse(true);
          };
      
          clickRef
            ?.send(transactionObj, sender, onStatusUpdate)
            .then((res: SendResult | undefined) => {
                setWaitingResponse(false);
                if (res?.transactionHash) {
                    setTransactionHash(res.transactionHash);
                    alert('Transaction sent successfully: ' + res.transactionHash +
                        '\n Status: ' +
                        res.status +
                        '\n Timestamp: ' +
                        res.csprCloudTransaction.timestamp);
              } else if (res?.cancelled) {
                alert('Sign cancelled');
              } else {
                alert('Error in send(): ' + res?.error + '\n' + res?.errorData);
              }
            })
            .catch((err: any) => {
              alert('Error: ' + err);
              throw err;
            });
  };

  const handleSignTransaction = (evt: any) => {
    evt.preventDefault();
    const senderPk = activeAccount?.public_key?.toLowerCase() || '';
    const transaction = new NativeTransferBuilder()
        .from(PublicKey.fromHex(senderPk))
        .target(PublicKey.fromHex(recipientPk))
        .amount('6' + '000000000')
        .id(Date.now())
        .chainName(clickRef.chainName!)
        .payment(100_000_000)
        .build();
    signAndSend(transaction.toJSON() as object, senderPk);
  };
	
  return (
    ...
    <button onClick={() => handleSignTransaction()} />Sign and send transaction</button>
    ...
  )
}
```


# Tracking your transactions in real time

When using the `send()`method to request a transaction approval and deploy it to the network, the SDK can, optionally, establish a websocket connection with CSPR.click backend and receive real-time updates about the transaction execution.

Traditionally, applications had to rely on polling a backend service or querying a Casper node to know whether a transaction had been processed, confirmed, or rejected. This approach added complexity, increased latency, and delayed the user experience.

Using a websockets connection to listen for real-time updates, your application can:

* Receive immediate status notifications during the full transaction lifecycle.
* Update your UI with progress states (e.g., pending, processed, failed).
* Access result data without the need for extra API calls.

This makes it easier to build responsive, user-friendly applications that keep users informed in real time as their transactions move through the Casper Network.

<figure><img src="/files/lFnLNlWEuPb8yXQd6Dzl" alt="Waiting for transaction completion"><figcaption></figcaption></figure>

## Receive transaction updates

To wait for transaction execution and receive status updates, pass a callback function to the `send()` method. This function will be called with status updates as the transaction is approved and processed.

```javascript
const onStatusUpdate = (status, data) => {
    console.log('STATUS UPDATE', status, data);
    if (status === TransactionStatus.SENT)
        setWaitingIndicator();
    if (status === TransactionStatus.PROCESSED)
        parseProcessedTransaction();
};

clickRef
    .send(transaction, sender, onStatusUpdate)
    .then((res) => {
        // check result and update UI accordingly
    })
    .catch((err) => {
        alert('Error: ' + err);
        throw err;
    });
```

### Status values

The `status` argument passed to the callback function can have the following values:

| Value       | Description                                                                                                                           |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `sent`      | The transaction has been signed and successfully deployed to a Casper node.                                                           |
| `processed` | The transaction has been executed by the network. May result in success or failure.                                                   |
| `expired`   | The transaction’s time-to-live (TTL) elapsed before execution.                                                                        |
| `cancelled` | The user rejected the signature request.                                                                                              |
| `timeout`   | The SDK stopped listening for updates before the transaction was finalized. A custom timeout can be specified (default: 120 seconds). |
| `error`     | An unexpected error occurred while submitting or monitoring the transaction.                                                          |
| `ping`      | A heartbeat event sent periodically to indicate that the connection is still active..                                                 |

### Data with processed Status

When the transaction reaches the processed state, the callback function receives an additional data argument.

This object contains the full `Deploy` entity, as defined in the [CSPR.cloud REST API documentation](https://docs.cspr.cloud/rest-api/deploy#properties).

Your application can use this information to:

* Show whether the transaction succeeded or failed.
* Provide more detailed feedback (e.g., execution cost, error messages).


# Customizing the top bar

{% hint style="info" %}
While we recommend to include the CSPR.click top bar in your application, if you have your own Sign in and session management controls you can opt-out and hide the navigation bar. Read below how to do it.
{% endhint %}

CSPR.click includes a navigation bar that displays on the top of the web application. It's the same navigation bar you can find on CSPR.live and other applications that integrate CSPR.click.

<figure><img src="/files/JVuzSOKM00sFOxwKvjFu" alt=""><figcaption><p>CSPR.click navigation bar</p></figcaption></figure>

In this top bar you always see the CSPR Products menu on the left side, and the Account menu on the right side. The rest are customizable selectors that you can choose to add or not. Most of them are customizable as we'll see in the next pages.

### Hide the navigation bar

if your application already has its own Sign in and session management controls you can hide CSPR.click navigation bar. To do so, do not include any of the settings selector and set `showTopBar` to `false`:

```json
const clickUIOptions = {
  uiContainer: 'csprclick-ui',
  rootAppElement: '#app',
  defaultTheme: 'light',
  showTopBar: false,
};
```


# Account dropdown menu

You can customize the account dropdown menu in our top bar with your own menu items. Options to switch to another account and sign out are always present at the end of the list. The rest, depends on your needs. We provide a couple of common menu item components you may add, and one component for you to include anything you need.

<figure><img src="/files/HhdropnVqmhm6MKSt0qs" alt=""><figcaption></figcaption></figure>

## Account dropdown menu set up

To customize the account dropdown menu, add the menu items you want to display into an array:

```javascript
const csprClickDocsMenuItem = {
    label: 'CSPR.click docs',
    icon: './csprclick-icon.svg',
    badge: { title: 'New', variation: 'green' },
    onClick: () => { window.open('https://docs.cspr.click', '_blank'); },
};

const accountMenuItems = [
    'AccountCardMenuItem',
    'CopyHashMenuItem',
    csprClickDocsMenuItem,
    'BuyCSPRMenuItem',
];
```

Then, add the array to the `clickUIOptions` object you defined before:

```javascript
const clickUIOptions = {
  uiContainer: 'csprclick-ui', 
  rootAppElement: '#app',
  showTopBar: true,
  accountMenuItems,
};
```

## Prebuilt menu items

### Account card

```javascript
const accountMenuItems = [
    'AccountCardMenuItem',
];
```

Renders a card with account information at the top of the dropdown menu. The card includes the account name, public key and liquid/total balances. The account also links to CSPR.live.

### View account on CSPR.live

```javascript
const accountMenuItems = [
    'ViewAccountOnExplorerMenuItem',
];
```

Alternative to the account card. Renders a menu item in the account dropdown menu to open the CSPR.live account page in a new tab.

### Copy public key

```javascript
const accountMenuItems = [
    'CopyHashMenuItem',
];
```

Renders a menu item in the account dropdown menu to copy the connected public key to the clipboard.

### Buy CSPR

```javascript
const accountMenuItems = [
    'BuyCSPRMenuItem',
];
```

Renders a menu item in the account dropdown menu to open the [Topper by Uphold](https://www.topperpay.com/) widget on a new tab. This widget allows the user to top-up his account with a credit card payment.

### Custom menu item

```javascript
const csprClickDocsMenuItem = {
    label: 'CSPR.click docs',
    icon: './csprclick-icon.svg',
    badge: { title: 'New', variation: 'green' },
    onClick: () => { window.open('https://docs.cspr.click', '_blank'); },
};

const accountMenuItems = [
    csprClickDocsMenuItem,
];
```

Renders a menu item in the account dropdown menu with a custom text, icon, and handler action.

Optionally, you can add a small badge right to the menu item title. Valid variation values are `green`, `blue`, `violet`, and `gray`.


# Theme selector

<figure><img src="/files/RwM5KDwuNBPNY34ZuIxw" alt=""><figcaption><p>Theme selector widget</p></figcaption></figure>

CSPR.click navigation bar has two themes: **light** and **dark**. You can use one or the other. And if your application also has light and dark modes, you can add to the navigation bar a theme selector to let the user easily change between both.

## Theme selector set up

In your application, define your default theme and a callback function to handle theme change. For example:

```javascript
const defaultTheme = 'light';

const onThemeChanged =  (theme) => {
    const page = document.querySelector('body');
    if (theme === 'dark') page?.classList.add('dark');
    else page?.classList.remove('dark');
    console.log('Theme switched to', theme);
};
```

Then, add these two values to the UI initialization object:

```javascript
const clickUIOptions = {
  uiContainer: 'csprclick-ui', 
  rootAppElement: '#app',
  showTopBar: true,
  defaultTheme,
  onThemeChanged,
};
```


# Network selector

<figure><img src="/files/6CZuAGFieSStmi8sYwk7" alt=""><figcaption><p>Network selector widget</p></figcaption></figure>

If your application can switch between Mainnet and Testnet networks you may want to add the network selector widget to the CSPR.click navigation bar.

## Network selector set up

Define an array with the list of networks your application supports:

```javascript
const NETWORKS = ['Mainnet', 'Testnet'];

const networkSettings = {
    networks: NETWORKS,
    currentNetwork: NETWORKS[0],
    onNetworkSwitch: (n) => {
        console.log('Network selected', n);
        window.csprclickUI.setNetwork(n);
    },
}
```

Then, add this settings object to the UI initialization defined before:

```javascript
const clickUIOptions = {
  uiContainer: 'csprclick-ui', 
  rootAppElement: '#app',
  showTopBar: true,
  networkSettings,
};
```

### Customize the network icons

You can also specify your custom icons for each of the networks:

```tsx
import mainnetIcon from './assets/ico-mainnet.svg'
import testnetIcon from './assets/ico-testnet.svg'

const NETWORKS = [
  { title: 'Mainnet', icon: mainnetIcon },
  { title: 'Testnet', icon: testnetIcon }
];
```


# Examples

We have several examples of CSPR.click integration for different tech stacks. Visit the following GitHub repository;

<https://github.com/make-software/csprclick-examples>


# Reference


# Properties

The following properties are available in `csprclick` global object after initialization.

### appName

```typescript
appName: string
```

Returns the name of the application. This name is set during the library initialization.

### appId

```typescript
appId: string
```

Returns the id of the application.

### casperNode

```typescript
casperNode: string
```

Returns the URL of the RPC interface CSPR.click uses to get or send information from/to the Casper network.

### chainName

```typescript
chainName: string
```

Returns the name of the Casper network the application interacts with.

### csprclickHost

```
csprclickHost: string
```

Returns the CSPR.click server.


# Methods

### connect

```typescript
connect(provider: string, options: any): Promise<AccountType|undefined>
```

Call the `connect()` method using a provider name as the first parameter to request a connection using that wallet or login mechanism.

Some providers may need an options argument to indicate the connection behavior requested.

### disconnect

```typescript
 disconnect(fromWallet: string, options?: any): void
```

Usually you will call `signOut()` method to close a user session. Use `disconnect()` when you want to clear the connection between the wallet and your app. Next time the user signs in with that wallet, he'll must gran connection permission again.

Send empty arguments or empty string to disconnect from currently active account. Or call disconnect with a wallet provider key to force the disconnection of a specific wallet.

### forgetAccount

```typescript
forgetAccount(account: AccountType): void
```

Removes an account from the list of known accounts in CSPR.click. It won’t be returned to the list of known accounts unless it’s connected again using the `connect()` method.

### getAccountIdenticon

`typescript` getAccountIdenticon(hex: string, size: number = 20): HTMLCanvasElement

````

This method generates a `<canvas>` HTML element to display the account identicon (aka avatar) of the public key.

It can be used with an account hash to display the hash ('#') symbol instead of a public key identicon.

On React, the `<AccountIdenticon>` component is available to wrap the call to this method.

### getActiveAccount

```typescript
getActiveAccount(): AccountType | null 
````

Gets the account for the current session (if any). Or `undefined` if there is no active session.

### getActiveAccountAsync

```typescript
getActiveAccountAsync(options?: GetActiveAccountOptions): Promise<AccountType | null> 
```

Gets the account for the current session (if any). Returns `undefined` if there is no active session.

Pass `options.withBalance = true` to include the balance of the account.

### getActivePublicKey

```typescript
getActivePublicKey(): Promise<string | undefined>
```

Gets the public key for the current session (if any). Or undefined if no active session.

### getCsprCloudProxy

```typescript
getCsprCloudProxy(): ICsprCloudProxy
```

Returns a CSPR.cloud proxy object that can be used to interact with the CSPR.cloud REST and Streaming APIs, as well to set up an Node RPC client with `casper-js-sdk`.

### getProviderInfo

```typescript
getProviderInfo(provider?: string): Promise<ProviderInfo|undefined>
```

Returns a [ProviderInfo](/cspr.click-v1.12/cspr.click-sdk/reference/types#providerinfo) object containing the information of the connected wallet, or the specified in the `provider` argument. Keep in mind that some information is only available if the wallet is connected (e.g. Version of Ledger can only be recovered if the hardware device is connected).

### getSignInOptions

```typescript
getSignInOptions(refresh: boolean = false): Promise<any>
```

Returns an object with a list of providers enabled to use in the application and a list of known accounts that can be used to sign in automatically with `signInWithAccount()`.

### init

```typescript
init(options: CsprClickInitOptions): void
```

Call `init` to initialize CSPR.click in your web application. This MUST be the first method you call after the downloading of the library.

See [CsprClickInitOptions ](/cspr.click-v1.12/cspr.click-sdk/reference/types#csprclickinitoptions)for reference on the `options` parameter.

### isConnected

```typescript
isConnected(provider: string): Promise<boolean | undefined>
```

Checks if the provider (not the account) indicated as the first argument is connected to the application. Note this check is independent of whether there's an active account on CSPR.click or not or even if that account belongs to the given provider.

### isProviderPresent

```typescript
isProviderPresent(provider: string): boolean
```

Checks if the provider indicated as the first argument is enabled in the application and installed (in case it’s a browser extension).

### isUnlocked

```typescript
isUnlocked(provider: string): Promise<boolean | undefined>
```

Returns `true` if the provider is unlocked. `false` if the provider is locked.

This method returns `undefined` when the provider does not offer this information.

### send

```typescript
send(transactionJSON: string | object, 
     signingPublicKey: string,
     onStatusUpdate: ((status: string, data: any) => void) | undefined = undefined,
     timeout: number = 120
  ): Promise<SendResult | undefined>
```

Triggers the mechanisms to request your user to sign a transaction with the active wallet.

When the user approves the signature, CSPR.click sends the transaction to the Casper network. A [SendResult ](/cspr.click-v1.12/cspr.click-sdk/reference/types#sendresult)object is returned with status information.

The `transactionJSON` is a json object (or a string) containing either a `Deploy` or a `TransactionV1`.

**Note:** If you're working with `Transaction` objects from `casper-js-sdk`, use the `transaction.toJSON()` method to get the object to pass as the first argument.

`signingPublicKey` MUST be the public key for the active account. Otherwise, this method will return an error.

Use `onStatusUpdate` to establish a websockets communication with CSPR.click backend and receive updates on the processing of the transaction sent.

There's a default waiting time of `120sec`. If the transaction is not processed in that time, the caller receives a `timeout` status update and the websocket connection is closed.

Example (see full example in CSPR.click project template):

```typescript
/* build a transaction object using Casper JS SDK */
const senderPk = activeAccount?.public_key?.toLowerCase() || '';
const transaction = new NativeTransferBuilder()
    .from(PublicKey.fromHex(senderPk))
    .target(PublicKey.fromHex(recipientPk))
    .amount('6' + '000000000')
    .id(Date.now())
    .chainName(clickRef.chainName!)
    .payment(100_000_000)
    .build();

/* define a status callback method to get updates during the transaction processing. 
   use this callback to update your UI on each step of the processing
*/
const onStatusUpdate = (status: string, data: any) => {
    console.log('STATUS UPDATE', status, data);
    if(status === TransactionStatus.SENT)
      setWaitingIndicator();
    if(status === TransactionStatus.PROCESSED)
      parseProcessedTransaction();
  };    

/* request a transaction signature and deploy the transaction via a node proxy */  
window.csprclick
  .send(transaction.toJSON() as object, sender, onStatusUpdate)
  .then((res: SendResult) => {
    // check result and update UI accordingly
  })
  .catch((err: any) => {
    alert('Error: ' + err);
    throw err;
  });
```

Check a list with possible processing status in the [SendResult](/cspr.click-v1.12/cspr.click-sdk/reference/types#sendresult) type reference.

### sign

```typescript
sign(transactionJSON: string | object, signingPublicKey: string): Promise<SignResult | undefined>
```

Triggers the mechanisms to request your user to sign a transaction with the active wallet.

A [SignResult ](/cspr.click-v1.12/cspr.click-sdk/reference/types#signresult)object is returned with the signature value or an `error`.

The `transactionJSON` is a json object (or a string) containing either a `Deploy` or a `TransactionV1`.

**Note:** If you're working with `Transaction` objects from `casper-js-sdk`, use the `transaction.toJSON()` method to get the object to pass as the first argument.

`signingPublicKey` MUST be the public key for the active account. Otherwise, this method will return an error.

### signIn

```typescript
signIn(): void
```

Triggers a request to a UI library to show a sign-in dialog.

### signInWithAccount

```typescript
signInWithAccount(account: AccountType): Promise<AccountType | undefined>
```

Starts a session with the indicated account. This account must be one of the accounts returned in `getKnownAccounts` or `getSignInOptions`.

Note that no interaction with the account provider is required to sign-in. CSPR.click will check and restore the connection if needed when there's a transaction or message to sign.

### signMessage

```typescript
signMessage(message: string, signingPublicKey: string): Promise<SignResult|undefined>
```

Triggers the mechanisms to request your user to sign a text message with the active wallet.

`signingPublicKey` MUST be the public key for the active account. Otherwise, this method will return an error.

### signOut

```typescript
signOut(): void
```

Closes an active session in your dApp.

Triggers the [`csprclick:signed_out`](/cspr.click-v1.12/cspr.click-sdk/reference/events#csprclick-signed_out) event.

### showBuyCsprUi

```typescript
showBuyCsprUi(): void
```

Displays the Buy CSPR widget. This widget allows the user to top-up his account with a credit card payment.

### switchAccount

```typescript
switchAccount(withProvider: string | undefined, options?: any): Promise<void>
```

Call this method to request to the specified wallet to offer the user the selection of a different account. This is valid for providers with its own UI (like browser extenstions).

Call this method without any provider to request CSPR.click UI to show the Switch Account modal window.


# Types

### AccountType

```
type AccountType = {
    provider: string,
    providerSupports: string[]|undefined,
    cspr_name: string | null,
    public_key: string | null,
    connected_at: Number,
    token: string | null,
    custom?: any,
    balance?: string,
    liquid_balance?: string;
    logo?: string;
}
```

<table><thead><tr><th width="201.33333333333331">Property</th><th>Description</th></tr></thead><tbody><tr><td>provider</td><td>The provider to which the account belongs to.</td></tr><tr><td>providerSupports</td><td>An array of supported capabilities in the connected wallet. Possible values: "sign-deploy", "sign-transactionv1", "sign-message".</td></tr><tr><td>cspr_name</td><td>CSPR.name name</td></tr><tr><td>public_key</td><td>The public key.</td></tr><tr><td>connected_at</td><td>Timestamp for the initial connection of the account</td></tr><tr><td>token</td><td>n/a (for future use)</td></tr><tr><td>custom</td><td>Custom data. Depends on the provider.</td></tr><tr><td>balance</td><td>Total balance of the account in CSPR motes (includes liquid +staked balance)</td></tr><tr><td>liquid_balance</td><td>Liquid balance of the account in CSPR motes (includes liquid +staked balance)</td></tr><tr><td>logo</td><td>A URL to the account avatar or logo.</td></tr></tbody></table>

### CsprClickInitOptions

```
type CsprClickInitOptions = {
    appName: string,
    appId: string,
    contentMode: 'iframe' | 'popup',
    casperNode?: string,
    chainName?: string,
    providers: Array<string>,
}
```

<table><thead><tr><th width="201.33333333333331">Property</th><th>Description</th></tr></thead><tbody><tr><td>appName</td><td>The name of your app as it will be shown in the pop-up windows.</td></tr><tr><td>appId</td><td>An application identifier. Read more about it <a href="/pages/XE4wdI9S2eIeAIJpWLRE">here</a>.</td></tr><tr><td>contentMode</td><td>Defines whether the sign in interface is shown within an iframe in your application or in external pop-up windows.</td></tr><tr><td>casperNode</td><td>The RPC endpoint CSPR.click uses to get information from the Casper network and to send deploys.</td></tr><tr><td>chainName</td><td>Use <code>casper</code> or <code>casper-test</code> to interact with Casper Mainnet or Casper Testnet, respectively.</td></tr><tr><td>providers</td><td>The list of providers (wallets) you want to allow in your application</td></tr><tr><td></td><td></td></tr></tbody></table>

The wallets you can add to the `providers` array are:

* `casper-wallet`
* `ledger`
* `metamask-snap`

### ProviderInfo

```
type ProviderInfo = {
    key: string,
    name: string,
    version: string,
    supports: Array<string>,
}
```

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td>key</td><td>Internal name of the provider (wallet).</td></tr><tr><td>name</td><td>Friendly/Huma readable name of the provider.</td></tr><tr><td>version</td><td>Version of the provider. Only available for some wallets, when they're installed and/or connected.</td></tr><tr><td>supports</td><td><p>Array of keys of the features supported. The values returned may depend on the connected version of the provider.</p><p>Currently, the possible supported features are: <code>sign-deploy</code>, <code>sign-transactionv1</code>, and <code>sign-message</code>.</p></td></tr></tbody></table>

### SendResult

```
type SendResult = {
    cancelled: boolean,
    deployHash: string | null,
    transactionHash: string | null,
    error: string | null,
    errorData: object | null,
    status: string | null;
    csprCloudTransaction: any;
}
```

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td>cancelled</td><td><code>true</code> when the user has declined the signature of the transaction. <code>false</code> otherwise</td></tr><tr><td>deployHash</td><td>The hash of the deploy signed and sent to the Casper network. <code>null</code> when the deploy signature has been cancelled or there was an error sending it to the network</td></tr><tr><td>error</td><td><code>null</code> if the deploy has been successfully signed and sent to the network. It contains an error message when the network rejects the deploy.</td></tr><tr><td>errorData</td><td>extra information on the error. It's usually a json object.</td></tr><tr><td>status</td><td>Indicates the status of the transaction sent. This property is helpful when used in combination with the `waitProcessing` in the `send()` method. Possible values: "sent", "processed", "created", "cancelled", "error", "timeout".</td></tr><tr><td>csprCloudTransaction</td><td>Raw json object returned by CSPR.cloud streaming API for a processed transaction. Check CSPR.cloud docs for detailed info on the contents.</td></tr></tbody></table>

### SignResult

```
type SignResult = {
    cancelled: boolean,
    signatureHex: string | null,
    signature: Uint8Array | null,
    deploy: object | null,
    transaction: object | null,
    error: string | null,
}
```

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td>cancelled</td><td><code>true</code> when the user has declined the signature of the transaction. <code>false</code> otherwise</td></tr><tr><td>signatureHex</td><td>An hexadecimal string with the crytpographic signature of the deploy.</td></tr><tr><td>signature</td><td>A byte array with the cryptographic signature of the deploy.</td></tr><tr><td>deploy</td><td>A json object containing the deploy with the user approval entry (i.e., the new signature).</td></tr><tr><td>error</td><td><code>null</code> if the deploy has been successfully signed. It contains an error message otherwise.</td></tr></tbody></table>


# Events

The CSPR.click library emits several events you may need to handle to update your app accordingly.

Listen to these events calling the `on()` method with a callback handler. For example:

```typescript
csprclick.on('csprclick:signed_in', async (evt) => {
  //update your app content for the new session
  console.log("Connected account: " + evt.account.public_key)
});
```

### csprclick:loaded

This event is emitted when the CSPR.click library initialization is complete. Usually, you shouldn’t call any method in the library (apart from init()) before this event occurs.

Use `once()` to bind the callback handler instead of `on()` for this event since it’s triggered only once.

### csprclick:signed\_in

This event is emitted when the CSPR.click library connects to a new account. Previously, either `csprclick.connect()` or `csprclick.signInWithAccount()` methods must have been called by the application.

Receives an [AccountType](/cspr.click-v1.12/cspr.click-sdk/reference/types#accounttype) object with data about the newly connected account.

### csprclick:switched\_account

This event is emitted when CSPR.click library switches connection from one account to another after the application has called `csprclick.switchAccount()` method.

Receives an [AccountType ](/cspr.click-v1.12/cspr.click-sdk/reference/types#accounttype)object with data about the newly connected account.

### csprclick:unsolicited\_account\_change

This event is emitted when there's an account connected to the application and the user changes the active account in his wallet, but the application hasn't requested the change calling `connect()` or `switchAccount()` methods.

When CSPR.click UI SDK is being used, the application shows a pop up notice where the user can confirm if he wants to switch the current session to the new account or keep the current one.

If you're not using CSPR.click UI SDK, your application should define a handler for this event and confirm the account change by calling `signInWithAccount()` method. For example:

```typescript
csprclick.on('csprclick:unsolicited_account_change', async (evt) => {
  window.csprclick.signInWithAccount(evt.account);
});
```

When the new account is connected, the SDK will emit the event `csprclick:signed_in`.

### csprclick:signed\_out

This event is emitted when the CSPR.click library disconnects the active account due to a call to the `signOut()` SDK method.

### csprclick:disconnected

This event is emitted when CSPR.click library receives a disconnect request or event from the connected wallet. The app should close the current session as a consequence of this event.

Receives the provider that has been disconnected.

### csprclick:sign\_in

Indicates that the signIn() method has been called. In your app, you should typically respond to these event showing the sign-in options to the user (e.g. list of wallets, list of known accounts, etc.).


# CSPR.cloud proxies

CSPR.click provides a proxy to interact with the CSPR.cloud REST and Streaming APIs, as well as to set up a Node RPC client with `casper-js-sdk`. This is helpful when you want to interact with the CSPR.cloud APIs from the frontend of your application, as CSPR.cloud APIs require authentication and you must not expose your API keys in the frontend.

## Configuration of CSPR.cloud proxy on CSPR.build

The proxy functionality is disabled by default to protect your CSPR.cloud usage quota. To enable it, you need to edit your CSPR.click app configuration on [CSPR.build](https://console.cspr.build).

Enable only the proxies you need and only for the methods you require in your frontend application for better security.

## REST API proxy

The REST API proxy allows you to interact with the [CSPR.cloud REST APIs](https://docs.cspr.cloud/rest-api/reference) from the frontend of your application. The proxy will add the necessary authentication headers to your requests.

Use the `fetch()` method of the `ICsprCloudProxy` instance obtained from the `getCsprCloudProxy()` method. The method signature is the same as the `fetch()` method of the browser's `window` object.

Example of calculating the current APY:

```typescript
const getAPY = async () => {
  const cloudProxy = window.csprclick.getCsprCloudProxy();
  const metrics = await cloudProxy.fetch('/auction-metrics?includes=total_active_era_stake');
  const supply = await cloudProxy.fetch('/supply');
  
  const totalStakeInMotes = Big(metrics.data.total_active_era_stake).div(1000000000);
  
  return Big(supply.data.total)
    .mul(supply.data.annual_issuance)
    .div(totalStakeInMotes)
    .toString();
};
```

## Streaming API proxy

The Streaming API proxy allows you to interact with the [CSPR.cloud Streaming APIs](https://docs.cspr.cloud/streaming-api/reference) from the frontend of your application. The proxy will add the necessary authentication headers to your requests.

Use the `newWebSocket()` method of the `ICsprCloudProxy` instance obtained from the `getCsprCloudProxy()` method. The method returns a [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) instance.

Example of setting up a WebSocket connection to listen for native transfers:

```typescript
  const proxy = window.csprclick.getCsprCloudProxy();
  // @ts-ignore
  const ws = proxy.newWebSocket('/transfers');

  // Set up event listeners
  ws.onopen = (event) => {
    console.log('WebSocket connection opened:', event);
  };

  ws.onmessage = (event) => {
    console.log('WebSocket message received:', event.data);

    // Try to parse JSON if possible
    try {
      const parsedData = JSON.parse(event.data);
      console.log('Parsed WebSocket data:', parsedData);
    } catch (error) {
      console.log('WebSocket data (raw):', event.data);
    }
  };

  ws.onerror = (error) => {
    console.error('WebSocket error:', error);
  };

  ws.onclose = (event) => {
    console.log('WebSocket connection closed:', event.code, event.reason);
  };
```

### Node RPC client proxy

The Node RPC client proxy allows you to interact with the Casper node RPC interface from the frontend of your application. In this case, CSPR.click provides you with the proxy URL and a token to use with the `RpcClient` class from the `casper-js-sdk` library.

```typescript
  const proxy = window.csprclick.getCsprCloudProxy();
  const rpcHandler = new HttpHandler(proxy.RpcURL, 'fetch');
  rpcHandler.setCustomHeaders({ Authorization: proxy.RpcDigestToken });
  const rpcClient = new RpcClient(rpcHandler);

  const stateRootHash = await rpcClient.getStateRootHashLatest();
  console.log('State root hash:', stateRootHash.stateRootHash.toHex());
```


# Contact us

Should you have any questions about CSPR.click or need assistance with the integration, please join our telegram channel CSPR Developers Group with this link:

* CSPR Developers Group: <https://t.me/CSPRDevelopers>


# Introduction

<figure><img src="/files/tUWFyFMTNpBXgjBwFUK6" alt="" width="563"><figcaption></figcaption></figure>

CSPR.click is a unified SDK that simplifies Web3 application onboarding by offering seamless integration with all wallets, facilitating easy user transitions between Web3 apps, and providing developers and users a consistent and secure interface for managing Web3 assets and interactions. Please check out the CSPR.click home page for more information: [CSPR.click](https://cspr.click).

This documentation compiles important guidelines on how to use the CSPR.click SDKs.

## Reference

To get familiar with CSPR.click, we recommend that you read these documents:

* [Overview](/cspr.click-v1.11/documentation/overview)\
  Learn about the general technical aspects of CSPR.click SDK, and how it works.
* [Getting started](/cspr.click-v1.11/documentation/getting-started)\
  Learn the basic concepts while creating a dApp from zero with CSPR.click React template.

## Support

If you have any questions or run into any issues while using the CSPR.click SDKs, you can find help in the [CSPR.click Developer Community](https://t.me/CSPRDevelopers). Here you can connect and get help from other developers.

## Legal

By using CSPR.click, you agree to our [Developer Terms of Service](https://cspr.click/terms-of-service/) and acknowledge that you have read our [Privacy Policy](https://cspr.click/privacy-policy/).


# Overview

In any web application that integrates CSPR.click you'll be using the Core Web SDK. It provides the essential functionality to interact with wallets and the CSPR.click servers. Through it, you'll request a connection with a wallet to start a user session, and ask the user to sign a transaction or a message. You'll get a complete graphical interface that manages for you the interactions with the user to perform the account management and the signature requests operations.

## Get your application Id

To initialize CSPR.click library, you need an `appId` for your application. By default, our examples use the `csprclick-template` identifier. You may use this value to try out CSPR.click and start developing your application.

Note, though, that this identifier is *only valid for development on `localhost`*. Before you push your application to a server, you must get your own `appId` on [console.cspr.build](https://console.cspr.build).

## Supported wallets

CSPR.click supports almost every wallet built for the Casper ecosystem.

<table><thead><tr><th width="120">Wallet</th><th>Provider key</th><th>Name</th></tr></thead><tbody><tr><td><img src="https://accounts.cspr.click/assets/casper-wallet-sign.png" alt="Casper Wallet logo"></td><td><code>casper-wallet</code></td><td>Casper Wallet</td></tr><tr><td><img src="https://accounts.cspr.click/assets/ledger-logo-small.png" alt="Ledger logo"></td><td><code>ledger</code></td><td>Ledger</td></tr><tr><td><img src="https://accounts.cspr.click/assets/walletconnect-sign.svg" alt="WalletConnect logo"></td><td><code>walletconnect</code></td><td>WalletConnect</td></tr><tr><td><img src="https://accounts.cspr.click/assets/metamask-logo-small.png" alt="Metamask logo"></td><td><code>metamask-snap</code></td><td>Metamask (Snap)</td></tr></tbody></table>

In your application, you can decide which wallets you want to enable. To do so, set accordingly the array of providers in the [CsprClickInitOptions ](https://github.com/make-software/casper-click-websdk/blob/documentation-v1.11/docs/csprclick-sdk/reference/types.md#csprclickinitoptions)initialization object.

```javascript
const clickOptions: CsprClickInitOptions = {
    appName: 'CSPR.playground',
    appId: 'csprclick-template',
    contentMode: CONTENT_MODE.IFRAME,
    providers: [
        WALLET_KEYS.CASPER_WALLET,
        WALLET_KEYS.LEDGER,
        WALLET_KEYS.METAMASK_SNAP,
    ],
};
```

### WalletConnect

WalletConnect is a protocol that provides a secure and convenient way for users to interact with decentralized applications. CSPR.click supports WalletConnect as a provider, allowing users to connect their WalletConnect-compatible wallets to your application.

To use WalletConnect with CSPR.click, you need to have a WalletConnect project ID. You can get one by creating a project on the [WalletConnect Cloud](https://dashboard.reown.com/).

Once you have your project ID, you can add it to your CSPR.click initialization options like this:

```javascript
const clickOptions: CsprClickInitOptions = {
    appName: 'CSPR.playground',
    appId: 'csprclick-template',
    contentMode: CONTENT_MODE.IFRAME,
    providers: [
        WALLET_KEYS.CASPER_WALLET,
        WALLET_KEYS.LEDGER,
        WALLET_KEYS.METAMASK_SNAP,
        WALLET_KEYS.WALLET_CONNECT,
    ],
    walletConnect: {
        relayUrl: 'wss://relay.walletconnect.com',
        projectId: '6cdf3...9cc4d'
    }
};
```


# Getting started

This page guides you through the steps to create a new React application for your project with CSPR.click UI SDK integrated and ready to use.

{% hint style="info" %}
If you want to integrate CSPR.click UI SDK into your existing React application, go to the [React](/cspr.click-v1.11/cspr.click-sdk/react) section. If you're not using React in your application, you can learn how to integrate CSPR.click in the [Javascript](/cspr.click-v1.11/cspr.click-sdk/javascript) section.
{% endhint %}

## Create a new project

To create a new React project with CSPR.click ready to use, write the following command in a terminal session:

```
npx create-react-app my-casper-app --template @make-software/csprclick-react
```

Next, go to the newly created project directory and run the app:

```
cd my-casper-app
npm start
```

Your new app will open in your browser. If it doesn't, browse to the URL: <http://localhost:3000>.

<figure><img src="/files/1Rckjh2Jtvr4lQgPWmci" alt=""><figcaption><p>Your new application</p></figcaption></figure>

## Adjust the initialization options

Your new project comes with some default initialization options. You'll need to review them and adjust some.

Open the file `src/index.tsx` and locate the definition of the `clickOptions` variable. It'll look similar to this:

```typescript
import { CONTENT_MODE } from '@make-software/csprclick-core-types';

const clickOptions: CsprClickInitOptions = {
    appName: 'CSPR.app',
    appId: 'csprclick-template',
    contentMode: CONTENT_MODE.IFRAME,
    providers: [
        'casper-wallet',
        'ledger',
        'casper-signer',
    ]
};
```

You can use the default `csprclick-template` application identifier while you're working locally on your application. But to upload your new project to a server, you'll need to [get your own application id](/cspr.click-v1.11/documentation/overview).

Update the properties according to your needs. Read more about the [CsprClickInitOptions ](/cspr.click-v1.11/cspr.click-sdk/reference/types#csprclickinitoptions)type in the Core JS SDK reference.

These options are sent to CSPR.click through the `<ClickProvider>` component that wraps your main application component:

```tsx
<ClickProvider options={clickOptions}>
  <App/>
</ClickProvider>
```

## What's next

You're almost ready to start developing the next web3 killer app. Before you get cracking on your project, get familiar with some crucial aspects of CSPR.click that are demonstrated in the template:

#### Responding to CSPR.click events

The `App` component sets handlers to listen and respond to events triggered by CSPR.click when the user connects an account, switches to a different one, or closes the session.

Refer to the [Handling events](/cspr.click-v1.11/cspr.click-sdk/react/handling-events) page for information on how to add your listener functions.

#### Customize the top navigation bar

The template displays some settings selectors in the top navigation bar. Find the `ClickTopBar` component in `src/components/ClickTopBar/index.tsx` and see how these settings are defined.

Refer to the [Customizing the top bar](/cspr.click-v1.11/cspr.click-sdk/react/customizing-the-top-bar) section for complete reference on how to work with each of the setting elements in the top bar.

#### Request transaction approvals

At some point, your application will need to interact with the Casper network by sending a transaction (aka deploy).\
CSPR.click manages this process communicating with the active wallet to request the user to approve or reject the transaction. The UI depends on the wallet.

The template includes the `BuyMeACoffee` components to demonstrate how to request a transaction signature and send the approved deploy to the network.

Refer to the [Signing transactions](/cspr.click-v1.11/cspr.click-sdk/react/signing-transactions) page for information on how to request the user a transaction approval. Also, look at [Processing status updates](https://github.com/make-software/casper-click-websdk/blob/documentation-v1.11/docs/public/javascript/processing-status-updates.md) for information on how to listen for real-time status updates.


# Changelog

*Note: patch versions are not released as npm packages if interfaces haven't changed with respect to the previous version.*

## v1.11.0 - October 13th, 2025

* Enhanced WalletConnect sign in flows for a better user experience with Casper Wallet Mobile.

## v1.10.0 - September 12th, 2025

* new `<AccountCardMenuItem>` component to display account information in the account dropdown menu (includes account name, public key and liquid/total balances). Replaces `<ViewAccountOnExplorerMenuItem>`.

## v1.9.0 - July 22th, 2025

* new `onStatusUpdate` in the `send()` methods arguments. When used, CSPR.click opens a websockets connection with CSPR.cloud backend to receive processing status updates for the deployed transaction.
* Integration with Google Sign in and Apple Id for CSPR.click web wallet.

## v1.8.0 - Apr 30th, 2025

* new `providerSupports` property in the account object to indicate if the connected wallet supports signing with the `TransactionV1` transaction model.
* CSPR.name enhanced support.

## v1.7.0 - Dec 23rd, 2024

* Support for the new transaction model `TransactionV1`.
* Updated Casper Wallet, Ledger, and Metamask Snap integrations to newest versions (all support now Casper 2.0).
* Deprecation notice for CasperDash wallet.

## v1.6.0 - Oct 16th, 2024

* Enhanced colors customization for the CSPR.click top bar UI elements.

## v1.5.0 - July 18th, 2024

* Torus and Casper Signer deprecation notices. These wallets will be removed in the next minor version.
* Added CSPR.name names to accounts in the UI overlays.

## v1.4.0 - Mar 5th, 2024

* Added Casper Wallet mobile universal links to enhance the user experience on mobile applications.
* New JWT provider for CSPR.click web wallet.
* New identicon component available to developers.

## v1.3.0 - Jan 19th, 2024

{% hint style="info" %}
**Important note if you're upgrading your app to `1.3.0` from a previous version.** `<ClickTopBar>` component has been replaced with new `<ClickUI>` component. The latter permits a more granular configuration for the elements that the developer wants to display in their application. For example, to not include the top navigtaion bar.

Check [this](https://docs.cspr.click/ui-sdk/integrating-the-ui-sdk-into-your-application#add-less-than-clickui-greater-than-component-to-your-app) section for `<ClickUI>` component reference.
{% endhint %}

* New Buy CSPR UI to select between different onramp platforms.
* Integration with Ramp.
* CSPR.click navigation bar is now optional. Applications that have their own controls for signing in and displaying connected accounts, can exclude this component.

## v1.2.1 - Jan 8th, 2024

* fixed a bug that caused people using different Ledger devices to not be able to sign in with the second device without signing out and reloading the web page.
* fixed a bug that might cause transaction signature rejection when the user had different accounts in different tabs for the same application.
* UI fixes

## v1.2.0 - Dec 12th, 2023

* new API csprclick.switchAccount() to trigger the UI that permits to connect to another account.
* Previously used accounts are now shown in most recently used order.
* UI fixes.
* new API csprclick.switchAccount() to trigger the UI that permits to connect to another account.
* Previously used accounts are now shown in most recently used order.
* UI fixes.

## v1.1.4 - Dec 1st, 2023

* CSPR.click now detects if it's running within a mobile wallet in-app browser to skip wallet selection UI in sign-in flow.
* Ledger now works on Android devices.
* UI now shows an animation in account widget during loading.
* CSPR.click now display a warning if Casper app version in the Ledger device is outdated.

## v1.1.0 - Nov 1st, 2023

* Added Buy CSPR menu item to account dropdown menu.
* UI/UX improvements.

## v1.0.0 - Oct 10th, 2023

* Initial release.


# React

{% hint style="info" %}
To create a new application with CSPR.click already integrated, we recommend you to use the `create-react-app` template as described in [Getting started](/cspr.click-v1.11/documentation/getting-started).
{% endhint %}

This page guides you through the steps required to integrate the CSPR.click SDK into your existing React web application.

## Install CSPR.click packages

Run the following command in a terminal window to install CSPR.click packages:

```bash
npm install --save-dev @make-software/csprclick-ui @make-software/csprclick-core-client @make-software/csprclick-core-types
```

If you're using Typescript, the command above also installs type definitions for CSPR.click.

## ClickProvider context provider

First, define the initialization options for the CSPR.click library:

```typescript
import { CONTENT_MODE } from '@make-software/csprclick-core-types';

const clickOptions: CsprClickInitOptions = {
    appName: 'Casper dApp',
    appId: 'csprclick-template',
    contentMode: CONTENT_MODE.IFRAME,
    providers: ['casper-wallet', 'ledger', 'metamask-snap', 'casperdash'],
};
```

Next, wrap your main application component with the `<ClickProvider>` context provider:

```tsx
<ClickProvider options={clickOptions}>
  <App />
</ClickProvider>
```

This component will manage the download and initialization of the CSPR.click runtime library.

Read more about the [CsprClickInitOptions ](/cspr.click-v1.11/cspr.click-sdk/reference/types#csprclickinitoptions)type in the SDK reference section.

{% hint style="info" %}
You can use the default `csprclick-template` application identifier while you're working locally on your application. But to upload your new project to a server, you'll need to [get your own application id](https://github.com/make-software/casper-click-websdk/blob/documentation-v1.11/docs/overview.md).
{% endhint %}

## Add \<ClickUI> component to your app

All the CSPR.click UI elements are managed from the `<ClickUI>` component. This component must be added to the very beginning of your main UI component and it's responsible for displaying the top bar and all the modal windows and pop-ups needed for connecting with wallets, showing information to the user, etc.

```tsx
const topBarSettings = {
    accountMenuItems: [<ViewAccountOnExplorerMenuItem key='0' />],
}

const App = () => {
    return (
        <!-- ... -->
        <ClickUI topBarSettings={topBarSettings}/>
        <!-- ... -->
    )
}
```

Refer to the [Customizing the top bar ](/cspr.click-v1.11/cspr.click-sdk/react/customizing-the-top-bar)section in this guide for complete reference on how to work with each of the setting elements in the top bar.

{% hint style="info" %}
While we recommend to include the CSPR.click top bar in your application, if you have your own Sign in and session management controls you can opt-out. To do so, do not include the `topBarSettings` prop to `ClickUI` and CSPR.click won't render the top bar.
{% endhint %}

## Add CSPR.click styles

### Option 1: your application uses styled-components

When your application already uses the \<ThemeProvider> component from styled-components library, you just need to add CSPR.click styles to your themes.

Considering as an example that your application has `light` and `dark` themes, you may merge the styles into your theme settings like this:

```typescript
import { CsprClickThemes } from '@make-software/csprclick-ui';

const YourAppThemes = {
	dark: {
		...CsprClickThemes.dark,
		// your styles for dark theme here
	},
	light: {
		...CsprClickThemes.light,
		// your styles for light theme here
	},
};
```

### Option 2: your application doesn't use styled-components

CSPR.click requires the `styled-components` library to work. Add it to your dependencies by running the command:

```
npm install --save styled-components@5.3.9
```

Next, add the theme provider to your application:

```tsx
import { CsprClickThemes } from '@make-software/csprclick-ui';

<ThemeProvider theme={CsprClickThemes.light}>
  <ClickProvider options={clickOptions}>
    <App />
  </ClickProvider>
</ThemeProvider>
```

Currently, you can choose between two themes: `light` and `dark`.

### Import required fonts

In your main CSS file, import the Inter and Jetbrains mono fonts:

```
@import url('https://fonts.cdnfonts.com/css/inter');

@font-face {
    font-family: 'JetBrains Mono';
    src: url('https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff2/JetBrainsMono-Regular.woff2')
        format('woff2'),
      url('https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff/JetBrainsMono-Regular.woff')
        format('woff');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
  }
```

## What's next

At this point, your application is prepared to display the CSPR.click UI to interact with the user and connect with wallets, switch to other accounts and approve transactions. Build and run your application, and take a look.

From here, your application needs to interact with CSPR.click library to, for example, respond to wallet connection and request transaction approvals. Go through the following sections as required to complete the integration:

#### Listen to CSPR.click events

You'll need to listen and respond to some events triggered when the user connects an account, switches to a different one, or closes the session.

Refer to the [Handling events](/cspr.click-v1.11/cspr.click-sdk/react/handling-events) page for information on how to add your listener functions.

#### Ask the user to connect a wallet

If you don't display the CSPR.click top navigation bar, you must have your own Sign in or Connect buttons and respond calling the CSPR.click library .

Refer to the [Connecting a wallet](/cspr.click-v1.11/cspr.click-sdk/react/connecting-a-wallet) page for information on how to trigger the wallet connection process.

#### Request transaction approvals

At some point, your application will need to interact with the Casper network by sending a transaction (aka deploy).\
CSPR.click manages this process communicating with the active wallet to request the user to approve or reject the transaction. The UI depends on the wallet.

Refer to the [Signing transactions](/cspr.click-v1.11/cspr.click-sdk/react/signing-transactions) page for information on how to request the user a transaction approval. Also, look at [Processing status updates](/cspr.click-v1.11/cspr.click-sdk/react/processing-status-updates) for information on how to listen for real-time status updates.

#### Customize the top navigation bar

You can add any of our predefined settings selectors or account menu items. And you can define your own.

Refer to the [Customizing the top bar](/cspr.click-v1.11/cspr.click-sdk/react/customizing-the-top-bar) section for complete reference on how to work with each of the setting elements in the top bar.


# Handling events

In your application, you'll need to listen and respond to different events emitted by the CSPR.click library. On this page, we're covering the most common. Check the [Events](/cspr.click-v1.11/cspr.click-sdk/reference/events) page for a complete list of events.

The following code snippet shows an example of how to bind your handlers to the CSPR.click events with the React `useEffect()` hook:

```tsx
const clickRef = useClickRef();

useEffect(() => {
  clickRef?.on('csprclick:signed_in', async (evt) => {
    // update your app accordingly
  });
  clickRef?.on('csprclick:signed_out', async (evt) => {
    // update your app accordingly
  });
}, [clickRef?.on]);
```

### csprclick:signed\_in

This event is emitted every time the CSPR.click library connects to an account.

[csprclick:signed\_in](/cspr.click-v1.11/cspr.click-sdk/reference/events#csprclick-signed_in) reference.

### csprclick:switched\_account

This event is emitted instead of `csprclick:signed_i` when the user has clicked on the Switch Account menu item and has switched to another account in the same or a different wallet.

[csprclick:switched\_account](/cspr.click-v1.11/cspr.click-sdk/reference/events#csprclick-switched_account) reference.

### csprclick:signed\_out

This event is emitted when the CSPR.click library disconnects the active account due to a call to the `signOut()` SDK method.

[csprclick:signed\_out](/cspr.click-v1.11/cspr.click-sdk/reference/events#csprclick-signed_out) reference.

### csprclick:disconnected

This event is emitted when CSPR.click library receives a disconnect request or event from the connected wallet. The app should close the current session as a consequence of this event.

It receives in the event object the provider that has been disconnected.

[csprclick:disconnected](/cspr.click-v1.11/cspr.click-sdk/reference/events#csprclick-disconnected) reference.


# Connecting a wallet

If you're not displaying the top navigation bar you'll need to have you own UI components to let the user connect a wallet, display the connected account, switch to another account, and disconnect. In this page we're describing how to use the CSPR.click library to perform these operations.

## Sign in

When the user clicks on your 'Sign in' or 'Connect wallet' button, call the `signIn()` method to display the wallet selector window:

```tsx
clickRef.signIn()
```

This method returns immediately. Listen to the library events to get a notification of connection.

## Switch account

To let the user to change to another account, call the `switchAccount()` method:

```tsx
clickRef.switchAccount()
```

This method returns immediately. Listen to the library events to get a notification of connection.

## Disconnect

To close the current user session, call the `signOut()` method:

```tsx
clickRef.signOut()
```

This call does not request the connected wallet to disconnect from your application, so next time the user wants to sign in he'll not need to go through the connection step. If you want to disconnect completely the wallet from your app, call the `disconnect()` method:

```tsx
clickRef.disconnect()
```


# Signing transactions

Applications interacting with the Casper Network must submit transactions. Every transaction requires explicit user approval, which is done by digitally signing it.

Your frontend application is not always responsible for creating the transaction. Depending on your architecture, a transaction may be constructed by your backend service, or even by a third party, before being sent to the user for approval.

Typically, you'll handle a transaction without approvals. And such approval is what you want to get from the user. Then, the transaction will be ready to be processed by a Casper node.

The CSPR.click SDK provides two ways to obtain this approval:

1. [`send()`](/cspr.click-v1.11/cspr.click-sdk/reference/methods#send).

* Requests the active wallet to prompt the user for approval (signature).
* Automatically submits the signed transaction to a Casper node for processing.
* Optionally accepts a callback function to receive live status updates during execution (e.g., pending, confirmed, rejected).

This is the most common method. In most applications, you can simply call send() and use its result or the status updates to inform the user whether their transaction is being processed, or if it was rejected (by either the user or the network).

2. [`sign()`](/cspr.click-v1.11/cspr.click-sdk/reference/methods#sign).

* Requests the active wallet to prompt the user for approval.
* Returns the signature value to your application, without submitting the transaction.

This method is intended for advanced scenarios, where you need the raw signature for custom workflows (e.g., off-chain processing, server-side validation, or multi-step transaction orchestration).

## Buy Alice a Coffee on testnet

In the React `create-react-app` [template ](/cspr.click-v1.11/documentation/getting-started#create-a-new-project)we've added an example that shows how to request the approval for a transaction that sends to Alice (an imaginary colleague in our team) 50 CSPR testnet tokens;

<figure><img src="/files/Kiu9Nj2wTo71dgSuZpvv" alt=""><figcaption><p>Example in the template project</p></figcaption></figure>

Take a look into the `<BuyMeACoffee>` component. Here are the key parts:

1. **Build the transaction**

First, construct a transfer transaction. Thecasper-js-sdk is included in this template to help you with this step. Refer to the official Casper SDK documentation for more detailed usage and examples.

2. **Send the transaction**

Next, call the clickRef.send() method. CSPR.click will:

* Prompt the user in the active wallet to review and sign the transaction.
* Forward the signed transaction to a Casper node for processing.

3. **Handle responses**

Your application should be prepared to handle all possible outcomes:

* Success: The transaction was sent and you receive a transaction hash.
* User rejection: The user declined to sign the transaction.
* Network rejection: The Casper node rejected the transaction.

You can handle responses using the .then() and .catch() blocks, or use the status updates as explained in the next step.

4. **(Optional) Track transaction status**

The `.send()` method accepts an optional callback function as its second argument. This callback receives transaction status updates while the transaction is being executed, enabling you to:

* Show progress indicators in your UI (e.g., “Transaction pending…”)
* Update users when the transaction is confirmed or fails
* Provide richer feedback beyond just the final outcome

```tsx
function BuyMeACoffee() {
  const clickRef = useClickRef();
  const activeAccount = clickRef?.getActiveAccount();
  const [transactionHash, setTransactionHash] = useState<string>('');
  const [waitingResponse, setWaitingResponse] = useState<boolean>(false);

  const signAndSend = (transactionObj: object, sender: string) => {
          const onStatusUpdate = (status: string, data: any) => {
            console.log('STATUS UPDATE', status, data);
            if(status === TransactionStatus.SENT)
              setWaitingResponse(true);
          };
      
          clickRef
            ?.send(transactionObj, sender, onStatusUpdate)
            .then((res: SendResult | undefined) => {
                setWaitingResponse(false);
                if (res?.transactionHash) {
                    setTransactionHash(res.transactionHash);
                    alert('Transaction sent successfully: ' + res.transactionHash +
                        '\n Status: ' +
                        res.status +
                        '\n Timestamp: ' +
                        res.csprCloudTransaction.timestamp);
              } else if (res?.cancelled) {
                alert('Sign cancelled');
              } else {
                alert('Error in send(): ' + res?.error + '\n' + res?.errorData);
              }
            })
            .catch((err: any) => {
              alert('Error: ' + err);
              throw err;
            });
  };

  const handleSignTransaction = (evt: any) => {
    evt.preventDefault();
    const sender = activeAccount?.public_key?.toLowerCase() || '';
    const transaction = makeTransferTransaction(
            sender,
            recipientPk,
            '50' + '000000000',
            clickRef.chainName!
    );
    signAndSend(transaction as object, sender);
  };
	
  return (
    ...
    <button onClick={() => handleSignTransaction()} />Sign and send transaction</button>
    ...
  )
}
```


# Tracking your transactions in real time

When using the `send()`method to request a transaction approval and deploy it to the network, the SDK can, optionally, establish a websocket connection with CSPR.click backend and receive real-time updates about the transaction execution.

Traditionally, applications had to rely on polling a backend service or querying a Casper node to know whether a transaction had been processed, confirmed, or rejected. This approach added complexity, increased latency, and delayed the user experience.

Using a websockets connection to listen for real-time updates, your application can:

* Receive immediate status notifications during the full transaction lifecycle.
* Update your UI with progress states (e.g., pending, processed, failed).
* Access result data without the need for extra API calls.

This makes it easier to build responsive, user-friendly applications that keep users informed in real time as their transactions move through the Casper Network.

<figure><img src="/files/HWfT94c0G5JCiJf56qFp" alt="Waiting for transaction completion"><figcaption></figcaption></figure>

## Receive transaction updates

To wait for transaction execution and receive status updates, pass a callback function to the `send()` method. This function will be called with status updates as the transaction is approved and processed.

```javascript
const onStatusUpdate = (status, data) => {
    console.log('STATUS UPDATE', status, data);
    if (status === TransactionStatus.SENT)
        setWaitingIndicator();
    if (status === TransactionStatus.PROCESSED)
        parseProcessedTransaction();
};

clickRef
    .send(transaction, sender, onStatusUpdate)
    .then((res) => {
        // check result and update UI accordingly
    })
    .catch((err) => {
        alert('Error: ' + err);
        throw err;
    });
```

### Status values

The `status` argument passed to the callback function can have the following values:

| Value       | Description                                                                                                                           |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `sent`      | The transaction has been signed and successfully deployed to a Casper node.                                                           |
| `processed` | The transaction has been executed by the network. May result in success or failure.                                                   |
| `expired`   | The transaction’s time-to-live (TTL) elapsed before execution.                                                                        |
| `cancelled` | The user rejected the signature request.                                                                                              |
| `timeout`   | The SDK stopped listening for updates before the transaction was finalized. A custom timeout can be specified (default: 120 seconds). |
| `error`     | An unexpected error occurred while submitting or monitoring the transaction.                                                          |
| `ping`      | A heartbeat event sent periodically to indicate that the connection is still active..                                                 |

### Data with processed Status

When the transaction reaches the processed state, the callback function receives an additional data argument.

This object contains the full `Deploy` entity, as defined in the [CSPR.cloud REST API documentation](https://docs.cspr.cloud/rest-api/deploy#properties).

Your application can use this information to:

* Show whether the transaction succeeded or failed.
* Provide more detailed feedback (e.g., execution cost, error messages).


# Customizing the top bar

{% hint style="info" %}
While we recommend to include the CSPR.click top bar in your application, if you have your own Sign in and session management controls you can opt-out. To do so, do not include the `topBarSettings` prop to `ClickUI` and CSPR.click won't render the top bar.
{% endhint %}

CSPR.click includes a navigation bar that displays on the top of the web application. It's the same navigation bar you can find on CSPR.live and other applications that integrate CSPR.click.

<figure><img src="/files/rc1WgfG5MdI45vHoAYjG" alt=""><figcaption><p>CSPR.click navigation bar</p></figcaption></figure>

In this top bar you always see the CSPR Products menu on the left side, and the Account menu on the right side. The rest are customizable selectors that you can choose to add or not. Most of them are customizable as we'll see in the next pages.

### TopBarSettings object

This object wraps all settings in the navigation bar and is included to `<ClickUI>` as a prop. More on each configuration in the following subpages.

```tsx
const topBarSettings: TopBarSettings = {
    accountMenuItems,
    onThemeSwitch: toggleTheme,
    languageSettings: languageSettings(lang, setLang),
    currencySettings: currencySettings(currency, setCurrency),
    networkSettings: networkSettings(network, setNetwork),
};

<ClickUI
    topBarSettings={topBarSettings}
    themeMode={themeMode}
/>
```


# Account dropdown menu

You can customize the account dropdown menu in our top bar with your own menu items. Options to switch to another account and sign out are always present at the end of the list. The rest, depends on your needs. We provide a couple of common menu item components you may add, and one component for you to include anything you need.

<figure><img src="/files/A1Xjj24e7AfooidhCsxf" alt=""><figcaption></figcaption></figure>

## Account dropdown menu set up

To customize the account dropdown menu, add the menu items you want to display into an array:

```tsx
const accountMenuItems = [
  <AccountCardMenuItem key={0} />,
  <CopyHashMenuItem key={1} />,
  <AccountMenuItem
    key={2}
    onClick={() => {
        window.location.href = 'https://cspr.click';
    }}
    icon={CSPRClickIcon}
    label={'CSPR.click docs'}
    badge={{ title: 'new', variation: 'green' }}
  />,
];
```

Then, add the array to the `<ClickUI>` component:

```tsx
<ClickUI
    topBarSettings={{
        accountMenuItems
    }}
/>
```

## Prebuilt menu items

### Account card

```tsx
<AccountCardMenuItem />
```

Renders a card with account information at the top of the dropdown menu. The card includes the account name, public key and liquid/total balances. The account also links to CSPR.live.

By default, balances are shown in `USD` currency. If your application supports multiple currencies, you can pass the `currency` prop to the `<ClickUI>` component to display the balances in the selected currency:

```tsx
<ClickUI
    topBarSettings={topBarSettings}
    themeMode={themeMode}
    currencyCode={currency.code}
/>
```

See in the template project how to set up the currency selector connected to the account card.

### View account on CSPR.live

```tsx
<ViewAccountOnExplorerMenuItem />
```

Alternative to the account card. Renders a menu item in the account dropdown menu to open the CSPR.live account page in a new tab.

### Copy public key

```tsx
<CopyHashMenuItem />
```

Renders a menu item in the account dropdown menu to copy the connected public key to the clipboard.

### Buy CSPR

```tsx
<BuyCSPRMenuItem />
```

Renders a menu item in the account dropdown menu to open the [Topper by Uphold](https://www.topperpay.com/) widget on a new tab. This widget allows the user to top-up his account with a credit card payment.

### Custom menu item

```tsx
<AccountMenuItem
  onClick={() => {
    window.location.href = 'https://docs.cspr.click';
  }}
  icon={CSPRClickIcon}
  label={'CSPR.click docs'}
  badge={{ title: 'new', variation: 'green' }}
/>
```

Renders a menu item in the account dropdown menu with a custom text, icon, and handler action.

Optionally, you can add a small badge right to the menu item title. Valid variation values are `green`, `blue`, `violet`, and `gray`.


# Theme selector

<figure><img src="/files/KMDe6LbfJSBOLZgT0CAy" alt=""><figcaption><p>Theme selector widget</p></figcaption></figure>

CSPR.click navigation bar has two themes: **light** and **dark**. You can use one or the other. And if your application also has light and dark modes, you can add to the navigation bar a theme selector to let the user easily change between both.

## Theme selector set up

In your application, create a state value to store the current theme. For example, with `useState()` hook, but you can use any other method.

```tsx
const [themeMode, setThemeMode] = useState<ThemeModeType>(ThemeModeType.light);
```

Next, define a callback function that will be invoked when the theme selector is used to change the theme:

```tsx
const handleThemeSwitch = () => 
      setThemeMode(themeMode === ThemeModeType.light ?
            ThemeModeType.dark : 
            ThemeModeType.light);
```

Finally, indicate the current theme mode and the theme switch callback method to the `<ClickUI>` component:

```tsx
<ClickUI
    themeMode={themeMode}
    topBarSettings={{
        onThemeSwitch:handleThemeSwitch
    }}
/>
```


# Network selector

<figure><img src="/files/4bufSoFuBTxpid38jgbD" alt=""><figcaption><p>Network selector widget</p></figcaption></figure>

If your application can switch between Mainnet and Testnet networks you may want to add the network selector widget to the CSPR.click navigation bar.

## Network selector set up

Define an array with the list of networks your application supports:

```tsx
export const NETWORKS = ['Mainnet', 'Testnet'];
```

Create a state value to store the current network. For example, with `useState()` hook, but you can use any other method.

```tsx
const [network, setNetwork] = useState<string>(NETWORKS[1]);
```

Define a `networkSettings` object with the list of networks, the current network, and a callback method to handle network selection by the user. Add this object to the `topBarSettings` prop in the `<ClickUI>` component:

```typescript
const networkSettings = {
  networks: NETWORKS,
  currentNetwork: network,
  onNetworkSwitch: (n: string) => { setNetwork(n); },
}
```

```tsx
<ClickUI 
    topBarSettings={{
        networkSettings
    }}
/>
```

### Customize the network icons

You can also specify your custom icons for each of the networks:

```tsx
import mainnetIcon from './assets/ico-mainnet.svg'
import testnetIcon from './assets/ico-testnet.svg'

const NETWORKS = [
  { title: 'Mainnet', icon: mainnetIcon },
  { title: 'Testnet', icon: testnetIcon }
];
```


# Language selector

<figure><img src="/files/u2AD517snikmT350eEKP" alt=""><figcaption><p>Language selector widget</p></figcaption></figure>

If your application supports multiple languages, you can add to the CSPR.click navigation bar a language selector.

## Language selector set up

Define an array with the list of languages your application supports:

```tsx
export const LANGUAGES: Lang[] = [
    Lang.EN,
    Lang.AZ,
    Lang.DE,
    Lang.ES,
    //...,
];
```

Create a state value to store the current language. For example, with `useState()` hook, but you can use any other method.

```tsx
const [language, setLanguage] = useState<Lang>(Lang.EN);
```

Define a `languageSettings` object with the list of languages, the current language, and a callback method to handle language selection by the user. Add this object to the `topBarSettings` prop in the `<ClickUI>` component:

```typescript
const languageSettings = {
    languages: LANGUAGES,
    creditsUrl: "/credits",
    contributeUrl: "/contribute",
    currentLanguage:  language,
    onChangeLanguage: (l: Lang) => { setLanguage(l); }
}
```

```tsx
<ClickUI
    topBarSettings={{
        languageSettings
    }}
/>
```

If you want to show a credits page to shout out your contributors, specify a URL in the `credits` field.

And if you want to ask your visitors to help you maintain the translations, specify a URL in the `contribute` field.

Note that both, `credits` and `contribute` links are optional. If you don't specify one or both, such options won't show in the language selector widget.


# Currency selector

<figure><img src="/files/iB1JZvEDQg7B0KGxA5vY" alt=""><figcaption><p>Currency selector widget</p></figcaption></figure>

If your application supports multiple currencies, you can add to the CSPR.click navigation bar a currency selector.

## Language selector set up

Define an array with the list of currencies your application supports:

```tsx
export const CURRENCIES: Currency[] = [
    {
        code: 'USD',
        title: 'US Dollar',
        type_id: CurrencyType.FIAT,
    },
    {
        code: 'EUR',
        title: 'Euro',
        type_id: CurrencyType.FIAT,
    },
    //...,
    {
        code: 'BTC',
        title: 'Bitcoin',
        type_id: CurrencyType.CRYPTO,
    },
    {
        code: 'ETH',
        title: 'Ethereum',
        type_id: CurrencyType.CRYPTO,
    },
];
```

Note in the image above how currencies are grouped in cryptocurrencies and fiat currencies. In your list of currencies, classify them using the `type_id` property in one of the groups.

Create a state value to store the current currency. For example, with `useState()` hook, but you can use any other method.

```tsx
	const [currency, setCurrency] = useState(CURRENCIES[0]);
```

Define a `currencySettings` object with the list of currencies, the selected currency, and a callback method to handle currency selection by the user. Add this object to the `topBarSettings` prop in the `<ClickUI>` component:

```typescript
const currencySettings= {
  currencies: CURRENCIES,
  currentCurrency: currency,
  onChangeCurrency: (c: any) => { setCurrency(c); },
}
```

```tsx
<ClickUI
    topBarSettings={{
        currencySettings
    }}
/>
```


# Custom selector

<figure><img src="/files/0OKjtJ5Rc5RUqtK8IwTD" alt=""><figcaption></figcaption></figure>

In addition to the standard settings selectors described in the previous pages, you can define your own dropdown menus with the options your application requires.

The code below shows an example with a menu that allows to choose between three different tokens:

```tsx
const TOKENS: CustomTopBarMenuItem[] = [
  {title:'Token 1', icon: <LogoGreen/>  },
  {title: 'Token 2', icon: <LogoYellow/>},
  {title: 'Token 3', icon: <LogoOrange/> }
];

const tokenSettings = {
    items: TOKENS,
    currentItem: currentToken,
    onItemSwitch: (t: string) => {
      // update your app upon item change
    },
};
```

```tsx
<ClickUI
    topBarSettings={{
        customTopBarMenuSettings:[tokenSettings]
    }}
/>
```


# Theme customization

CSPR.click provides set of different ui themes out of box, such as `red`, `green`, `blue` and `csprclick` as default theme. Each theme has its own set of `Dark` and `Light` version where all necessary colours are specified. Customer can easily use and modify set of colours for each theme and for its Dark or Light version.

### Default themes declaration

To use one of default theme, you need to export `DefaultThemes` object and `builtThemes` helper function from `@make-software/csprclick-ui`

DefaultThemes object consist of four properties which actually are themes itself. So by default we got four themes:

* `csprclick`
* `red`
* `green`
* `blue`

By default you'll get `csprclick` theme.

```tsx
import {DefaultThemes, buildTheme} from '@make-software/csprclick-ui';

export const AppTheme = buildTheme({
    ...DefaultThemes.csprclick,
});
```

You can easily change it to any of available themes from `DefaultThemes` object.

```tsx
export const AppTheme = buildTheme({
    ...DefaultThemes.red,
});
```

or

```tsx

export const AppTheme = buildTheme({
    ...DefaultThemes.blue,
});
```

### Default themes usage

To connect and apply theme you have selected all you need it just to pass it as a props to `ThemeProvider` which you can import from `styled-components` And wrap with it the whole application.

`ThemeModeType` enum which consist theme modes:

* `light`
* `dark`

```tsx
import { ThemeProvider } from 'styled-components';
import { AppTheme } from "./settings/theme";
import { ThemeModeType } from '@make-software/csprclick-ui';

<ThemeProvider theme={AppTheme[ThemeModeType.light]}>
    ...
    <App/>
    ...
</>
```

### Customise whole application alongside with `<ClickUI>` component

Besides customizing `<ClickUI>` component you can also customize the whole body of your application.

To do that, we have declared two properties:

* `appDarkTheme` - to customize application in dark mode
* `appLightTheme` - to customize application in light mode

Each of them has its own set of properties:

```tsx

export const AppTheme = buildTheme({
    ...DefaultThemes.csprclick,
    appDarkTheme: {
        topBarSectionBackgroundColor: DefaultThemes.csprclick.csprclickDarkTheme[clickStyleguide.backgroundTopBarColor],
        [clickStyleguide.textColor]: '#DADCE5',
        bodyBackgroundColor: '#0f1429'
    },
    appLightTheme: {
        topBarSectionBackgroundColor: DefaultThemes.csprclick.csprclickLightTheme[clickStyleguide.backgroundTopBarColor],
        [clickStyleguide.textColor]: '#1A1919',
        bodyBackgroundColor: '#f2f3f5'
    },
});

```

* `topBarSectionBackgroundColor` - stands for wrapping `<ClickUI>` component and set appropriate color for this wrapper
* `[clickStyleguide.textColor]` - stands for changing text color. Applies to the part of application which is inside `<body>` tag
* `bodyBackgroundColor` - stands for changing background color. Applies to the part of application which is inside `<body>` tag


# Create your own custom theme

If you're not enough with default set of themes you can easily create the new one. To do that, all you need is to directly extend `AppTheme` object with new property which would be the title of new theme and add appropriate structure.

### Theme creation structure

First of all, from `@make-software/csprclick-ui` you need to import`clickStyleguide` object which consist all necessary colors constructors to cover you application with new theme. Also you'll need helper function to build your own theme `buildTheme`.

To create the new custom theme, please follow the signature:

**note: (instead of hardcoded hex, please use your own color values)**

```tsx
import { clickStyleguide, buildTheme } from '@make-software/csprclick-ui';

const newCustomTheme = {
        csprclickDarkTheme: {
            [clickStyleguide.backgroundTopBarColor]: '#6305a2',
            [clickStyleguide.backgroundMenuColor]: '#b6a3e5',
            [clickStyleguide.hoverProductMenu]: '#b193ec',
            [clickStyleguide.hoverAccountMenu]: '#b193ec',
            [clickStyleguide.textColor]: '#500383',
            [clickStyleguide.topBarTextColor]: '#9770ef',
            [clickStyleguide.menuIconAndLinkColor]: '#af05f3',
            [clickStyleguide.topBarIconHoverColor]: '#6a3be0',
        },
        csprclickLightTheme: {
            [clickStyleguide.backgroundTopBarColor]: '#9d13cb',
            [clickStyleguide.backgroundMenuColor]: '#a15fe0',
            [clickStyleguide.hoverProductMenu]: '#693388',
            [clickStyleguide.hoverAccountMenu]: '#693388',
            [clickStyleguide.textColor]: '#c9b6ea',
            [clickStyleguide.topBarTextColor]: '#d8cae8',
            [clickStyleguide.menuIconAndLinkColor]: '#ec06c5',
            [clickStyleguide.topBarIconHoverColor]: '#ec06c5',
        },
}
```

Then, you need to inject newly created theme object into `buildTheme` constructor function alongside with `appDarkTheme` and `appLightTheme` if needed.

```tsx
export const AppTheme = buildTheme({
    ...newCustomTheme,
    appDarkTheme: {
        topBarSectionBackgroundColor: newCustomTheme.csprclickDarkTheme[clickStyleguide.backgroundTopBarColor],
        [clickStyleguide.textColor]: '#DADCE5',
        bodyBackgroundColor: newCustomTheme.csprclickDarkTheme[clickStyleguide.backgroundTopBarColor],
    },
    appLightTheme: {
        topBarSectionBackgroundColor: newCustomTheme.csprclickLightTheme[clickStyleguide.backgroundTopBarColor],
        [clickStyleguide.textColor]: '#1A1919',
        bodyBackgroundColor: newCustomTheme.csprclickLightTheme[clickStyleguide.backgroundTopBarColor],
    },
});
```

### Colors matching examples

`clickStyleguide` has a set of colors. Each color from `clickStyleguide` has its own corresponding area of usage and responsibility.

Here you can find all matching with colors and its corresponding area of usage on `<ClickUI>` component

* `csprclickDarkTheme` - stands for customise `<ClickUI>` component and all child or relative components in Dark mode.
* `csprclickLightTheme` - stands for customise `<ClickUI>` component and all child or relative components in Light mode.

Each of above properties has the same set of colors:

* `[clickStyleguide.backgroundTopBarColor]: 'blue'` - stands for whole `<ClickUI>` background color

Example on the screen below:

<figure><img src="/files/FmNSguEJzOSrv8oBTaxt" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.backgroundMenuColor]: 'blue'` - stands for all dropdown backgrounds Applies for the following components: `<ProductMenu>`, `<AccountMenu>`, `<Currencies>`, `<Languages>`, `<Network>` and `<CustomSelect>` component.

Example on the screen below:

<figure><img src="/files/2ptoFFrj2rugqf66MCcu" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/kgSePETT9Ppt5VPQ5LFV" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/ndV226m3lFmvB2lt2c9G" alt=""><figcaption></figcaption></figure>

<figure><img src="https://github.com/make-software/casper-click-websdk/blob/documentation-v1.11/docs/public/.gitbook/assets/theme-customization/languages-background.png" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/urLiMaD32FELfYpQ0AZe" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.hoverProductMenu]: 'blue'` - stands for changing colour when hovering on items inside `<ProductMenu>`

Example on the screen below:

<figure><img src="/files/i6jMLcSAnGIDiSR1naI5" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.hoverAccountMenu]: 'blue'` - stands for changing colour when hovering on items inside `<AccountMenu>`, `<Currencies>`, `<Languages>`, `<Network>` and `<CustomSelect>` component.

Example on the screen below:

<figure><img src="/files/qZNNVPzm27k69WHKHhq6" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/1GSOlwpnOStO9TryyzEx" alt=""><figcaption></figcaption></figure>

<figure><img src="https://github.com/make-software/casper-click-websdk/blob/documentation-v1.11/docs/public/.gitbook/assets/theme-customization/hover-currencies.png.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://github.com/make-software/casper-click-websdk/blob/documentation-v1.11/docs/public/.gitbook/assets/theme-customization/hover-network.png.png" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.textColor]: 'blue'` - stands for text colour inside each dropdown which is under `<ClickUI>`

Example on the screen below:

<figure><img src="/files/bFyPqBxbh7Jkj4NgMT6c" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/kFX1po65uoEIjGTIepzV" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.topBarTextColor]: 'blue'` - stands for text colour specific for `<ClickUI` and `ClickModals` components

Example on the screen below:

<figure><img src="/files/9RuRczwtbnquWj9KT4BY" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/eMtTt4liVP2wLq9iJQoT" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.topBarIconHoverColor]: 'blue'` - stands for changing colour when hovering on items which are on `<ClickUI>` component

Example on the screen below:

<figure><img src="/files/hLbX7SfFnqqnijbcq29J" alt=""><figcaption></figcaption></figure>

* `[clickStyleguide.menuIconAndLinkColor]: 'blue'` - stands for links and icons colour

Example on the screen below:

<figure><img src="/files/82y561WVX4JSiKV9ZjCh" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/ZkmXAIJtTO33L3HsAaIy" alt=""><figcaption></figcaption></figure>

It's really easy and fast to create you own color theme! Enjoy the process!


# Add custom information badge

In case you want to add some information badge on the ClickTopBar, you can use `useClickBadge()` hook to do it.

### `useClickBadge` structure

useClickBadge hook returns two functions: `setLeftBadge` and `setRightBadge`. Both are responsible to add info badge on specific ClickTopBar side. Each of these functions accepts the same set of parameters.\
Here the list of props for badge customization.

```tsx
export type BadgeSettings = {
        title: string;
        link?: string;
        color?: string;
        background: string;
   };
```

Here the example of having one badge with custom color, link and title on the left side of ClickTopBar:

```tsx
const ClickTopBar = ({ themeMode, onThemeSwitch }) => {

  const {setLeftBadge} = useClickBadge();

  setLeftBadge({
      title: `📄 Go to CSPR.click docs`,
      background: 'blue',
      color:'white',
      link: 'https://docs.cspr.click/'
  });

}
```

Then you should see the result: one left side badge with your own color, link and title. Like on the screen below:

<figure><img src="/files/aieCb5plQO5pjz2Jrcah" alt=""><figcaption></figcaption></figure>

So, to create your own custom badge dynamically, all you need is to use `useClickBadge()` hook and call `setLeftBadge` or `setRightBadge` functions.


# Hooks and Components

### Hooks

#### useClickRef() hook

In your components, you'll often need to call the CSPR.click API to get data or request an operation. To get a reference to the CSPR.click SDK instance make use of the `useClickRef()` React hook:

```tsx
import { useClickRef } from '@make-software/csprclick-ui';

function MyComponent() {
  const clickRef = useClickRef();
  ...
}
```

Then, in your application you'll be able to request CSPR.click to perform some operations using the class [methods](/cspr.click-v1.11/cspr.click-sdk/reference/methods), or get values reading the class [properties](/cspr.click-v1.11/cspr.click-sdk/reference/properties).

### Components

#### \<AccountIdenticon>

Use the `AccountIdenticon` component to display the public key identicon (or avatar). It can be used also with an account hash string.

<figure><img src="/files/lIVYhQs1jybAtH6XI74c" alt="AccountIdenticon component example"><figcaption></figcaption></figure>

In addition to the public key or account hash, indicate the size of the resulting image: `'xs'` for `16px`; `'sm'` for `20px`; `'m'` for `32px`; or `'l'` for `40px`.

```tsx
<AccountIdenticon hex={publicKey} size={'l'} />
```

The size can be indicated with a number of pixels:

```tsx
<AccountIdenticon hex={accountHash} size={40}  />
```


# JavaScript

This page guides you through the steps required to integrate the UI SDK into a non-React application.

Check also the HTML/Javascript demo in the [csprclick-examples](https://github.com/make-software/csprclick-examples) repository to see the resulting application. In that repo you can find also examples or few other libraries/frameworks.

## Download the CSPR.click UI runtime library from the CDN:

Before the closing `head` tag, add a `script` element to download the CSPR.click scripts:

```html
  <!-- update to latest released version -->
  <script defer="defer" src="https://cdn.cspr.click/ui/v1.9.0/csprclick-client-1.9.0.js"></script>
</head>
```

## Add a container for the CSPR.click UI

In your main layout file, add a `<div>` container where CSPR.click will inject some UI components like the navigation top bar or the 1-click sign in modal. Set an `id`, you'll need it later during CSPR.click initialization.

```html
<body>
  <div id="app">
    <div id="csprclick-ui"></div>
    <div id="content">
     <!-- you rapplication goes here -->
    </div>
  </div>
</body>
```

Also, depending on the layout of your application and the grid system you're using, you'll need to add some CSS styles to this container to match the styles of the rest of the app (width, background color, etc).

## Configure the initialization of the CSPR.click SDK

In a javascript file, add the initialization options for the CSPR.click SDK. Make sure this script loads before CSPR.click is downloaded.

The minimal configuration for the UI just defines the container for the navigation top bar and the root container of your app. We'll see other options later in this document.

```javascript
const clickUIOptions = {
  uiContainer: 'csprclick-ui', 
  rootAppElement: '#app',
  showTopBar: true,  
};
```

Next, define Client SDK options:

```javascript
const clickSDKOptions = {
  appName: 'CSPR.click demo',
  appId: 'csprclick-template',
  providers: ['casper-wallet', 'casper-signer'],
};
```

You can read more about the [CsprClickInitOptions ](/cspr.click-v1.11/cspr.click-sdk/reference/types#csprclickinitoptions)object in the reference section.

## What's next

At this point, your application should show the CSPR.click top navigation bar and you can click on Sign in button to connect your favorite wallet.

<figure><img src="/files/AkVhLKrWrbDlX9JAB7jj" alt=""><figcaption></figcaption></figure>

#### Listen to CSPR.click events

You'll need to listen and respond to some events triggered when the user connects an account, switches to a different one, or closes the session.

Refer to the [Handling events](/cspr.click-v1.11/cspr.click-sdk/javascript/handling-events) page for information on how to add your listener functions.

#### Ask the user to connect a wallet

If you don't display the CSPR.click top navigation bar, you must have your own Sign in or Connect buttons and respond calling the CSPR.click library .

Refer to the [Connecting a wallet](/cspr.click-v1.11/cspr.click-sdk/javascript/connecting-a-wallet) page for information on how to trigger the wallet connection process.

#### Request transaction approvals

At some point, your application will need to interact with the Casper network by sending a transaction (aka deploy).\
CSPR.click manages this process communicating with the active wallet to request the user to approve or reject the transaction. The UI depends on the wallet.

Refer to the [Signing transactions](/cspr.click-v1.11/cspr.click-sdk/javascript/signing-transactions) page for information on how to request the user a transaction approval. Also, look at [Processing status updates](/cspr.click-v1.11/cspr.click-sdk/javascript/processing-status-updates) for information on how to listen for real-time status updates.

#### Customize the top navigation bar

You can add any of our predefined settings selectors or account menu items. And you can define your own.

Refer to the [Customizing the top bar](/cspr.click-v1.11/cspr.click-sdk/javascript/customizing-the-top-bar) section for complete reference on how to work with each of the setting elements in the top bar.


# Handling events

In your application, you'll need to listen and respond to different events emitted by the CSPR.click library. On this page, we're covering the most common. Check the [Events](/cspr.click-v1.11/cspr.click-sdk/reference/events) page for a complete list of events.

For that purpose, add a listener for the `csprclick:loaded` message and register your callback functions for the different events triggered by the CSPR.click library.

```javascript
window.addEventListener('csprclick:loaded', () => {
  window.csprclick.on('csprclick:signed_in', async (evt) => {
    console.log("csprclick:signed_in", evt);
  });
  window.csprclick.on('csprclick:switched_account', async (evt) => {
    console.log("csprclick:switched_account", evt);
  });
  window.csprclick.on('csprclick:signed_out', async (evt) => {
    console.log("csprclick:signed_out", evt);
  });
  window.csprclick.on('csprclick:disconnected', async (evt) => {
    console.log("csprclick:disconnected", evt);
  });
});
```

### csprclick:signed\_in

This event is emitted every time the CSPR.click library connects to an account.

[csprclick:signed\_in](/cspr.click-v1.11/cspr.click-sdk/reference/events#csprclick-signed_in) reference.

### csprclick:switched\_account

This event is emitted instead of `csprclick:signed_i` when the user has clicked on the Switch Account menu item and has switched to another account in the same or a different wallet.

[csprclick:switched\_account](/cspr.click-v1.11/cspr.click-sdk/reference/events#csprclick-switched_account) reference.

### csprclick:signed\_out

This event is emitted when the CSPR.click library disconnects the active account due to a call to the `signOut()` SDK method.

[csprclick:signed\_out](/cspr.click-v1.11/cspr.click-sdk/reference/events#csprclick-signed_out) reference.

### csprclick:disconnected

This event is emitted when CSPR.click library receives a disconnect request or event from the connected wallet. The app should close the current session as a consequence of this event.

It receives in the event object the provider that has been disconnected.

[csprclick:disconnected](/cspr.click-v1.11/cspr.click-sdk/reference/events#csprclick-disconnected) reference.


# Connecting a wallet

If you're not displaying the top navigation bar you'll need to have you own UI components to let the user connect a wallet, display the connected account, switch to another account, and disconnect. In this page we're describing how to use the CSPR.click library to perform these operations.

## Sign in

When the user clicks on your 'Sign in' or 'Connect wallet' button, call the `signIn()` method to display the wallet selector window:

```tsx
window.csprclick.signIn()
```

This method returns immediately. Listen to the library events to get a notification of connection.

## Switch account

To let the user to change to another account, call the `switchAccount()` method:

```tsx
window.csprclick.switchAccount()
```

This method returns immediately. Listen to the library events to get a notification of connection.

## Disconnect

To close the current user session, call the `signOut()` method:

```tsx
window.csprclick.signOut()
```

This call does not request the connected wallet to disconnect from your application, so next time the user wants to sign in he'll not need to go through the connection step. If you want to disconnect completely the wallet from your app, call the `disconnect()` method:

```tsx
window.csprclick.disconnect()
```


# Signing transactions

Applications interacting with the Casper Network must submit transactions. Every transaction requires explicit user approval, which is done by digitally signing it.

Your frontend application is not always responsible for creating the transaction. Depending on your architecture, a transaction may be constructed by your backend service, or even by a third party, before being sent to the user for approval.

Typically, you'll handle a transaction without approvals. And such approval is what you want to get from the user. Then, the transaction will be ready to be processed by a Casper node.

The CSPR.click SDK provides two ways to obtain this approval:

1. [`send()`](/cspr.click-v1.11/cspr.click-sdk/reference/methods#send).

* Requests the active wallet to prompt the user for approval (signature).
* Automatically submits the signed transaction to a Casper node for processing.
* Optionally accepts a callback function to receive live status updates during execution (e.g., pending, confirmed, rejected).

This is the most common method. In most applications, you can simply call send() and use its result or the status updates to inform the user whether their transaction is being processed, or if it was rejected (by either the user or the network).

2. [`sign()`](/cspr.click-v1.11/cspr.click-sdk/reference/methods#sign).

* Requests the active wallet to prompt the user for approval.
* Returns the signature value to your application, without submitting the transaction.

This method is intended for advanced scenarios, where you need the raw signature for custom workflows (e.g., off-chain processing, server-side validation, or multi-step transaction orchestration).

## Buy Alice a Coffee on testnet

In the React `create-react-app` [template ](/cspr.click-v1.11/documentation/getting-started#create-a-new-project)we've added an example that shows how to request the approval for a transaction that sends to Alice (an imaginary colleague in our team) 50 CSPR testnet tokens;

<figure><img src="/files/Kiu9Nj2wTo71dgSuZpvv" alt=""><figcaption><p>Example in the template project</p></figcaption></figure>

Take a look into the `<BuyMeACoffee>` component. Here are the key parts:

1. **Build the transaction**

First, construct a transfer transaction. Thecasper-js-sdk is included in this template to help you with this step. Refer to the official Casper SDK documentation for more detailed usage and examples.

2. **Send the transaction**

Next, call the clickRef.send() method. CSPR.click will:

* Prompt the user in the active wallet to review and sign the transaction.
* Forward the signed transaction to a Casper node for processing.

3. **Handle responses**

Your application should be prepared to handle all possible outcomes:

* Success: The transaction was sent and you receive a transaction hash.
* User rejection: The user declined to sign the transaction.
* Network rejection: The Casper node rejected the transaction.

You can handle responses using the .then() and .catch() blocks, or use the status updates as explained in the next step.

4. **(Optional) Track transaction status**

The `.send()` method accepts an optional callback function as its second argument. This callback receives transaction status updates while the transaction is being executed, enabling you to:

* Show progress indicators in your UI (e.g., “Transaction pending…”)
* Update users when the transaction is confirmed or fails
* Provide richer feedback beyond just the final outcome

```tsx
function BuyMeACoffee() {
  const clickRef = useClickRef();
  const activeAccount = clickRef?.getActiveAccount();
  const [transactionHash, setTransactionHash] = useState<string>('');
  const [waitingResponse, setWaitingResponse] = useState<boolean>(false);

  const signAndSend = (transactionObj: object, sender: string) => {
          const onStatusUpdate = (status: string, data: any) => {
            console.log('STATUS UPDATE', status, data);
            if(status === TransactionStatus.SENT)
              setWaitingResponse(true);
          };
      
          clickRef
            ?.send(transactionObj, sender, onStatusUpdate)
            .then((res: SendResult | undefined) => {
                setWaitingResponse(false);
                if (res?.transactionHash) {
                    setTransactionHash(res.transactionHash);
                    alert('Transaction sent successfully: ' + res.transactionHash +
                        '\n Status: ' +
                        res.status +
                        '\n Timestamp: ' +
                        res.csprCloudTransaction.timestamp);
              } else if (res?.cancelled) {
                alert('Sign cancelled');
              } else {
                alert('Error in send(): ' + res?.error + '\n' + res?.errorData);
              }
            })
            .catch((err: any) => {
              alert('Error: ' + err);
              throw err;
            });
  };

  const handleSignTransaction = (evt: any) => {
    evt.preventDefault();
    const sender = activeAccount?.public_key?.toLowerCase() || '';
    const transaction = makeTransferTransaction(
            sender,
            recipientPk,
            '50' + '000000000',
            clickRef.chainName!
    );
    signAndSend(transaction as object, sender);
  };
	
  return (
    ...
    <button onClick={() => handleSignTransaction()} />Sign and send transaction</button>
    ...
  )
}
```


# Tracking your transactions in real time

When using the `send()`method to request a transaction approval and deploy it to the network, the SDK can, optionally, establish a websocket connection with CSPR.click backend and receive real-time updates about the transaction execution.

Traditionally, applications had to rely on polling a backend service or querying a Casper node to know whether a transaction had been processed, confirmed, or rejected. This approach added complexity, increased latency, and delayed the user experience.

Using a websockets connection to listen for real-time updates, your application can:

* Receive immediate status notifications during the full transaction lifecycle.
* Update your UI with progress states (e.g., pending, processed, failed).
* Access result data without the need for extra API calls.

This makes it easier to build responsive, user-friendly applications that keep users informed in real time as their transactions move through the Casper Network.

<figure><img src="/files/HWfT94c0G5JCiJf56qFp" alt="Waiting for transaction completion"><figcaption></figcaption></figure>

## Receive transaction updates

To wait for transaction execution and receive status updates, pass a callback function to the `send()` method. This function will be called with status updates as the transaction is approved and processed.

```javascript
const onStatusUpdate = (status, data) => {
    console.log('STATUS UPDATE', status, data);
    if (status === TransactionStatus.SENT)
        setWaitingIndicator();
    if (status === TransactionStatus.PROCESSED)
        parseProcessedTransaction();
};

clickRef
    .send(transaction, sender, onStatusUpdate)
    .then((res) => {
        // check result and update UI accordingly
    })
    .catch((err) => {
        alert('Error: ' + err);
        throw err;
    });
```

### Status values

The `status` argument passed to the callback function can have the following values:

| Value       | Description                                                                                                                           |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `sent`      | The transaction has been signed and successfully deployed to a Casper node.                                                           |
| `processed` | The transaction has been executed by the network. May result in success or failure.                                                   |
| `expired`   | The transaction’s time-to-live (TTL) elapsed before execution.                                                                        |
| `cancelled` | The user rejected the signature request.                                                                                              |
| `timeout`   | The SDK stopped listening for updates before the transaction was finalized. A custom timeout can be specified (default: 120 seconds). |
| `error`     | An unexpected error occurred while submitting or monitoring the transaction.                                                          |
| `ping`      | A heartbeat event sent periodically to indicate that the connection is still active..                                                 |

### Data with processed Status

When the transaction reaches the processed state, the callback function receives an additional data argument.

This object contains the full `Deploy` entity, as defined in the [CSPR.cloud REST API documentation](https://docs.cspr.cloud/rest-api/deploy#properties).

Your application can use this information to:

* Show whether the transaction succeeded or failed.
* Provide more detailed feedback (e.g., execution cost, error messages).


# Customizing the top bar

{% hint style="info" %}
While we recommend to include the CSPR.click top bar in your application, if you have your own Sign in and session management controls you can opt-out and hide the navigation bar. Read below how to do it.
{% endhint %}

CSPR.click includes a navigation bar that displays on the top of the web application. It's the same navigation bar you can find on CSPR.live and other applications that integrate CSPR.click.

<figure><img src="/files/rc1WgfG5MdI45vHoAYjG" alt=""><figcaption><p>CSPR.click navigation bar</p></figcaption></figure>

In this top bar you always see the CSPR Products menu on the left side, and the Account menu on the right side. The rest are customizable selectors that you can choose to add or not. Most of them are customizable as we'll see in the next pages.

### Hide the navigation bar

if your application already has its own Sign in and session management controls you can hide CSPR.click navigation bar. To do so, do not include any of the settings selector and set `showTopBar` to `false`:

```json
const clickUIOptions = {
  uiContainer: 'csprclick-ui',
  rootAppElement: '#app',
  defaultTheme: 'light',
  showTopBar: false,
};
```


# Account dropdown menu

You can customize the account dropdown menu in our top bar with your own menu items. Options to switch to another account and sign out are always present at the end of the list. The rest, depends on your needs. We provide a couple of common menu item components you may add, and one component for you to include anything you need.

<figure><img src="/files/A1Xjj24e7AfooidhCsxf" alt=""><figcaption></figcaption></figure>

## Account dropdown menu set up

To customize the account dropdown menu, add the menu items you want to display into an array:

```javascript
const csprClickDocsMenuItem = {
    label: 'CSPR.click docs',
    icon: './csprclick-icon.svg',
    badge: { title: 'New', variation: 'green' },
    onClick: () => { window.open('https://docs.cspr.click', '_blank'); },
};

const accountMenuItems = [
    'AccountCardMenuItem',
    'CopyHashMenuItem',
    csprClickDocsMenuItem,
    'BuyCSPRMenuItem',
];
```

Then, add the array to the `clickUIOptions` object you defined before:

```javascript
const clickUIOptions = {
  uiContainer: 'csprclick-ui', 
  rootAppElement: '#app',
  showTopBar: true,
  accountMenuItems,
};
```

## Prebuilt menu items

### Account card

```javascript
const accountMenuItems = [
    'AccountCardMenuItem',
];
```

Renders a card with account information at the top of the dropdown menu. The card includes the account name, public key and liquid/total balances. The account also links to CSPR.live.

### View account on CSPR.live

```javascript
const accountMenuItems = [
    'ViewAccountOnExplorerMenuItem',
];
```

Alternative to the account card. Renders a menu item in the account dropdown menu to open the CSPR.live account page in a new tab.

### Copy public key

```javascript
const accountMenuItems = [
    'CopyHashMenuItem',
];
```

Renders a menu item in the account dropdown menu to copy the connected public key to the clipboard.

### Buy CSPR

```javascript
const accountMenuItems = [
    'BuyCSPRMenuItem',
];
```

Renders a menu item in the account dropdown menu to open the [Topper by Uphold](https://www.topperpay.com/) widget on a new tab. This widget allows the user to top-up his account with a credit card payment.

### Custom menu item

```javascript
const csprClickDocsMenuItem = {
    label: 'CSPR.click docs',
    icon: './csprclick-icon.svg',
    badge: { title: 'New', variation: 'green' },
    onClick: () => { window.open('https://docs.cspr.click', '_blank'); },
};

const accountMenuItems = [
    csprClickDocsMenuItem,
];
```

Renders a menu item in the account dropdown menu with a custom text, icon, and handler action.

Optionally, you can add a small badge right to the menu item title. Valid variation values are `green`, `blue`, `violet`, and `gray`.




---

[Next Page](/llms-full.txt/1)

