Get Started Quickly

Get up and running quickly with the Quadrata SDK

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

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.

Install Dependencies

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

The client libraries all depend on react, react-dom, and @tanstack/react-query, while wagmi, viem, and @rainbow-me/rainbowkit are typically used for on-chain actions.

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 or use another supported library.

npm i --save @rainbow-me/rainbowkit

RainbowKit has a CSS file that needs to be imported and supports theming options.

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

import '@rainbow-me/rainbowkit/styles.css';

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 and @quadrata/kyb-react, and both of them use @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.

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.

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

@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';

The SDK supports lazy loading and code splitting. You can read more in the advanced section of this documentation.

Wagmi + Connector

Before setting up the onboarding components, you need to set up wagmi and RainbowKit (or another supported Wagmi Connector) 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.

If you are using NextJS, remember to place the 'use client'; directive at the top of the file.

// 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 and 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.

If you are using NextJS, remember to place the 'use client'; directive at the top of the file.

// 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 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.

For styling purposes, it's common to place your WagmiConnect component somewhere near the top of the main layout body.

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.

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.

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

'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>
    );
}

Last updated