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.

The most common reason for signing a message is to authorize a transaction. On CKB, the Cell Model (opens in a new tab) is used for all smart contract transactions. Transactions are typically built using an SDK framework like Lumos (opens in a new tab). SDKs are available for several languages including JavaScript (opens in a new tab), Rust (opens in a new tab), Go (opens in a new tab), and Java (opens in a new tab). To learn how to program smart contracts using the Cell Model, please visit CKB Academy (opens in a new tab).

ℹ️

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 established a connection with JoyID and obtained the user's JoyID information. It's essential to retain this information so it can be used in the signing process later on. There are many ways this can be done. Below, we demonstrate two common methods: using a state variable in a React component and employing the Vuex store in a 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(authData);
      console.log(`JoyID user info:`, authData);
    } catch (error) {
      console.error(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, add a button with a click event. This will 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, because it contains the 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.error(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