For your customers using Paper Wallets, we provide an easy way to authenticate their identity so that you can focus on delivering the benefits and utility. <VerifyOwnershipWithPaper> provides a button which opens a pop-up for user's to sign into their Paper Wallets. The implementation follows the OAuth2 specification.

Note: This flow will allow users to sign-up as well and will automatically create a Paper Wallet behind the scenes for the user. To specifically create a Paper Wallet without having users login.

389389

VerifyOwnershipWithPaper button

402402

Getting Stared

  1. Head to the Developer Dashboard.
  2. Click on the "developers" tab.
  3. Create a new OAuth Client.
844844
  1. The newly created client will produce a Client ID. Pass this ID into the <PaperSDKProvider>. You can now use the <VerifyOwnershipWithPaper> component to add to your login page.

The main prop for <VerifyOwnershipWithPaper> is the onSuccess prop. This is a function which will be passed with a code which your backend will use to exchange with a permanent user token (as long as the user doesn't revoke access). See the code sample for more details.

Code Snippet

export function VerifyComponent() {
  const onSuccessLogin = async (code: string) => {
    // code is the temporary access code that you can swap for a permenant user access token
    const resp = await fetch("/api/get-user-token", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        code,
      }),
    });
    if (resp.status !== 200) {
      console.log("resp", resp);
      throw new Error("Failed to get user token");
    }
    const { userToken } = await resp.json();
  };
  // Ensure that you have a PaperSDKProvider set-up with the proper chain name and client Id.
  return (
    <PaperSDKProvider clientId="Your_client_id_here">
        <VerifyOwnershipWithPaper onSuccess={onSuccessLogin} />
        </PaperSDKProvider>
  );
}
import { NextApiRequest, NextApiResponse } from "next";

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  if (req.method !== "POST") {
    return res.status(404).json({ error: "Method not allowed" });
  }
  const body: { code: string } = req.body;
  const code = body.code;

  const resp = await fetch("https://paper.xyz/api/v1/oauth/token", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: "Bearer <YOUR-API-SECRET-KEY>",
    },
    body: JSON.stringify({
      code,
      clientId: "<YOUR-CLIENT-ID>",
    }),
  });

  if (resp.status !== 200) {
    return res.status(500).json({ error: "Error getting user token" });
  }
  const { userToken } = await resp.json();

  return res.status(200).json({ userToken });
}

Customization

In order to customize the button to your liking, we provide three ways of using the <VerifyOwnershipWithPaper> component:

Provided Button:

389389

VerifyOwnershipWithPaper button

<VerifyOwnershipWithPaper className='verify-ownership-with-paper-btn' onSuccess={onSuccessLogin} />

Wrapping your own login Button with the <VerifyOwnershipWithPaper> component:

<VerifyOwnershipWithPaper onSuccess={onSuccessLogin}>
    <YourComponentHere />
</VerifyOwnershipWithPaper>

Control everything yourself:

<VerifyOwnershipWithPaper onSuccess={onSuccessLogin}>
    {({ onClick } : { onClick : () => void}) => {
        return <YourButtonHere onClick={onClick} />
    }}
</VerifyOwnershipWithPaper>

Props

These props can be used as arguments within the <VerifyOwnershipWithPaper> component. See the name, type, and description for each prop in the table below.

Prop

Type

Description

className

string

Optional
This is only used to customize the default styling of the VerifyOwnershipWithPaper button. Note that the default button already have styling so you might need to override with !important in order to see you styling take effect.

Callback Functions

The following callback function can be passed on as arguments within the <VerifyOwnershipWithPaper> component. See the name, type, and description for each prop in the table below.

Callback Function

Description

onSuccess: (code: string) => void

Optional
This callback is called once the user successfully logs in to their paper wallet.

onError: (error: PaperSDKError) => void

Optional
This function is called when the user fails to login. This could happen because the user gave an invalid email, or they failed to verify their email. See PaperSDKError for more.

onClose: () => void

Optional
This function is called when the login window is closed.