# About

Polkadot.js integrated into a No-Code plugin for Bubble.io

The polkadot.js features wrapped into a free, no-code plugin for one of the biggest no-code platforms: [bubble.io](<https://bubble.io?ref=32w0zloj >)&#x20;

**Provided by** [**NovaBloq**](https://novabloq.com/) **team, supported by** [**Web3 Foundation**](https://web3.foundation/)\
\
Build projects on Polkadot network without code.\
This plugin opens a door to the Polkadot ecosystem for no-code developers.\
\
The main target of this plugin is every potential user of the Substrate / Polkadot / Kusama ecosystem. No-Code requires much less time to start work with, making it very easy for everyone that wants to experiment with it to bring their ideas to life.

{% hint style="success" %}
If you are new to Bubble, take a look at this step by step guide first <https://ezcodeco.gitbook.io/polkadot-testing-guide/>
{% endhint %}

## Links

* [Forum thread](https://forum.bubble.io/t/free-plugin-polkadot-js-by-ezcode/187940)
* [Marketplace](https://bubble.io/plugin/polkadot-wallet-1639402639641x977692461648052200)
* [Demo page](https://polkadotjs.bubbleapps.io/version-test/)

## Implemented Features

### [Wallet Extension](https://polkadot.js.org/docs/extension)

*Details in the* [*Polkadot Wallet element*](/element-polkadot-wallet/actions) *section*

### [Utilities](https://polkadot.js.org/docs/util-crypto)

*Details in the* [*Polkadot Utils*](/element-polkadot-utils/actions) *section*

### [API](https://polkadot.js.org/docs/api)

*Details in the* [*Polkadot API*](/element-polkadot-api/getting-started) *section*

### [Keyring](https://polkadot.js.org/docs/keyring)

*Details in the* [*Polkadot Keyring*](/element-polkadot-keyring/getting-started) *section*


# F.A.Q.

### What are "actions"?

Think of it as a function that can run with some parameters and it will return a response and trigger events.\
Bubble has its own **integrated actions**, such as: *run an animation, change data in the database* etc.&#x20;

### What is "plugin element"?

When we are adding the **plugin element** on the page, its actions becomes available to use, extending the default integrated actions. \
This is why we need to add the plugin element on the page, to add all its actions to our Bubble app\
Of course, the plugin can have some actions without the plugin element, such as API calls, they become available automatically after installing the plugin in the app.

### What are "states"?

States are Bubble form of variables. It can contain any kind of data that can dynamically change. \
For example, when running a plugin action, its response can be found the plugin element states.

Lets take the *Utils* element as an example,  if we will dynamically select it in a text field, we can see all states available for this element:

![](/files/2VHdDCv02Vfrbf6L6oFi)

### What are "events"?

Events as the name says, is when something happened in our app. In same way as actions, Bubble has its own integrated events, such as: *page is loaded, input value changed etc.*\
\
When we are adding the plugin element on the page, all its event become available to us, so we use them to know when a plugin action was executed and let the user know about its response.\
\
Lets see the events from the Polkadot API element:

![](/files/FySieDMEG2n5CUp74XYh)

{% hint style="info" %}
Note! Some states are updated only after a certain event was triggered. \
For example: The state *Last Block Nr* will be updated only after the event New Block was triggered.
{% endhint %}


# Installation

How to install the plugin

Add the plugin element on the page where you will use it, it can also be inside a reusable element like Header or Footer.&#x20;

{% hint style="info" %}
Make sure that the plugin element is **not** inside a group that can be hidden under certain circumstances, for example on mobile devices.
{% endhint %}

## Initialise the plugin

### Run - Load App action

First step that you need to do to run the plugin, is start the action *Load App.* \
This will initialise the polkadot.js instance, API connection and if it is the first time a user visits your app, he will be asked to allow connection of your app to his wallet extension.\
[Example](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIMKdkPzZeUlk7WD5V4J8%2Fuploads%2F2Gahs9XIa4rnCWeE4L6Y%2FScreenshot%202022-01-16%20at%2012.51.56.png?alt=media\&token=1f74278d-20bf-4bbe-8599-88f98f794319)\
\
There are 2 fields in this action, **App Name** and **RCP**

#### **App Name**

This is the name of your app that will be shown in extension popups when the user will be asked to accept certain actions.\
For example, on the Authorise popup:\
![](/files/V06AKwKZ2ifqEbWtWL3m)

#### RPC url

This field is Optional! Leave empty to use the default Polkadot RPC url.<br>

## Example

In our [wallet demo](https://polkadotjs.bubbleapps.io/version-test/simple_connect), we have added this action on *Page is loaded* event.\
![](/files/tacM7bf3LwYqVrOnMxx3)\
\
You can run this event on any other event, for example when a certain button click.

As you can see, for the demo we use **Westend testnet**, and for that, in the **RPC** field we use Westend RPC URL that is: **wss\://westend-rpc.polkadot.io**<br>

## Useful States

A few useful states will inform you about the plugin status.

### Is Extension installed&#x20;

*State type: Yes/No*

This state will inform if the user has the extension installed.

{% hint style="info" %}
Note: If it is NO, this also could mean that the user denied your app access.
{% endhint %}

### Connected Wallets

*State type: Text List*

Will show the connected wallet addresses from the extension. Can be more than one.

### Connected Wallets Name

*State type: Text List*

Names of the connected wallet, each index represents the wallet address at the same index from Connected Wallets state.

For example:\
Wallet with index 1: AB123

Wallet Name index 1: My Main Wallet

So it means that the wallet with the index 1 (*AB123*) has the name with the index 1 that is *My Main Wallet*

\
See an example of how it can be used in the demo app editor [here](https://bubble.io/page?type=page\&name=simple_connect\&id=polkadotjs\&test_plugin=1639402639641x977692461648052200_current\&tab=tabs-1)\
Look for the Repeating Group called *Connected Wallets*

### API is initializing

State type: Yes/No

The API connection may load longer than the plugin connection, the API connection is needed when doing the Sign and Send Transaction, so before doing it, make sure this state is NO.\
\
If the API is still loading, the state will be Yes, when it will finish loading and will be ready to use, it will be NO.


# Technology Stack

In this plugin, we have implemented the main features that from the [polkadot.js](https://github.com/polkadot-js) that could be integrated into Bubble plugin in a practical usable way.&#x20;

```
"dependencies": {
    "@polkadot/api": "^7.8.1",
    "@polkadot/extension-dapp": "^0.42.7",
    "@polkadot/keyring": "^8.4.1",
    "@polkadot/util": "^8.4.1",
    "@polkadot/util-crypto": "^8.4.1"
  }
```

Features were separated in these plugin elements:

### [Polkadot Wallet](https://github.com/ezcodeco/Bubble-Plugin-Polkadot.js/tree/main/elements/AAC-850m6)

Dependencies: @polkadot/api, @polkadot/extension-dapp\
Demo: \
<https://polkadotjs.bubbleapps.io/version-test/simple_connect>

### [Polkadot Utils](https://github.com/ezcodeco/Bubble-Plugin-Polkadot.js/tree/main/elements/AAW-850ne)

Dependencies: @polkadot/util, @polkadot/util-crypto\
Demo:\
<https://polkadotjs.bubbleapps.io/version-test/utils>

### [Polkadot API](https://github.com/ezcodeco/Bubble-Plugin-Polkadot.js/tree/main/elements/ABk-8516p)

Dependencies: @polkadot/api, @polkadot/util\
Demo:\
<https://polkadotjs.bubbleapps.io/version-test/polkadot_api>

### [Polkadot Keyring](https://github.com/ezcodeco/Bubble-Plugin-Polkadot.js/tree/main/elements/ACW-851ne)

Dependencies: @polkadot/keyring, @polkadot/util-crypto, @polkadot/util

Demo:\
<https://polkadotjs.bubbleapps.io/version-test/keyring>\ <br>

<br>


# Beginners guide

{% hint style="success" %}
This guide will cover the basic of Bubble platform and how to install and test the plugin
{% endhint %}


# Bubble basics

## 1. Create a Bubble account

1.1 Go to [bubble.io](https://bubble.io/)

1.2 Create an account and login

## 2. Add a new app

2.1 In your account click on the New app button

![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFRESVNhuvL3m59YS5kan%2Fuploads%2FbRvaRgTtdBit8XY1ZOa8%2FMy_Apps___Bubble.png?alt=media\&token=dc021efd-af9e-47f4-bf4d-9a66470b6a95)

2.2 It will ask a few details about your app, you can write whatever you want, it doesn't matter for our test.

![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFRESVNhuvL3m59YS5kan%2Fuploads%2FaBYlbvBwKqW4tMXvl64x%2FScreenshot%202022-02-10%20at%2016.52.14.png?alt=media\&token=0452dbb4-76cf-4c93-a20b-4c83b0a7f0f8)

The app will be created with default examples and texts.

{% hint style="info" %}
If you see any errors/warnings, ignore them, they don't matter for our testing.
{% endhint %}

## 3. Install the plugin

3.1 Now on the left side you will see all sections of your app, go to **Plugins** and then **Add plugin** button

![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFRESVNhuvL3m59YS5kan%2Fuploads%2F0IrvyVp3SLbjdEz4rHUf%2Fadd_plugin.png?alt=media\&token=1ac58d5f-feba-4428-baa9-64a58a90a570)

3.2 In the search bar of the opened window, just write Polkadot and click install.

## 4. Plugin elements

4.1 Create a new blank page\
&#x20;    In the top left corner of your app you will see **Page: index,** click there \
&#x20;    then click **Add a new page...**

4.2 On the newly created page, you will see all available tools in the **Visual elements** section\
This includes our plugin elements that we need to add on the page.\
Find the element you want to test and Drag\&Drop it somewhere on the page:

![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFRESVNhuvL3m59YS5kan%2Fuploads%2Ff4CRIo32mMgRM1W1weSY%2Fdragndrop.png?alt=media\&token=e4bb901c-a4eb-4795-9464-1173bd4dda1a)

{% hint style="info" %}
Before testing, please take a look into [F.A.Q. page](https://polkadotjs.docs.ezcodeplugins.com/f.a.q.) in the plugin documentation.
{% endhint %}

## App preview

To see how your app looks and start testing it, click the **Preview** button in the top right corner.

![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFRESVNhuvL3m59YS5kan%2Fuploads%2FRwzWgdvcBYrSJIcogpUm%2Fpreview.png?alt=media\&token=d52888b4-45fc-4e0f-b2ee-ee9f579ee22c)

### Now let's install the plugin functions and proceed to test them.


# Plugin - install and test

Install and run plugin features

{% hint style="info" %}
First, make sure you have added the Polkadot API element on the page
{% endhint %}

![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFRESVNhuvL3m59YS5kan%2Fuploads%2F2vdzOlnnT68e1UkwBmOp%2Fapi_element.png?alt=media\&token=ad9bb0cc-9a86-452e-be18-7e85604ce90a)

\
There's a field RPC URL, you can leave it empty, the plugin will connect to Polkadot mainnet RPC automatically in this case.&#x20;

## Get latest block

### 1. Add a text element on the page

Find it in the same category where are the plugin elements, and drag and drop it on the page.\
\
2\. Click in the text field, you will see a blue button that says, **Insert dynamic data**, click on it, and then select Polkadot API.\
\
You will see a list of all [plugin states](https://polkadotjs.docs.ezcodeplugins.com/f.a.q.#what-are-states), select **Last Block Nr**

![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFRESVNhuvL3m59YS5kan%2Fuploads%2FUS5Fy1JTVXCdV8kOQO2i%2Fdynamic.gif?alt=media\&token=ee991b4c-54a7-4461-97dd-3ac6df482c47)

Now to get the result in this action, we need to run the plugin function (action) to get the latest block.

### **2. Call action Last Block**

We will call this action when we will click a button. \
In the same way you added the text element, add a button on your page.\
\
In the button settings, click **Start/Edit workflow**

{% hint style="success" %}
Workflow is where all the actions/functions are made. It is the logic of your app.
{% endhint %}

![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFRESVNhuvL3m59YS5kan%2Fuploads%2Fjc3DV0TQVnDbQouRdL44%2Fbutton.png?alt=media\&token=2547db01-7def-41c4-9382-b177aefa3a0e)

### 3. Run Get Last Block action

Click on add an action field, and look for **Last Block** in the Element Actions category

![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFRESVNhuvL3m59YS5kan%2Fuploads%2FCFDGcXzm2PX8iJyMEapF%2Factions.png?alt=media\&token=7170b7f3-14b5-4345-8a3e-30eb1e23c677)<br>

### 4. Test it

Open your page by clicking on Preview button (see Bubble basics page).\
Click on the button and see result in the text field that we have added earlier.

{% hint style="info" %}
Note that sometimes the API may take a few seconds to load.
{% endhint %}

## Handle API loading

Sometimes the API can take longer to load, the plugin have a state that shows if it is ready to be used.\
[Check API is initialising state](https://polkadotjs.docs.ezcodeplugins.com/element-polkadot-api/getting-started#api-is-initialising)\
\
Let's add this to our button, we will make it disabled if the API is still loading.

### 2. Add condition to the button

In the app editor, click on the button then do these steps (See the video bellow)

{% embed url="<https://www.youtube.com/watch?v=8RkKgR9FLTY>" %}

### 2. Test the button

As in previous steps, open preview, you will notice that you can't click the button instantly when page loads, it depends on how fast the API loads.

{% hint style="info" %}
You can add this condition when testing any other feature to avoid errors in case the API is not ready.
{% endhint %}

## Dynamic settings

\
The function we tested above is a simple one without any parameters. \
\
Let's try the action to get the balance for the given address.

{% hint style="info" %}
For this action, I will switch the RPC to Westend testnet, where I have something on my balance. You can use any other RPC where you have something to test.
{% endhint %}

### 1. Add a button and an input

In the same way we did before, add an input and a new button on the page.\
\
On the new button, click Start/Edit workflow, it will open a separate workflow for this button specifically.

![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFRESVNhuvL3m59YS5kan%2Fuploads%2FE5s53cIanVKl51sxx55E%2FScreenshot%202022-02-16%20at%2017.21.36.png?alt=media\&token=c04002d4-f6b5-43b9-b899-6b51d7c11aa3)

### 2. Setup Get Balance Workflow

In the same way we added Last Block action, look for **Get Balance of Address** action and add it.\
You will notice that it has a **field Address**

![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFRESVNhuvL3m59YS5kan%2Fuploads%2F5yyb0zfGHi4JlzsptNSD%2FScreenshot%202022-02-16%20at%2017.23.19.png?alt=media\&token=6b2a2257-7277-487d-aede-a04dded35482)

Click in this field and then on the button insert dynamic data that will appear.\
Select the input that we were added earlier and then the value of it.

![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFRESVNhuvL3m59YS5kan%2Fuploads%2FB7gjlozJDhoYfXcYi4rf%2Fezgif.com-gif-maker%20\(4\).gif?alt=media\&token=51373f67-5327-4d72-b65b-4f5f91d12302)

### 3. Show balance

We will do it the same way we did when showing the last block number. \
Add a new text element, and using the **dynamic button**, select **Polkadot API Get balance result**

![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFRESVNhuvL3m59YS5kan%2Fuploads%2FTGyskTTEoPztu3Ht226K%2FScreenshot%202022-02-16%20at%2017.30.34.png?alt=media\&token=a591ace1-db99-487e-9338-850d1f763844)

### 4. Test it

Here is my result

![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFRESVNhuvL3m59YS5kan%2Fuploads%2FfIgll9pHcCHU3XJazVLp%2Fbalance.png?alt=media\&token=e255aeca-da54-4cc6-9e02-8feae26d9345)

#### You are ready to implement any other action.

You can open the demo page in the [app editor](https://bubble.io/page?type=page\&name=polkadot_api\&id=polkadotjs\&tab=tabs-1), see how it works from the inside with other features implemented.\
In the same way we implement API features, you can implement the features from keyring element or any other element.


# Actions


# Sign a message

Sign a simple message. Will return the signature when signed.

## Demo

Find an example in the demo app editor [here](https://bubble.io/page?version=test\&name=simple_connect\&id=polkadotjs\&tab=tabs-2)\
To see how it works in the workflow, find the Sign message folder in the Workflow folders, there you will see all related actions and events.

<details>

<summary>Where to find Workflow Folders?</summary>

![](/files/zGbY3sewC45m0V6UdIjf)

![](/files/jwnyZFMH23prnAHhNfqd)

</details>

## Events

### Message Signed

If the user will sign the message, an event will be triggered **Message Signed**

The signature is available in the **state** **Signature**.

![](/files/A2p5iSMcQLiC9eeob2M0)

{% hint style="info" %}
Note: The state will be available only after the event Message Signed was triggered
{% endhint %}

### **User Canceled the Action**

If the user will deny (cancel) signing message, an event called **User Canceled the Action** will be triggered.\ <br>


# Sign and Send Transaction

Send a token to wallet address.

## Setup

To run this action, you need to provide the **wallet address** that will receive the tokens and the **amount** to send.

![](/files/ddXd3ttLUX7kuTo2JSco)

## Events

### Transaction Sent

This event will be triggered when the transaction will be successfully sent, and the transaction hash is available.

### User canceled Sending Transaction

If the user rejects a transaction sending, this event will be triggered.

### Not enough balance

If the balance to send is lower than the amount to send, the transaction will be canceled and this event will trigger.<br>

## States

### Transaction hash

![](/files/flF9rxs8YxSs5JbxRRhA)

{% hint style="info" %}
Note: The hash will be available only if the transaction was successfully sent.
{% endhint %}

### Transaction status

Here you will see at was stage is the current transaction, for example: Broadcast, Sent etc.  \
Useful to inform the user.

## Demo

Find an example in the demo app editor [here](https://bubble.io/page?version=test\&name=simple_connect\&id=polkadotjs\&tab=tabs-2). \
Look for the workflow folder *Send Transaction*


# Load App

#### Detailed explained in the Installation section [here](https://polkadotjs.docs.ezcodeplugins.com/instalation#run-load-app-action)


# Actions

{% hint style="success" %}
All demo pages of the Utils element can be found [here](https://polkadotjs.bubbleapps.io/version-test/utils)
{% endhint %}


# Create Mnemonic

Will generate a new mnemonic phrase (new wallet)

## States

This action will publish only one state called, Generated Mnemonic.

### Generated Mnemonic

*State type - text*

Includes the newly generated mnemonic phrase. \
Try to import it in your wallet (Do not remove the empty spaces!)\ <br>

## Demo

Simple demo page [here](https://polkadotjs.bubbleapps.io/version-test/create_mnemonic)\
Demo page [app editor](https://bubble.io/page?version=test\&name=create_mnemonic\&id=polkadotjs\&tab=tabs-1)


# Validate address

## States

This action will publish only one state called, Generated Mnemonic.Is Address valid

### Is Address valid

*State type - Yes/No*

This state will return Yes if the given address is a legitamate Polkadot address and No if it is not.

## Demo

Simple demo page [here](https://polkadotjs.bubbleapps.io/version-test/validate_address)

Demo page [app editor](https://polkadotjs.bubbleapps.io/version-test/utils)


# Encrypt Message

Encrypt and Decrypt a message with NaCl (pronouced "salt"), which is a Networking and Cryptography library used in util-crypto.

When encrypting a message, the result will be divided in 3 states, see them bellow. You will need all of them to decrypt the message, so, make sure to save them somewhere, for example, in the Bubble user's database.

## States

### Encrypted Message

*State type - text*

This state is the result of the encrypted message, it is a list of numbers but in text format to simplify using/saving it in Bubble.

### Encrypted Secret

*State type - text*

This state is the result of the encrypted message, it will be needed for the Decrypt action, so, save it as well.

### Encrypted Nonce

*State type - text*

This state is the result of the encrypted message, it will be needed for the Decrypt action, so, save it as well.

## Demo

Demo page [here](https://polkadotjs.bubbleapps.io/version-test/encrypt_decrypt_message)

Demo page [app editor](https://bubble.io/page?type=page\&name=encrypt_decrypt_message\&version=test\&id=polkadotjs\&tab=tabs-1)

The demo page includes both actions, Encrypt and [Decrypt](/element-polkadot-utils/actions/decrypt-encrypted), it was made to easily test both of them on one page as they depend on each other.


# Decrypt Encrypted

Encrypt and Decrypt a message with NaCl (pronouced "salt"), which is a Networking and Cryptography library used in util-crypto.

This action will decrypt the encrypted message with [Encrypt Message](/element-polkadot-utils/actions/encrypt-message) action.

Note that to decrypt the message you will need the Encrypted message, Nonce and Secret, you will get all of them when encrypting a message, so, make sure to save them.&#x20;

![](/files/nwm6Ap7aQcJgqf6LqoVb)

## States

### Decrypted Message

*State type - text*

This state includes the result of the decrypted message. If the given data(nonce, secret and encrypted message) was right, you will see the decrypted message that will be the exact same as the original encrypted message. \
If some of the given data is wrong, this state will be empty.

## Demo

Demo page [here](https://polkadotjs.bubbleapps.io/version-test/encrypt_decrypt_message)

Demo page [app editor](https://bubble.io/page?type=page\&name=encrypt_decrypt_message\&version=test\&id=polkadotjs\&tab=tabs-1)

The demo page includes both actions, [Encrypt](/element-polkadot-utils/actions/encrypt-message) and Decrypt, it was made to easily test both of them on one page as they depend on each other.

{% hint style="info" %}
Note! The data to decrypt the message is taken from the inputs on the page, this was done for demo purpose only, you can save that data in the database and get it from there.
{% endhint %}


# Generate a Multisig Account

Generates the address that would correspond to a set of addresses and threshold.

This action takes 2 fields, Addresses and Threshold

#### Addresses

A list of addresses that will make up the multisig account.\
In bubble this is a list of text. \
In case you didn't knew, you can't manually write a list of text in the bubble editor, it must be taken from somewhere, it could be database or a custom state. You will see an example of using a custom state on demo page.

#### Threshold

The number of accounts that must approve. Must be greater than 0 and less than or equal to the total number of addresses.\
In bubble this is a number type.

![](/files/81hUiEH1aVFUDIKTzVUx)

## States

### Multisig Address

*State type - text*

The generated multisig address.

## Demo

Demo page [here](https://polkadotjs.bubbleapps.io/version-test/encrypt_decrypt_message)

Demo page [app editor](https://bubble.io/page?type=page\&name=generate_multisig\&version=test\&id=polkadotjs\&tab=tabs-1)\
\
To generate the multising, add at least 2 addresses, after that, a button to start generating will appear.


# Verify Signature

To verify a signature you will need the original signed message, the signature itself and the wallet that signed it.

## States

### Is Signature Valid

*State type - Yes/No*

Will return Yes if the signature is right and No if it is wrong (if the given wallet or signature doesn't match).

## Demo

Demo page [here](https://polkadotjs.bubbleapps.io/version-test/verify_signature)

Demo page [app editor](https://bubble.io/page?type=page\&name=verify_signature\&version=test\&id=polkadotjs\&tab=tabs-1)

{% hint style="info" %}
Note! The data to verify the signature is taken from the inputs on the page, this was done for demo purpose only, you can save that data in the database and get it from there
{% endhint %}


# Hash Data

The plugin currently supports these type hashing: Keccak, Blake2, Xxhash\
You will need to choose one from the dropdown.

![](/files/4GtnYBOhoSvVRlQKzToG)

## States

### Hash Data Result

*State type - text*

This state contains the result of hashing the given data, if it is empty, then something went wrong or the given data is invalid. \
Note that the result is not always instantly available in the state, it may take a few milliseconds, so you may need to add a pause in workflow of 100 milliseconds (this is up to you).

## Demo

Demo page [here](https://polkadotjs.bubbleapps.io/version-test/hash_data)

Demo page [app editor](https://bubble.io/page?type=page\&name=hash_data\&version=test\&id=polkadotjs\&tab=tabs-1)


# Getting Started

To start using API features, as the other elements, we start by adding the **Polkadot API** element on the page. Make sure it is not in a hidden element or popup.\
\
Once you added the element, you will notice that it has one optional field.

![](/files/MLlVIcDAwRdDTth6xRmY)

**RPC URL**\
This is an optional field, here you can indicate the chain to connect to. \
You can leave it empty, the plugin will connect to Polkadot mainnet in this case, the RPC URL of which is *wss\://rpc.polkadot.io*\
\
For example, if you want to connect to Westend testnet, use its url which is:\
*wss\://westend-rpc.polkadot.io*

## Useful states

### API is initialising

The API initialisation can take a few seconds, this state will show you if it is in progress or no.&#x20;

* If the state is **YES**, it means that the API is still initialising and it is not ready to be used yet
* If it is **NO**, the API is ready to be used

### Chain Decimals

Shows the decimals of the token of the connected chain.

### Connected Chain Name

Shows the full chain name, for example Polkadot, Westend etc.

### Chain Symbol

Short symbol of the chain, for example DOT, WND etc.


# Actions

All actions for the API element.


# Get Balance of Address

## Setup

First of all, make sure the API is not initialising, see details in the Getting Started, [Useful States section](/element-polkadot-api/getting-started#api-is-initialising)

Only one parameter is needed, the address of the wallet you want to get balance.

![](/files/vmxajTV2hjOEdFbHQoSO)

### State - Get balance result

This state shows the balance of the given wallet.

## Demo

Find a demo on the [polkadot api](https://bubble.io/page?type=page\&name=polkadot_api\&id=polkadotjs\&test_plugin=1639402639641x977692461648052200_current\&tab=tabs-1) page.


# Get Balance at Block

## Setup

Works same way the [Get Balance of Address](/element-polkadot-api/actions/get-balance-of-address#setup) except that you can indicate a certain block number and get the **balance at that block** specifically.

![](/files/vxj6m2lhLjAvT84IbQVp)

### Event - Get Balance at block is Ready

This event will trigger when the result was successfully extracted and it is ready to be used.

### State - Balance at block

Shows the balance at given block number. Will be ready to be used only after the event described above triggers.

## Demo

Find a demo on the [polkadot api](https://bubble.io/page?type=page\&name=polkadot_api\&id=polkadotjs\&test_plugin=1639402639641x977692461648052200_current\&tab=tabs-1) page. See workflow folder Get balance.


# Subscribe to Balance Changes

This action will subscribe to any balance changes and will trigger an event and a state that shows new wallet balance.&#x20;

## Setup

Only one parameter is needed, the address of the wallet you want to subscribe to.

### Action - Unsubscribe from Balance Changes

After subscribing you can of course unsubscribe by running this action and stop receiving events about balance changes.

### Event - Balance Changed

After subscribing, anytime the balance of given address changes, this event will be triggered.<br>

### State - New balance&#x20;

This state shows the new changed balance of the given address.

## Demo

Find a demo on the [polkadot api](https://bubble.io/page?type=page\&name=polkadot_api\&id=polkadotjs\&test_plugin=1639402639641x977692461648052200_current\&tab=tabs-1) page. See the workflow folder **Subscribe balance**

![](/files/CPaFlJdeq4AXiN7m1oiD)


# Subscribe to new Blocks

Just like subscribing to balance changes, this will trigger an event every time a new block is mined, and publish a state with the block number.

## Setup

This action doesn't have any fields, just run it after the api was initialised.

### Action - Unsubscribe from new Block event

After subscribing you can of course unsubscribe by running this action and receiving events about new blocks.

### Event - New Block

This is the event that will be triggered every time a new block is mined.

### State - Last Block Nr

In this state you will find the number of the latest block.

## Demo

Find a demo on the [polkadot api](https://bubble.io/page?type=page\&name=polkadot_api\&id=polkadotjs\&test_plugin=1639402639641x977692461648052200_current\&tab=tabs-1) page. See the workflow folder **Subscribe blocks**

![](/files/C0Y9GViZRveVoRsz6hWG)


# Last Block

Get number of the latest block

### State - Last Block Nr


# Getting Started

To start using the Keyring features, as the other elements, we start by adding the **Polkadot Keyring** element on the page. Make sure it is not in a hidden element or popup.\
\
Once you added the element, you will notice that it has one optional field.&#x20;

**RPC URL**\
*This is the same field as in the other elements. All elements has this exact same field in case you want to use them separately.* \
*If at least one element has this field setup, any other elements on the page will automatically get the settings from the element that has it setup.* \
*In other words, you can setup this field only for one element on the page, all others will have the same setup automatically.*\
\
This is an optional field, here you can indicate the chain to connect to. \
\
You can leave it empty, the plugin will connect to Polkadot mainnet in this case, the RPC URL of which is *wss\://rpc.polkadot.io*\
\
For example, if you want to connect to Westend testnet, use its url which is:\
*wss\://westend-rpc.polkadot.io*<br>


# Actions

#### All keyring actions can be found and tested on [this page](https://polkadotjs.bubbleapps.io/version-test/keyring)<br>


# Add Pair to Keyring

This action will add a pair to the keyring, you can add as many as you need.

## Setup

This an action, as any other action, it can be used in Bubble workflow actions.\
To add the account you will need its mnemonic phrase.

<img src="/files/otYlmHY5xvjyaZjdxdCi" alt="" data-size="original"><br>

### Event - Wallet added to keyring&#x20;

After running this action, it will trigger an event called ***Wallet added to keyring*** if it was successfully executed, so you know that everything is alright. \
For example, in our demo we are showing a success popup when this event triggers

![](/files/owBO3HAU7LAozawK1QpB)

### State - Added pair address

This state shows the address of added pair and it will be available when the event described above triggers.

## Demo

Find an example with this action on [keyring page](https://bubble.io/page?type=page\&name=keyring\&id=polkadotjs\&test_plugin=1639402639641x977692461648052200_current\&tab=tabs-2), select the *Add/Remove pairs* workflow folder, to see all related workflows.

![](/files/q3rSVqeks3ziK9finbu4)


# Remove pair from Keyring

This action will remove the added pair from the keyring

## Setup

To remove a pair from the keyring, you need to know its address.

![](/files/4MT8sRu0cgaTrBX8EEe2)<br>

### Event - Pair removed

When removing a pair, this event will be triggered if it was successfully removed. \
If it didn't triggered, that means that the given address is wrong or it was not added to the keyring.

## Demo

Find an example with this action on [keyring page](https://bubble.io/page?type=page\&name=keyring\&id=polkadotjs\&test_plugin=1639402639641x977692461648052200_current\&tab=tabs-2), select the *Add/Remove pairs* workflow folder, to see all related workflows.

![](/files/q3rSVqeks3ziK9finbu4)


# Get Pair Metadata

## Setup

To run this action you will need the pair address or its number in the pairs list (remember that lists in programming world starts at 0)

![](/files/fXbbvD9LXjhK4m8sOiRo)

### State - Pair Metadata

The state will be available almost instantly after calling the action. It contains the JSON metadata in text format. You can then parse it using Bubble's integrated tools and regex.

## Demo

Find an example with this action on [keyring page](https://bubble.io/page?type=page\&name=keyring\&id=polkadotjs\&test_plugin=1639402639641x977692461648052200_current\&tab=tabs-2)


# Get All Pairs in Keyring

Gives a list of addresses of all the added pairs

## Setup

This action doesn't need any parameters, you can run it right away.

### Event - All Pairs State ready

The result will be ready to be used only after this event will trigger.<br>

### State - All Pairs

A list of texts, it contains all addresses of all added pairs in the keyring.\
You can use this state as a source of data in a repeating group to list all of them, just like we did in our demo

![](/files/basXuGSPP4wQjHtx774c)

## Demo

Find an example with this action on [keyring page](https://bubble.io/page?type=page\&name=keyring\&id=polkadotjs\&test_plugin=1639402639641x977692461648052200_current\&tab=tabs-2)\
See the repeating group all pairs.


# Set SS58 Format

You can change the SS58 dynamically by running this action. All addresses inside the added pairs will be changed automatically according to new given format. \
\
You can see it in action on demo page. Firstly, add a few pairs in the keyring and then click on Load Pairs to see their current format.\
Now run the set 2258 action, click again on Load Pairs to refresh the state, and see the how they has changed.<br>

Find an example with this action on [keyring page](https://polkadotjs.bubbleapps.io/version-test/keyring)


# Sign a Message

Sign a message with one of the added pairs.

## Setup

This action has 2 fields, first one is for the message itself. The second one is *Wallet to sign with*, it is the pair address, make sure it was added in the keyring first.

![](/files/CrJT4cp9DelIcVHZD2OD)

### Event - Signed

If the message was successfully signed, the event Signed will trigger. The signature will be available only after this event triggers.

### State - Signature

The signature is a list of numbers but in text format to easily safe it in Bubble database if needed.

## Demo

Find an example of this feature in the *Signature* workflow folder

![](/files/x38EzrI2VNUe1EOkNGrM)


# Verify Signature

Verify if the signature is valid

## Setup

First of all, you will need the signature itself from the sign message action, so make sure you save it somewhere in the database.

![](/files/QMaBoYu9LXT60XXtb2ds)

### State - Signature is Valid

The state is of Yes/No type.

## Demo

To try this feature on our demo page, you need to add a pair, load all pairs and sign a message first, then a popup will be shown with the signature, in this popup you can verify the signature.

It is easier than it sounds :) \
\
![](/files/a7IVMXfHJR7zqD88srEZ)\ <br>


