Sign with Popup

Once the authentication is complete, we will get the user's JoyID information, such as username, address, credential, etc. In this guide, we will continue our previous journey in Auth with Popup by signing a challenge after the authentication is complete.

To sign a challenge with the user's JoyID, with the pop-up feature, we need to do the following steps:

Step 1: Save authentication info

In the previous guide, we have already authenticated the user with JoyID, and we have got the user's JoyID information. Now we need to save the user's JoyID information. We can save it in the local storage, or in the state of the React component, or in the Vuex store of the Vue app, etc.

React
import * as React from 'react';
import { authWithPopup } from '@joyid/core';
import './style.css';

export default function App() {
  const [joyidInfo, setJoyidInfo] = React.useState(null);
  const authOnClick = async () => {
      const res = await authWithPopup({
          redirectURL: location.origin + '/',
          name: 'Awesome App',
          challenge: 'Sign this for me',
          logo: 'https://reactjs.org/logo-180x180.png',
      });
      if (res.error == null) {
          setJoyidInfo(res.data);
      }
  };
  return (
      <div>
          <h1>Hello JoyID!</h1>
          <button onClick={authOnClick}>Auth With JoyID</button>
      </div>
  );
}
Vue
<template>
  <div id="app">
      <h1>Hello JoyID!</h1>
      <button @click="auth">Auth with JoyID</button>
  </div>
</template>

<script>
import { authWithPopup } from '@joyid/core';

export default {
  name: 'App',
  data() {
      return {
          joyidInfo: null,
      };
  },
  methods: {
      async auth() {
          const res = await authWithPopup({
              redirectURL: location.href,
              name: 'Awesome App',
              challenge: 'Sign this for me',
              logo: 'https://vuejs.org/images/logo.png',
          });
          if (res.error == null) {
              this.joyidInfo = res.data;
          }
      },
  },
};
</script>

Step 2: Sign the challenge

After the authentication is complete, we need to add a button element and listen to the click event. When the user clicks the button, we will call the signWithPopup function to sign the challenge with the user's JoyID.

Note that address is required in the signWithPopup function. You can only sign the challenge with the user's JoyID if you know the user's address. The address is included in authentication info.

Verify the credential before signing the challenge

React
import * as React from 'react';
import { authWithPopup, signWithPopup } from '@joyid/core';
import './style.css';

export default function App() {
  const [joyidInfo, setJoyidInfo] = React.useState(null);
  const authOnClick = async () => {
      const res = await authWithPopup({
          redirectURL: location.origin + '/',
          name: 'Awesome App',
          challenge: 'Sign this for me',
          logo: 'https://reactjs.org/logo-180x180.png',
      });
      if (res.error == null) {
          setJoyidInfo(res.data);
      }
  };
  const signOnClick = async () => {
      const { keyType, address, pubkey, alg } = joyidInfo;
      if (keyType === 'main_session_key' || keyType === 'sub_session_key') {
          const isValid = await verifyCredential(pubkey, address, keyType, alg);
          if (!isValid) {
              alert('Your key is expired, please re-authenticate with JoyID');
              return;
          }
      }
      const res = await signWithPopup({
          redirectURL: location.origin + '/',
          name: 'Awesome App',
          challenge,
          logo: 'https://reactjs.org/logo-180x180.png',
          address: joyidInfo?.address,
      });
      if (res.error == null) {
          // see console for details
          console.log(res.data);
      }
  };
  return (
      <div>
          <h1>Hello JoyID!</h1>
          {joyidInfo ? null : (
              <button onClick={authOnClick}>Auth With JoyID</button>
          )}
          {joyidInfo ? (
              <div>
                  <textarea
                      value={challenge}
                      onChange={(e) => setChallenge(e.target.value)}
                  />
                  <button onClick={signOnClick}>Sign With JoyID</button>
              </div>
          ) : null}
      </div>
  );
}
Vue
<template>
  <div id="app">
      <h1>Hello JoyID!</h1>
      <button @click="auth" v-if="!joyidInfo">Auth with JoyID</button>
      <div v-else>
          <textarea v-model="challenge" />
          <button @click="sign">Sign With JoyID</button>
      </div>
  </div>
</template>

<script>
import { authWithPopup, signWithPopup } from '@joyid/core';

export default {
  name: 'App',
  data() {
      return {
          joyidInfo: null,
          challenge: 'Sign this for me'
      };
  },
  methods: {
      async auth() {
          const res = await authWithPopup({
              redirectURL: location.href,
              name: 'Awesome App',
              challenge: 'Sign this for me',
              logo: 'https://vuejs.org/images/logo.png',
          });
          if (res.error == null) {
              this.joyidInfo = res.data;
          }
      },
      async sign() {
          const { keyType, address, pubkey, alg } = this.joyidInfo;
          if (keyType === 'main_session_key' || keyType === 'sub_session_key') {
              const isValid = await verifyCredential(pubkey, address, keyType, alg);
              if (!isValid) {
                  alert('Your key is expired, please re-authenticate with JoyID');
                  return;
              }
          }
          const res = await signWithPopup({
              redirectURL: location.origin + '/',
              name: 'Awesome App',
              logo: 'https://vuejs.org/images/logo.png',
              address: this.joyidInfo?.address,
              challenge: this.challenge,
          });
          if (res.error == null) {
              // see console for details
              console.log(res.data);
          }
      },
  },
};
</script>
To learn more about the signWithPopup function, please check the API Reference.

challenge vs. message

Try it out

Loading Sandbox...
Loading Sandbox...