Polkadot.js
Introduction
Polkadot.js is a collection of tools that allow you to interact with Polkadot and its parachains, such as Phron. The Polkadot.js API is one component of Polkadot.js and is a library that allows application developers to query a Phron node and interact with the node's Substrate interfaces using JavaScript, enabling you to read and write data to the network.
You can use the Polkadot.js API to query on-chain data and send extrinsics from the Substrate side of Phron. You can query Phron's runtime constants, chain state, events, transaction (extrinsic) data, and more.
Here you will find an overview of the available functionalities and some commonly used code examples to get you started on interacting with Phron networks using the Polkadot.js API library.
Checking Prerequisites
Installing and using Polkadot.js API library requires Node.js to be installed.
You need to install Node.js (for this example, you can use v16.x) and the npm package manager. You can download directly from Node.js or in your terminal:
You can verify that everything is installed correctly by querying the version for each package:
To test out the examples in this guide on Phron, you will need to have your own endpoint and API key, which you can get from one of the supported Endpoint Providers.
Install Polkadot.js API
First, you need to install the Polkadot.js API library for your project through a package manager such as yarn
. Install it in your project directory with the following command:
The library also includes other core components like Keyring for account management, or some utilities that are used throughout this guide.
Create an API Provider Instance
Similar to Ethereum API libraries, you must first instantiate an API instance of the Polkadot.js API. Create the WsProvider
using the WebSocket endpoint of the Phron network you wish to interact with.
To test out the examples in this guide on Phron, you will need to have your own endpoint and API key, which you can get from one of the supported Endpoint Providers.
Metadata and Dynamic API Decoration
Before diving into the details of performing different tasks via the Polkadot.js API library, it's useful to understand some of the basic workings of the library.
When the Polkadot.js API connects to a node, one of the first things it does is retrieve the metadata and decorate the API based on the metadata information. The metadata effectively provides data in the form of:
Where <type>
can be either:
query
- for endpoints to read all the state queriestx
- for endpoints related to transactionsrpc
- for endpoints specific to RPC callsconsts
- for endpoints specific to runtime constants
And therefore, none of the information contained in the api.{query, tx, rpc, consts}.<module>.<method>
endpoints are hard-coded in the API. This allows parachains like Phron to have custom endpoints through its pallets that can be directly accessed via the Polkadot.js API library.
Query On-Chain Data on Phron
In this section, you will learn how to query for on-chain information using the Polkadot.js API library.
Phron Chain State Queries
This category of queries retrieves information related to the current state of the chain. These endpoints are generally of the form api.query.<module>.<method>
, where the module and method decorations are generated through metadata. You can see a list of all available endpoints by examining the api.query
object, for example via:
Assuming you've initialized the API, here is a code sample for retrieving basic account information given its address :
Phron RPC Queries
The RPC calls provide the backbone for the transmission of data to and from the node. This means that all API endpoints such as api.query
, api.tx
or api.derive
just wrap RPC calls, providing information in the encoded format as expected by the node. You can see a list of all available endpoints by examining the api.rpc
object, for example via:
The api.rpc
interface follows the a similar format to api.query
, for instance:
Query Subscriptions
The rpc
API also provide endpoints for subscriptions. You can adapt the previous example to start using subscriptions to listen to new blocks. Note that you need to remove the API disconnect when using subscriptions, to avoid normal closures of the WSS connection.
The general pattern for api.rpc.subscribe*
functions is to pass a callback into the subscription function, and this will be triggered on each new entry as they are imported.
Other calls under api.query.*
can be modified in a similar fashion to use subscription, including calls that have parameters. Here is an example of how to subscribe to balance changes in an account:
Create a Keyring for a Phron Account
The Keyring object is used for maintaining key pairs, and the signing of any data, whether it's a transfer, a message, or a contract interaction.
Create a Keyring Instance
You can create an instance by just creating an instance of the Keyring class, and specifying the default type of wallet address used. For Phron networks, the default wallet type should be ethereum
.
Add an Account to a Keyring
There are a number of ways to add an account to the keyring instance, including from the mnemonic phrase and from the shortform private key.
Send Transactions on Phron
Transaction endpoints are exposed on endpoints generally of the form api.tx.<module>.<method>
, where the module and method decorations are generated through metadata. These allow you to submit transactions for inclusion in blocks, be it transfers, interacting with pallets, or anything else Phron supports. You can see a list of all available endpoints by examining the api.tx
object, for example via:
Send a Transaction
The Polkadot.js API library can be used to send transactions to the network. For example, assuming you've initialized the API and a keyring instance, you can use the following snippet to send a basic transaction (this code sample will also retrieve the encoded calldata of the transaction as well as the transaction hash after submitting):
Note!Prior to client v0.35.0, the extrinsic used to perform a simple balance transfer was the
balances.transfer
extrinsic. It has since been deprecated and replaced with thebalances.transferAllowDeath
extrinsic.
Note that the signAndSend
function can also accept optional parameters, such as the nonce
. For example, signAndSend(alice, { nonce: aliceNonce })
. You can use the sample code from the State Queries section to retrieve the correct nonce, including transactions in the mempool.
Fee Information
The transaction endpoint also offers a method to obtain weight information for a given api.tx.<module>.<method>
. To do so, you'll need to use the paymentInfo
function after having built the entire transaction with the specific module
and method
.
The paymentInfo
function returns weight information in terms of refTime
and proofSize
, which can be used to determine the transaction fee. This is extremely helpful when crafting remote execution calls via XCM.
For example, assuming you've initialized the API, the following snippet shows how you can get the weight information for a simple balance transfer between two accounts:
Transaction Events
Any transaction will emit events, as a bare minimum this will always be either a system.ExtrinsicSuccess
or system.ExtrinsicFailed
event for the specific transaction. These provide the overall execution result for the transaction, i.e. execution has succeeded or failed.
Depending on the transaction sent, some other events may however be emitted, for instance for a balance transfer event, this could include one or more balance.Transfer
events.
The Transfer API page includes an example code snippet for subscribing to new finalized block headers, and retrieving all balance.Transfer
events.
Batch Transactions
The Polkadot.js API allows transactions to be batch processed via the api.tx.utility.batch
method. The batched transactions are processed sequentially from a single sender. The transaction fee can be estimated using the paymentInfo
helper method.
For example, assuming you've initialized the API, a keyring instance and added an account, the following example makes a couple of transfers and also uses the api.tx.parachainStaking
module to schedule a request to decrease the bond of a specific collator candidate:
Note!You can check out all of the available functions for the
parachainStaking
module by addingconsole.log(api.tx.parachainStaking);
to your code.
Substrate and Custom JSON-RPC Endpoints
RPCs are exposed as a method on a specific module. This means that once available, you can call any RPC via api.rpc.<module>.<method>(...params[])
. This also works for accessing Ethereum RPCs using the Polkadot.js API, in the form of polkadotApi.rpc.eth.*
.
Some of the methods availabe through the Polkadot.js API interface are also available as JSON-RPC endpoints on Phron nodes. This section will provide some examples; you can check for a list of exposed RPC endpoints by calling api.rpc.rpc.methods()
or the rpc_methods
endpoint listed below.
Interface -
api.rpc.rpc.methods
JSON-RPC -
rpc_methods
Returns - The list of RPC methods that are exposed by the node
Interface -
api.rpc.chain.getBlock
JSON-RPC -
chain_getBlock
Returns - The header and body of a block as specified by the block hash parameter
Interface
api.rpc.chain.getFinalizedHead
JSON-RPC
chain_getFinalizedHead
Returns The block hash of the last finalized block in the canonical chain
The Consensus and Finality page has sample code for using the exposed custom and Substrate RPC calls to check the finality of a given transaction.
Polkadot.js API Utility Functions
The Polkadot.js API also includes a number of utility libraries for computing commonly used cryptographic primitives and hash functions.
The following example computes the deterministic transaction hash of a raw Ethereum legacy transaction by first computing its RLP (Recursive Length Prefix) encoding, then hashing the result with keccak256.
You can check the respective NPM repository page for a list of available methods in the @polkadot/util-crypto
library and their descriptions.
This tutorial is for educational purposes only. As such, any contracts or code created in this tutorial should not be used in production.The information presented herein has been provided by third parties and is made available solely for general information purposes. Phron does not endorse any project listed and described on the Phron Doc Website (https://docs.Phron.ai/). Phron does not warrant the accuracy, completeness or usefulness of this information. Any reliance you place on such information is strictly at your own risk. Phron disclaims all liability and responsibility arising from any reliance placed on this information by you or by anyone who may be informed of any of its contents. All statements and/or opinions expressed in these materials are solely the responsibility of the person or entity providing those materials and do not necessarily represent the opinion of Phron. The information should not be construed as professional or financial advice of any kind. Advice from a suitably qualified professional should always be sought in relation to any particular matter or circumstance. The information herein may link to or integrate with other websites operated or content provided by third parties, and such other websites may link to this website. Phron has no control over any such other websites or their content and will have no liability arising out of or related to such websites or their content. The existence of any such link does not constitute an endorsement of such websites, the content of the websites, or the operators of the websites. These links are being provided to you only as a convenience and you release and hold Phron harmless from any and all liability arising from your use of this information or the information provided by any third-party website or service.
Last updated