Skip to content

SnickerdoodleLabs/Testbed-React

Repository files navigation

Snickerdoodle Protocol

Web Integration Testbed for React

This is a minimal React application for demonstrating the Snickerdoodle web-native analytics package. It is meant to be an example guide for adding Snickerdoodle analytics to your own React-based dApp.

This example repo specifically uses RainbowKit in conjunction with Wagmi for establishing a connection with a user's wallet. However, Snickerdoodle analytics is unopinionated in regards to the wallet connection technology. It can easily be used with other technologies like WalletConnect or simply use the window.ethereum object available on most browser extension-based wallet applications.

If you want to run this project locally or make your own modification, see DEV.md.

1. Install Dependencies

You'll need to add @snickerdoodlelabs/web-integration to your dependency list:

yarn add @snickerdoodlelabs/web-integration

or if you are using NPM:

npm install @snickerdoodlelabs/web-integration

2. Configuration of Web3 Data Providers

Snickerdoodle's web analytics package can fetch web3 data from multiple API providers (for redundancy and robustness). Checkout .example.env.local for a template environment variable file. Snickerdoodle recommends that you provide your own web3 API keys if you have hundreds of thousands of users or more so that indexer requests are not throttled. You will use these environment variables in your application.

If you choose to provide your own API keys, put them into an object which will be used as an input for step 3. The Typescript interface IConfigOverrides defines this type if you are using TS. In this full running example, we are using environnement variables that are referenced with process.env. You project may be configured to reference environment variables in a different fashion.

const webIntegrationConfig = {
  primaryInfuraKey: process.env.REACT_APP_INFURA_API_KEY!,
  ankrApiKey: process.env.REACT_APP_ANKR_API_KEY!,
  covalentApiKey: process.env.REACT_APP_COVALENT_API_KEY!,
  poapApiKey: process.env.REACT_APP_POAP_API_KEY!,
};

Note: You do not need to specify your own API keys. Snickerdoodle's web-integration analytics package comes with default API keys. The default keys may be rate limited, however, and this may affect your performance. Snickerdoodle recommends all integrators acquire their own keys before deploying to production. If you choose to rely on the default API keys set your config object to {}:

const webIntegrationConfig = {};

3. Import Snickerdoodle Analytics

You must import SnickerdoodleWebIntegration into your application:

import { SnickerdoodleWebIntegration } from '@snickerdoodlelabs/web-integration';

Additionally, if you choose one of the signature-based authentication methods in step 4, you must also import some objects:

import { EVMAccountAddress, Signature, EChain } from "@snickerdoodlelabs/objects";

Note You do not need to import from @snickerdoodlelabs/objects if you simply use the default initialization method described in section 4.

4. Choose Your Preferred Authentication Method

Snickerdoodle analytics offers 3 equivalent methods to authenticate a user's wallet against their decentralized user profile:

  1. A Snickerdoodle-managed EIP-191 (personal sign) prompt
  2. An application-managed EIP-191 (personal sign)) prompt
  3. An application-managed EIP-712 (sign typed data) prompt

Snickerdoodle-managed EIP-191 Personal Sign Authentication

If your dApp does not already ask a user for a login signature, allowing the Snickerdoodle analytics package to prompt the user for a simple login signature is likely the simplest route. See the LetSnickerdoodleSign() component. The relevant code block is the following:

const webIntegration = new SnickerdoodleWebIntegration(webIntegrationConfig, ethersSigner);
webIntegration.initialize();

Note: The ethersSigner object is assumed to be a V5 Ethers signer object. If you are using wagmi to manage signature requests, you'll probably need to add ethers.ts to you project and import it in an appropriate location;

Application-managed EIP-191 Personal Sign Authentication

If your dApp is already prompting the user to perform a simple signature of a login message, you can use the result of that operation to authenticate the user's wallet against their decentralized profile. See the AskToSimpleSign() component. The relevant code block is the following:

const webIntegration = new SnickerdoodleWebIntegration(webIntegrationConfig,);
webIntegration.initialize().andThen((proxy) => {
    return proxy.account.addAccountWithExternalSignature(
      EVMAccountAddress(address),
      myMessage,
      Signature(data),
      EChain.EthereumMainnet, // you can set this to an appropriate network for your app
    );
  }).mapErr((err) => {console.log(err);});

Important

When calling new on the SnickerdooodleWebIntegration object, leave the second argument empty, otherwise the end user will be prompted with a Snickerdoodle login message.

Application-managed EIP-712 Sign Typed Data Authentication

If you dApp is already prompting the user to perform a signature of a typed data payload that is EIP-712 compatible, you can use the result of that operation to authenticate the user's wallet against their decentralized user profile. See the AskToSignTypedData() component. The relevant code block is the following:

const webIntegration = new SnickerdoodleWebIntegration(webIntegrationConfig,);
webIntegration.initialize().andThen((proxy) => {
    return proxy.account.addAccountWithExternalTypedDataSignature(
      EVMAccountAddress(address),
      domain,
      types,
      message,
      Signature(data),
      EChain.EthereumMainnet, // you can set this to an appropriate network for your app
    );
  }).mapErr((err) => {
    console.log(err);
  });

Important

When calling new on the SnickerdooodleWebIntegration object, leave the second argument empty, otherwise the end user will be prompted with a Snickerdoodle login message.

5. Add a TXT Record to Your Application's DNS Settings

You must add a single TXT Record to your application's DNS Records so that the analytics package will trigger the user agreement popup when a new user connects their wallet to your dApp. See our official documentation for more info.

Support for Non-EVM Chains

Snickerdoodle offers support for non-EVM chains through the addAccountWithExternalSignature method as described in section 4. For example, if you are integrating this package into a Solana application, you can activate the analytics package by passing a Solana signature in a similar fashion:

import { SolanaAccountAddress, Signature, EChain } from "@snickerdoodlelabs/objects";
const webIntegration = new SnickerdoodleWebIntegration(webIntegrationConfig,);
webIntegration.initialize().andThen((proxy) => {
    return proxy.account.addAccountWithExternalSignature(
      SolanaAccountAddress(address),
      myMessage,
      Signature(data),
      EChain.Solana, // Solana's chain id is -1 by convention in Snickerdoodle's enum type
    );
  }).mapErr((err) => {console.log(err);});