# Get Started Quickly

This is a developer guide and example to get started with the Quadrata SDK quickly.&#x20;

{% hint style="info" %}
The examples on this guide use some libraries that are optional, such as `RainbowKit`, which you may choose to use or replace with another implementation.

`Wagmi` is used to support wallet connect abstraction through the Quadrata SDK, to make integrating easier.
{% endhint %}

## Install Dependencies

Before getting started with the Quadrata SDK, you need to install the required dependencies.

The client libraries all depend on [react](https://react.dev/), [react-dom](https://react.dev/), and [@tanstack/react-query](https://tanstack.com/query/v5), while [wagmi](https://wagmi.sh/), [viem](https://viem.sh/), and [@rainbow-me/rainbowkit](https://www.rainbowkit.com/) are typically used for on-chain actions.&#x20;

```sh
npm i --save react react-dom
npm i --save @tanstack/react-query wagmi viem@2.x
```

### RainbowKit Is Optional

If you choose to use RainbowKit, which is optional, you need to install it as a dependency and add their CSS library to your application. If you do not want to use RainbowKit, you need to implement your own [Wagmi Connector](https://wagmi.sh/react/api/connectors) or use another supported library.

```sh
npm i --save @rainbow-me/rainbowkit
```

{% hint style="warning" %}
RainbowKit has a CSS file that needs to be imported and supports [theming options](https://www.rainbowkit.com/docs/theming).&#x20;

You can import the CSS library from within your code as follows:

`import '@rainbow-me/rainbowkit/styles.css';`
{% endhint %}

## Install Quadrata Libraries

Quadrata has a library for each onboarding application which you need to install in order to use the SDK. They are [@quadrata/client-react](https://www.npmjs.com/package/@quadrata/client-react) and [@quadrata/kyb-react](https://www.npmjs.com/package/@quadrata/kyb-react), and both of them use [@quadrata/core-react](https://www.npmjs.com/package/@quadrata/core-react).

Quadrata also has a library for dealing with contracts, which contains ABIs and contract addresses and the SDK takes advantage of these: [@quadrata/contracts](https://www.npmjs.com/package/@quadrata/contracts).

The SDK itself is an abstraction layer around all the client components and provides API services to communicate with the Quadrata REST API: [@quadrata/sdk](https://www.npmjs.com/package/@quadrata/sdk).

```sh
npm i --save @quadrata/sdk @quadrata/contracts
npm i --save @quadrata/core-react @quadrata/client-react @quadrata/kyb-react
```

{% hint style="warning" %}
`@quadrata/core-react` has a CSS file that needs to be imported.

You can import the CSS library from within your code as follows:

`import '@quadrata/core-react/lib/cjs/quadrata-ui.min.css';`
{% endhint %}

{% hint style="info" %}
The SDK supports [lazy loading](https://docs.quadrata.com/integration/how-to-integrate/quadrata-sdk/advanced/client-libraries/client-lazy-loading) and code splitting. You can read more in the [advanced section](https://docs.quadrata.com/integration/how-to-integrate/quadrata-sdk/advanced) of this documentation.
{% endhint %}

## Wagmi + Connector

Before setting up the onboarding components, you need to set up [wagmi](https://wagmi.sh/) and [RainbowKit](https://www.rainbowkit.com/) (or another supported [Wagmi Connector](https://wagmi.sh/react/api/connectors)) so that users can connect a wallet and sign transactions.

The set up is minimal and requires a structure of react providers that your onboarding component must be nested within.

To demonstrate this, the following code defines a component called `WagmiWrapper` which is intended to be placed in a file called `WagmiWrapper.tsx`.&#x20;

{% hint style="info" %}
If you are using NextJS, remember to place the `'use client';` directive at the top of the file.
{% endhint %}

```tsx
// WagmiWrapper.tsx

import type { PropsWithChildren } from 'react';
import { WagmiProvider, http } from 'wagmi';
import * as chains from 'wagmi/chains';
import { getDefaultConfig, RainbowKitProvider } from '@rainbow-me/rainbowkit';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

// NOTE: you should only map the chains and transports you actually want to support.

/* NOTE: Every dApp that relies on WalletConnect now needs to obtain a projectId 
         from WalletConnect Cloud. This is absolutely free and only takes a few 
         minutes. */

const config = getDefaultConfig({
    appName: 'Quadrata Demo App',
    projectId: {{ WALLET_CONNECT_CLOUD_PROJECT_ID }},
    ssr: true,
    chains: [
        chains.arbitrum,
        chains.avalanche,
        chains.avalancheFuji,
        chains.base,
        chains.evmos,
        chains.evmosTestnet,
        chains.mainnet,
        chains.optimism,
        chains.polygon,
        chains.polygonMumbai,
        chains.sepolia,
        chains.zkSync,
        chains.zkSyncSepoliaTestnet,
    ],
    transports: {
        [chains.arbitrum.id]: http(),
        [chains.avalanche.id]: http(),
        [chains.avalancheFuji.id]: http(),
        [chains.base.id]: http(),
        [chains.evmos.id]: http(),
        [chains.evmosTestnet.id]: http(),
        [chains.mainnet.id]: http(),
        [chains.optimism.id]: http(),
        [chains.polygon.id]: http(),
        [chains.polygonMumbai.id]: http(),
        [chains.sepolia.id]: http(),
        [chains.zkSync.id]: http(),
        [chains.zkSyncSepoliaTestnet.id]: http(),
    },
});

const queryClient = new QueryClient();

export default function WagmiWrapper(props: PropsWithChildren) {
    return (
        <QueryClientProvider client={queryClient}>
            <WagmiProvider config={config}>
                <RainbowKitProvider>
                    {props.children}
                </RainbowKitProvider>
            </WagmiProvider>
        </QueryClientProvider>
    );
}
```

## Onboarding Component

The Quadrata SDK client component requires some minimal configuration and allows you to pass in properties for both [Individual Passport Onboarding](https://docs.quadrata.com/integration/how-to-integrate/onboard-users/individual-passport-onboarding) and [Business Passport Onboarding](https://docs.quadrata.com/integration/how-to-integrate/onboard-users/business-passport-onboarding).

To demonstrate this, the following code defines a component called `OnboardingComponent` which is intended to be placed in a file called `OnboardingComponent.tsx`.

{% hint style="info" %}
If you are using NextJS, remember to place the `'use client';` directive at the top of the file.
{% endhint %}

```tsx
// OnboardingComponent.tsx

import * as QuadrataTypes from '@quadrata/sdk/types';
import { withWagmiConnect, Quadrata } from '@quadrata/sdk/client';

export default function OnboardingComponent(props: { accessToken: string }) {
    const quadrataProps = withWagmiConnect({
        accessToken: props.accessToken,
        sdkConfig: {
            // NOTE: use QuadrataEnvironment.PRODUCTION for production
            environment: QuadrataTypes.QuadrataEnvironment.SANDBOX
        },
        clientConfig: {
            _debug: true,
            protocolName: {{ YOUR_COMPANY_NAME }}
        },
        sharedProps: {
            onApplicationEnd: (data: Record<string, any>) => {
                console.log('Application ended', data.status, data.error);
            },
        },
        kycProps: {
            // see available props at
            // https://docs.quadrata.com/integration/how-to-integrate/onboard-users/individual-passport-onboarding/4.-quadclient-package#less-than-quadclient-greater-than-props
            attributes: [
                QuadrataTypes.QuadrataAttribute.DID,
                QuadrataTypes.QuadrataAttribute.COUNTRY,
                QuadrataTypes.QuadrataAttribute.AML
            ],
            privacyScopes: [
                QuadrataTypes.QuadrataPrivacyConsent.EMAIL,
                QuadrataTypes.QuadrataPrivacyConsent.DATE_OF_BIRTH,
                QuadrataTypes.QuadrataPrivacyConsent.FIRST_NAME,
                QuadrataTypes.QuadrataPrivacyConsent.LAST_NAME,
                QuadrataTypes.QuadrataPrivacyConsent.ADDRESS
            ],
        },
        kybProps: {
            // this is optional - see available props at
            // https://docs.quadrata.com/integration/how-to-integrate/onboard-users/business-passport-onboarding/3.-quadratakyb-package
        }
    });
    return (
        <Quadrata {...quadrataProps}>
            {((helper: QuadrataTypes.Client.Components.Helper) => {
                if (helper.isApplicationComplete) {
                    return <p>Application is Complete</p>;
                }
                if (helper.isPassportInReview) {
                    return <p>Your application is in review.</p>;
                }
                if (helper.isLoading) {
                    return <p>Quadrata is loading...</p>;
                }
                return (
                    <button
                        disabled={!helper.isApplicationReady}
                        onClick={helper.launchApplication}
                    >
                        Onboarding Application
                    </button>
                );
            })}
        </Quadrata>
    );
}
```

## Putting It Together

In order for this all to work, the `OnboardingComponent` needs to be a child of `WagmiWrapper`. You are free to place the `WagmiWrapper` anywhere in your layout so long as the `OnboardingComponent` is somewhere in the child tree.

RainbowKit also has a [Connect Button](https://www.rainbowkit.com/docs/connect-button) that you need to add which initiates Wallet Connect for the user.  It is responsible for rendering the connect/disconnect button, as well as chain-swapping UI. The `ConnectButton` must also be nested as a child of `WagmiWrapper`.

To demonstrate this, the following code defines a component called `MyComponent`. This component serves as an example of how to nest the `OnboardingComponent` and `ConnectButton` inside the `WagmiWrapper`. For the purpose of this example, the following code should go into a file called `MyComponent.tsx`.

{% hint style="info" %}
For styling purposes, it's common to place your `WagmiConnect` component somewhere near the top of the main layout body.&#x20;

This way you can add your connect button on the top of the screen or off to the side, while the `OnboardingComponent` can be centered or conditionally rendered somewhere inside your page body.
{% endhint %}

```tsx
import { ConnectButton } from '@rainbow-me/rainbowkit';

import WagmiWrapper from './WagmiWrapper';
import OnboardingComponent from './OnboardingComponent';

export default function MyComponent(props: { accessToken: string }) {
    return (
        <WagmiWrapper>
            <ConnectButton/>
            <OnboardingComponent
                accessToken={props.accessToken}
            />
        </WagmiWrapper>
    );
}
```

## The Access Token

In order to authenticate with the onboarding components and Quadrata REST API, you need to fetch an access token.

You can use the `createAccessToken` API service in the SDK to generate an access token to pass into your component.

You should do this on the server so that your API key is not exposed to anyone using your dApp.

If you cannot do this on the server, you are permitted to make this call from the client, but you should consider rotating your API keys frequently.

{% tabs %}
{% tab title="NextJS / Server Page" %}
If you are using NextJS, you can use this example to fetch the access token on the server and pass it to your client component

```tsx
'use server';

// app/onboarding/page.tsx

import { createAccessToken, QuadrataEnvironment } from '@quadrata/sdk/api';

// change this to import MyComponet from the example above
import MyComponent from '~/components/MyComponent';

export default async function OnboardingPage() {
    const { data: { accessToken } } = await createAccessToken(
        {
            // api service params
            apiKey: {{ QUADRATA_API_KEY }},
            options: {
                // fetch options
                cache: 'no-cache'
            }
        },
        {
            // sdk config
            // NOTE: use QuadrataEnvironment.PRODUCTION for production
            environment: QuadrataEnvironment.SANDBOX
        }
    );
    return (
        <div>
            <h1>Onboarding With NextJS</h1>
            <MyComponent accessToken={accessToken} />
        </div>
    );
}
```

{% endtab %}

{% tab title="Client Component" %}
{% hint style="warning" %}
NOTE: This approach will expose your API key to anyone using your dApp!
{% endhint %}

```tsx
import { useEffect, useState } from 'react';

import { createAccessToken, QuadrataEnvironment } from '@quadrata/sdk/api';

// change this to import MyComponet from the example above
import MyComponent from './MyComponent';

export default function App() {
    const [accessToken, setAccessToken] = useState<string|undefined>(undefined);
    useEffect(() => {
        createAccessToken(
            {
                // api service params
                apiKey: {{ QUADRATA_API_KEY }},
                options: {
                    // this is necessary for client components
                    allowUnsafeClientApiCall: true,
                    
                    // fetch options
                    cache: 'no-cache'
                }
            },
            {
                // sdk config
                // NOTE: use QuadrataEnvironment.PRODUCTION for production
                environment: QuadrataEnvironment.SANDBOX
            }
        ).then(response => {
            setAccessToken(response.data.accessToken);
        });
    }, []);
    if (!accessToken) {
        return <p>Loading...</p>;
    }
    return (
        <div>
            <h1>Client Component Onboarding</h1>
            <MyComponent accessToken={accessToken} />
        </div>
    );
}
```

{% endtab %}
{% endtabs %}
