diff --git a/content/md/en/docs/reference/command-line-tools/subxt.md b/content/md/en/docs/reference/command-line-tools/subxt.md index bc0ecda02..c37ff5a41 100644 --- a/content/md/en/docs/reference/command-line-tools/subxt.md +++ b/content/md/en/docs/reference/command-line-tools/subxt.md @@ -8,8 +8,8 @@ The [`subxt`](https://github.com/paritytech/subxt) library enables you to submit Before you use the `subxt` library, you can use the standalone `subxt` command-line interface to download the metadata for the Substrate node you want to use as the target for submitting transactions. The `subxt-cli` tool enables you to perform two key tasks that are critical to using the `subxt` library: -* You can use the `subxt-cli` tool to download the metadata from any target Substrate node. -* You can use the `subxt-cli` tool to generate the runtime API code from the metadata from any target Substrate node. +- You can use the `subxt-cli` tool to download the metadata from any target Substrate node. +- You can use the `subxt-cli` tool to generate the runtime API code from the metadata from any target Substrate node. You can use the `subxt` library and `subxt-cli` tool for any node that uses metadata v14 and later. For examples of how to use the `subxt` library, see the [examples](https://github.com/paritytech/subxt/tree/master/examples/examples) folder. @@ -21,7 +21,7 @@ To install `subxt-cli`: 1. Open a terminal shell, if necessary. 1. Verify that you have the Rust compiler and toolchain, if necessary. 1. Download the required packages with the following command: - `cargo install subxt-cli` + `cargo install subxt-cli` ## Basic command usage @@ -36,28 +36,28 @@ If the metadata is already provided, it is possible to use the `codegen` subcomm You can use the following optional flags with the `subxt` command. -| Flag | Description -| ------- | ----------- -| -h, --help | Displays usage information. -| -V, --version | Displays version information. +| Flag | Description | +| ------------- | ----------------------------- | +| -h, --help | Displays usage information. | +| -V, --version | Displays version information. | ### Subcommands You can use the following subcommands with the `subxt` command-line interface. -| Command | Description -| ------- | ----------- -| `codegen` | Generates runtime API client code from metadata. -| `metadata` | Downloads metadata from a Substrate node for use with `subxt` codegen. +| Command | Description | +| ---------- | ---------------------------------------------------------------------- | +| `codegen` | Generates runtime API client code from metadata. | +| `metadata` | Downloads metadata from a Substrate node for use with `subxt` codegen. | ### Output Depending on how you specify the subcommand, the output from `subxt` displays some or all of the following information: -| This field | Contains -| ---------- | ---------- -| Metadata | A file with the metadata of a target chain. -| API | A file with the API of the target chain. +| This field | Contains | +| ---------- | ------------------------------------------- | +| Metadata | A file with the metadata of a target chain. | +| API | A file with the API of the target chain. | ### Examples @@ -83,19 +83,19 @@ This could be useful for debugging or modifying a node's API to meet certain har You can use the following optional flags with the `subxt codegen` command. -| Flag | Description -| ------ | ----------- -| `-h, --help` | Displays usage information. -| `-V, --version` | Prints version information. +| Flag | Description | +| --------------- | --------------------------- | +| `-h, --help` | Displays usage information. | +| `-V, --version` | Prints version information. | #### Options You can use the following command-line options with the `subxt codegen` command. -| Option | Description -| -------- | ----------- -| `-f, --file ` | Specifies the path to the encoded metadata file. -| `--url ` | Specifies the URL of the Substrate node to query for metadata for codegen. +| Option | Description | +| ------------------- | -------------------------------------------------------------------------- | +| `-f, --file ` | Specifies the path to the encoded metadata file. | +| `--url ` | Specifies the URL of the Substrate node to query for metadata for codegen. | #### Examples @@ -119,19 +119,19 @@ Use the `subxt metadata` command to get the metadata of the target Substrate nod You can use the following optional flags with the `subxt metadata` command. -| Flag | Description -| ------ | ----------- -| `-h, --help` | Displays usage information. -| `-V, --version` | Prints version information. +| Flag | Description | +| --------------- | --------------------------- | +| `-h, --help` | Displays usage information. | +| `-V, --version` | Prints version information. | #### Options You can use the following command-line options with the `subxt metadata` command. -| Option | Description -| -------- | ----------- -| `-f, --format ` | Specifies the format of the metadata to display. Valid formats are `json`, `hex` or `bytes`. The default format is `json`. -| `--url ` | Specifies the URL of the Substrate node to query for metadata. The default URL is `http://localhost:9933`. +| Option | Description | +| ----------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `-f, --format ` | Specifies the format of the metadata to display. Valid formats are `json`, `hex` or `bytes`. The default format is `json`. | +| `--url ` | Specifies the URL of the Substrate node to query for metadata. The default URL is `http://localhost:9933`. | #### Examples diff --git a/content/md/en/docs/tutorials/build-application-logic/use-macros-in-a-custom-pallet.md b/content/md/en/docs/tutorials/build-application-logic/use-macros-in-a-custom-pallet.md index 185b04fa6..7ace105f4 100644 --- a/content/md/en/docs/tutorials/build-application-logic/use-macros-in-a-custom-pallet.md +++ b/content/md/en/docs/tutorials/build-application-logic/use-macros-in-a-custom-pallet.md @@ -82,58 +82,58 @@ Therefore, the first step is to remove some files and content from the files in 1. Change to the `pallets/template/src` directory by running the following command: - ```bash - cd pallets/template/src - ``` + ```bash + cd pallets/template/src + ``` 1. Remove the following files: - ```bash - benchmarking.rs - mock.rs - tests.rs - ``` + ```bash + benchmarking.rs + mock.rs + tests.rs + ``` 1. Open the `lib.rs` file in a text editor. - This file contains code that you can use as a template for a new pallet. - You won't be using the template code in this tutorial. - However, you can review the template code to see what it provides before you delete it. + This file contains code that you can use as a template for a new pallet. + You won't be using the template code in this tutorial. + However, you can review the template code to see what it provides before you delete it. 1. Delete all of the lines in the `lib.rs` file. 1. Add the macro required to build both the native Rust binary (`std`) and the WebAssembly (`no_std`) binary. - ```rust - #![cfg_attr(not(feature = "std"), no_std)] - ``` + ```rust + #![cfg_attr(not(feature = "std"), no_std)] + ``` - All of the pallets used in a runtime must be set to compile with the `no_std` features. + All of the pallets used in a runtime must be set to compile with the `no_std` features. 1. Add a skeleton set of pallet dependencies and [macros](/reference/frame-macros) that the custom pallet requires by copying the following code: - ```rust - // Re-export pallet items so that they can be accessed from the crate namespace. - pub use pallet::*; + ```rust + // Re-export pallet items so that they can be accessed from the crate namespace. + pub use pallet::*; - #[frame_support::pallet] - pub mod pallet { - use frame_support::pallet_prelude::*; - use frame_system::pallet_prelude::*; + #[frame_support::pallet] + pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; - #[pallet::pallet] - #[pallet::generate_store(pub(super) trait Store)] - pub struct Pallet(_); + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); - #[pallet::config] // <-- Step 2. code block will replace this. - #[pallet::event] // <-- Step 3. code block will replace this. - #[pallet::error] // <-- Step 4. code block will replace this. - #[pallet::storage] // <-- Step 5. code block will replace this. - #[pallet::call] // <-- Step 6. code block will replace this. - } - ``` + #[pallet::config] // <-- Step 2. code block will replace this. + #[pallet::event] // <-- Step 3. code block will replace this. + #[pallet::error] // <-- Step 4. code block will replace this. + #[pallet::storage] // <-- Step 5. code block will replace this. + #[pallet::call] // <-- Step 6. code block will replace this. + } + ``` - You now have a framework that includes placeholders for _events_, _errors_, _storage_, and _callable functions_. + You now have a framework that includes placeholders for _events_, _errors_, _storage_, and _callable functions_. 1. Save your changes. @@ -149,14 +149,14 @@ To define the `Config` trait for the proof-of-existence pallet: 1. Replace the `#[pallet::config]` line with the following code block: - ```rust - /// Configure the pallet by specifying the parameters and types on which it depends. - #[pallet::config] - pub trait Config: frame_system::Config { - /// Because this pallet emits events, it depends on the runtime's definition of an event. - type RuntimeEvent: From> + IsType<::RuntimeEvent>; - } - ``` + ```rust + /// Configure the pallet by specifying the parameters and types on which it depends. + #[pallet::config] + pub trait Config: frame_system::Config { + /// Because this pallet emits events, it depends on the runtime's definition of an event. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + } + ``` 1. Save your changes. @@ -177,18 +177,18 @@ To implement the pallet events: 1. Replace the `#[pallet::event]` line with the following code block: - ```rust - // Pallets use events to inform users when important changes are made. - // Event documentation should end with an array that provides descriptive names for parameters. - #[pallet::event] - #[pallet::generate_deposit(pub(super) fn deposit_event)] - pub enum Event { - /// Event emitted when a claim has been created. - ClaimCreated { who: T::AccountId, claim: T::Hash }, - /// Event emitted when a claim is revoked by the owner. - ClaimRevoked { who: T::AccountId, claim: T::Hash }, - } - ``` + ```rust + // Pallets use events to inform users when important changes are made. + // Event documentation should end with an array that provides descriptive names for parameters. + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// Event emitted when a claim has been created. + ClaimCreated { who: T::AccountId, claim: T::Hash }, + /// Event emitted when a claim is revoked by the owner. + ClaimRevoked { who: T::AccountId, claim: T::Hash }, + } + ``` 1. Save your changes. @@ -210,17 +210,17 @@ To implement the errors for the proof-of-existence pallet: 1. Replace the `#[pallet::error]` line with the following code block: - ```rust - #[pallet::error] - pub enum Error { - /// The claim already exists. - AlreadyClaimed, - /// The claim does not exist, so it cannot be revoked. - NoSuchClaim, - /// The claim is owned by another account, so caller can't revoke it. - NotClaimOwner, - } - ``` + ```rust + #[pallet::error] + pub enum Error { + /// The claim already exists. + AlreadyClaimed, + /// The claim does not exist, so it cannot be revoked. + NoSuchClaim, + /// The claim is owned by another account, so caller can't revoke it. + NotClaimOwner, + } + ``` 1. Save your changes. @@ -236,10 +236,10 @@ To implement storage for the proof-of-existence pallet: 1. Replace the `#[pallet::storage]` line with the following code block: - ```rust - #[pallet::storage] - pub(super) type Claims = StorageMap<_, Blake2_128Concat, T::Hash, (T::AccountId, T::BlockNumber)>; - ``` + ```rust + #[pallet::storage] + pub(super) type Claims = StorageMap<_, Blake2_128Concat, T::Hash, (T::AccountId, T::BlockNumber)>; + ``` 1. Save your changes. @@ -262,67 +262,68 @@ To implement this logic in the proof-of-existence pallet: 1. Replace the `#[pallet::call]` line with the following code block. You might try to implement the `revoke_claim` function yourself. Just copy the function signature and not the content. The `Claims::::get` and `Claims::::remove` should be used to get or remove a claim. - ```rust - // Dispatchable functions allow users to interact with the pallet and invoke state changes. - // These functions materialize as "extrinsics", which are often compared to transactions. - // Dispatchable functions must be annotated with a weight and must return a DispatchResult. - #[pallet::call] - impl Pallet { - #[pallet::weight(0)] - #[pallet::call_index(1)] - pub fn create_claim(origin: OriginFor, claim: T::Hash) -> DispatchResult { - // Check that the extrinsic was signed and get the signer. - // This function will return an error if the extrinsic is not signed. - let sender = ensure_signed(origin)?; - - // Verify that the specified claim has not already been stored. - ensure!(!Claims::::contains_key(&claim), Error::::AlreadyClaimed); - - // Get the block number from the FRAME System pallet. - let current_block = >::block_number(); - - // Store the claim with the sender and block number. - Claims::::insert(&claim, (&sender, current_block)); - - // Emit an event that the claim was created. - Self::deposit_event(Event::ClaimCreated { who: sender, claim }); - - Ok(()) - } - - #[pallet::weight(0)] - #[pallet::call_index(2)] - pub fn revoke_claim(origin: OriginFor, claim: T::Hash) -> DispatchResult { - // Check that the extrinsic was signed and get the signer. - // This function will return an error if the extrinsic is not signed. - let sender = ensure_signed(origin)?; - - // Get owner of the claim, if none return an error. - let (owner, _) = Claims::::get(&claim).ok_or(Error::::NoSuchClaim)?; - - // Verify that sender of the current call is the claim owner. - ensure!(sender == owner, Error::::NotClaimOwner); - - // Remove claim from storage. - Claims::::remove(&claim); - - // Emit an event that the claim was erased. - Self::deposit_event(Event::ClaimRevoked { who: sender, claim }); - Ok(()) - } - } - ``` + ```rust + // Dispatchable functions allow users to interact with the pallet and invoke state changes. + // These functions materialize as "extrinsics", which are often compared to transactions. + // Dispatchable functions must be annotated with a weight and must return a DispatchResult. + #[pallet::call] + impl Pallet { + #[pallet::weight(0)] + #[pallet::call_index(1)] + pub fn create_claim(origin: OriginFor, claim: T::Hash) -> DispatchResult { + // Check that the extrinsic was signed and get the signer. + // This function will return an error if the extrinsic is not signed. + let sender = ensure_signed(origin)?; + + // Verify that the specified claim has not already been stored. + ensure!(!Claims::::contains_key(&claim), Error::::AlreadyClaimed); + + // Get the block number from the FRAME System pallet. + let current_block = >::block_number(); + + // Store the claim with the sender and block number. + Claims::::insert(&claim, (&sender, current_block)); + + // Emit an event that the claim was created. + Self::deposit_event(Event::ClaimCreated { who: sender, claim }); + + Ok(()) + } + + #[pallet::weight(0)] + #[pallet::call_index(2)] + pub fn revoke_claim(origin: OriginFor, claim: T::Hash) -> DispatchResult { + // Check that the extrinsic was signed and get the signer. + // This function will return an error if the extrinsic is not signed. + let sender = ensure_signed(origin)?; + + // Get owner of the claim, if none return an error. + let (owner, _) = Claims::::get(&claim).ok_or(Error::::NoSuchClaim)?; + + // Verify that sender of the current call is the claim owner. + ensure!(sender == owner, Error::::NotClaimOwner); + + // Remove claim from storage. + Claims::::remove(&claim); + + // Emit an event that the claim was erased. + Self::deposit_event(Event::ClaimRevoked { who: sender, claim }); + Ok(()) + } + } + ``` 1. Save your changes and close the file. 1. Check that your code compiles by running the following command: - ```bash - cargo check -p node-template-runtime --release - ``` - The `[-p](https://doc.rust-lang.org/cargo/commands/cargo-check.html#options) node-template-runtime` directive tells cargo to only check the `node_template_runtime` package. + ```bash + cargo check -p node-template-runtime --release + ``` - You can refer to the node template [solution](https://github.com/substrate-developer-hub/substrate-node-template/blob/tutorials/solutions/proof-of-existence/pallets/template/src/lib.rs) if you get stuck. + The `[-p](https://doc.rust-lang.org/cargo/commands/cargo-check.html#options) node-template-runtime` directive tells cargo to only check the `node_template_runtime` package. + + You can refer to the node template [solution](https://github.com/substrate-developer-hub/substrate-node-template/blob/tutorials/solutions/proof-of-existence/pallets/template/src/lib.rs) if you get stuck. ## Build the runtime with your new pallet @@ -336,18 +337,18 @@ To compile and start the updated Substrate node: 1. Compile the node template by running the following command: - ```bash - cargo build --release - ``` + ```bash + cargo build --release + ``` 1. Start the node in development mode by running the following command: - ```bash - ./target/release/node-template --dev - ``` + ```bash + ./target/release/node-template --dev + ``` - The `--dev` option starts the node using the predefined `development` chain specification. - Using the `--dev` option ensures that you have a clean working state any time you stop and restart the node. + The `--dev` option starts the node using the predefined `development` chain specification. + Using the `--dev` option ensures that you have a clean working state any time you stop and restart the node. 1. Verify the node produces blocks. @@ -371,23 +372,23 @@ To test the proof-of-existence pallet using the front-end: 1. Navigate to the ["Developer > Extrinsics"](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/extrinsics) tab. - ![Extrinsics Tab](/media/images/docs/tutorials/custom-pallet/poe-extrinsics-tab.png) + ![Extrinsics Tab](/media/images/docs/tutorials/custom-pallet/poe-extrinsics-tab.png) 1. Adjust the extrinsics page to select "ALICE" as the account, and "templateModule > createClaim" as the extrinsic. - ![Create Claim](/media/images/docs/tutorials/custom-pallet/poe-create-claim.png) + ![Create Claim](/media/images/docs/tutorials/custom-pallet/poe-create-claim.png) 1. Then you can toggle "hash a file", which will allow you to select a file to hash and claim on the blockchain. - ![Hash File](/media/images/docs/tutorials/custom-pallet/poe-hash-file.png) + ![Hash File](/media/images/docs/tutorials/custom-pallet/poe-hash-file.png) 1. Click "Submit Transaction" in the bottom right corner, then on the pop up click "Sign and Submit". - ![Submit Extrinsic](/media/images/docs/tutorials/custom-pallet/poe-submit.png) + ![Submit Extrinsic](/media/images/docs/tutorials/custom-pallet/poe-submit.png) 1. If everything was successful, you should see a green extrinsic success notification! - ![Extrinsic Success](/media/images/docs/tutorials/custom-pallet/poe-success.png) + ![Extrinsic Success](/media/images/docs/tutorials/custom-pallet/poe-success.png) ### Read a claim @@ -395,21 +396,21 @@ The final step of this tutorial is to check what claims have been stored on your 1. Navigate to the ["Developer > Chain State"](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/chainstate) tab. - ![Chain State](/media/images/docs/tutorials/custom-pallet/poe-chain-state.png) + ![Chain State](/media/images/docs/tutorials/custom-pallet/poe-chain-state.png) 1. Adjust the state query to "templateModule > claims". 1. Toggle off the "include option" on the hash input to leave the input empty. - This will allow us to see all the claims, rather than just one at a time. + This will allow us to see all the claims, rather than just one at a time. - ![Query All Claims](/media/images/docs/tutorials/custom-pallet/poe-claims.png) + ![Query All Claims](/media/images/docs/tutorials/custom-pallet/poe-claims.png) 1. Press the "+" button to execute the query. - ![Query Results](/media/images/docs/tutorials/custom-pallet/poe-query.png) + ![Query Results](/media/images/docs/tutorials/custom-pallet/poe-query.png) - Now you can see that the claim is stored in the blockchain with the data about the owners address and the block number when the claim was made! + Now you can see that the claim is stored in the blockchain with the data about the owners address and the block number when the claim was made! ## Next steps diff --git a/content/md/en/docs/tutorials/integrate-with-tools/integrate-a-light-client-node.md b/content/md/en/docs/tutorials/integrate-with-tools/integrate-a-light-client-node.md index 146f7537a..ef7e58e13 100644 --- a/content/md/en/docs/tutorials/integrate-with-tools/integrate-a-light-client-node.md +++ b/content/md/en/docs/tutorials/integrate-with-tools/integrate-a-light-client-node.md @@ -28,7 +28,7 @@ By completing this tutorial, you will accomplish the following objectives: ## Connect to a well-known chain Before the light client can connect to a network, you must have a web application that specifies the network the light client should connect to, the nodes for it to communicate with, and the consensus-critical state it must have at genesis. -This information is available in the [chain specification](/build/chain-spec/) file for the network. +This information is available in the [chain specification](/build/chain-spec/) file for the network. Substrate Connect is preconfigured to recognize several chains that are defined in the [WellKnownChain](https://paritytech.github.io/substrate-connect/api/enums/connect_src.WellKnownChain.html) enumeration list. These well-known chains are: @@ -43,31 +43,31 @@ To connect to one of these chains: 1. Open a new terminal shell on your computer. 2. Create a web application to use Substrate Connect by cloning the `empty-webapp` template with the following command: - + ```bash git clone https://github.com/bernardoaraujor/empty-webapp ``` 3. Change to the `empty-webapp` directory by running the following command: - + ```bash cd empty-webapp ``` - + 4. Install Substrate Connect by running the following command: - + ```bash yarn add @substrate/connect ``` 5. Install dependencies from the Polkadot-JS RPC provider by running the following command: - + ```bash yarn add @polkadot/rpc-provider ``` 6. Install dependencies from the Polkadot-JS API by running the following command: - + ```bash yarn add @polkadot/api ``` @@ -75,95 +75,90 @@ To connect to one of these chains: After you install these dependencies, you can use them in the sample application. 7. Open the `empty-webapp/index.ts` file in your preferred code editor. - 8. Copy and paste the following application code to create a Substrate Connect instance with `substrate-connect` as the provider that connects to the Polkadot relay chain using the `polkadot` chain specification file. - + ```typescript import { ScProvider } from "@polkadot/rpc-provider/substrate-connect"; import * as Sc from "@substrate/connect"; import { ApiPromise } from "@polkadot/api"; - - window.onload = () => { - void (async () => { - try { - const provider = new ScProvider(Sc, Sc.WellKnownChain.polkadot); - - await provider.connect(); - const api = await ApiPromise.create({ provider }); - await api.rpc.chain.subscribeNewHeads( - (lastHeader: { number: unknown; hash: unknown }) => { - console.log( - `💡 New block #${lastHeader.number} has hash ⚡️ ${lastHeader.hash}` - ); - } - ); - } catch (error) { - console.error(error); - } - })(); - }; + + window.onload = () => { + void (async () => { + try { + const provider = new ScProvider(Sc, Sc.WellKnownChain.polkadot); + + await provider.connect(); + const api = await ApiPromise.create({ provider }); + await api.rpc.chain.subscribeNewHeads((lastHeader: { number: unknown; hash: unknown }) => { + console.log(`💡 New block #${lastHeader.number} has hash ⚡️ ${lastHeader.hash}`); + }); + } catch (error) { + console.error(error); + } + })(); + }; ``` - + In this sample application code, creating a Substrate Connect instance is similar to how you create a WebSocket instance using the Polkadot-JS API. With the Polkadot-JS API only, you would create an instance like this: - + ```javascript // Import - import { ApiPromise, WsProvider } from '@polkadot/api'; - + import { ApiPromise, WsProvider } from "@polkadot/api"; + // Construct - const wsProvider = new WsProvider('wss://rpc.polkadot.io'); + const wsProvider = new WsProvider("wss://rpc.polkadot.io"); const api = await ApiPromise.create({ provider: wsProvider }); ``` - + For Substrate Connect, you replace the WebSocket (`WsProvider`) provider with the Substrate Connect (`ScProvider`) provider, and, instead of a WebSocket URL client address, you specify the chain specification for the network to connect to (`WellKnownChain.polkadot`). 9. Install any remaining dependencies by running the following command: - + ```bash yarn ``` 10. Start the web application by running the following command: - - ```bash - yarn dev - ``` - If there are compiler errors when you start the local server, you might be missing a dependency not accounted for by the current `yarn` configuration. - If a dependency is missing, you can add the package by running a command similar to the following: +```bash +yarn dev +``` + +If there are compiler errors when you start the local server, you might be missing a dependency not accounted for by the current `yarn` configuration. +If a dependency is missing, you can add the package by running a command similar to the following: + +```bash +yarn add -D buffer +``` + +11. Verify the browser opens the URL `http://localhost:3001/`. + +12. Open the browser console for your browser. + +How you navigate to and open the browser console varies depending on the browser and operating system you use. +For example, on Chrome, select **More Tools**, **Developer Tools**, then click **Console**. - ```bash - yarn add -D buffer - ``` - -11. Verify the browser opens the URL `http://localhost:3001/`. - -12. Open the browser console for your browser. - - How you navigate to and open the browser console varies depending on the browser and operating system you use. - For example, on Chrome, select **More Tools**, **Developer Tools**, then click **Console**. - 13. Verify the `smoldot` process is initialized, followed by the hashes of the incoming blocks from Polkadot. - - For example, the console should display log entries similar to the following: - - ```console - [substrate-connect-extension] [smoldot] Smoldot v0.7.7 - [substrate-connect-extension] [smoldot] Chain initialization complete for polkadot. Name: "Polkadot". Genesis hash: 0x91b1…90c3. State root hash: 0x29d0d972cd27cbc511e9589fcb7a4506d5eb6a9e8df205f00472e5ab354a4e17. Network identity: 12D3KooWRse9u6Z9ukP4C92YCCH2gXziNm8ThRch2owaaFh9H6D1. Chain specification or database starting at: 0x7f52…8902 (#14614672) - ... - 💡 New block #14614893 has hash ⚡️ 0x18f8086952aa5f8f1f8a36ea05af462f6bb26615b481145f7c5daa24ebc0c4cd - 💡 New block #14614894 has hash ⚡️ 0x92ca6fd51bc7a2fc5991441e9736bcccf3be45cee6fc88d40d145fc4211ba477 - 💡 New block #14614894 has hash ⚡️ 0x2353ce49f06206c6dd9882200666fa7d51fc43c1cc6a61cca81ce9fa543409cb - ``` - - This simple web application only connects to Polkadot to retrieve block hashes. - The primary purpose of this application is to demonstrate connecting to the chain without using a centralized entry point to the network, such as the URL for a specific RPC node. - However, you could extend this application to do a lot more, because—after you replace `WsProvider` with `ScProvider`—you can write code for your application simply by using the existing [Polkadot-JS API](https://polkadot.js.org/docs/). + +For example, the console should display log entries similar to the following: + +```console +[substrate-connect-extension] [smoldot] Smoldot v0.7.7 +[substrate-connect-extension] [smoldot] Chain initialization complete for polkadot. Name: "Polkadot". Genesis hash: 0x91b1…90c3. State root hash: 0x29d0d972cd27cbc511e9589fcb7a4506d5eb6a9e8df205f00472e5ab354a4e17. Network identity: 12D3KooWRse9u6Z9ukP4C92YCCH2gXziNm8ThRch2owaaFh9H6D1. Chain specification or database starting at: 0x7f52…8902 (#14614672) +... +💡 New block #14614893 has hash ⚡️ 0x18f8086952aa5f8f1f8a36ea05af462f6bb26615b481145f7c5daa24ebc0c4cd +💡 New block #14614894 has hash ⚡️ 0x92ca6fd51bc7a2fc5991441e9736bcccf3be45cee6fc88d40d145fc4211ba477 +💡 New block #14614894 has hash ⚡️ 0x2353ce49f06206c6dd9882200666fa7d51fc43c1cc6a61cca81ce9fa543409cb +``` + +This simple web application only connects to Polkadot to retrieve block hashes. +The primary purpose of this application is to demonstrate connecting to the chain without using a centralized entry point to the network, such as the URL for a specific RPC node. +However, you could extend this application to do a lot more, because—after you replace `WsProvider` with `ScProvider`—you can write code for your application simply by using the existing [Polkadot-JS API](https://polkadot.js.org/docs/). 14. Stop the `smoldot` light client node by pressing Control-c. -## Connect to a custom chain specification +## Connect to a custom chain specification Connecting to a custom chain specification or a publicly-accessible parachain is similar to connecting to one of the well-known chains. The primary difference in the code is that you must explicitly identify the chain specification for Substrate Connect to use. @@ -175,60 +170,55 @@ To connect to Statemint: 2. Copy the downloaded chain specification to the `empty-webapp` directory you created in [Connect to a well-known chain](#connect-to-a-well-known-chain). 3. Open the `index.ts` file in your code editor. - 4. Replace the contents with the following code. - + ```typescript - import { ApiPromise } from "@polkadot/api"; - import { ScProvider } from "@polkadot/rpc-provider/substrate-connect"; - import * as Sc from "@substrate/connect"; - import jsonParachainSpec from "./statemint.json"; - - window.onload = () => { - void (async () => { - try { - const relayProvider = new ScProvider(Sc, Sc.WellKnownChain.polkadot); - const parachainSpec = JSON.stringify(jsonParachainSpec); - const provider = new ScProvider(Sc, parachainSpec, relayProvider); - - await provider.connect(); - const api = await ApiPromise.create({ provider }); - await api.rpc.chain.subscribeNewHeads( - (lastHeader: { number: unknown; hash: unknown }) => { - console.log( - `💡 New block #${lastHeader.number} has hash ⚡️ ${lastHeader.hash}` - ); - } - ); - } catch (error) { - console.error(error); - } - })(); - }; + import { ApiPromise } from "@polkadot/api"; + import { ScProvider } from "@polkadot/rpc-provider/substrate-connect"; + import * as Sc from "@substrate/connect"; + import jsonParachainSpec from "./statemint.json"; + + window.onload = () => { + void (async () => { + try { + const relayProvider = new ScProvider(Sc, Sc.WellKnownChain.polkadot); + const parachainSpec = JSON.stringify(jsonParachainSpec); + const provider = new ScProvider(Sc, parachainSpec, relayProvider); + + await provider.connect(); + const api = await ApiPromise.create({ provider }); + await api.rpc.chain.subscribeNewHeads((lastHeader: { number: unknown; hash: unknown }) => { + console.log(`💡 New block #${lastHeader.number} has hash ⚡️ ${lastHeader.hash}`); + }); + } catch (error) { + console.error(error); + } + })(); + }; ``` - + As you can see, this code has a few important differences. - + - The `statemint.json` chain specification file is imported into the `jsonParachainSpec` object. - The chain specification is converted to a JSON-encoded string and stored in the `parachainSpec` variable, so that it can be exchanged with the web server. - The `ScProvider` provider is created for the `polkadot` relay chain but is used as a parameter for creating and connecting to the parachain provider. - - Substrate Connect requires this information to determine the relay chain that the parachain communicates with. + +Substrate Connect requires this information to determine the relay chain that the parachain communicates with. 6. Start the web application by running the following command: - + ```bash yarn dev ``` -7. Verify the browser opens the URL `http://localhost:3001/`. - +7. Verify the browser opens the URL `http://localhost:3001/`. + 8. Open the browser console for your browser. 9. Verify the `smoldot` process is initialized, followed by the hashes of the incoming blocks from Polkadot. - + For example, the console should display log entries similar to the following: - + ```console [substrate-connect-extension] [smoldot] Parachain initialization complete for statemint. Name: "Statemint". Genesis hash: 0x68d5…de2f. State root hash: 0xc1ef26b567de07159e4ecd415fbbb0340c56a09c4d72c82516d0f3bc2b782c80. Network identity: 12D3KooWNicu1ZCX6ZNUC96B4TQSiet2NkoQc7SfitxWWE4fQgpK. Relay chain: polkadot (id: 1000) ... @@ -246,14 +236,14 @@ Have a look at [this demo](https://github.com/paritytech/substrate-connect/tree/ The examples in this tutorial used `@polkadot/rpc-provider/substrate-connect` because this provider makes it straightforward to create applications that interact with the chain using the [Polkadot-JS API](https://polkadot.js.org/docs/). For more advanced application development that doesn't depend on the Polkadot-JS API, you can install and use the `@substrate-connect` package. For example, if you are building your own application library or programming interfaces, you should install the Substrate Connect dependencies by running the following command: - + ```bash yarn add @substrate/connect ``` To use `@substrate-connect` -1. Open a terminal shell and create a new working directory. +1. Open a terminal shell and create a new working directory. For example: @@ -262,19 +252,19 @@ To use `@substrate-connect` ``` 2. Clone the `empty-webapp` template and change to the template directory by running the following command: - + ```bash git clone https://github.com/bernardoaraujor/empty-webapp && cd empty-webapp ``` - + 3. Install the Substrate Connect dependencies by running the following command: - + ```bash yarn add @substrate/connect ``` 4. Copy and paste the following application code. - + ```typescript import { WellKnownChain, createScClient } from '@substrate/connect'; // Create the client diff --git a/plugins/gatsby-plugin-substrate b/plugins/gatsby-plugin-substrate index ae6287327..798d7c609 160000 --- a/plugins/gatsby-plugin-substrate +++ b/plugins/gatsby-plugin-substrate @@ -1 +1 @@ -Subproject commit ae62873274a4d24fe1fbfcaf9af8a2218594445b +Subproject commit 798d7c609fa30f9c1f81f795b6862d9debe64c01