# CKBull Signer API

Documentation

## What is CKBull Signer API?

**CKBull Signer API** is a platform that allows dApps within the CKB ecosystem to integrate a transaction signing system via the [**CKBull Wallet**](https://ckbull.app/).

Developers can register their dApps on this platform using a developer interface, and they can interact with the signer API to create transactions.

{% hint style="info" %}
The **initial release** of the CKBull Signer API is completely free. As a developer, you are free to register a variety of dApps and use the API.
{% endhint %}


# Create an account

## Email registration

The first step to start using the platform is to create an account in **CKBull Developer Console.** To achieve this, you can register yourself with an **email address.**

{% hint style="info" %}
If you do register with an email address, you will need to **verify your account** with the token sent to the provided email. If the token expires, you can also resend a verification email.
{% endhint %}

{% hint style="warning" %}
Remember that if your account is not verified, **you won't be able to access the developer console** and, so on, register your dApps.
{% endhint %}

<figure><img src="https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-c074099deea7190a97b1ad002f95793068d7ee64%2FScreenshot%202023-06-28%20at%2011.55.31.png?alt=media" alt=""><figcaption></figcaption></figure>

## Google registration

Another registration option is using a Google account, which is also supported.

{% hint style="info" %}
If you register with Google, you will be **automatically verified**.
{% endhint %}

To register, click the **Continue with Google** button on the login page.

<figure><img src="https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-a318fbb0cb55eeb85beaae5b77a97046800d7990%2FScreenshot%202023-06-28%20at%2011.54.12.png?alt=media" alt=""><figcaption></figcaption></figure>


# Register a dApp

## dApp registration

Once you are registered in **CKBull Developer Console**, you can start adding your dApps to the console. On the main page, next to **Your dApps,** click the button **Create new dApp.** This action will redirect you to the dApp creation form which should look like the following image.

<figure><img src="https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-694cbd2b32bf07590c85db5a699f027ad859a171%2FScreenshot%202023-06-28%20at%2011.58.16.png?alt=media" alt=""><figcaption></figcaption></figure>

Once you have added all the necessary information, click the **Create application** button at the bottom of the form. Your dApp is now registered in the platform.

{% hint style="warning" %}
Be aware that the dApp **name**, **description** and **logo** will be displayed in the **CKBull Wallet** every time a sign in request is scanned.
{% endhint %}

<figure><img src="https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-462c3083cdc3e78886fd6e0f7abe8ed7bcb43e88%2FIMG_9800.PNG?alt=media" alt="" width="375"><figcaption><p>Sign in request data</p></figcaption></figure>

## dApp API keys

You will notice that after creating your dApp a modal is displayed. This modal contains the API keys that will let the dApp connect with the Signer API to send transactions.

{% hint style="danger" %}
Your API Keys **must never be shared**. They may impersonate the dApp and send malicious queries if they are leaked. In that case, see how you can [**regenerate new API keys**](/getting-started/regenerate-api-keys).
{% endhint %}

<figure><img src="https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-103206e84afb56b93a9ad2733276949d4a969641%2FScreenshot%202023-04-19%20at%2012.20.17.png?alt=media" alt=""><figcaption></figcaption></figure>


# Regenerate API keys

In case you want to regenerate the API keys of a dApp, you can do so by selecting the dApp in the list of your dApps and clicking on the **Regenerate** button.

{% hint style="warning" %}
Be sure to **copy the new API secret.** It will not be displayed again.
{% endhint %}

{% hint style="danger" %}
Remember to **update the new secret** if you used the API keys in your dApp so that you can use the API. **The old API Secret will immediately stop working**.
{% endhint %}

<figure><img src="https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-2ebd249df1283a62815cc5510f24939d595d69e1%2FScreenshot%202023-06-28%20at%2012.00.49.png?alt=media" alt=""><figcaption></figcaption></figure>


# Next steps

Continue learning

## I completed the introduction, what can I do now?

Congratulations! You have registered your dApp on the Signer platform. Here we list some paths to keep understanding how the Signer works and how you can generate requests for your dApp users.

* If you wish to learn the main concepts of the Signer API, continue reading [**Guides and Concepts.**](/guides-and-concepts/introduction)
* If you already understand how the platform works and you are looking for API documentation, start reading [**API**](/api/introduction) section.


# Introduction

In this section, you can find detailed information about the main concepts that revolve around **CKBull Signer API.**

{% hint style="info" %}
Please note that this platform is in its first version, and therefore new concepts could be introduced in future versions.
{% endhint %}

The main concepts are:

* **Sign in requests:** Requests generated by the dApp meant to identify a user and retrieve its metadata.
* **Transaction requests:** Requests that contain a transaction proposal and are expected to be signed by an identified user.

Since the two concepts are related, we recommend following the order of the guide.


# Sign in request

Guide

## What are sign in requests?

A sign in request is **the way a dApp can identify a user**. Let's explain it with the following example:

When a user wants to log in or register in your dApp, the dApp has to know how to identify a user to know which operations to perform. To do so, it uses the **CKBull Signer API** with the dApp credentials to generate a new and unique sign in request that needs to be signed by the user who requested it.

Here's a workflow on how a sign in request is generated and signed by a user and how it affects all the entities in the system:

<figure><img src="https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-0662e821cd697c1daac377cd6d22a61a92b6407d%2FRequests%20status%20graph%20-%20Page%202.png?alt=media" alt=""><figcaption><p>Sign in request workflow</p></figcaption></figure>

## Sign in request life cycle

In the lifetime of a sign in request, it may contain multiple states depending on the actions performed by a user. The next flow shows the complete life cycle of a sign in request and its states.

<figure><img src="https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-b3759089a8323e788541a49a456abcad53189462%2FRequests%20status%20graph%20-%20Page%203%20(1).png?alt=media" alt=""><figcaption><p>Sign in request life cycle</p></figcaption></figure>

## How does the request identifies the user?

To identify who signed the transaction via **CKBull Wallet**, a payload containing the address and network of the signer is passed when the user signs the request. For a detailed explanation, read the [**API docs**](/api/requests/sign-in-request). A sign in request has the following appearance in CKBull Wallet, showing the dApp's name, description and logo.<br>

<figure><img src="https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-462c3083cdc3e78886fd6e0f7abe8ed7bcb43e88%2FIMG_9800%20(1).PNG?alt=media" alt="" width="375"><figcaption><p>Sign in request in CKBull Wallet</p></figcaption></figure>

Having explained sign in requests, we can now introduce the second key concept of the platform, transaction requests.


# Transaction request

Guide

After explaining the sign in request concept, it is time to introduce transaction requests.

{% hint style="warning" %}
If you don't know what sign in request are or you haven't read the docs, we recommend to learn how they work in the [previous section](/guides-and-concepts/sign-in-request).
{% endhint %}

## What is a transaction request?

To answer this question, first we need to clarify what a transaction is, which corresponds to a transaction made in the CKB blockchain. Therefore, a transaction request is the dApp's way of asking a **CKBull Wallet** user to sign a transaction.

## How do sign-in requests and transaction requests relate to each other?

The logic is quite simple. In order to create a transaction, you need someone responsible for signing it. So, you cannot generate a transaction request without a user who wants to sign it.

The responsible party to bring this information is **a signed sign in request**, which will contain the user's metadata to later provide the transaction request related to that user.

Here is the workflow of a transaction request generated by the dApp with a signed sign in request.

<figure><img src="https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-b4cafc2b1e49f7124f732a14adc427183f73ddf1%2FRequests%20status%20graph%20-%20Page%204%20(1).png?alt=media" alt=""><figcaption><p>Transaction request workflow</p></figcaption></figure>

When an identified user triggers an event in your frontend app, a transaction request will be generated via API.

The user will then sign the transaction request received in CKBull Wallet, broadcast it to the blockchain, and return the transaction hash to the API for subsequent use by the dApp. To know how to check the status of a transaction request check the [**API docs**](/api/requests/transaction-request).

## Transaction request life cycle

As with sign in requests, transaction requests also have a certain life cycle depending on the actions taken by the user.

When a transaction request is generated, it gets a **pending** status that will not change unless it is signed, rejected or expired.

<figure><img src="https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-11d06c0b1faf17df2aef5ae54108fb1d95d32ee6%2FRequests%20status%20graph%20-%20Page%203%20(2).png?alt=media" alt=""><figcaption><p>Transaction request life cycle</p></figcaption></figure>

Once the dApp has generated a transaction request, the CKBull Wallet user will receive the request in the application, where he or she can sign or reject it. The transaction request will display information about the dApp, such as its name, description and logo, along with the transaction summary.

{% hint style="danger" %}
For transaction requests, **no QR code must be generated** to receive them. Once created, the user will be able to view them in the Activity > Pending tab.
{% endhint %}

<figure><img src="https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-e03f83c97ed6d39913182c03156fd176ac383e41%2Ftransaction-request.png?alt=media" alt="" width="563"><figcaption><p>Transaction request view from CKBull Wallet</p></figcaption></figure>


# Introduction

This section contains the API specification, including all calls that the dApp can make to interact with sign in requests and transaction requests.

During the reading, you are likely to encounter certain calls that have a :unlock: icon. These refer to calls that need to provide the authentication explained in the following document.

The specification is separated into the following sections:

* [**Authentication**](/api/authentication): Security mechanism to interact with the API.
* [**Requests**](/api/requests): Sign in and transaction request specification.
* [**Polling**](/api/polling): Resource for dApps.

{% hint style="info" %}
All API calls specified in this section must be made to the host **console.ckbull.app**
{% endhint %}


# Authentication

How to authenticate yourself with CKBull Signer API

To be able to **generate sign in requests** and **transaction requests** your dApp must use the API keys provided in **CKBull Developer Console** after registering it.

{% hint style="warning" %}
**CKBull Signer API** is meant to be called from a **server**. Don't make calls from your dApp frontend; **always use your own dApp backend**.
{% endhint %}

You will need:

* **API Key.**
* **API Secret.**

CKBull Signer API uses the **HMAC-SHA512 algorithm** to validate the dApp in every call to generate sign in and transaction requests. The following **HTTP headers** need to be passed to authenticate the dApp:

* **x-timestamp:** A timestamp generated when making the call.
* **x-api-key:** The dApp API key provided in CKBull Developer Console.
* **x-signature:** The signature hash obtained using the **timestamp** and **your** **dApp API secret.**

Here you can find the code to generate the required headers.

{% tabs %}
{% tab title="Javascript" %}

```javascript
const crypto = require('crypto');

const apiSecret = "your-api-secret";
const timestamp = Math.floor(Date.now() / 1000);

const hmac = crypto.createHmac('sha512', apiSecret);
hmac.update(timestamp.toString());

const timestampHeader = timestamp;
const signatureHeader = hmac.digest('base64');
const apiKeyHeader = "your-api-key";
```

{% endtab %}

{% tab title="Python" %}

```python
import hashlib
import os
import base64
import time

apiSecret = 'your-api-secret';
timestamp = str(int(time.time()))

hmac = hashlib.sha512(random_string.encode('utf-8'))
hmac.update(timestamp.encode('utf-8'))
hash = hmac.digest()
hash_b64 = base64.b64encode(hash).decode('utf-8')

timestamp_header = timestamp
signature_header = hash_b64
api_key_header = 'your-api-key';

```

{% endtab %}
{% endtabs %}


# Transactions

## How do I prepare transaction requests?

In order to send transaction requests to CKBull Wallet users, the [**Lumos**](https://github.com/ckb-js/lumos) library must be used. Specifically, it is necessary to provide a JSON object of type **TransactionSkeletonType** containing the **outputs** corresponding to the reason for the transaction.

When the user receives the request and proceeds to sign it, the rest of the fields of the transaction (cellDeps, inputs, witnesses, etc.) will be **filled in automatically**, once the transaction is signed, it will be sent.

## Supported transactions

* **CKB** transactions
* **Token** transactions
* **NFTs** transactions

## Lumos versions supported

This section will list all supported versions for transaction generation:

* **✅ v0.19.0**
* **✅ v0.18.0**


# Requests

This section provides API specification for every request type in the system.

* [**Sign in request**](/api/requests/sign-in-request) specification.
* [**Transaction request**](/api/requests/transaction-request) specification.


# Sign in request

Sign in request API specification

## Generate :unlock:

To create a sign in request as a dApp, call the following endpoint with the necessary parameters.

{% hint style="warning" %}
This is a protected call which uses API authentication. See how to implement it in [**API authentication**](/api/authentication) section.
{% endhint %}

{% openapi src="/files/IoEMLLlEMYecgfMTUZ2D" path="/api/sign-in-requests" method="post" %}
[openapi-spec.json](https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-cbbcae6fea374cebec1fa40b6477c93b3c9f8e5b%2Fopenapi-spec.json?alt=media)
{% endopenapi %}

{% hint style="info" %}
Each sign in request has **7 days** to be signed or rejected before it expires.
{% endhint %}

## Get

With the provided sign in token, this method will return all pertinent information from the sign in request.

{% openapi src="/files/IoEMLLlEMYecgfMTUZ2D" path="/api/sign-in-requests/{signInToken}" method="get" %}
[openapi-spec.json](https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-cbbcae6fea374cebec1fa40b6477c93b3c9f8e5b%2Fopenapi-spec.json?alt=media)
{% endopenapi %}


# Transaction request

Transaction request API specification

## Generate :unlock:

To create a transaction request as a dApp, you will need to provide a sign in token and a transaction.

{% hint style="info" %}
A **partial transaction** is a transaction with the **TransactionSkeletonType** format specified in the library [**Lumos**](https://github.com/ckb-js/lumos). You need to attach the necessary fields that you want your transaction to have so that it can be processed by the API.
{% endhint %}

{% hint style="info" %}
Each transaction request has **7 days** to be signed or rejected before it expires.
{% endhint %}

{% openapi src="/files/IoEMLLlEMYecgfMTUZ2D" path="/api/transaction-request" method="post" %}
[openapi-spec.json](https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-cbbcae6fea374cebec1fa40b6477c93b3c9f8e5b%2Fopenapi-spec.json?alt=media)
{% endopenapi %}

{% hint style="warning" %}
Remember that to create a transaction request successfully **you need to provide a signed sign in token.** If the provided token is not signed your request will be rejected.
{% endhint %}

{% hint style="warning" %}
This is a protected call which uses API authentication. See how to implement it in [**API authentication**](/api/authentication) section.
{% endhint %}

## Get

With the provided transaction token, this method will return all pertinent information from the transaction request, including the sign in request and transaction data

{% openapi src="/files/IoEMLLlEMYecgfMTUZ2D" path="/api/transaction-request/{transactionToken}" method="get" %}
[openapi-spec.json](https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-cbbcae6fea374cebec1fa40b6477c93b3c9f8e5b%2Fopenapi-spec.json?alt=media)
{% endopenapi %}


# Polling

Requests status polling

As a dApp, you may want to check the status of a certain request in order to adapt your frontend. To achieve this, CKBull Signer API has two prepared endpoints to obtain the status of a request.

## Sign in request polling

A simple endpoint to obtain the status of a sign in request by its token.

{% openapi src="/files/IoEMLLlEMYecgfMTUZ2D" path="/api/sign-in-requests/{signInToken}/status" method="get" %}
[openapi-spec.json](https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-cbbcae6fea374cebec1fa40b6477c93b3c9f8e5b%2Fopenapi-spec.json?alt=media)
{% endopenapi %}

As mentioned in [**Guides and concepts**](/guides-and-concepts/sign-in-request)**,** a sign in request can have the following status: **pending**, **expired**, **signed**, **declined** or **session expired.**

## Transaction request polling

A simple endpoint to obtain the status of a transaction request by its token.

{% openapi src="/files/IoEMLLlEMYecgfMTUZ2D" path="/api/transaction-request/{transactionToken}/status" method="get" %}
[openapi-spec.json](https://4100684485-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPlB1oN5qXYGlSUWHxkql%2Fuploads%2Fgit-blob-cbbcae6fea374cebec1fa40b6477c93b3c9f8e5b%2Fopenapi-spec.json?alt=media)
{% endopenapi %}

As mentioned in [**Guides and concepts**](/guides-and-concepts/transaction-request)**,** a sign in request can have the following status: **pending**, **expired**, **signed**, **declined.**


