Guide
CKB
Sign Message

Sign Message

In this guide we will use a JoyID connection to sign a message/challenge using the @joyid/ckb SDK signChallenge() function.

ℹ️

Understanding the difference between a challenge and a message.

A challenge is what you as a developer need JoyID to sign. A message is the piece of data that JoyID actually signs. A message is a combination of a challenge and some other data needed to complete the process, such as authenticator data, etc. The challenge is always included within the message.

For more information, you can check out the WebAuthn Spec (opens in a new tab).

To sign a challenge with the user's JoyID session, complete the following steps.

Step 1: Save the User's JoyID Information

In the connect guide, we created a connection with JoyID and received the user's JoyID information. Now we need to retain this information so it can be used for signing. There are many ways this can be done, but we will demonstrate this below using a state variable of the React component and the Vuex store of the Vue app.

App.tsx
import * as React from 'react';
import { connect } from '@joyid/ckb';
import './style.css';
 
export default function App() {
  const [joyidInfo, setJoyidInfo] = React.useState(null);
 
  const onConnect = async () => {
    try {
      const authData = await connect();
      setJoyidInfo(setJoyidInfo);
      console.log(`JoyID user info:`, authData);
    } catch (error) {
      console.log(error);
    }
  }
 
  return (
    <div>
      <h1>Hello JoyID!</h1>
      <button onClick={onConnect}>Connect JoyID</button>
    </div>
  );
}

Step 2: Sign a Challenge

The next step after establishing a connection is to call the signChallenge() function. To do this we add a button element with a click event handler to sign the challenge text contained in the textarea using the user's JoyID connection.

Note: In order to use the signChallenge() function, we must provide the address to sign with. This is why we specifically retained the user's JoyID information after establishing a connection, beucase it contains user's address.

App.tsx
import * as React from 'react';
import { connect, signChallenge } from '@joyid/ckb';
import './style.css';
 
export default function App() {
  const [joyidInfo, setJoyidInfo] = React.useState(null);
  const [challenge, setChallenge] = React.useState('Sign this for me');
 
  const onConnect = async () => {
    try {
      const authData = await connect();
      setJoyidInfo(authData);
      console.log(`JoyID user info:`, authData);
    } catch (error) {
      console.log(error);
    }
  }
  const onSign = async () => {
    const res = await signChallenge(challenge, joyidInfo.address);
    if (res) {
      alert('Sign message successful');
      console.log(`Sign message result: ${res}`);
    }
  }
  return (
    <div id="app">
      <h1>Hello JoyID!</h1>
      {joyidInfo ? null : <button onClick={onConnect}>Connect JoyID</button>}
      {joyidInfo ? (
        <div>
          <textarea value={challenge} onChange={e => setChallenge(e.target.value)} />
          <button onClick={onSign}>Sign With JoyID</button>
        </div>
      ) : null}
    </div>
  );
}
💡

To learn more about the signChallenge() function, please check the API Reference.

Try it Out