Skip to main content

Code Sample

In addition to providing deeper integrations via our JS SDK and APIs, Bitski also offers a set of plug-and-play connectors which work with the existing Web3 ecosystem. Use the following code snippets below to easily add Bitski to your RainbowKit setup. These code snippets provide a Bitski connector which can hook into our browser extension if installed. As a fallback, users can also login or sign up for a Bitksi Wallet using username and password. This gives Dapps the ability to not only provide a native Web3 solution for crypto natives, but also provide an intuitive onboarding process for new users.
Required dependencies: @rainbow-me/rainbowkit, bitski, wagmi. See the CodeSandbox’s package.json for more details.
import '../styles/globals.css';
import '@rainbow-me/rainbowkit/styles.css';
import { connectorsForWallets, RainbowKitProvider } from '@rainbow-me/rainbowkit';
import type { AppProps } from 'next/app';
import { configureChains, createClient, WagmiConfig } from 'wagmi';
import { arbitrum, goerli, mainnet, optimism, polygon } from 'wagmi/chains';
import { publicProvider } from 'wagmi/providers/public';
import {
  injectedWallet,
  walletConnectWallet,
  rainbowWallet,
  metaMaskWallet,
  coinbaseWallet
} from '@rainbow-me/rainbowkit/wallets';
import { Bitski } from 'bitski';

import { bitskiWallet } from './bitskiWallet';

const { chains, provider, webSocketProvider } = configureChains(
  [
    mainnet,
    polygon,
    optimism,
    arbitrum,
  ],
  [publicProvider()]
);

/*
 * Replace the clientId and callbackUrl with your own.
 * You can get a clientId and setup your callback url at https://developer.bitski.com.
 */
const bitski = new Bitski(
  'your-client-id'
  'https://your-callback-url.com/callback'
);

const connectors = connectorsForWallets([
  {
    groupName: 'Recommended',
    wallets: [
      bitskiWallet({ bitski, chains }),
    ],
  },
  {
    groupName: 'Other Wallets',
    wallets: [
      injectedWallet({ chains }),
      walletConnectWallet({ chains, projectId: 'YOUR_PROJECT_ID' }),
      metaMaskWallet({ chains }),
      coinbaseWallet({ appName: 'YOUR_APP_NAME', chains }),
      rainbowWallet({ chains }),
    ],
  },
])

const wagmiClient = createClient({
  autoConnect: true,
  connectors,
  provider,
  webSocketProvider,
});

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <WagmiConfig client={wagmiClient}>
      <RainbowKitProvider chains={chains}>
        <Component {...pageProps} />
      </RainbowKitProvider>
    </WagmiConfig>
  );
}

export default MyApp;
import { Chain, Wallet } from "@rainbow-me/rainbowkit";
import {
  Ethereum,
  InjectedConnector,
  InjectedConnectorOptions,
} from "@wagmi/core";
import { Bitski } from "bitski";

export interface BitskiWalletOptions {
  bitski?: Bitski;
  chains: Chain[];
}

class BitskiConnector extends InjectedConnector {
  bitski?: Bitski;
  windowEthereum?: Ethereum;

  constructor({
    bitski,
    chains,
    options: options_,
  }: {
    bitski?: Bitski;
    chains?: Chain[];
    options?: InjectedConnectorOptions;
  } = {}) {
    let provider: any;

    if (
      typeof window !== "undefined" &&
      (window.ethereum as any) &&
      (window.ethereum as any).isBitski
    ) {
      provider = window.ethereum;
    }

    if (typeof window !== "undefined" && !provider) {
      provider = bitski?.getProvider();
    }

    const options = {
      shimDisconnect: true,
      getProvider: () => provider,
      ...options_,
    };

    super({ chains, options });

    this.windowEthereum = provider;
    this.bitski = bitski;
  }

  private injectProvider() {
    if (!global.window) return;
    global.window.ethereum = this.bitski?.getProvider() as unknown as Ethereum;
  }

  private ejectProvider() {
    if (!global.window) return;
    global.window.ethereum = this.windowEthereum;
  }

  async connect({ chainId }: { chainId?: number } = {}) {
    this.injectProvider();

    const user = await this.bitski?.signIn();
    const result = await super.connect({ chainId });
    return result;
  }

  async disconnect(): Promise<void> {
    this.ejectProvider();

    await super.disconnect();
    await this.bitski?.signOut();
    await this.bitski?.getAuthStatus();
  }
}

export const bitskiWallet = ({
  bitski,
  chains,
  ...options
}: BitskiWalletOptions & InjectedConnectorOptions): Wallet => ({
  id: "bitski",
  name: "Bitski",
  installed:
    !!bitski ||
    (typeof window !== "undefined" &&
      typeof window.ethereum !== "undefined" &&
      ((window.ethereum as any).isBitski === true ||
        !!window.ethereum.providers?.find((p: any) => p.isBitski === true))),
  iconUrl: "https://cdn.bitskistatic.com/docs-web/bitskiWallet.svg",
  iconBackground: "#fff",
  downloadUrls: {
    browserExtension:
      "https://chrome.google.com/webstore/detail/bitski/feejiigddaafeojfddjjlmfkabimkell",
    ios: "https://apps.apple.com/us/app/bitski-wallet/id1587199538",
  },
  createConnector: () => ({
    connector: new BitskiConnector({
      bitski,
      chains,
      options,
    }),
  }),
});

CodeSandbox

View an interactive demo of the Bitski connector for RainbowKit

More info

If you’re tailoring your Dapp to only crypto natives, see the official RainbowKit connector for Bitski