npm package: @ragsters/raggie-wallet-connector
Description: This is a React component built by the CryptoRaggies team to enable any React website to easily connect to popular Cardano wallets. The user's choice of wallet is persisted to local storage and the wallet connector will automatically reconnect the previou
Latest version: 1.0.1

## Raggie Wallet Connector

This is a React component built by the CryptoRaggies team to enable any React website to easily connect to popular Cardano wallets. The user's choice of wallet is persisted to local storage and the wallet connector will automatically reconnect the previously chosen wallet upon site reload.

The wallets supported by this connector include:

- Begin
- Eternl
- Flint
- Gero
- Lace
- Nami
- Nufi
- Purrse
- RaggiePurrse
- Tokeo
- Typhon
- Vespr

### Key features

**Native RaggiePurrse support**  
RaggiePurrse is our very own ecosystem wallet which works in a different way to all existing Cardano wallets. We created RaggiePurrse specifically because all current wallets are browser extensions and have no capability to connect to native mobile apps. We needed a solution for wallet connections in our native mobile game RaggieRun, and hence RaggiePurrse was created.

RaggiePurrse can be used like any Cardano wallet, with the added benefit that it can connect to native mobile apps via its own connection protocol. Using Raggie Wallet Connector, any dApp can then leverage on this and provide a native experience to users without needing to be run within a wallet dApp browser on mobile. That's right - users can now access dApps on their preferred mobile browser such as Brave or Chrome, and still retain 100% connectivity with their Cardano wallet using RaggiePurrse via Raggie Wallet Connector.

For the developer, there is no additional code to write or additional libraries to install. Simple install Raggie Wallet Connector and RaggiePurrse support is enabled as default. You will, however, need to contact us to whitelist your app's domain for CORS whitelisting as RaggiePurrse requires a live connection to our backend websocket.

**Persistence of connected user data across sessions**  
Details of the connected wallet is written into local storage and persists across user sessions for the same domain. Therefore when a user connects to your dApp the first time, the preferred wallet and any choice of ADA Handle will be stored. The next time the user visits your website, the data will be read from local storage and the wallet connector will automatically reconnect to the user's preferred wallet.

**Abstraction of transaction chaining logic**  
Raggie Wallet Connector handles transaction chaining out of the box. When a transaction is created and signed via the `signTx(tx: string, partialSign?: boolean)` method supplied by Raggie Wallet Connector, all inputs originating from, and outputs directed to, the user's wallet will be cached. This caching is reversed when the user cancels the transaction.

There is support for HD wallets with multiple addresses under the same account.

When the `getUtxos()` method is called, Raggie Wallet Connector first calls the native `getUtxos()` method from the connected wallet's CIP-30 API, then compares the output to its internal cache to remove UTxOs that were previously cached as used inputs. It then adds UTxOs that have previously been cached as new outputs to this array and returns this to the dApp.

The result is a straightforward developer experience in which one could simply call the `getUtxos()` and `signTx()` methods just like one would with the native CIP-30 API without needing to handle complex caching logic to support transaction chaining, allowing for a better user experience as users no longer need to wait for transactions to confirm on-chain before initiaing another transaction.

**UTxO health detection**
![UTxO Health Bar in wallet connection drawer](https://raggies-api.onrender.com/v0/public/getimage/?path=images/drawer.png)
We implemented a proprietary _UTxO Health_ system to analyse a user's wallet and make a recommendation to the user regarding their wallet's UTxO setup. This system particularly looks for "red flags" such as large UTxOs with too many native tokens and too little ADA, and relative scarcity of pure ADA UTxOs, and a few other metrics.

![Option to use Unfrack.it when UTxO Health is low](https://raggies-api.onrender.com/v0/public/getimage/?path=images/unfrackit.png)
The Raggie Wallet Connector drawer shows the user a colour-coded health bar and an explanation of the score. If a user's UTxO health is below optimum, we display a button link to <a href="https://unfrack.it">UnFrack.it</a> and recommend the user to use the tool to optimise their UTxO setup to reduce likelihood of transactions failing to build, especially when smart contracts are involved.

**ADA balance with indication of "locked ADA"**  
![ADA balance display with locked ADA and explanation](https://raggies-api.onrender.com/v0/public/getimage/?path=images/adabalance.png)
We also display the user's ADA balance along with the amount of "locked ADA". There is also an explanation about the concept of "locked ADA". It is our hope that, through education within the UI, users will understand better how the eUTxO system works on Cardano and understand why sometimes transactions cannot be built with their wallet and, at the same time, get tips and ideas to solve and prevent such problems in the future.

**Customisable ad space for projects**
The wallet connector comes with an ad space which can be used by projects for monetisation or announcements.

### How to use

To install:

```
npm install raggie-wallet-connector
```

To import into your project, import `RaggieUserProvider` at app level (e.g. App.tsx). We also recommend importing our stylesheet for the wallet connector:

```
import "raggie-wallet-connector/styles";
import { RaggieUserProvider } from "raggie-wallet-connector";
```

In order to use the `RaggieWallet` component, all child components of the project that need access to wallet and user data need to be enclosed by the `RaggieUserProvider` context provider. We recommend adding the provider at app level (e.g. App.tsx), as such:

```
export function App() {
  return (
    <>
      <RaggieUserProvider>
        <ChildComponent1 />
        <ChildComponent2 />
      </RaggieUserProvider>
    </>
  );
}
```

You are now able to add the component to any child component within your app and access data held by the wallet connector anywhere. To add the component:

```
import { RaggieWallet } from "raggie-wallet-connector";

export function ChildComponent1() {
  return (
      <RaggieWallet />
  )
}
```

Note that the `RaggieWallet` component has an optional prop `adBanners: string[]`. If included, your custom ad or announcement banners will be shown inside the wallet connector as a carousel. The `string` to include within the array is the path to your ad or announcement banner image. This can be a path within your project or a remote URL.

The Raggie Wallet Connector provides the wallet user's data as a React Context which can be imported into any child component nested within `RaggieUserProvider`. For example:

```
import { useRaggieUserContext } from "raggie-wallet-connector";

export function ChildComponent2() {
  const { RaggieUserState } = useRaggieUserContext()

  return (
    {RaggieUserState.walletAddress}
  )
}
```

The `RaggieUserState` state variable is a pre-defined `UserState` type and is defined as follows:

```
interface UserState {
  walletAddress: string;
  preferredHandle: string;
  lovelaceBalance: number;
  lockedLovelace: number;
  walletNameSpace: string;
  walletApi: Cip30Api | undefined;
}
```

The individual components of the `RaggieUserState` export are described as follows:

- `RaggieUserState.walletAddress`: returns the wallet address of the user's connected wallet. An empty string `""` is returned if no wallet is connected.
- `RaggieUserState.preferredHandle`: returns the chosen adahandle of the user, if any. If the user did not choose a handle within the wallet connector, the return is an empty string `""`.
- `RaggieUserState.lovelaceBalance`: returns the full lovelace balance of the user's connected wallet. Note that this is returned as lovelace and not ADA. Each ADA is equal to 1_000_000 lovelace.
- `RaggieUserState.lockedLovelace`: returns the amount of lovelace in the user's connected wallet that is not part of "minimum UTxO ADA".
- `RaggieUserState.walletNameSpace`: returns the name of the user's chosen wallet. This is usually the name of the CIP-30 API which can be called by using `window.cardano[walletNameSpace]`. However we recommend using our internally modified `RaggieUserState.walletApi` export instead in order to take advantage of our advanced features such as transaction chaining.

The `RaggieUserState.walletApi` variable provides a modified version of the full injected CIP-30 wallet API object chosen by the user and can be called to interact with the user's wallet to perform various blockchain actions. For more details on the full CIP-30 API, visit [Cardano dApp-Wallet Web Bridge](https://cips.cardano.org/cip/CIP-30/)

This modified CIP-30 API consists of the following methods from the original API:

- `getNetworkId(): Promise<string>`: returns the Network ID of the connected wallet.
- `getBalance(): Promise<string>`: returns the balance of the connected wallet. This is a cbor hex `Value`.
- `getUsedAddresses(): Promise<string[]>`: returns an array of used addresses as cbor hex `Address`.
- `getUnusedAddresses(): Promise<string[]>`: returns an array of unused addresses as cbor hex `Address`.
- `submitTx(tx: string): Promise<string>`: takes in a cbor hex `Transaction` string representation of a signed transaction and returns the transaction hash if submission was successful.

The following methods have been modified:

- `getUtxos(): Promise<string[]>`: returns an array of _available_ UTxOs as cbor hex `TransactionUnspentOutput`.
- `signTx(tx: string, partialSign?: boolean, complete?: boolean): Promise<string>`: takes in a cbor hex `Transaction` string, optional `partialSign` and `complete` boolean arguments. If `partialSign` is true or `complete` is false, it returns the `WitnessSet` as cbor hex string. If `complete` is true, the return value will be a fully signed `Transaction` as a cbor hex string which can be submitted directly using any Cip30 wallet API. This will only work if `partialSign` is set to false, i.e. the transaction is expecting the user's signature as the _only_ remaining signature required to fully sign the transaction.

The `getUtxos()` method returns _available_ UTxOs only. It compares the UTxOs returned from the wallet against Raggie Wallet Connector's internal cache and removes UTxOs used as inputs in recently signed transactions. It also adds new outputs generated from recently signed transactions to the returned array. Note that this mechanism is solely local and _off-chain_. It works only if the user is not concurrently using the same wallet in another context to spend UTxOs within the wallet, as Raggie Wallet Connector will not check on-chain or in any mempool for pending transactions signed by the wallet. For vast majority of usecases, this is sufficient to ensure smooth chaining of transactions.

The `signTx(tx: string, partialSign?: boolean)` method signs the transaction and returns the witness set. At the same time it parses the transaction and caches all inputs and outputs relevant to the connected wallet to facilitate transaction chaining.