diff --git a/docs/assets/dvm/app/d1.png b/docs/assets/dvm/apps/d1.png
similarity index 100%
rename from docs/assets/dvm/app/d1.png
rename to docs/assets/dvm/apps/d1.png
diff --git a/docs/assets/dvm/metamask/m0.png b/docs/assets/dvm/metamask/m0.png
index ed602191..d584468d 100644
Binary files a/docs/assets/dvm/metamask/m0.png and b/docs/assets/dvm/metamask/m0.png differ
diff --git a/docs/assets/dvm/metamask/m1.png b/docs/assets/dvm/metamask/m1.png
index be813c3d..de2f21a1 100644
Binary files a/docs/assets/dvm/metamask/m1.png and b/docs/assets/dvm/metamask/m1.png differ
diff --git a/docs/assets/dvm/metamask/m10.png b/docs/assets/dvm/metamask/m10.png
new file mode 100644
index 00000000..14347feb
Binary files /dev/null and b/docs/assets/dvm/metamask/m10.png differ
diff --git a/docs/assets/dvm/metamask/m11.png b/docs/assets/dvm/metamask/m11.png
new file mode 100644
index 00000000..2a3cd7eb
Binary files /dev/null and b/docs/assets/dvm/metamask/m11.png differ
diff --git a/docs/assets/dvm/metamask/m12.png b/docs/assets/dvm/metamask/m12.png
new file mode 100644
index 00000000..493a95fc
Binary files /dev/null and b/docs/assets/dvm/metamask/m12.png differ
diff --git a/docs/assets/dvm/metamask/m13.png b/docs/assets/dvm/metamask/m13.png
new file mode 100644
index 00000000..a0769442
Binary files /dev/null and b/docs/assets/dvm/metamask/m13.png differ
diff --git a/docs/assets/dvm/metamask/m14.png b/docs/assets/dvm/metamask/m14.png
new file mode 100644
index 00000000..daad49d5
Binary files /dev/null and b/docs/assets/dvm/metamask/m14.png differ
diff --git a/docs/assets/dvm/metamask/m15.png b/docs/assets/dvm/metamask/m15.png
new file mode 100644
index 00000000..991e12b0
Binary files /dev/null and b/docs/assets/dvm/metamask/m15.png differ
diff --git a/docs/assets/dvm/metamask/m16.png b/docs/assets/dvm/metamask/m16.png
new file mode 100644
index 00000000..c10e7213
Binary files /dev/null and b/docs/assets/dvm/metamask/m16.png differ
diff --git a/docs/assets/dvm/metamask/m17.png b/docs/assets/dvm/metamask/m17.png
new file mode 100644
index 00000000..b3d9a069
Binary files /dev/null and b/docs/assets/dvm/metamask/m17.png differ
diff --git a/docs/assets/dvm/metamask/m2.png b/docs/assets/dvm/metamask/m2.png
index 695f04bc..07f203a7 100644
Binary files a/docs/assets/dvm/metamask/m2.png and b/docs/assets/dvm/metamask/m2.png differ
diff --git a/docs/assets/dvm/metamask/m3.png b/docs/assets/dvm/metamask/m3.png
index eb0d8c99..7abb349c 100644
Binary files a/docs/assets/dvm/metamask/m3.png and b/docs/assets/dvm/metamask/m3.png differ
diff --git a/docs/assets/dvm/metamask/m4.png b/docs/assets/dvm/metamask/m4.png
index e4c51d18..30527557 100644
Binary files a/docs/assets/dvm/metamask/m4.png and b/docs/assets/dvm/metamask/m4.png differ
diff --git a/docs/assets/dvm/metamask/m5.png b/docs/assets/dvm/metamask/m5.png
index 9f2dd1bf..6879c8bc 100644
Binary files a/docs/assets/dvm/metamask/m5.png and b/docs/assets/dvm/metamask/m5.png differ
diff --git a/docs/assets/dvm/metamask/m6.png b/docs/assets/dvm/metamask/m6.png
index f1e54cc1..3b0f12f2 100644
Binary files a/docs/assets/dvm/metamask/m6.png and b/docs/assets/dvm/metamask/m6.png differ
diff --git a/docs/assets/dvm/metamask/m7.png b/docs/assets/dvm/metamask/m7.png
index e11d69db..4bbdc0ba 100644
Binary files a/docs/assets/dvm/metamask/m7.png and b/docs/assets/dvm/metamask/m7.png differ
diff --git a/docs/assets/dvm/metamask/m8.png b/docs/assets/dvm/metamask/m8.png
index 7d73ea86..28bb832c 100644
Binary files a/docs/assets/dvm/metamask/m8.png and b/docs/assets/dvm/metamask/m8.png differ
diff --git a/docs/assets/dvm/metamask/m9.png b/docs/assets/dvm/metamask/m9.png
new file mode 100644
index 00000000..1a1ce4d3
Binary files /dev/null and b/docs/assets/dvm/metamask/m9.png differ
diff --git a/docs/builders/_category_.json b/docs/builders/_category_.json
new file mode 100644
index 00000000..9b5cd25e
--- /dev/null
+++ b/docs/builders/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Builders",
+ "position": 5
+}
diff --git a/docs/builders/get-started/_category_.json b/docs/builders/get-started/_category_.json
new file mode 100644
index 00000000..1bf165d4
--- /dev/null
+++ b/docs/builders/get-started/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Get Started",
+ "position": 1
+}
diff --git a/docs/builders/get-started/darwinia-crab.md b/docs/builders/get-started/darwinia-crab.md
new file mode 100644
index 00000000..afd114b4
--- /dev/null
+++ b/docs/builders/get-started/darwinia-crab.md
@@ -0,0 +1,44 @@
+---
+title: Connect to Crab
+sidebar_position: 3
+description: How to connect to crab network.
+---
+
+# Connect to Crab
+
+## Introduction
+
+Darwinia Crab Network (Crab) is a canary network with real economic value for Darwinia, and its positioning is similar to Polkadot's Kusama Network.
+
+Crab has two endpoints available for users to connect to: one for HTTPS and one for WSS.
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+
+
+
+```
+https://crab-rpc.darwinia.network
+```
+
+
+
+
+```
+wss://crab-rpc.darwinia.network
+```
+
+
+
+
+## Features
+
+- Compatible with EVM, Ethereum contracts, Ethereum contract tools.
+- Support ethereum-substrate bi-directional bridge
diff --git a/docs/builders/get-started/darwinia-dev.md b/docs/builders/get-started/darwinia-dev.md
new file mode 100644
index 00000000..009693d4
--- /dev/null
+++ b/docs/builders/get-started/darwinia-dev.md
@@ -0,0 +1,120 @@
+---
+title: Development Node
+sidebar_position: 1
+description: How to setup a Darwinia Development Node.
+---
+
+# Getting Started with a Darwinia Development Node
+
+## Introduction
+
+This guide outlines the steps needed to create a development node for latest features of Darwinia.
+
+A Darwinia development node is your own personal development environment for building and testing applications on Darwinia. For Ethereum developers, it is comparable to Ganache. If you follow to the end of this guide, you will have a Darwinia development node running in your local environment, and will be able to connect it to the default Darwinia Apps GUI.
+
+## Getting Started With The Binary
+
+> If you know what you are doing, you can directly download the precompiled binaries attached to each release on the [Darwinia Release Page](https://github.com/darwinia-network/darwinia-common/releases). These will not work in all systems. For example, the binaries only work with x86-64 Linux with specific versions of dependencies. The safest way to ensure compatibility is to compile the binary in the system where it will be run from.
+
+First, start by cloning the [darwinia-common](https://github.com/darwinia-network/darwinia-common) codebase:
+
+```
+git clone https://github.com/darwinia-network/darwinia-common
+cd darwinia-common
+```
+
+If you already have Rust installed, you can skip the next two steps. Otherwise, install Rust and its prerequisites [via Rust's recommended method](https://www.rust-lang.org/tools/install) by executing:
+
+```
+curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+```
+
+Next, update your PATH environment variable by running:
+
+```
+source $HOME/.cargo/env
+```
+
+Now, build the development node by running:
+
+```
+cargo build --release
+```
+
+If a _cargo not found error_ shows up in the terminal, manually add Rust to your system path or restart your system:
+```
+source $HOME/.cargo/env
+```
+
+> The initial build will take a while. Depending on your hardware, you should expect approximately 30 minutes for the build process to finish.
+
+Here is what the tail end of the build output should look like:
+
+
+
+Then, you will want to run the node in dev mode using the following command:
+
+```
+./target/release/drml --dev --tmp
+```
+
+> For people not familiar with Substrate, the `--dev` flag is a way to run a Substrate-based node in a single node developer configuration for testing purposes. You can learn more about `--dev` in [this Substrate tutorial](https://substrate.dev/docs/en/tutorials/create-your-first-substrate-chain/interact).
+
+You should see an output that looks like the following, showing some blocks has been produced:
+
+
+
+For more information on some of the flags and options used in the example, check out [Common Options](#common-options). If you want to see a complete list of all of the flags, options, and subcommands, open the help menu by running:
+
+```
+./target/release/drml --help
+```
+## Connecting To Darwinia Apps
+
+Start by connecting to it with [Darwinia Apps Explorer](https://apps.darwinia.network/?rpc%3Dwss%253A%252F%252Fpangolin-rpc.darwinia.network#/explorer). This will automatically connects to Pangolin TestNet.
+
+
+
+Click on the top left corner to open the menu to configure the networks, and then navigate down to open the Development sub-menu. In there, you will want to toggle the "Local Node" option, which points to `ws://127.0.0.1:9944`. Next, select the "Save & Reload" button, and the site should connect to your Darwinia development node.
+
+
+
+With Darwinia Apps connected, you will see the the development node has began producing blocks.
+
+
+
+## Common Options
+
+Flags do not take an argument. To use a flag, add it to the end of a command. For example:
+
+```
+./target/release/drml --dev --tmp
+```
+
+- `--dev`: Specifies the development chain
+- `--no-telemetry`: Disable connecting to the Substrate telemetry server. For global chains, telemetry is on by default. Telemetry is unavailable if you are running a development (`--dev`) node.
+- `--tmp`: Runs a temporary node in which all of the configuration will be deleted at the end of the process
+- `--rpc-external`: Listen to all RPC interfaces
+- `--ws-external`: Listen to all Websocket interfaces
+
+For a complete list of flags and options, spin up your Darwinia development node with `--help` added to the end of the command.
+## Pre-funded Development Accounts
+
+Your Darwinia development node comes with some pre-funded substrate accounts for development. There are two test accounts are derived from Substrate's canonical development mnemonic:
+
+```
+bottom drive obey lake curtain smoke basket hold race lonely fit walk
+```
+
+- Alice:
+ - Public Address: `2sy7imEZs1Y9GgYrR5Vqkb8EZTmpv2BKr5QNRzB9gkzdAEU2`
+ - Private Key: `0xe5be9a5092b81bca64be81d212e7f2f9eba183bb7a90954f7b76361f6edb5c0a`
+
+- Bob
+ - Public Address: `2rPxSh4RjHYF7g4Lz9Xu1FDGTckwTUmzMFG3Nd3Ucn5PPKJr`
+ - Private Key: `0x398f0c28f98885e046333d4a41c19cee4c37368a9832c6502f6cfd182e2aef89`
+
+Also, included with the development node is a prefunded evm account used for testing purposes:
+
+- Public Address: `0x6be02d1d3665660d22ff9624b7be0551ee1ac91b`
+- Private Key: `0x99b3c12287537e38c90a9219d4cb074a89a16e9cdb20bf85728ebd97c343e342`
diff --git a/docs/builders/get-started/darwinia-pangolin.md b/docs/builders/get-started/darwinia-pangolin.md
new file mode 100644
index 00000000..1663d144
--- /dev/null
+++ b/docs/builders/get-started/darwinia-pangolin.md
@@ -0,0 +1,83 @@
+---
+title: Connect to Pangolin
+sidebar_position: 2
+description: How to connect to Pangolin network
+---
+
+# Connect to Pangolin
+
+## Introduction
+
+The Darwinia official TestNet, named Pangolin, is the easiest way to get started with a Darwinia network environment. Follow this tutorial to connect to the Pangolin network.
+
+The Pangolin Network has two endpoints available for users to connect to: one for HTTPS and one for WSS.
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+
+
+
+```
+https://pangolin-rpc.darwinia.network
+```
+
+
+
+
+```
+wss://pangolin-rpc.darwinia.network
+```
+
+
+
+
+## Features
+
+- Testing the latest technology products.
+- Compatible with EVM, Ethereum contracts, Ethereum contract tools.
+- Support substrate-substrate bi-directional bridge
+- Support ethereum-substrate bi-directional bridge.
+- Have some unstable features, may be reset.
+
+## Get Tokens
+
+To start building on Pangolin, you can get DEV tokens(PRING) from our [Pangolin Faucet Official](https://t.me/darwiniafaucet_official), in our Tg Group. For specific amounts, you can always reach out directly to us via our community channels.
+
+### Pangolin Faucet Official
+
+- Visit [Pangolin Apps Portal](https://apps.darwinia.network/#/account) and select the **Pangolin Test Network** in the network list in the upper left corner.
+
+
+
+- Create an account on Pangolin Test Network. For detailed tutorials on creating an account, please refer to [here](https://docs.crab.network/crab-tut-create-account)!
+- Click the avatar and you can copy your Pangolin address.
+
+
+
+- Join the Telegram group named "[Darwinia Faucet Official](https://t.me/darwiniafaucet_official)".
+- Send `/faucet`+ Pangolin address.
+
+
+
+- You can open the link of the darwinia_bot to check the transaction on Subscan.
+
+
+
+
+
+- When the transaction is successful, a certain number of test tokens will appear in your pangolin address.
+
+
+
+- Each telegram account can get 100 PRINGs every seven days.
+
+### Manual Procedure
+
+For token requests of more than the limited account allowed by our Tg group, contact a moderator directly via our [Element](https://app.element.io/?pk_vid=6961ca0f7c45f8bf16052310122d2437#/room/#darwinia:matrix.org). We are happy to provide the tokens needed to test your applications.
diff --git a/docs/builders/integrations/_category_.json b/docs/builders/integrations/_category_.json
new file mode 100644
index 00000000..cb22d16e
--- /dev/null
+++ b/docs/builders/integrations/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Interaction",
+ "position": 4
+}
diff --git a/docs/builders/integrations/bridges/_category_.json b/docs/builders/integrations/bridges/_category_.json
new file mode 100644
index 00000000..e65e8650
--- /dev/null
+++ b/docs/builders/integrations/bridges/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Bridges",
+ "position": 1
+}
diff --git a/docs/pangolin-bridge-ropsten.md b/docs/builders/integrations/bridges/pangolin-ropsten.md
similarity index 91%
rename from docs/pangolin-bridge-ropsten.md
rename to docs/builders/integrations/bridges/pangolin-ropsten.md
index 9f9575ff..c86a4b43 100644
--- a/docs/pangolin-bridge-ropsten.md
+++ b/docs/builders/integrations/bridges/pangolin-ropsten.md
@@ -1,6 +1,7 @@
---
id: pangolin-bridge-ropsten
title: Ropsten Bridge
+sidebar_position: 1
sidebar_label: Ropsten Bridge
---
@@ -8,14 +9,14 @@ sidebar_label: Ropsten Bridge
### Relay Contract
-1. Relayer sends `Authority Set` change
+1. Relayer sends `Authority Set` change
2. Relayer listens to the `Authority Set` changed event
```
address: 0xD35Bb6F1bc1C84b53E0995c1830454AB7C4147f1
topic: 0x91d6d149c7e5354d1c671fe15a5a3332c47a38e15e8ac0339b24af3c1090690f
```
-
+
### TokenIssuing Contract
User claims RING & KTON
@@ -34,4 +35,4 @@ address: 0x98fAE9274562FE131e2CF5771ebFB0bB232aFd25
```
address: 0x49262b932e439271d05634c32978294c7ea15d0c
topic: 0xc9dcda609937876978d7e0aa29857cb187aea06ad9e843fd23fd32108da73f10
-```
\ No newline at end of file
+```
diff --git a/docs/builders/integrations/indexers/_category_.json b/docs/builders/integrations/indexers/_category_.json
new file mode 100644
index 00000000..e70f17c2
--- /dev/null
+++ b/docs/builders/integrations/indexers/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Indexers",
+ "position": 1
+}
diff --git a/docs/builders/integrations/indexers/thegraph.md b/docs/builders/integrations/indexers/thegraph.md
new file mode 100644
index 00000000..c4ac04ce
--- /dev/null
+++ b/docs/builders/integrations/indexers/thegraph.md
@@ -0,0 +1,266 @@
+---
+id: dvm-thegraph
+title: Using The Graph
+sidebar_position: 1
+sidebar_label: Using The Graph
+---
+
+The Graph is a decentralized and open-source protocol for indexing and querying data from blockchains. It is very difficult to query data directly from blockchains. And The Graph makes it easy to save data from blockchain to database and query. The darwinia DVM is compatible with EVM, we suggest using The Graph as the indexer. Developers can easily deploy The Graph Node, build APIs called Subgraphs, and query data from it. The data is saved in postgres, and with a standard GraphQL API to query. For more detail of the usage of The Graph, you can visit their [docs](https://thegraph.com/docs/about/introduction).
+
+Here we introduce you about how to deploy a local The Graph Node, create and deploy a Subgraph to listen event from DVM contract.
+
+## The Graph Node
+The docker-compose file is like this. Before start the server, you need to set a URL for the network. Here we use the darwinia testnet `pangolin` http://pangolin-rpc.darwinia.network.
+```
+version: '3'
+services:
+ graph-node:
+ image: graphprotocol/graph-node
+ ports:
+ - '8000:8000'
+ - '8001:8001'
+ - '8020:8020'
+ - '8030:8030'
+ - '8040:8040'
+ depends_on:
+ - ipfs
+ - postgres
+ environment:
+ postgres_host: postgres
+ postgres_user: graph-node
+ postgres_pass: let-me-in
+ postgres_db: graph-node
+ ipfs: 'ipfs:5001'
+ ethereum: 'pangolin:http://pangolin-rpc.darwinia.network'
+ GRAPH_LOG: info
+ ipfs:
+ image: ipfs/go-ipfs:v0.4.23
+ ports:
+ - '5001:5001'
+ volumes:
+ - ./data/ipfs:/data/ipfs
+ postgres:
+ image: postgres
+ ports:
+ - '5432:5432'
+ command: ["postgres", "-cshared_preload_libraries=pg_stat_statements"]
+ environment:
+ POSTGRES_USER: graph-node
+ POSTGRES_PASSWORD: let-me-in
+ POSTGRES_DB: graph-node
+ volumes:
+ - ./data/postgres:/var/lib/postgresql/data
+
+```
+
+To start The Graph Node docker server, enter the command
+```
+docker-compose up -d
+```
+
+The server will open some ports to support subgraph depoly, graphQL query, etc.
+
+| Port | Usage |
+| ----- | ----------------- |
+| 8000 | GraphQL(http) |
+| 8001 | GraphQL(ws) |
+| 8020 | Subgraph(deploy) |
+
+## Deploy Subgraph
+
+If you're creating a new project, you can enter the following command to generate a demo.
+Before do this, please prepare a contract and the ABI file of the contract. For example, we have such a contract and deploy it at address `0xA6BDC789074A8b5C6eA697EE74B2e3a363b2dAA1`.
+
+```js
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity >=0.7.0 <0.9.0;
+
+contract TheGraphExample {
+ event TestEvent(address indexed sender);
+
+ function triggerTestEvent () external {
+ emit TestEvent(msg.sender);
+ }
+}
+```
+
+the ABI file is `example.json`
+```json
+[
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "TestEvent",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "triggerTestEvent",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
+```
+Then enter the follow command to generate a subgraph project.
+```
+graph init --product subgraph-studio. --abi
+```
+follow the steps, then you can have this output.
+```js
+>> graph init --product subgraph-studio. --abi
+✔ Product for which to initialize · hosted-service
+✔ Subgraph name · example/TheGraphExample
+✔ Directory to create the subgraph in · TheGraphExample
+✔ Ethereum network · ropsten
+✔ Contract address · 0xA6BDC789074A8b5C6eA697EE74B2e3a363b2dAA1
+✔ ABI file (path) · ./example.json
+✔ Contract Name · TheGraphExample
+———
+ Generate subgraph from ABI
+ Write subgraph to directory
+✔ Create subgraph scaffold
+✔ Initialize subgraph repository
+✔ Install dependencies with yarn
+✔ Generate ABI and schema types with yarn codegen
+
+Subgraph example/TheGraphExample created in TheGraphExample
+
+Next steps:
+
+ 1. Run `graph auth` to authenticate with your deploy key.
+
+ 2. Type `cd TheGraphExample` to enter the subgraph.
+
+ 3. Run `yarn deploy` to deploy the subgraph.
+
+Make sure to visit the documentation on https://thegraph.com/docs/ for further information.
+```
+A Subgraph project has three parts.
+### schema.graphql
+This used to define the entity used. For example
+```graphql
+type ExampleEntity @entity {
+ id: ID!
+ count: BigInt!
+ sender: Bytes! # address
+}
+```
+Once you modify this schema file, you need regenerate the TypeScript types for The Graph, running:
+```js
+>> npx graph codegen --output-dir generated/
+ Skip migration: Bump mapping apiVersion from 0.0.1 to 0.0.2
+ Skip migration: Bump mapping apiVersion from 0.0.2 to 0.0.3
+ Skip migration: Bump mapping apiVersion from 0.0.3 to 0.0.4
+ Skip migration: Bump mapping specVersion from 0.0.1 to 0.0.2
+✔ Apply migrations
+✔ Load subgraph from subgraph.yaml
+ Load contract ABI from abis/TheGraphExample.json
+✔ Load contract ABIs
+ Generate types for contract ABI: TheGraphExample (abis/TheGraphExample.json)
+ Write types to generated/TheGraphExample/TheGraphExample.ts
+✔ Generate types for contract ABIs
+✔ Generate types for data source templates
+✔ Load data source template ABIs
+✔ Generate types for data source template ABIs
+✔ Load GraphQL schema from schema.graphql
+ Write types to generated/schema.ts
+✔ Generate types for GraphQL schema
+
+Types generated successfully
+```
+### subgraph.yaml
+This file tells you the basic infomation of the subgraph(contract address, abi, event...) and which network to use.
+```yaml
+specVersion: 0.0.2
+schema:
+ file: ./schema.graphql
+dataSources:
+ - kind: ethereum/contract
+ name: TheGraphExample
+ network: pangolin
+ source:
+ address: "0xA6BDC789074A8b5C6eA697EE74B2e3a363b2dAA1"
+ abi: TheGraphExample
+ mapping:
+ kind: ethereum/events
+ apiVersion: 0.0.4
+ language: wasm/assemblyscript
+ entities:
+ - TestEvent
+ abis:
+ - name: TheGraphExample
+ file: ./abis/TheGraphExample.json
+ eventHandlers:
+ - event: TestEvent(indexed address)
+ handler: handleTestEvent
+ file: ./src/mapping.ts
+```
+### AssemblyScript mappings
+In this file, users define their own logic to save the event as entities.
+```js
+import { BigInt } from "@graphprotocol/graph-ts"
+import {
+ TheGraphExample,
+ TestEvent
+} from "../generated/TheGraphExample/TheGraphExample"
+import { ExampleEntity } from "../generated/schema"
+
+export function handleTestEvent(event: TestEvent): void {
+ let entity = ExampleEntity.load(event.transaction.from.toHex())
+ if (entity == null) {
+ entity = new ExampleEntity(event.transaction.from.toHex())
+ entity.count = BigInt.fromI32(0)
+ }
+
+ entity.count = entity.count + BigInt.fromI32(1)
+ entity.sender = event.params.sender
+ entity.save()
+}
+```
+### Deploy
+First we need to create the subgraph on The Graph server.
+```js
+>> npx graph create example/TheGraphExample --node http://127.0.0.1:8020
+Created subgraph: example/TheGraphExample
+```
+Then we deploy it to the server.
+```js
+>> npx graph deploy example/TheGraphExample --ipfs http://localhost:5001 --node http://localhost:8020
+✔ Version Label (e.g. v0.0.1) ·
+ Skip migration: Bump mapping apiVersion from 0.0.1 to 0.0.2
+ Skip migration: Bump mapping apiVersion from 0.0.2 to 0.0.3
+ Skip migration: Bump mapping apiVersion from 0.0.3 to 0.0.4
+ Skip migration: Bump mapping specVersion from 0.0.1 to 0.0.2
+✔ Apply migrations
+✔ Load subgraph from subgraph.yaml
+ Compile data source: TheGraphExample => build/TheGraphExample/TheGraphExample.wasm
+✔ Compile subgraph
+ Copy schema file build/schema.graphql
+ Write subgraph file build/TheGraphExample/abis/TheGraphExample.json
+ Write subgraph manifest build/subgraph.yaml
+✔ Write compiled subgraph to build/
+ Add file to IPFS build/schema.graphql
+ .. QmVRyRF12mxYcKAd9YfsiXkeHHc79wkU5LqWLDinrfnmbg
+ Add file to IPFS build/TheGraphExample/abis/TheGraphExample.json
+ .. QmTDhpdjATMtKcmxoeAR9nZ59fhhm2cJ1xuQ5dikJiWNyL
+ Add file to IPFS build/TheGraphExample/TheGraphExample.wasm
+ .. QmTDJcE1hZ1cbSa9kTx7iGVQ5VM2H8XVg7tQKCRwz3iSwZ
+✔ Upload subgraph to IPFS
+
+Build completed: QmSAjoWQcHa9B56DGuE3WTSahWR3dTy7d7VpVNuWj3VFmS
+
+Deployed to http://localhost:8000/subgraphs/name/example/TheGraphExample/graphql
+
+Subgraph endpoints:
+Queries (HTTP): http://localhost:8000/subgraphs/name/example/TheGraphExample
+Subscriptions (WS): http://localhost:8001/subgraphs/name/example/TheGraphExample
+```
+After we deploy the subgraph, the server start to scan blocks. Wait for the scan result and then we can use the Subgraph endpoints `http://localhost:8000/subgraphs/name/example/TheGraphExample` to query the entity.
diff --git a/docs/builders/integrations/oracles/_category_.json b/docs/builders/integrations/oracles/_category_.json
new file mode 100644
index 00000000..0268ce09
--- /dev/null
+++ b/docs/builders/integrations/oracles/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Oracles",
+ "position": 2
+}
diff --git a/docs/builders/integrations/oracles/chainlink.md b/docs/builders/integrations/oracles/chainlink.md
new file mode 100644
index 00000000..8cad7b77
--- /dev/null
+++ b/docs/builders/integrations/oracles/chainlink.md
@@ -0,0 +1,145 @@
+---
+title: Chainlink
+sidebar_position: 2
+description: How to use request data from a Chainlink Oracle in your Pangolin Ethereum Dapp using smart contracts or Javascript
+---
+
+# Chainlink Oracle
+
+## Introduction
+
+Developers can now use [Chainlink's decentralized Oracle network](https://chain.link/) to fetch data in the Pangolin TestNet. This tutorial goes through two different ways of using Chainlink Oracles:
+
+ - [Basic Request Model](https://docs.chain.link/docs/architecture-request-model), where the end-user sends a request to an Oracle provider, which fetches the data through an API, and fulfils the request storing this data on-chain
+ - [Price Feeds](https://docs.chain.link/docs/architecture-decentralized-model), where data is continuously updated by Oracle operators in a smart contract so that other smart contracts can fetch it
+
+## Basic Request Model
+
+Before we go into fetching the data itself, it is important to understand the basics of the "basic request model."
+
+import ChainlinkBRM from '/snippets/text/chainlink/chainlink-brm.md';
+
+
+
+### The Client Contract
+
+The Client contract is the element that starts the communication with the Oracle by sending a request. As shown in the diagram, it calls the _transferAndCall_ method from the LINK token contract, but there is more processing that is needed to track the request to the Oracle. For this example, you can use the code in [this file](/snippets/code/chainlink/Client.sol), and deploy it on [Remix](/builders/tools/remix/) to try it out. Let's look at the core functions of the contract:
+
+ - _constructor_: runs when the contract is deployed. It sets the address of the LINK token and the owner of the contract
+ - _requestPrice_: needs the Oracle contract address, the job ID, and the payment (in LINK) tokens to the fulfiller of the request. Builds the new request that is sent using the _sendChainlinkRequestTo_ function from the _ChainlinkClient.sol_ import
+ - _fulfill_: callback used by the Oracle node to fulfill the request by storing the queried information in the contract
+
+```solidity
+pragma solidity 0.6.6;
+
+import "https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.6/ChainlinkClient.sol";
+/**
+ * @title Client based in ChainlinkClient
+ * @notice End users can deploy this contract to request the Prices from an Oracle
+ */
+contract Client is ChainlinkClient {
+ //... there is mode code here
+
+ // Deploy with the address of the LINK token
+ constructor(address _link) public {
+ // Set the address for the LINK token for the network
+ setChainlinkToken(_link);
+ owner = msg.sender;
+ }
+
+ // Creates Chainlink Request
+ function requestPrice(address _oracle, string memory _jobId, uint256 _payment)
+ public
+ onlyOwner
+ {
+ // newRequest takes a JobID, a callback address, and callback function as input
+ Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), address(this), this.fulfill.selector);
+ // Sends the request with the amount of payment specified to the oracle
+ sendChainlinkRequestTo(_oracle, req, _payment);
+ }
+
+ // Callback function called by the Oracle when it has resolved the request
+ function fulfill(bytes32 _requestId, uint256 _price)
+ public
+ recordChainlinkFulfillment(_requestId)
+ {
+ currentPrice = _price;
+ }
+
+ //... there is more code here
+```
+
+Note that the Client contract must have a LINK tokens balance to be able to pay for this request. However, if you deploy your setup, you can set the LINK value to 0 in your `ChainlinkClient.sol` contract, but you still need to have the LINK token contract deployed.
+
+### Try it on Pangolin
+
+If you want to skip the hurdles of deploying all contracts, setting up your Oracle node, creating job IDs, and so on, we've got you covered.
+
+A custom Client contract on Pangolin that makes all requests to our Oracle contract, with a 0 LINK token payment, is available. These requests are fulfilled by an Oracle node that we are running. You can try it out with the following interface contract and the custom Client contract deployed at `0xab8eC6D46717a2CC91f4394F253a52E9719e308f`:
+
+```solidity
+pragma solidity 0.6.6;
+
+/**
+ * @title Simple Interface to interact with Universal Client Contract
+ * @notice Client Address 0xab8eC6D46717a2CC91f4394F253a52E9719e308f
+ */
+interface ChainlinkInterface {
+
+ /**
+ * @notice Creates a Chainlink request with the job specification ID,
+ * @notice and sends it to the Oracle.
+ * @param _oracle The address of the Oracle contract fixed top
+ * @param _jobId The job spec ID that we want to call in string format
+ * @param _payment For this example the PAYMENT is set to zero
+ */
+ function requestPrice(address _oracle, string calldata _jobId, uint256 _payment) external;
+
+ function currentPrice() external view returns (uint);
+
+}
+```
+
+This provides two functions. `requestPrice()` needs the job ID of the data you want to query. This function starts the chain of events explained before. `currentPrice()` is a view function that returns the latest price stored in the contract.
+
+Currently, the Oracle node has a set of Job IDs for different price datas for the following pairs:
+
+| Base/Quote | | Job ID Reference |
+| :----------: | --- | :-----------------------------------------------: |
+| RING to USD | | 4cda609794884c58a8690d402e80bfea |
+| BTC to USD | | 66f0d2a59b82482799bee1e714d94991 |
+| ETH to USD | | 8f032a4cf422438b835f243b96ecfc7a |
+| DOT to USD | | fd5e3c79e83344d5a6c3de75501a4c54 |
+| KSM to USD | | dd3a14692e68435da5b28b8716d06423 |
+| AAVE to USD | | 764e831e1d30420ca52aab23c6489319 |
+| ALGO to USD | | 5fa0cb97996f4e5cbe5954c09c3544b3 |
+| BAND to USD | | b494823291974e50bc5d8c6466a18b38 |
+| LINK to USD | | bf322091c7d44d418761754d367534d4 |
+| SUSHI to USD | | 5e47777ecc664801a64bd4b23c5e912c |
+| UNI to USD | | ea3111fdc33e4a9c9af8dd0ede87b279 |
+
+Let's go ahead and use the interface contract with the `BTC to USD` Job ID in [Remix](/builders/tools/remix/).
+
+After creating the file and compiling the contract, head to the "Deploy and Run Transactions" tab, enter the Client contract address, and click on "At Address." Make sure you have set the "Environment" to "Injected Web3" so you are connected to Pangolin. This will create an instance of the Client contract that you can interact with. Use the function `requestPrice()` to query the data of the corresponding Job ID. Once the transaction is confirmed, we have to wait until the whole process explained before occurs. We can check the price using the view function `currentPrice()`.
+
+
+
+If there is any specific pair you want us to include, feel free to reach out to us through our [Telegram](https://t.me/DarwiniaDev).
+
+### Run your Client Contract
+
+If you want to run your Client contract but use our Oracle node, you can do so with the following information:
+
+| Contract Type | | Address |
+| :-------------: | --- | :-----------------------------------------------: |
+| Oracle Contract | | 0x97C02719aEf6B70f0abDa6402f9Bb136aFF7043d |
+| LINK Token | | 0xbE872fFa86274E9717884394f088C02EE929c18d |
+
+Remember that the LINK token payment is set to zero.
+
+### Other Requests
+
+Chainlink's Oracles can tentatively provide many different types of data feeds with the use of external adapters. However, for simplicity, our Oracle node is configured to deliver only price feeds.
+
+If you are interested in running your own Oracle node in Pangolin, please visit [this guide](https://docs.chain.link/docs/running-a-chainlink-node/). Also, we recommend going through [Chainlink's documentation site](https://docs.chain.link/docs).
+
diff --git a/docs/builders/interact/_category_.json b/docs/builders/interact/_category_.json
new file mode 100644
index 00000000..20862461
--- /dev/null
+++ b/docs/builders/interact/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Interact",
+ "position": 2
+}
diff --git a/docs/dvm-rpc.md b/docs/builders/interact/dvm-rpc.md
similarity index 98%
rename from docs/dvm-rpc.md
rename to docs/builders/interact/dvm-rpc.md
index 748160ae..84b8ef11 100644
--- a/docs/dvm-rpc.md
+++ b/docs/builders/interact/dvm-rpc.md
@@ -2,6 +2,7 @@
id: dvm-rpc
title: DVM RPC list
sidebar_label: DVM RPC list
+sidebar_position: 0
---
> Note: The currently implemented RPC apis is compatible with Ethereum, but some apis are not yet implemented.
diff --git a/docs/builders/interact/eth-libraries/_category_.json b/docs/builders/interact/eth-libraries/_category_.json
new file mode 100644
index 00000000..8aa3dd71
--- /dev/null
+++ b/docs/builders/interact/eth-libraries/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Eth Libraries",
+ "position": 1
+}
diff --git a/docs/builders/interact/eth-libraries/deploy-contract.mdx b/docs/builders/interact/eth-libraries/deploy-contract.mdx
new file mode 100644
index 00000000..7ac3d009
--- /dev/null
+++ b/docs/builders/interact/eth-libraries/deploy-contract.mdx
@@ -0,0 +1,1264 @@
+---
+title: Deploy a Contract
+sidebar_position: 2
+description: Learn how to deploy unmodified and unchanged Solidity-based smart contracts to a Darwinia node with a simple script using Web3.js, Ethers.js, or Web3.py.
+---
+
+# Using Ethereum Libraries to Deploy To Pangolin
+
+## Introduction
+
+This guide walks through using the Solidity compiler and three different Ethereum libraries to deploy a contract to Pangolin manually. The three libraries covered by this tutorial are:
+
+ - [Web3.js](/builders/tools/eth-libraries/web3js)
+ - [Ethers.js](/builders/tools/eth-libraries/etherjs)
+ - [Web3.py](/builders/tools/eth-libraries/web3py)
+
+:::note
+If you would like to find the simplest way to get started, check out the quick start guide for each library by clicking the links above
+:::
+
+Besides, two other libraries will be used to compile the smart contract:
+
+ - [Solc-js](https://www.npmjs.com/package/solc) to compile Solidity smart contracts using JavaScript
+ - [Py-solc-x](https://pypi.org/project/py-solc-x/) to compile Solidity smart contracts using Python
+
+## Checking Prerequisites
+
+The examples using both web3.js and ethers.js need you to install Node.js and NPM previously. For the web3.py, you need Python and PIP. As of the writing of this guide, the versions used were:
+
+ - Node.js v16.0.0
+ - NPM v7.10.0
+ - Python v3.6.9 (web3 requires Python >= 3.5.3 and < 4)
+ - PIP3 v9.0.1
+
+:::note
+The examples in this guide assumes you have a MacOS or Ubuntu 18.04-based environment and will need to be adapted accordingly for Windows.
+:::
+
+Next, create a directory to store all of the relevant files:
+
+```
+mkdir incrementer && cd incrementer/
+```
+
+For the JavaScript libraries, first, you can create a simple `package.json` file (not required):
+
+```
+npm init --yes
+```
+
+In the directory, install the corresponding library and the Solidity compiler (_web3.py_ and _py-solc-x_ are installed in the default directory of PIP3):
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+
+
+```
+npm i web3 solc@0.8.0
+```
+
+
+
+
+```
+npm i ethers solc@0.8.0
+```
+
+
+
+
+```
+pip3 install web3 py-solc-x
+```
+
+
+
+
+The versions used when this guide was published were
+
+ - Web3.js v1.5.2 (`npm ls web3`)
+ - Ethers.js v5.4.7 (`npm ls ethers`)
+ - Web3.py v5.23.1 (`pip3 show web3`)
+ - Solc (JS) v0.8.0 (`npm ls solc`)
+ - Py-solc-x v1.1.0 (`pip3 show py-solc-x`)
+
+The setup for this example will be relatively simple, and it'll contain the following files:
+
+ - **_Incrementer.sol_** — the file with our Solidity code
+ - **_compile.\*_** — compiles the contract with the Solidity compiler
+ - **_deploy.\*_**: it will handle the deployment to our local Pangolin node
+ - **_get.\*_** — it will make a call to the node to get the current value of the number
+ - **_increment.\*_** — it will make a transaction to increment the number stored on the Pangolin node
+ - **_reset.\*_** — the function to call that will reset the number stored to zero
+
+## The Contract File
+
+The contract used is a simple incrementer, arbitrarily named _Incrementer.sol_, which you can find [here](/snippets/code/web3-contract-local/Incrementer.sol). The Solidity code is the following:
+
+```solidity
+pragma solidity ^0.8.0;
+
+contract Incrementer {
+ uint256 public number;
+
+ constructor(uint256 _initialNumber) {
+ number = _initialNumber;
+ }
+
+ function increment(uint256 _value) public {
+ number = number + _value;
+ }
+
+ function reset() public {
+ number = 0;
+ }
+}
+```
+
+The `constructor` function, which runs when the contract is deployed, sets the initial value of the number variable stored on-chain (default is 0). The `increment` function adds the `_value` provided to the current number, but a transaction needs to be sent, which modifies the stored data. Lastly, the `reset` function resets the stored value to zero.
+
+:::note
+This contract is a simple example for illustration purposes only and does not handle values wrapping around.
+:::
+
+## Compiling the Contract
+
+The only purpose of the compile file is to use the Solidity compiler to output the bytecode and interface (ABI) our contract. You can find the code snippet for each library here (they were arbitrarily named `compile.*`):
+
+ - Web3.js: [_compile.js_](/snippets/code/web3-contract-local/compile.js)
+ - Ethers.js: [_compile.js_](/snippets/code/web3-contract-local/compile.js)
+ - Web3.py: [_compile.py_](/snippets/code/web3py-contract/compile.py)
+
+:::note
+The compile file for both JavaScript libraries is the same as they share the JavaScript bindings for the Solidity compiler (same package)
+:::
+
+import CodeBlock from '@theme/CodeBlock';
+import web3CompileSource from '!!raw-loader!/snippets/code/web3-contract-local/compile.js';
+
+
+
+ {web3CompileSource}
+
+
+ {web3CompileSource}
+
+
+
+```python
+import solcx
+
+# If you haven't already installed the Solidity compiler, uncomment the following line
+# solcx.install_solc()
+
+# Compile contract
+temp_file = solcx.compile_files('Incrementer.sol')
+
+# Export contract data
+abi = temp_file['Incrementer.sol:Incrementer']['abi']
+bytecode = temp_file['Incrementer.sol:Incrementer']['bin']
+```
+
+
+
+
+### Web3.js and Ethers.js
+
+In the first part of [the script](/snippets/code/web3-contract-local/compile.js), the contract's path is fetched, and its content read.
+
+Next, the Solidity compiler's input object is built, and it is passed as input to the `solc.compile` function.
+
+Lastly, extract the data of the `Incrementer` contract of the `Incrementer.sol` file, and export it so that the deployment script can use it.
+
+### Web3.py
+
+In the first part of [the script](/snippets/code/web3py-contract/compile.py), the contract file is compiled using the `solcx.compile_files` function. Note that the contract file is in the same directory as the compile script.
+
+:::note
+When running the `compile.py` you might be get an error stating that `Solc` needs to be installed. If so, uncomment the line in the file that executes `solcx.install_solc()` and rerun the compile file again with `python3 compile.py`. More information can be found in [this link](https://pypi.org/project/py-solc-x/).
+:::
+
+Next, and wrapping up the script, the contract data is exported. In this example, only the interface (ABI) and bytecode were defined.
+
+## Deploying the Contract
+
+Regardless of the library, the strategy to deploy the compiled smart contract is somewhat similar. A contract instance is created using its interface (ABI) and bytecode. From this instance, a deployment function is used to send a signed transaction that deploys the contract. You can find the code snippet for each library here (they were arbitrarily named `deploy.*`):
+
+ - Web3.js: [_deploy.js_](/snippets/code/web3-contract-local/deploy.js)
+ - Ethers.js: [_deploy.js_](/snippets/code/ethers-contract-local/deploy.js)
+ - Web3.py: [_deploy.py_](/snippets/code/web3py-contract/deploy.py)
+
+For simplicity, the deploy file is composed of two sections. In the first section ("Define Provider & Variables"), the library to use and the ABI and bytecode of the contract are imported. Also, the provider and account from (with the private key) are defined. Note that `providerRPC` has three the standard node RPC endpoint, the one for development, the one for [Pangolin](/builders/get-started/darwinia-pangolin.md) and another one for [Crab](/builders/get-started/darwinia-crab.md).
+
+The second section ("Deploy Contract") outlines the actual contract deployment part. Note that for this example, the initial value of the `number` variable was set to 5. Some of the key takeaways are discussed next.
+
+
+
+
+```js
+const Web3 = require('web3');
+const contractFile = require('./compile');
+
+/*
+ -- Define Provider & Variables --
+*/
+// Provider
+const providerRPC = {
+ development: 'http://localhost:9933',
+ pangolin: 'http://pangolin-rpc.darwinia.network',
+ crab: 'http://crab-rpc.darwinia.network',
+};
+const web3 = new Web3(providerRPC.development); //Change to correct network
+
+// Variables
+const account_from = {
+ privateKey: 'YOUR-PRIVATE-KEY-HERE',
+ address: 'PUBLIC-ADDRESS-OF-PK-HERE',
+};
+const bytecode = contractFile.evm.bytecode.object;
+const abi = contractFile.abi;
+
+/*
+ -- Deploy Contract --
+*/
+const deploy = async () => {
+ console.log(`Attempting to deploy from account ${account_from.address}`);
+
+ // Create Contract Instance
+ const incrementer = new web3.eth.Contract(abi);
+
+ // Create Constructor Tx
+ const incrementerTx = incrementer.deploy({
+ data: bytecode,
+ arguments: [5],
+ });
+
+ // Sign Transacation and Send
+ const createTransaction = await web3.eth.accounts.signTransaction(
+ {
+ data: incrementerTx.encodeABI(),
+ gas: await incrementerTx.estimateGas(),
+ },
+ account_from.privateKey
+ );
+
+ // Send Tx and Wait for Receipt
+ const createReceipt = await web3.eth.sendSignedTransaction(
+ createTransaction.rawTransaction
+ );
+ console.log(
+ `Contract deployed at address: ${createReceipt.contractAddress}`
+ );
+};
+
+deploy();
+```
+
+
+
+
+```js
+const ethers = require('ethers');
+const contractFile = require('./compile');
+
+/*
+ -- Define Provider & Variables --
+*/
+// Provider
+const providerRPC = {
+ development: {
+ name: 'development',
+ rpc: 'http://localhost:9933',
+ chainId: 43,
+ },
+ pangolin: {
+ name: 'pangolin',
+ rpc: 'http://pangolin-rpc.darwinia.network',
+ chainId: 43,
+ },
+ crab: {
+ name: 'crab',
+ rpc: 'http://crab-rpc.darwinia.network',
+ chainId: 44,
+ },
+};
+const provider = new ethers.providers.StaticJsonRpcProvider(
+ providerRPC.development.rpc,
+ {
+ chainId: providerRPC.development.chainId,
+ name: providerRPC.development.name,
+ }
+); //Change to correct network
+
+// Variables
+const account_from = {
+ privateKey: 'YOUR-PRIVATE-KEY-HERE',
+};
+const bytecode = contractFile.evm.bytecode.object;
+const abi = contractFile.abi;
+
+// Create Wallet
+let wallet = new ethers.Wallet(account_from.privateKey, provider);
+
+/*
+ -- Deploy Contract --
+*/
+// Create Contract Instance with Signer
+const incrementer = new ethers.ContractFactory(abi, bytecode, wallet);
+
+const deploy = async () => {
+ console.log(`Attempting to deploy from account: ${wallet.address}`);
+
+ // Send Tx (Initial Value set to 5) and Wait for Receipt
+ const contract = await incrementer.deploy([5]);
+ await contract.deployed();
+
+ console.log(`Contract deployed at address: ${contract.address}`);
+};
+
+deploy();
+```
+
+
+
+
+```python
+from compile import abi, bytecode
+from web3 import Web3
+
+#
+# -- Define Provider & Variables --
+#
+# Provider
+provider_rpc = {
+ 'development': 'http://localhost:9933',
+ "pangolin": 'http://pangolin-rpc.darwinia.network',
+ "crab": 'http://crab-rpc.darwinia.network',
+}
+web3 = Web3(Web3.HTTPProvider(provider_rpc['development'])) # Change to correct network
+
+# Variables
+account_from = {
+ 'private_key': 'YOUR-PRIVATE-KEY-HERE',
+ 'address': Web3.toChecksumAddress('PUBLIC-ADDRESS-OF-PK-HERE'),
+}
+
+#
+# -- Deploy Contract --
+#
+print(f'Attempting to deploy from account: { account_from["address"] }')
+
+# Create Contract Instance
+Incrementer = web3.eth.contract(abi=abi, bytecode=bytecode)
+
+# Build Constructor Tx
+construct_txn = Incrementer.constructor(5).buildTransaction(
+ {
+ 'from': account_from['address'],
+ 'nonce': web3.eth.getTransactionCount(account_from['address']),
+ }
+)
+
+# Sign Tx with PK
+tx_create = web3.eth.account.signTransaction(construct_txn, account_from['private_key'])
+
+# Send Tx and Wait for Receipt
+tx_hash = web3.eth.sendRawTransaction(tx_create.rawTransaction)
+tx_receipt = web3.eth.waitForTransactionReceipt(tx_hash)
+
+print(f'Contract deployed at address: { tx_receipt.contractAddress }')
+```
+
+
+
+
+:::note
+The _deploy.\*_ script provides the contract address as an output. This comes in handy, as it is used for the contract interaction files.
+:::
+
+### Web3.js
+
+In the first part of [the script](/snippets/code/web3-contract-local/deploy.js), the `web3` instance (or provider) is created using the `Web3` constructor with the provider RPC. By changing the provider RPC given to the constructor, you can choose which network you want to send the transaction to.
+
+The private key, and the public address associated with it, are defined for signing the transaction and logging purposes. Only the private key is required. Also, the contract's bytecode and interface (ABI) are fetched from the compile's export.
+
+In the second section, a contract instance is created by providing the ABI. Next, the `deploy` function is used, which needs the bytecode and arguments of the constructor function. This will generate the constructor transaction object.
+
+Afterwards, the constructor transaction can be signed using the `web3.eth.accounts.signTransaction()` method. The data field corresponds to the bytecode, and the constructor input arguments are encoded together. Note that the value of gas is obtained using `estimateGas()` option inside the constructor transaction.
+
+Lastly, the signed transaction is sent, and the contract's address is displayed in the terminal.
+
+### Ethers.js
+
+In the first part of [the script](/snippets/code/ethers-contract-local/deploy.js), different networks can be specified with a name, RPC URL (required), and chain ID. The provider (similar to the `web3` instance) is created with the `ethers.providers.StaticJsonRpcProvider` method. An alternative is to use the `ethers.providers.JsonRpcProvide(providerRPC)` method, which only requires the provider RPC endpoint address. But this might created compatibility issues with individual project specifications.
+
+The private key is defined to create a wallet instance, which also requires the provider from the previous step. The wallet instance is used to sign transactions. Also, the contract's bytecode and interface (ABI) are fetched from the compile's export.
+
+In the second section, a contract instance is created with `ethers.ContractFactory()`, providing the ABI, bytecode, and wallet. Thus, the contract instance already has a signer. Next, the `deploy` function is used, which needs the constructor input arguments. This will send the transaction for contract deployment. To wait for a transaction receipt you can use the `deployed()` method of the contract deployment transaction.
+
+Lastly, the contract's address is displayed in the terminal.
+
+### Web3.py
+
+In the first part of [the script](/snippets/code/web3py-contract/deploy.py), the `web3` instance (or provider) is created using the `Web3(Web3.HTTPProvider(provider_rpc))` method with the provider RPC. By changing the provider RPC, you can choose which network you want to send the transaction to.
+
+The private key and the public address associated with it are defined for signing the transaction and establishing the from address.
+
+In the second section, a contract instance is created with `web3.eth.contract()`, providing the ABI and bytecode imported from the compile file. Next, the constructor transaction can be built using the `constructor().buildTransaction()` method of the contract instance. Note that inside the `constructor()`, you need to specify the constructor input arguments. The `from` account needs to be outlined as well. Make sure to use the one associated with the private key. Also, the transaction count can be obtained with the `web3.eth.getTransactionCount(address)` method.
+
+The constructor transaction can be signed using `web3.eth.account.signTransaction()`, passing the constructor transaction and the private key.
+
+Lastly, the signed transaction is sent, and the contract's address is displayed in the terminal.
+
+## Reading from the Contract (Call Methods)
+
+Call methods are the type of interaction that don't modify the contract's storage (change variables), meaning no transaction needs to be sent.
+
+Let's overview the _get.\*_ file (the simplest of them all), which fetches the current value stored in the contract. You can find the code snippet for each library here (they were arbitrarily named `get.*`):
+
+ - Web3.js: [_get.js_](/snippets/code/web3-contract-local/get.js)
+ - Ethers.js: [_get.js_](/snippets/code/ethers-contract-local/get.js)
+ - Web3.py: [_get.py_](/snippets/code/web3py-contract/get.py)
+
+For simplicity, the get file is composed of two sections. In the first section ("Define Provider & Variables"), the library to use and the ABI of the contract are imported. Also, the provider and the contract's address are defined. Note that `providerRPC` has three the standard node RPC endpoint, the one for development, the one for [Pangolin](/builders/get-started/darwinia-pangolin.md) and another one for [Crab](/builders/get-started/darwinia-crab.md).
+
+The second section ("Call Function") outlines the actual call to the contract. Regardless of the library, a contract instance is created (linked to the contract's address), from which the call method is queried. Some of the key takeaways are discussed next.
+
+
+
+
+```js
+const Web3 = require('web3');
+const { abi } = require('./compile');
+
+/*
+ -- Define Provider & Variables --
+*/
+// Provider
+const providerRPC = {
+ development: 'http://localhost:9933',
+ pangolin: 'http://pangolin-rpc.darwinia.network',
+ crab: 'http://crab-rpc.darwinia.network',
+};
+const web3 = new Web3(providerRPC.development); //Change to correct network
+
+// Variables
+const contractAddress = 'CONTRACT-ADDRESS-HERE';
+
+/*
+ -- Call Function --
+*/
+// Create Contract Instance
+const incrementer = new web3.eth.Contract(abi, contractAddress);
+
+const get = async () => {
+ console.log(`Making a call to contract at address: ${contractAddress}`);
+
+ // Call Contract
+ const data = await incrementer.methods.number().call();
+
+ console.log(`The current number stored is: ${data}`);
+};
+
+get();
+```
+
+
+
+
+```js
+const ethers = require('ethers');
+const { abi } = require('./compile');
+
+/*
+ -- Define Provider & Variables --
+*/
+// Provider
+const providerRPC = {
+ development: {
+ name: 'development',
+ rpc: 'http://localhost:9933',
+ chainId: 43,
+ },
+ pangolin: {
+ name: 'pangolin',
+ rpc: 'http://pangolin-rpc.darwinia.network',
+ chainId: 43,
+ },
+ crab: {
+ name: 'crab',
+ rpc: 'http://crab-rpc.darwinia.network',
+ chainId: 44,
+ },
+};
+const provider = new ethers.providers.StaticJsonRpcProvider(
+ providerRPC.development.rpc,
+ {
+ chainId: providerRPC.development.chainId,
+ name: providerRPC.development.name,
+ }
+); //Change to correct network
+
+// Variables
+const contractAddress = 'CONTRACT-ADDRESS-HERE';
+
+/*
+ -- Call Function --
+*/
+// Create Contract Instance
+const incrementer = new ethers.Contract(contractAddress, abi, provider);
+
+const get = async () => {
+ console.log(`Making a call to contract at address: ${contractAddress}`);
+
+ // Call Contract
+ const data = await incrementer.number();
+
+ console.log(`The current number stored is: ${data}`);
+};
+
+get();
+```
+
+
+
+
+```python
+from compile import abi, bytecode
+from web3 import Web3
+
+#
+# -- Define Provider & Variables --
+#
+# Provider
+provider_rpc = {
+ 'development': 'http://localhost:9933',
+ "pangolin": 'http://pangolin-rpc.darwinia.network',
+ "crab": 'http://crab-rpc.darwinia.network',
+}
+web3 = Web3(Web3.HTTPProvider(provider_rpc["development"])) # Change to correct network
+
+# Variables
+contract_address = 'CONTRACT-ADDRESS-HERE'
+
+#
+# -- Call Function --
+#
+print(f'Making a call to contract at address: { contract_address }')
+
+# Create Contract Instance
+Incrementer = web3.eth.contract(address=contract_address, abi=abi)
+
+# Call Contract
+number = Incrementer.functions.number().call()
+
+print(f'The current number stored is: { number } ')
+```
+
+
+
+
+### Web3.js
+
+In the first part of [the script](/snippets/code/web3-contract-local/get.js), the `web3` instance (or provider) is created using the `Web3` constructor with the provider RPC. By changing the provider RPC given to the constructor, you can choose which network you want to send the transaction to.
+
+The contract's interface (ABI) and address are needed as well to interact with it.
+
+In the second section, a contract instance is created with `web3.eth.Contract()` by providing the ABI and address. Next, the method to call can be queried with the `contract.methods.methodName(_input).call()` function, replacing `contract`, `methodName` and `_input` with the contract instance, function to call, and input of the function (if necessary). This promise, when resolved, will return the value requested.
+
+Lastly, the value is displayed in the terminal.
+
+### Ethers.js
+
+In the first part of [the script](/snippets/code/ethers-contract-local/get.js), different networks can be specified with a name, RPC URL (required), and chain ID. The provider (similar to the `web3` instance) is created with the `ethers.providers.StaticJsonRpcProvider` method. An alternative is to use the `ethers.providers.JsonRpcProvide(providerRPC)` method, which only requires the provider RPC endpoint address. But this might created compatibility issues with individual project specifications.
+
+The contract's interface (ABI) and address are needed as well to interact with it.
+
+In the second section, a contract instance is created with `ethers.Contract()`, providing its address, ABI, and the provider. Next, the method to call can be queried with the `contract.methodName(_input)` function, replacing `contract` `methodName`, and `_input` with the contract instance, function to call, and input of the function (if necessary). This promise, when resolved, will return the value requested.
+
+Lastly, the value is displayed in the terminal.
+
+### Web3.py
+
+In the first part of [the script](/snippets/code/web3py-contract/get.py), the `web3` instance (or provider) is created using the `Web3(Web3.HTTPProvider(provider_rpc))` method with the provider RPC. By changing the provider RPC, you can choose which network you want to send the transaction to.
+
+The contract's interface (ABI) and address are needed as well to interact with it.
+
+In the second section, a contract instance is created with `web3.eth.contract()` by providing the ABI and address. Next, the method to call can be queried with the `contract.functions.method_name(input).call()` function, replacing `contract`, `method_name` and `input` with the contract instance, function to call, and input of the function (if necessary). This returns the value requested.
+
+Lastly, the value is displayed in the terminal.
+
+## Interacting with the Contract (Send Methods)
+
+Send methods are the type of interaction that modify the contract's storage (change variables), meaning a transaction needs to be signed and sent.
+
+First, let's overview the _increment.\*_ file, which increments the current number stored in the contract by a given value. You can find the code snippet for each library here (they were arbitrarily named `increment.*`):
+
+ - Web3.js: [_increment.js_](/snippets/code/web3-contract-local/increment.js)
+ - Ethers.js: [_increment.js_](/snippets/code/ethers-contract-local/increment.js)
+ - Web3.py: [_increment.py_](/snippets/code/web3py-contract/increment.py)
+
+For simplicity, the increment file is composed of two sections. In the first section ("Define Provider & Variables"), the library to use and the ABI of the contract are imported. The provider, the contract's address, and the value of the `increment` function are also defined. Note that `providerRPC` has three the standard node RPC endpoint, the one for development, the one for [Pangolin](/builders/get-started/darwinia-pangolin.md) and another one for [Crab](/builders/get-started/darwinia-crab.md).
+
+The second section ("Send Function") outlines the actual function to be called with the transaction. Regardless of the library, a contract instance is created (linked to the contract's address), from which the function to be used is queried.
+
+
+
+
+```js
+const Web3 = require('web3');
+const { abi } = require('./compile');
+
+/*
+ -- Define Provider & Variables --
+*/
+// Provider
+const providerRPC = {
+ development: 'http://localhost:9933',
+ pangolin: 'http://pangolin-rpc.darwinia.network',
+ crab: 'http://crab-rpc.darwinia.network',
+};
+const web3 = new Web3(providerRPC.development); //Change to correct network
+
+// Variables
+const account_from = {
+ privateKey: 'YOUR-PRIVATE-KEY-HERE',
+};
+const contractAddress = 'CONTRACT-ADDRESS-HERE';
+const _value = 3;
+
+/*
+ -- Send Function --
+*/
+// Create Contract Instance
+const incrementer = new web3.eth.Contract(abi, contractAddress);
+
+// Build Increment Tx
+const incrementTx = incrementer.methods.increment(_value);
+
+const increment = async () => {
+ console.log(
+ `Calling the increment by ${_value} function in contract at address: ${contractAddress}`
+ );
+
+ // Sign Tx with PK
+ const createTransaction = await web3.eth.accounts.signTransaction(
+ {
+ to: contractAddress,
+ data: incrementTx.encodeABI(),
+ gas: await incrementTx.estimateGas(),
+ },
+ account_from.privateKey
+ );
+
+ // Send Tx and Wait for Receipt
+ const createReceipt = await web3.eth.sendSignedTransaction(
+ createTransaction.rawTransaction
+ );
+ console.log(`Tx successful with hash: ${createReceipt.transactionHash}`);
+};
+
+increment();
+```
+
+
+
+
+```js
+const ethers = require('ethers');
+const { abi } = require('./compile');
+
+/*
+ -- Define Provider & Variables --
+*/
+// Provider
+const providerRPC = {
+ development: {
+ name: 'development',
+ rpc: 'http://localhost:9933',
+ chainId: 43,
+ },
+ pangolin: {
+ name: 'pangolin',
+ rpc: 'http://pangolin-rpc.darwinia.network',
+ chainId: 43,
+ },
+ crab: {
+ name: 'crab',
+ rpc: 'http://crab-rpc.darwinia.network',
+ chainId: 44,
+ },
+};
+const provider = new ethers.providers.StaticJsonRpcProvider(
+ providerRPC.development.rpc,
+ {
+ chainId: providerRPC.development.chainId,
+ name: providerRPC.development.name,
+ }
+); //Change to correct network
+
+// Variables
+const account_from = {
+ privateKey: 'YOUR-PRIVATE-KEY-HERE',
+};
+const contractAddress = 'CONTRACT-ADDRESS-HERE';
+const _value = 3;
+
+// Create Wallet
+let wallet = new ethers.Wallet(account_from.privateKey, provider);
+
+/*
+ -- Send Function --
+*/
+// Create Contract Instance with Signer
+const incrementer = new ethers.Contract(contractAddress, abi, wallet);
+const increment = async () => {
+ console.log(
+ `Calling the increment by ${_value} function in contract at address: ${contractAddress}`
+ );
+
+ // Sign-Send Tx and Wait for Receipt
+ const createReceipt = await incrementer.increment([_value]);
+ await createReceipt.wait();
+
+ console.log(`Tx successful with hash: ${createReceipt.hash}`);
+};
+
+increment();
+```
+
+
+
+
+```python
+from compile import abi, bytecode
+from web3 import Web3
+
+#
+# -- Define Provider & Variables --
+#
+# Provider
+provider_rpc = {
+ 'development': 'http://localhost:9933',
+ "pangolin": 'http://pangolin-rpc.darwinia.network',
+ "crab": 'http://crab-rpc.darwinia.network',
+}
+web3 = Web3(Web3.HTTPProvider(provider_rpc["development"])) # Change to correct network
+
+# Variables
+account_from = {
+ 'private_key': 'YOUR-PRIVATE-KEY-HERE',
+ 'address': 'PUBLIC-ADDRESS-OF-PK-HERE',
+}
+contract_address = 'CONTRACT-ADDRESS-HERE'
+value = 3
+
+#
+# -- Send Function --
+#
+print(
+ f'Calling the increment by { value } function in contract at address: { contract_address }'
+)
+
+# Create Contract Instance
+Incrementer = web3.eth.contract(address=contract_address, abi=abi)
+
+# Build Increment Tx
+increment_tx = Incrementer.functions.increment(value).buildTransaction(
+ {
+ 'from': account_from['address'],
+ 'nonce': web3.eth.getTransactionCount(account_from['address']),
+ }
+)
+
+# Sign Tx with PK
+tx_create = web3.eth.account.signTransaction(increment_tx, account_from['private_key'])
+
+# Send Tx and Wait for Receipt
+tx_hash = web3.eth.sendRawTransaction(tx_create.rawTransaction)
+tx_receipt = web3.eth.waitForTransactionReceipt(tx_hash)
+
+print(f'Tx successful with hash: { tx_receipt.transactionHash.hex() }')
+```
+
+
+
+
+The second file to interact with the contract is the _reset.\*_ file, which resets the number stored in the contract to zero. You can find the code snippet for each library here (they were arbitrarily named `reset.*`):
+
+ - Web3.js: [_reset.js_](/snippets/code/web3-contract-local/reset.js)
+ - Ethers.js: [_reset.js_](/snippets/code/ethers-contract-local/reset.js)
+ - Web3.py: [_reset.py_](/snippets/code/web3py-contract/reset.py)
+
+Each file's structure is very similar to his _increment.\*_ counterpart for each library. The main difference is the method being called.
+
+
+
+
+```js
+const Web3 = require('web3');
+const { abi } = require('./compile');
+
+/*
+ -- Define Provider & Variables --
+*/
+// Provider
+const providerRPC = {
+ development: 'http://localhost:9933',
+ pangolin: 'http://pangolin-rpc.darwinia.network',
+ crab: 'http://crab-rpc.darwinia.network',
+};
+const web3 = new Web3(providerRPC.development); //Change to correct network
+
+// Variables
+const account_from = {
+ privateKey: 'YOUR-PRIVATE-KEY-HERE',
+};
+const contractAddress = 'CONTRACT-ADDRESS-HERE';
+
+/*
+ -- Send Function --
+*/
+// Create Contract Instance
+const incrementer = new web3.eth.Contract(abi, contractAddress);
+
+// Build Reset Tx
+const resetTx = incrementer.methods.reset();
+
+const reset = async () => {
+ console.log(
+ `Calling the reset function in contract at address: ${contractAddress}`
+ );
+
+ // Sign Tx with PK
+ const createTransaction = await web3.eth.accounts.signTransaction(
+ {
+ to: contractAddress,
+ data: resetTx.encodeABI(),
+ gas: await resetTx.estimateGas(),
+ },
+ account_from.privateKey
+ );
+
+ // Send Tx and Wait for Receipt
+ const createReceipt = await web3.eth.sendSignedTransaction(
+ createTransaction.rawTransaction
+ );
+ console.log(`Tx successful with hash: ${createReceipt.transactionHash}`);
+};
+
+reset();
+```
+
+
+
+
+```js
+const ethers = require('ethers');
+const { abi } = require('./compile');
+
+/*
+ -- Define Provider & Variables --
+*/
+// Provider
+const providerRPC = {
+ development: {
+ name: 'development',
+ rpc: 'http://localhost:9933',
+ chainId: 43,
+ },
+ pangolin: {
+ name: 'pangolin',
+ rpc: 'http://pangolin-rpc.darwinia.network',
+ chainId: 43,
+ },
+ crab: {
+ name: 'crab',
+ rpc: 'http://crab-rpc.darwinia.network',
+ chainId: 44,
+ },
+};
+const provider = new ethers.providers.StaticJsonRpcProvider(
+ providerRPC.development.rpc,
+ {
+ chainId: providerRPC.development.chainId,
+ name: providerRPC.development.name,
+ }
+); //Change to correct network
+
+// Variables
+const account_from = {
+ privateKey: 'YOUR-PRIVATE-KEY-HERE',
+};
+const contractAddress = 'CONTRACT-ADDRESS-HERE';
+
+// Create Wallet
+let wallet = new ethers.Wallet(account_from.privateKey, provider);
+
+/*
+ -- Send Function --
+*/
+// Create Contract Instance with Signer
+const incrementer = new ethers.Contract(contractAddress, abi, wallet);
+const reset = async () => {
+ console.log(
+ `Calling the reset function in contract at address: ${contractAddress}`
+ );
+
+ // Sign-Send Tx and Wait for Receipt
+ const createReceipt = await incrementer.reset();
+ await createReceipt.wait();
+
+ console.log(`Tx successful with hash: ${createReceipt.hash}`);
+};
+
+reset();
+```
+
+
+
+
+```python
+from compile import abi, bytecode
+from web3 import Web3
+
+#
+# -- Define Provider & Variables --
+#
+# Provider
+provider_rpc = {
+ 'development': 'http://localhost:9933',
+ "pangolin": 'http://pangolin-rpc.darwinia.network',
+ "crab": 'http://crab-rpc.darwinia.network',
+}
+web3 = Web3(Web3.HTTPProvider(provider_rpc["development"])) # Change to correct network
+
+# Variables
+account_from = {
+ 'private_key': 'YOUR-PRIVATE-KEY-HERE',
+ 'address': 'PUBLIC-ADDRESS-OF-PK-HERE',
+}
+contract_address = 'CONTRACT-ADDRESS-HERE'
+
+#
+# -- Call Function --
+#
+print(f'Calling the reset function in contract at address: { contract_address }')
+
+# Create Contract Instance
+Incrementer = web3.eth.contract(address=contract_address, abi=abi)
+
+# Build Reset Tx
+reset_tx = Incrementer.functions.reset().buildTransaction(
+ {
+ 'from': account_from['address'],
+ 'nonce': web3.eth.getTransactionCount(account_from['address']),
+ }
+)
+
+# Sign Tx with PK
+tx_create = web3.eth.account.signTransaction(reset_tx, account_from['private_key'])
+
+# Send Tx and Wait for Receipt
+tx_hash = web3.eth.sendRawTransaction(tx_create.rawTransaction)
+tx_receipt = web3.eth.waitForTransactionReceipt(tx_hash)
+
+print(f'Tx successful with hash: { tx_receipt.transactionHash.hex() }')
+```
+
+
+
+
+### Web3.js
+
+In the first part of the script ([increment](/snippets/code/web3-contract-local/increment.js) or [reset](/snippets/code/web3-contract-local/reset.js) files), the `web3` instance (or provider) is created using the `Web3` constructor with the provider RPC. By changing the provider RPC given to the constructor, you can choose which network you want to send the transaction to.
+
+The private key, and the public address associated with it, are defined for signing the transaction and logging purposes. Only the private key is required. Also, the contract's interface (ABI) and address are needed to interact with it. If necessary, you can define any variable required as input to the function you are going to interact with.
+
+In the second section, a contract instance is created with `web3.eth.Contract()` by providing the ABI and address. Next, you can build the transaction object with the `contract.methods.methodName(_input)` function, replacing `contract`, `methodName` and `_input` with the contract instance, function to call, and input of the function (if necessary).
+
+Afterwards, the transaction can be signed using the `web3.eth.accounts.signTransaction()` method. The data field corresponds to the transaction object from the previous step. Note that the value of gas is obtained using `estimateGas()` option inside the transaction object.
+
+Lastly, the signed transaction is sent, and the transaction hash is displayed in the terminal.
+
+### Ethers.js
+
+In the first part of the script ([increment](/snippets/code/ethers-contract-local/increment.js) or [reset](/snippets/code/ethers-contract-local/reset.js) files), different networks can be specified with a name, RPC URL (required), and chain ID. The provider (similar to the `web3` instance) is created with the `ethers.providers.StaticJsonRpcProvider` method. An alternative is to use the `ethers.providers.JsonRpcProvide(providerRPC)` method, which only requires the provider RPC endpoint address. But this might created compatibility issues with individual project specifications.
+
+The private key is defined to create a wallet instance, which also requires the provider from the previous step. The wallet instance is used to sign transactions. Also, the contract's interface (ABI) and address are needed to interact with it. If necessary, you can define any variable required as input to the function you are going to interact with.
+
+In the second section, a contract instance is created with `ethers.Contract()`, providing its address, ABI, and wallet. Thus, the contract instance already has a signer. Next, transaction corresponding to a specific function can be send with the `contract.methodName(_input)` function, replacing `contract`, `methodName` and `_input` with the contract instance, function to call, and input of the function (if necessary). To wait for a transaction receipt, you can use the `wait()` method of the contract deployment transaction.
+
+Lastly, the transaction hash is displayed in the terminal.
+
+### Web3.py
+
+In the first part of the script ([increment](/snippets/code/web3py-contract/increment.py) or [reset](/snippets/code/web3py-contract/reset.py) files), the `web3` instance (or provider) is created using the `Web3(Web3.HTTPProvider(provider_rpc))` method with the provider RPC. By changing the provider RPC, you can choose which network you want to send the transaction to.
+
+The private key and the public address associated with it are defined for signing the transaction and establishing the from address. Also, the contract's interface (ABI) and address are needed as well to interact with it.
+
+In the second section, a contract instance is created with `web3.eth.contract()` by providing the ABI and address. Next, you can build the transaction object with the `contract.functions.methodName(_input).buildTransaction` function, replacing `contract`, `methodName` and `_input` with the contract instance, function to call, and input of the function (if necessary). Inside `buildTransaction()`, the `from` account needs to be outlined. Make sure to use the one associated with the private key. Also, the transaction count can be obtained with the `web3.eth.getTransactionCount(address)` method.
+
+The transaction can be signed using `web3.eth.account.signTransaction()`, passing the transaction object of the previous step and the private key.
+
+Lastly, the transaction hash is displayed in the terminal.
+
+## Running the Scripts
+
+For this section, the code shown before was adapted to target a development node, which you can run by following [this tutorial](/builders/get-started/darwinia-dev/). Also, each transaction was sent from the pre-funded account that comes with the node:
+
+import DevAccount from '/snippets/text/metamask-local/dev-account.md';
+
+
+
+First, deploy the contract by running (note that the directory was renamed for each library):
+
+
+
+
+```
+node deploy.js
+```
+
+
+
+
+```
+node deploy.js
+```
+
+
+
+
+```
+python3 deploy.py
+```
+
+
+
+
+This will deploy the contract and return the address. Save the address for later use in `get.*`, `increment.*`, and `reset.*` scripts:
+
+
+
+
+
+
+
+
+
+
+
+
+
+Next, run the increment file. You can use the get file to verify the value of the number stored in the contract before and after increment it:
+
+
+
+
+```
+# Get value
+node get.js
+# Increment value
+node increment.js
+# Get value
+node get.js
+```
+
+
+
+
+```
+# Get value
+node get.js
+# Increment value
+node increment.js
+# Get value
+node get.js
+```
+
+
+
+
+```
+# Get value
+python3 get.py
+# Increment value
+python3 increment.py
+# Get value
+python3 get.py
+```
+
+
+
+
+This will display the value before the increment transaction, the hash of the transaction, and the value after:
+
+
+
+
+
+
+
+
+
+
+
+
+
+Lastly, run the reset file. Once again, you can use the get file to verify the value of the number stored in the contract before and after resetting it:
+
+
+
+
+```
+# Get value
+node get.js
+# Reset value
+node reset.js
+# Get value
+node get.js
+```
+
+
+
+
+```
+# Get value
+node get.js
+# Reset value
+node reset.js
+# Get value
+node get.js
+```
+
+
+
+
+```
+# Get value
+python3 get.py
+# Reset value
+python3 reset.py
+# Get value
+python3 get.py
+```
+
+
+
+
+This will display the value before the reset transaction, the hash of the transaction, and the value after:
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/builders/interact/eth-libraries/send-transaction.md b/docs/builders/interact/eth-libraries/send-transaction.md
new file mode 100644
index 00000000..f778d9f8
--- /dev/null
+++ b/docs/builders/interact/eth-libraries/send-transaction.md
@@ -0,0 +1,585 @@
+---
+title: Send a Transaction
+sidebar_position: 1
+description: Learn how to create and send transactions on Pangolin’s Ethereum-compatible network with a simple script using web3.js, ethers.js, or web3.py.
+---
+
+# Send Transactions using Ethereum Libraries on Pangolin
+
+## Introduction
+
+This guide walks through using three different Ethereum libraries to sign and send a transaction on Pangolin manually. The three libraries covered in this tutorial are:
+
+ - [Web3.js](https://web3js.readthedocs.io/)
+ - [Ethers.js](https://docs.ethers.io/)
+ - [Web3.py](https://web3py.readthedocs.io/)
+
+:::note
+The examples in this guide assumes you have a MacOS or Ubuntu 18.04-based environment and will need to be adapted accordingly for Windows.
+:::
+
+## Checking Prerequisites
+
+The examples using both web3.js and ethers.js require the previous installation of Node.js and NPM. The example using web3.py requires Python and PIP. As of the writing of this guide, the versions used were:
+
+ - Node.js v16.0.0
+ - NPM v7.10.0
+ - Python v3.6.9 (web3 requires Python >= 3.5.3 and < 4)
+ - PIP3 v9.0.1
+
+Next, create a directory to store all of the relevant files:
+
+```
+mkdir transaction && cd transaction/
+```
+
+For the JavaScript libraries, you can first create a simple `package.json` file (not required):
+
+```
+npm init --yes
+```
+
+In the directory, install the library to be used (web3.py is installed in the default directory of PIP3):
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+
+
+
+```
+npm i web3
+```
+
+
+
+
+```
+npm i ethers
+```
+
+
+
+
+```
+pip3 install web3
+```
+
+
+
+
+The versions used as of publishing this guide were:
+
+ - Web3.js v1.5.2 (`npm ls web3`)
+ - Ethers.js v5.4.7 (`npm ls ethers`)
+ - Web3.py v5.23.1 (`pip3 show web3`)
+
+## The Transaction File
+
+Only one file is needed to execute a transaction between accounts. The script shown in this section will transfer 1 Token from an origin address (from which you hold the private key), to another address. You can find the code snippet for each library here (they were arbitrarily named `transaction.*`):
+
+ - Web3.js: [_transaction.js_](/snippets/code/web3-tx-local/transaction.js)
+ - Ethers.js: [_transaction.js_](/snippets/code/ethers-tx-local/transaction.js)
+ - Web3.py: [_transaction.py_](/snippets/code/web3py-tx/transaction.py)
+
+Each of the files, regardless of the library used, has been divided into three sections. In the first section ("Define Provider & Variables"), the library to use is imported, and the provider and other variables are defined (variables depend on the library). Note that `providerRPC` has three standard node RPC endpoint, the one for development, the one for [Pangolin](/builders/get-started/darwinia-pangolin.md) and another one for [Crab](/builders/get-started/darwinia-crab.md).
+
+The second section ("Create and Deploy Transaction") outlines the functions needed to send the transaction itself. Some of the key takeaways are discussed next.
+
+
+
+
+```js
+const Web3 = require('web3');
+
+/*
+ -- Define Provider & Variables --
+*/
+// Provider
+const providerRPC = {
+ development: 'http://localhost:9933',
+ pangolin: 'http://pangolin-rpc.darwinia.network',
+ crab: 'http://crab-rpc.darwinia.network',
+};
+const web3 = new Web3(providerRPC.development); //Change to correct network
+
+const account_from = {
+ privateKey: 'YOUR-PRIVATE-KEY-HERE',
+ address: 'PUBLIC-ADDRESS-OF-PK-HERE',
+};
+const addressTo = 'ADDRESS-TO-HERE'; // Change addressTo
+
+/*
+ -- Create and Deploy Transaction --
+*/
+const deploy = async () => {
+ console.log(
+ `Attempting to send transaction from ${account_from.address} to ${addressTo}`
+ );
+
+ // Sign Tx with PK
+ const createTransaction = await web3.eth.accounts.signTransaction(
+ {
+ gas: 21000,
+ to: addressTo,
+ value: web3.utils.toWei('1', 'ether'),
+ },
+ account_from.privateKey
+ );
+
+ // Send Tx and Wait for Receipt
+ const createReceipt = await web3.eth.sendSignedTransaction(
+ createTransaction.rawTransaction
+ );
+ console.log(
+ `Transaction successful with hash: ${createReceipt.transactionHash}`
+ );
+};
+
+deploy();
+```
+
+
+
+
+```js
+const ethers = require('ethers');
+
+/*
+ -- Define Provider & Variables --
+*/
+// Provider
+const providerRPC = {
+ development: {
+ name: 'development',
+ rpc: 'http://localhost:9933',
+ chainId: 42,
+ },
+ pangolin: {
+ name: 'pangolin',
+ rpc: 'http://pangolin-rpc.darwinia.network',
+ chainId: 43,
+ },
+ crab: {
+ name: 'crab',
+ rpc: 'http://crab-rpc.darwinia.network',
+ chainId: 44,
+ },
+};
+const provider = new ethers.providers.StaticJsonRpcProvider(
+ providerRPC.development.rpc,
+ {
+ chainId: providerRPC.development.chainId,
+ name: providerRPC.development.name,
+ }
+); //Change to correct network
+
+// Variables
+const account_from = {
+ privateKey: 'YOUR-PRIVATE-KEY-HERE',
+};
+const addressTo = 'ADDRESS-TO-HERE';
+
+// Create Wallet
+let wallet = new ethers.Wallet(account_from.privateKey, provider);
+
+/*
+ -- Create and Deploy Transaction --
+*/
+const send = async () => {
+ console.log(
+ `Attempting to send transaction from ${wallet.address} to ${addressTo}`
+ );
+
+ // Create Tx Object
+ const tx = {
+ to: addressTo,
+ value: ethers.utils.parseEther('1'),
+ };
+
+ // Sign and Send Tx - Wait for Receipt
+ const createReceipt = await wallet.sendTransaction(tx);
+ await createReceipt.wait();
+ console.log(`Transaction successful with hash: ${createReceipt.hash}`);
+};
+
+send();
+```
+
+
+
+
+```python
+from web3 import Web3
+
+#
+# -- Define Provider & Variables --
+#
+# Provider
+provider_rpc = {
+ "development": "http://localhost:9933",
+ "pangolin": 'http://pangolin-rpc.darwinia.network',
+ "crab": 'http://crab-rpc.darwinia.network',
+}
+web3 = Web3(Web3.HTTPProvider(provider_rpc["development"])) # Change to correct network
+
+# Variables
+account_from = {
+ "private_key": "YOUR-PRIVATE-KEY-HERE",
+ "address": "PUBLIC-ADDRESS-OF-PK-HERE",
+}
+address_to = "ADDRESS-TO-HERE" # Change address_to
+
+#
+# -- Create and Deploy Transaction --
+#
+print(
+ f'Attempting to send transaction from { account_from["address"] } to { address_to }'
+)
+
+# Sign Tx with PK
+tx_create = web3.eth.account.signTransaction(
+ {
+ "nonce": web3.eth.getTransactionCount(account_from["address"]),
+ "gasPrice": 0,
+ "gas": 21000,
+ "to": address_to,
+ "value": web3.toWei("1", "ether"),
+ },
+ account_from["private_key"],
+)
+
+# Send Tx and Wait for Receipt
+tx_hash = web3.eth.sendRawTransaction(tx_create.rawTransaction)
+tx_receipt = web3.eth.waitForTransactionReceipt(tx_hash)
+
+print(f"Transaction successful with hash: { tx_receipt.transactionHash.hex() }")
+```
+
+
+
+
+### Web3.js
+
+In the first section of [the script](/snippets/code/web3-tx-local/transaction.js), the `web3` instance (or provider) is created using the `Web3` constructor with the provider RPC. By changing the provider RPC given to the constructor, you can choose which network you want to send the transaction to.
+
+The private key, and the public address associated with it, are defined for signing the transaction and logging purposes, respectively. Only the private key is required.
+
+The `addressTo`, where the transaction will be sent, is also defined here, and it is required.
+
+In the second section, the transaction object is created with the `to`, `value`, and `gas` fields. These describe the recipient, the amount to send, and the gas consumed by the transaction (21000 in this case). You can use the `web3.utils.toWei()` function to input the value in ETH (for example) and get the output in WEI. The transaction is signed with the private key using the `web3.eth.accounts.signTransaction()` method. Note that this returns a promise that needs to be resolved.
+
+Next, with the transaction signed (you can `console.log(createTransaction)` to see the v-r-s values), you can send it using the `web3.eth.sendSignedTransaction()` method, providing the signed transaction located in `createTransaction.rawTransaction`.
+
+Lastly, run the asynchronous deploy function.
+
+### Ethers.js
+
+In the first section of [the script](/snippets/code/ethers-tx-local/transaction.js), different networks can be specified with a name, RPC URL (required), and chain ID. The provider (similar to the `web3` instance) is created with the `ethers.providers.StaticJsonRpcProvider` method. An alternative is to use the `ethers.providers.JsonRpcProvide(providerRPC)` method, which only requires the provider RPC endpoint address. But this might cause compatibility issues with individual project specifications.
+
+The private key is defined to create a wallet instance, which also requires the provider from the previous step. The wallet instance is used to sign transactions.
+
+The `addressTo`, where the transaction will be sent, is also defined here, and it is required.
+
+In the second section, an asynchronous function wraps the `wallet.sendTransaction(txObject)` method. The transaction object is quite simple. It only requires the recipient's address and the amount to send. Note that `ethers.utils.parseEther()` can be used, which handles the necessary unit conversions from ETH to WEI - similar to using `ethers.utils.parseUnits(value,'ether')`.
+
+Once the transaction is sent, you can get the transaction response (named `createReceipt` in this example), which has a few properties. For instance, you can call the `createReceipt.wait()` method to wait until the transaction is processed (receipt status is OK).
+
+Lastly, run the asynchronous deploy function.
+
+### Web3.py
+
+In the first section of [the script](/snippets/code/web3py-tx/transaction.py), the `web3` instance (or provider) is created using the `Web3(Web3.HTTPProvider(provider_rpc))` method with the provider RPC. By changing the provider RPC, you can choose which network you want to send the transaction to.
+
+The private key and the public address associated with it are defined for signing the transaction and logging purposes. The public address is not required.
+
+The `addressTo`, where the transaction will be sent, is also defined here, and it is required.
+
+In the second section, the transaction object is created with the `nonce`, `gasPrice`, `gas`, `to`, and `value` fields. These describe the transaction count, gas price (larger than 1,000,000,000 for development and Pangolin), gas (21000 in this case), the recipient, and the amount to send. Note that the transaction count can be obtained with the `web3.eth.getTransactionCount(address)` method. Also, you can use the `web3.toWei()` function to input the value in ETH (for example) and get the output in WEI. The transaction is signed with the private key using the `web3.eth.account.signTransaction()` method.
+
+Next, with the transaction signed, you can send it by using the `web3.eth.sendSignedTransaction()` method, providing the signed transaction located in `createTransaction.rawTransaction`.
+
+## The Balance File
+
+Before running the script, another file checks the balances of both addresses before and after the transaction is needed. This can be easily done by a simple query of an account balance.
+
+You can find the code snippet for each library here (files were arbitrarily named `balances.*`):
+
+ - Web3.js: [_balances.js_](/snippets/code/web3-tx-local/balances.js)
+ - Ethers.js: [_balances.js_](/snippets/code/ethers-tx-local/balances.js)
+ - Web3.py: [_balances.py_](/snippets/code/web3py-tx/balances.py)
+
+For simplicity, the balance file is composed of two sections. In the first section ("Define Provider & Variables"), the library to use is imported, and the provider and addresses from/to (to check the balances) are defined.
+
+The second section ("Balance Call Function") outlines the functions needed to fetch the balances of the accounts previously defined. Note that `providerRPC` has three the standard node RPC endpoint, the one for development, the one for [Pangolin](/builders/get-started/darwinia-pangolin.md) and another one for [Crab](/builders/get-started/darwinia-crab.md). Some of the key takeaways are discussed next.
+
+
+
+
+```js
+const Web3 = require('web3');
+
+/*
+ -- Define Provider & Variables --
+*/
+// Provider
+const providerRPC = {
+ development: 'http://localhost:9933',
+ pangolin: 'http://pangolin-rpc.darwinia.network',
+ crab: 'http://crab-rpc.darwinia.network',
+};
+const web3 = new Web3(providerRPC.development); //Change to correct network
+
+// Variables
+const addressFrom = 'ADDRESS-FROM-HERE';
+const addressTo = 'ADDRESS-TO-HERE';
+
+/*
+ -- Balance Call Function --
+*/
+const balances = async () => {
+ const balanceFrom = web3.utils.fromWei(
+ await web3.eth.getBalance(addressFrom),
+ 'ether'
+ );
+ const balanceTo = web3.utils.fromWei(
+ await web3.eth.getBalance(addressTo),
+ 'ether'
+ );
+
+ console.log(`The balance of ${addressFrom} is: ${balanceFrom} PRING`);
+ console.log(`The balance of ${addressTo} is: ${balanceTo} PRING`);
+};
+
+balances();
+```
+
+
+
+
+```js
+const ethers = require('ethers');
+
+/*
+ -- Define Provider & Variables --
+*/
+// Provider
+const providerRPC = {
+ development: {
+ name: 'development',
+ rpc: 'http://localhost:9933',
+ chainId: 42,
+ },
+ pangolin: {
+ name: 'pangolin',
+ rpc: 'http://pangolin-rpc.darwinia.network',
+ chainId: 43,
+ },
+ crab: {
+ name: 'crab',
+ rpc: 'http://crab-rpc.darwinia.network',
+ chainId: 44,
+ },
+};
+const provider = new ethers.providers.StaticJsonRpcProvider(
+ providerRPC.development.rpc,
+ {
+ chainId: providerRPC.development.chainId,
+ name: providerRPC.development.name,
+ }
+); //Change to correct network
+
+// Variables
+const addressFrom = 'ADDRESS-FROM-HERE';
+const addressTo = 'ADDRESS-TO-HERE';
+
+/*
+ -- Balance Call Function --
+*/
+const balances = async () => {
+ const balanceFrom = ethers.utils.formatEther(
+ await provider.getBalance(addressFrom)
+ );
+
+ const balanceTo = ethers.utils.formatEther(
+ await provider.getBalance(addressTo)
+ );
+
+ console.log(`The balance of ${addressFrom} is: ${balanceFrom} PRING`);
+ console.log(`The balance of ${addressTo} is: ${balanceTo} PRING`);
+};
+
+balances();
+```
+
+
+
+
+```python
+from web3 import Web3
+
+#
+# -- Define Provider & Variables --
+#
+# Provider
+provider_rpc = {
+ "development": "http://localhost:9933",
+ "pangolin": 'http://pangolin-rpc.darwinia.network',
+ "crab": 'http://crab-rpc.darwinia.network',
+}
+web3 = Web3(Web3.HTTPProvider(provider_rpc["development"])) # Change to correct network
+
+# Variables
+address_from = "ADDRESS-FROM-HERE"
+address_to = "ADDRESS-TO-HERE"
+
+#
+# -- Balance Call Function --
+#
+balance_from = web3.fromWei(web3.eth.getBalance(address_from), "ether")
+balance_to = web3.fromWei(web3.eth.getBalance(address_to), "ether")
+
+print(f"The balance of { address_from } is: { balance_from } ETH")
+print(f"The balance of { address_to } is: { balance_to } ETH")
+```
+
+
+
+
+### Web3.js
+
+The first section of [the script](/snippets/code/web3-tx-local/balances.js) is very similar to the one in [transaction file](/builders/interact/eth-libraries/send-transaction/#web3js). The main difference is that no private key is needed because there is no need to send a transaction.
+
+In the second section, an asynchronous function wraps the web3 method used to fetch the balance of an address, `web3.eth.getBalance(address)`. Once again, you can leverage the `web3.utils.fromWei()` function to transform the balance into a more readable number in ETH.
+
+### Ethers.js
+
+The first section of [the script](/snippets/code/ethers-tx-local/balances.js) is very similar to the one in [transaction file](/builders/interact/eth-libraries/send-transaction/#ethersjs). The main difference is that no private key is needed because there is no need to send a transaction. On the contrary, the `addressFrom` needs to be defined.
+
+In the second section, an asynchronous function wraps the provider method used to fetch the balance of an address, which is `provider.getBalance(address)`. Once again, you can leverage the `ethers.utils.formatEther()` function to transform the balance into a more readable number in ETH.
+
+### Web3.py
+
+The first section of [the script](/snippets/code/web3py-tx/balances.py) is very similar to the one in [transaction file](/builders/interact/eth-libraries/send-transaction/#web3py). The main difference is that no private key is needed because there is no need to send a transaction.
+
+In the second section, the `web3.eth.getBalance(address)` method is used to fetch a target address's balance. Once again, you can leverage the `eb3.fromWei()` function to transform the balance into a more readable number in ETH.
+
+## Running the Scripts
+
+For this section, the code shown before was adapted to target a development node, which you can run by following [this tutorial](/builders/get-started/darwinia-dev/). Also, each transaction was sent from the pre-funded account that comes with the node:
+
+import DevAccount from '/snippets/text/metamask-local/dev-account.md';
+
+
+
+First, check the balances of both of the addresses before the transaction by running (note that the directory was renamed for each library):
+
+
+
+
+```
+node balances.js
+```
+
+
+
+
+```
+node balances.js
+```
+
+
+
+
+```
+python3 balances.py
+```
+
+
+
+
+Next, run the _transaction.\*_ script to execute the transaction:
+
+
+
+
+```
+node transaction.js
+```
+
+
+
+
+```
+node transaction.js
+```
+
+
+
+
+```
+python3 transaction.py
+```
+
+
+
+
+And lastly, recheck the balance to make sure the transfer was successful. The entire execution should look like this:
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/builders/interact/hardhat.md b/docs/builders/interact/hardhat.md
new file mode 100644
index 00000000..5a5c8c5a
--- /dev/null
+++ b/docs/builders/interact/hardhat.md
@@ -0,0 +1,310 @@
+---
+title: Using Hardhat
+sidebar_position: 3
+description: Use Hardhat to compile, deploy, and debug Ethereum smart contracts on Pangolin.
+---
+
+# Using Hardhat to Deploy To Pangolin
+
+## Introduction
+
+Hardhat is an Ethereum development environment that helps developers manage and automate the recurring tasks inherent to building smart contracts and DApps. Hardhat can directly interact with Pangolin's Ethereum API so it can also be used to deploy smart contracts into Pangolin.
+
+This guide will cover how to use Hardhat to compile, deploy, and debug Ethereum smart contracts on the Pangolin Network.
+
+## Checking Prerequisites
+
+import InstallNodeJs from '/snippets/text/common/install-nodejs.md';
+
+
+
+As of writing of this guide, the versions used were 16.0.0 and 7.10.0, respectively.
+
+Also, you will need the following:
+
+ - Have MetaMask installed and [connected to Pangolin](/dvm/wallets/dvm-metamask.md)
+ - Have an account with funds, which you can get from [Faucet](/builders/get-started/darwinia-pangolin/#get-tokens)
+
+Once all requirements have been met, you are ready to build with Hardhat.
+
+## Starting a Hardhat Project
+
+To start a new project, create a directory for it:
+
+```
+mkdir hardhat && cd hardhat
+```
+
+Then, initialize the project by running:
+
+```
+npm init -y
+```
+
+You will notice a newly created `package.json`, which will continue to grow as you install project dependencies.
+
+To get started with Hardhat, we will install it in our newly created project directory:
+
+```
+npm install hardhat
+```
+
+Once installed, run:
+
+```
+npx hardhat
+```
+
+This will create a Hardhat config file (`hardhat.config.js`) in our project directory.
+
+:::note
+`npx` is used to run executables installed locally in your project. Although Hardhat can be installed globally, we recommend installing locally in each project so that you can control the version on a project by project basis.
+:::
+
+After running the command, choose `Create an empty hardhat.config.js`:
+
+
+
+## The Contract File
+
+We are going to store our contract in the `contracts` directory. Create it:
+
+```
+mkdir contracts && cd contracts
+```
+
+The smart contract that we'll deploy as an example will be called Box: it will let people store a value that can be later retrieved.
+
+We will save this file as `contracts/Box.sol`:
+
+```solidity
+// contracts/Box.sol
+pragma solidity ^0.8.1;
+
+contract Box {
+ uint256 private value;
+
+ // Emitted when the stored value changes
+ event ValueChanged(uint256 newValue);
+
+ // Stores a new value in the contract
+ function store(uint256 newValue) public {
+ value = newValue;
+ emit ValueChanged(newValue);
+ }
+
+ // Reads the last stored value
+ function retrieve() public view returns (uint256) {
+ return value;
+ }
+}
+```
+
+## Hardhat Configuration File
+
+Let's modify our Hardhat configuration file so we can compile and deploy this contract to Pangolin.
+
+If you have not yet done so, create a MetaMask Account, [connect to Pangolin](/dvm/wallets/dvm-metamask.md), and fund it through [Faucet](/builders/get-started/darwinia-pangolin/#get-tokens). We will use the private key of the account created to deploy the contract.
+
+We start by requiring the [ethers plugin](https://hardhat.org/plugins/nomiclabs-hardhat-ethers.html), which brings the [ethers.js](/builders/tools/eth-libraries/etherjs/) library that allows you to interact with the blockchain in a simple way. We can install `ethers` plugin by running:
+
+```
+npm install @nomiclabs/hardhat-ethers ethers
+```
+
+Next, we import the private key that we've retrieved from MetaMask and store it in a `.json` file.
+
+:::note
+Please always manage your private keys with a designated secret manager or similar service. Never save or commit your private keys inside your repositories.
+:::
+
+Inside the `module.exports`, we need to provide the Solidity version (`0.8.1` according to our contract file), and the network details:
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+
+
+```
+dev: {
+ url: 'http://localhost:9933/',
+ chainId: 43,
+ accounts: [privateKeyDev] // Insert your private key here
+ },
+```
+
+
+
+
+```
+pangolin: {
+ url: `http://pangolin-rpc.darwinia.network`,
+ chainId: 43,
+ accounts: [privateKeyPangolin] // Insert your private key here
+ },
+```
+
+
+
+
+```
+crab: {
+ url: `http://crab-rpc.darwinia.network`,
+ chainId: 44,
+ accounts: [privateKeyCrab] // Insert your private key here
+ },
+```
+
+
+
+
+The Hardhat configuration file should look like this:
+
+```js
+// ethers plugin required to interact with the contract
+require('@nomiclabs/hardhat-ethers');
+
+// private key from the pre-funded Pangolin testing account
+const { privateKey } = require('./secrets.json');
+
+module.exports = {
+ // latest Solidity version
+ solidity: "0.8.1",
+
+ networks: {
+ // Pangolin network specification
+ pangolin: {
+ url: `http://pangolin-rpc.darwinia.network`,
+ chainId: 43,
+ accounts: [privateKey]
+ }
+ }
+};
+```
+
+Next, let's create a `secrets.json`, where the private key mentioned before is stored. Make sure to add the file to your project's `.gitignore`, and to never reveal your private key. The `secrets.json` file must contain a `privateKey` entry, for example:
+
+```js
+{
+ "privateKey": "YOUR-PRIVATE-KEY-HERE"
+}
+```
+
+Congratulations! We are ready for deployment!
+
+## Compiling Solidity
+
+Our contract, `Box.sol`, uses Solidity 0.8.1. Make sure the Hardhat configuration file is correctly set up with this solidity version. If so, we can compile the contract by running:
+
+```
+npx hardhat compile
+```
+
+
+
+After compilation, an `artifacts` directory is created: it holds the bytecode and metadata of the contract, which are `.json` files. It’s a good idea to add this directory to your `.gitignore`.
+
+## Deploying the Contract
+
+In order to deploy the Box smart contract, we will need to write a simple deployment script. First, let's create a new directory (`scripts`). Inside the newly created directory, add a new file `deploy.js`.
+
+```
+mkdir scripts && cd scripts
+touch deploy.js
+```
+
+Next, we need to write our deployment script using `ethers`. Because we'll be running it with Hardhat, we don't need to import any libraries. The script is a simplified version of that used in [this tutorial](/builders/interact/eth-libraries/deploy-contract/#deploying-the-contract).
+
+We start by creating a local instance of the contract with the `getContractFactory()` method. Next, let's use the `deploy()` method that exists within this instance to initiate the smart contract. Lastly, we wait for its deployment by using `deployed()`. Once deployed, we can fetch the address of the contract inside the box instantiation.
+
+```js
+// scripts/deploy.js
+async function main() {
+ // We get the contract to deploy
+ const Box = await ethers.getContractFactory('Box');
+ console.log('Deploying Box...');
+
+ // Instantiating a new Box smart contract
+ const box = await Box.deploy();
+
+ // Waiting for the deployment to resolve
+ await box.deployed();
+ console.log('Box deployed to:', box.address);
+}
+
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
+```
+
+Using the `run` command, we can now deploy the `Box` contract to `Pangolin`:
+
+```
+ npx hardhat run --network pangolin scripts/deploy.js
+```
+
+:::note
+To deploy to a Darwinia development node, replace `pangolin` for `dev` in the `run` command.
+:::
+
+After a few seconds, the contract is deployed, and you should see the address in the terminal.
+
+
+
+Congratulations, your contract is live! Save the address, as we will use it to interact with this contract instance in the next step.
+
+## Interacting with the Contract
+
+Let's use Hardhat to interact with our newly deployed contract in Pangolin. To do so, launch `hardhat console` by running:
+
+```
+npx hardhat console --network pangolin
+```
+
+:::note
+To deploy to a Darwinia development node, replace `pangolin` for `dev` in the `console` command.
+:::
+
+Then, add the following lines of code one line at a time. First, we create a local instance of the `Box.sol`contract once again. Don't worry about the `undefined` output you will get after each line is executed:
+
+```js
+const Box = await ethers.getContractFactory('Box');
+```
+
+Next, let's connect this instance to an existing one by passing in the address we obtained when deploying the contract:
+
+```js
+const box = await Box.attach('0x05ECF77bCAA70ea8F20B601F0d2E7987A4F6e554');
+```
+
+After attaching to the contract, we are ready to interact with it. While the console is still in session, let's call the `store` method and store a simple value:
+
+```
+await box.store(5)
+```
+
+The transaction will be signed by your Pangolin account and broadcast to the network. The output should look similar to:
+
+
+
+Notice your address labeled `from`, the address of the contract, and the `data` that is being passed. Now, let's retrieve the value by running:
+
+```
+(await box.retrieve()).toNumber()
+```
+
+We should see `5` or the value you have stored initially.
+
+Congratulations, you have completed the Hardhat tutorial! 🤯 🎉
+
+For more information on Hardhat, hardhat plugins, and other exciting functionality, please visit [hardhat.org](https://hardhat.org/).
diff --git a/docs/builders/interact/metamask-dapp.md b/docs/builders/interact/metamask-dapp.md
new file mode 100644
index 00000000..7a28e3d5
--- /dev/null
+++ b/docs/builders/interact/metamask-dapp.md
@@ -0,0 +1,158 @@
+---
+title: Integrate MetaMask into a DApp
+sidebar_position: 6
+description: Learn how to use MetaMask with the Pangolin TestNet. This tutorial shows you how to integrate MetaMask into a DApp and automatically connect users to Pangolin.
+---
+
+# Integrate MetaMask into a DApp
+
+## Introduction
+
+With the release of MetaMask's [Custom Networks API](https://consensys.net/blog/metamask/connect-users-to-layer-2-networks-with-the-metamask-custom-networks-api/), users can be prompted to add Pangolin's Testnet and Crab.
+
+This section will take you through the process of adding a "Connect to Pangolin" button that will prompt users to connect their MetaMask account(s) to Pangolin. Your users will no longer need to know or worry about Pangolin's network configurations and adding a custom network to MetaMask. To interact with Pangolin from your dApp, all users will need to do is click a few buttons to connect to Pangolin and get started.
+
+MetaMask injects a global Ethereum API into websites users visit at `window.ethereum`, which allows the websites to read and request the users' blockchain data. You'll be using the Ethereum provider to walk your users through the process of adding Pangolin as a custom network. In general, you will have to:
+
+- Check if the Ethereum provider exists and if it's MetaMask
+- Request the user's account address
+- Add Pangolin as a new chain
+
+This guide is divided into two sections. First, it'll cover adding a button that will be used to trigger MetaMask to pop-up and connect to Pangolin. The second part of the guide will create the logic for connecting the user to MetaMask. This way when you click the button you can actually test the functionality as you go through the guide.
+
+## Checking Prerequisites
+
+To add the Connect MetaMask button you'll need a JavaScript project and the MetaMask browser extension installed for local testing.
+
+It's recommended to use MetaMask's `detect-provider` utility package to detect the provider injected at `window.ethereum`. The package handles detecting the provider for the MetaMask extension and MetaMask Mobile. To install the package in your JavaScript project, run:
+
+```
+npm install @metamask/detect-provider
+```
+
+## Add a Button
+
+You'll start off by adding a button that will be used to connect MetaMask to Pangolin. You want to start with the button so when you create the logic in the next step you can test the code as you make your way through the guide.
+
+The function we will create in the next section of the guide will be called `configurePangolin`. So the button on click should call `configurePangolin`.
+
+```html
+
+```
+
+## Add Logic
+
+Now that you have created the button, you need to add the `configurePangolin` function that will be used on click.
+
+1. Detect the provider at `window.ethereum` and check if it's MetaMask. If you want a simple solution you can directly access `window.ethereum`. Or you can use MetaMask's `detect-provider` package and it will detect the provider for MetaMask extension and MetaMask Mobile for you.
+```javascript
+import detectEthereumProvider from '@metamask/detect-provider';
+
+const configurePangolin = async () => {
+ const provider = await detectEthereumProvider({ mustBeMetaMask: true });
+ if (provider) {
+ // Logic will go here
+ } else {
+ console.error("Please install MetaMask");
+ }
+}
+```
+
+2. Request the user's accounts by calling the `eth_requestAccounts` method. This will prompt MetaMask to pop-up and ask the user to select which accounts they would like to connect to. Behind the scenes, permissions are being checked by calling `wallet_requestPermissions`. Currently the only permissions are for `eth_accounts`. So you're ultimately verifying that you have access to the user's addresses returned from `eth_accounts`. If you're interested in learning more about the permissions system, check out [EIP-2255](https://eips.ethereum.org/EIPS/eip-2255).
+```javascript
+import detectEthereumProvider from '@metamask/detect-provider';
+
+const configurePangolin = async () => {
+ const provider = await detectEthereumProvider({ mustBeMetaMask: true });
+ if (provider) {
+ try {
+ await provider.request({ method: "eth_requestAccounts"});
+ } catch(e) {
+ console.error(e);
+ }
+ } else {
+ console.error("Please install MetaMask");
+ }
+}
+```
+
+3. Add Pangolin as a new chain by calling `wallet_addEthereumChain`. This will prompt the user to provide permission to add Pangolin as a custom network.
+```javascript
+import detectEthereumProvider from '@metamask/detect-provider';
+
+const configurePangolin = async () => {
+ const provider = await detectEthereumProvider({ mustBeMetaMask: true });
+ if (provider) {
+ try {
+ await provider.request({ method: "eth_requestAccounts"});
+ await provider.request({
+ method: "wallet_addEthereumChain",
+ params: [
+ {
+ chainId: "0x2b", // Pangolin's chainId is 43, which is 0x2b in hex
+ chainName: "Pangolin",
+ nativeCurrency: {
+ name: 'PRING',
+ symbol: 'PRING',
+ decimals: 18
+ },
+ rpcUrls: ["http://pangolin-rpc.darwinia.network"],
+ blockExplorerUrls: ["https://pangolin.subscan.io/"]
+ },
+ ]
+ })
+ } catch(e) {
+ console.error(e);
+ }
+ } else {
+ console.error("Please install MetaMask");
+ }
+}
+```
+
+Once the network has been successfully added, it will also prompt the user to then switch to Pangolin.
+
+
+So, now you should have a button that, on click, walks users through the entire process of connecting their MetaMask accounts to Pangolin.
+
+### Confirm Connection
+
+It's possible that you'll have logic that relies on knowing whether a user is connected to Pangolin or not. Perhaps you want to disable the button if the user is already connected. To confirm a user is connected to Pangolin, you can call `eth_chainId`, which will return the users current chain ID:
+
+```javascript
+ const chainId = await provider.request({
+ method: 'eth_chainId'
+ })
+ // Pangolin's chainId is 43, which is 0x2b in hex
+ if (chainId === "0x2b"){
+ // At this point, you might want to disable the "Connect" button
+ // or inform the user that they are already connected to the
+ // Pangolin testnet
+ }
+```
+
+## Listen to Account Changes
+
+To ensure that your project or dApp is staying up to date with the latest account information, you can add the `accountsChanged` event listener that MetaMask provides. MetaMask emits this event when the return value of `eth_accounts` changes. If an address is returned, it is your user's most recent account that provided access permissions. If no address is returned, that means the user has not provided any accounts with access permissions.
+
+```javascript
+ provider.on("accountsChanged", (accounts) => {
+ if (accounts.length === 0) {
+ // MetaMask is locked or the user doesn't have any connected accounts
+ console.log('Please connect to MetaMask.');
+ }
+ })
+```
+
+## Listen to Chain Changes
+
+To keep your project or dApp up to date with any changes to the connected chain, you'll want to subscribe to the `chainChanged` event. MetaMask emits this event every time the connected chain changes.
+
+```javascript
+ provider.on("chainChanged", () => {
+ // MetaMask recommends reloading the page unless you have good reason not to
+ window.location.reload();
+ })
+```
+
+MetaMask recommends reloading the page whenever the chain changes, unless there is a good reason not to, as it's important to always be in sync with chain changes.
diff --git a/docs/builders/interact/oz-remix.md b/docs/builders/interact/oz-remix.md
new file mode 100644
index 00000000..92d33d55
--- /dev/null
+++ b/docs/builders/interact/oz-remix.md
@@ -0,0 +1,241 @@
+---
+title: Using OpenZeppelin and Remix
+sidebar_position: 2
+description: Learn how to create common OpenZeppelin contracts with their Contracts Wizard easily and how to deploy them on Pangolin thanks to its Ethereum compatibility features
+---
+
+# Using OpenZeppelin Contracts and Remix To Deploy To Pangolin
+
+## Introduction
+
+OpenZeppelin contracts and libraries have become a standard in the industry. They help developers minimize risk, as their open-source code templates are battle-tested for Ethereum and other blockchains. Their code includes the most used implementations of ERC standards and add-ons and often appears in guides and tutorials around the community.
+
+Because Pangolin is fully Ethereum compatible, all of OpenZeppelin's contracts and libraries can be implemented without any changes.
+
+This guide is divided into two sections. The first part describes the OpenZeppelin Contracts Wizard, a great online tool to help you create smart contracts using OpenZeppelin code. The second section provides a step-by-step guide on how you can deploy these contracts using [Remix](https://remix.ethereum.org/) on Pangolin.
+
+## OpenZeppelin Contract Wizard
+
+OpenZeppelin has developed an online web-based interactive contract generator tool that is probably the easiest and fastest way to write your smart contract using OpenZeppelin code. The tool is called Contracts Wizard, and you can find it on their [documentation site](https://docs.openzeppelin.com/contracts/4.x/wizard).
+
+
+Currently, the Contracts Wizard support the following ERC standards:
+
+ - [**ERC20**](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/) — a fungible token standard that follows [EIP-20](https://eips.ethereum.org/EIPS/eip-20). Fungible means that all tokens are equivalent and interchangeable that is, of equal value. One typical example of fungible tokens is fiat currencies, where each equal-denomination bill has the same value.
+ - [**ERC721**](https://ethereum.org/en/developers/docs/standards/tokens/erc-721/) — a non-fungible token contract that follows [EIP-721](https://eips.ethereum.org/EIPS/eip-721). Non-fungible means that each token is different, and therefore, unique. An ERC721 token can represent ownership of that unique item, whether it is a collectible item in a game, real estate, and so on.
+ - [**ERC1155**](https://docs.openzeppelin.com/contracts/4.x/erc1155) — also known as the multi-token contract, because it can represent both fungible and non-fungible tokens in a single smart contract. It follows [EIP-1155](https://eips.ethereum.org/EIPS/eip-1155)
+
+The wizard is comprised of the following sections:
+
+ 1. **Token standard selection** — shows all the different standards supported by the wizard
+ 2. **Settings** — provides the baseline settings for each token standard, such as token name, symbol, pre-mint (token supply when the contract is deployed), and URI (for non-fungible tokens)
+ 3. **Features** — list of all features available for each token standard. You can find more information about the different features in the following links:
+ - [ERC20](https://docs.openzeppelin.com/contracts/4.x/api/token/erc20)
+ - [ERC721](https://docs.openzeppelin.com/contracts/4.x/api/token/erc721)
+ - [ERC1155](https://docs.openzeppelin.com/contracts/4.x/api/token/erc1155)
+ 4. **Access Control** — list of all the available [access control mechanisms](https://docs.openzeppelin.com/contracts/4.x/access-control) for each token standard
+ 5. **Interactive code display** — shows the smart contract code with the configuration as set by the user
+
+
+
+Once you have set up your contract with all the settings and features, it is just as easy as copying and pasting the code into your contract file.
+
+## Deploying OpenZeppelin Contracts on Pangolin
+
+This section goes through the steps for deploying OpenZeppelin contracts on Pangolin. It covers the following contracts:
+
+ - ERC20 (fungible tokens)
+ - ERC721 (non-fungible tokens)
+ - ERC1155 (multi-token standard)
+
+All the code of the contracts was obtained using OpenZeppelin [Contract Wizard](https://docs.openzeppelin.com/contracts/4.x/wizard).
+
+### Checking Prerequisites
+
+The steps described in this section assume you have [MetaMask](https://metamask.io/) installed and connected to the Pangolin Network. Contract deployment is done using the [Remix IDE](https://remix.ethereum.org/) via the "Injected Web3" environment. You can find corresponding tutorials in the following links:
+
+ - [Interacting with Pangolin using MetaMask](/dvm/wallets/dvm-metamask.md)
+ - [Interacting with Pangolin using Remix](/builders/tools/remix/)
+
+### Deploying an ERC20 Token
+
+For this example, an ERC20 token will be deployed to Pangolin. The final code used combines different contracts from OpenZeppelin:
+
+ - **ERC20.sol** — ERC20 token implementation with the optional features from the base interface. Includes the supply mechanism with a `mint` function but needs to be explicitly called from within the main contract
+ - **Ownable.sol** — extension to restrict access to certain functions
+
+The mintable ERC20 OpenZeppelin token contract provides a `mint` function that the owner of the contract can only call. By default, the owner is the contract's deployer address. There is also a premint of `1000` tokens sent to the contract's deployer configured in the `constructor` function.
+
+The first step is to go to [Remix](https://remix.ethereum.org/) and take the following steps:
+
+ 1. Click on the "Create New File" icon and set a file name. For this example, it was set to `ERC20.sol`
+ 2. Make sure the file was created successfully. Click on the file to open it up in the text editor
+ 3. Write your smart contract using the file editor. For this example, the following code was used:
+
+```solidity
+pragma solidity ^0.8.0;
+
+import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
+import "@openzeppelin/contracts/access/Ownable.sol";
+
+contract MyToken is ERC20, Ownable {
+ constructor() ERC20("MyToken", "MTK") {
+ _mint(msg.sender, 1000 * 10 ** decimals());
+ }
+
+ function mint(address to, uint256 amount) public onlyOwner {
+ _mint(to, amount);
+ }
+}
+```
+
+This ERC20 token smart contract was extracted from the [Contract Wizard](#openzeppelin-contract-wizard), setting a premint of `1000` tokens and activating the `Mintable` feature.
+
+
+
+Once your smart contract is written, you can compile it by taking the following steps:
+
+ 1. Head to the "Solidity Compiler"
+ 2. Click on the compile button
+ 3. Alternatively, you can check the "Auto compile" feature
+
+
+
+With the contract compiled, you are ready to deploy it taking the following steps:
+
+ 1. Head to the "Deploy & Run Transactions" tab
+ 2. Change the environment to "Injected Web3". This will use MetaMask's injected provider. Consequently, the contract will be deployed to whatever network MetaMask is connected to. MetaMask might show a pop-up outlining that Remix is trying to connect to your wallet
+ 3. Select the proper contract to deploy. In this example, it is the `MyToken` contract inside the `ERC20.sol` file
+ 4. If everything is ready, click on the "Deploy" button. Review the transaction information in MetaMask and confirm it
+ 5. After a few seconds, the transaction should get confirmed, and you should see your contract under "Deployed Contracts"
+
+
+
+And that is it! You've deployed an ERC20 token contract using OpenZeppelin's contracts and libraries. Next, you can interact with your token contract via Remix, or add it to MetaMask.
+
+### Deploying an ERC721 Token
+
+For this example, an ERC721 token will be deployed to Pangolin. The final code used combines different contracts from OpenZeppelin:
+
+ - **ERC721** — ERC721 token implementation with the optional features from the base interface. Includes the supply mechanism with a `_mint` function but needs to be explicitly called from within the main contract
+ - **Burnable** — extension to allow tokens to be destroyed by their owners (or approved addresses)
+ - **Enumerable** — extension to allow on-chain enumeration of tokens
+ - **Ownable.sol** — extension to restrict access to certain functions
+
+The mintable ERC721 OpenZeppelin token contract provides a `mint` function that can only be called by the owner of the contract. By default, the owner is the contract's deployer address.
+
+As with the [ERC20 contract](#deploying-an-erc20-token), the first step is to go to [Remix](https://remix.ethereum.org/) and create a new file. For this example, the file name will be `ERC721.sol`.
+
+Next, you'll need to write the smart contract and compile it. For this example, the following code is used:
+
+```solidity
+pragma solidity ^0.8.0;
+
+import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
+import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
+import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
+import "@openzeppelin/contracts/access/Ownable.sol";
+
+contract MyToken is ERC721, ERC721Enumerable, ERC721Burnable, Ownable {
+ constructor() ERC721("MyToken", "MTK") {}
+
+ function safeMint(address to, uint256 tokenId) public onlyOwner {
+ _safeMint(to, tokenId);
+ }
+
+ function _baseURI() internal pure override returns (string memory) {
+ return "Test";
+ }
+
+ function _beforeTokenTransfer(address from, address to, uint256 tokenId)
+ internal
+ override(ERC721, ERC721Enumerable)
+ {
+ super._beforeTokenTransfer(from, to, tokenId);
+ }
+
+ function supportsInterface(bytes4 interfaceId)
+ public
+ view
+ override(ERC721, ERC721Enumerable)
+ returns (bool)
+ {
+ return super.supportsInterface(interfaceId);
+ }
+}
+```
+
+This ERC721 token smart contract was extracted from the [Contract Wizard](#openzeppelin-contract-wizard), setting the `Base URI` as `Test` and activating the `Mintable`, `Burnable`, and `Enumerable` features.
+
+With the contract compiled, head to the "Deploy & Run Transactions" tab. In here, you need to:
+
+ 1. Change the environment to "Injected Web3". This will use MetaMask's injected provider. Consequently, the contract will be deployed to whatever network MetaMask is connected to. MetaMask might show a pop-up outlining that Remix is trying to connect to your wallet
+ 2. Select the proper contract to deploy. In this example, it is the `MyToken` contract inside the `ERC721.sol` file
+ 3. If everything is ready, click on the "Deploy" button. Review the transaction information in MetaMask and confirm it
+ 4. After a few seconds, the transaction should get confirmed, and you should see your contract under "Deployed Contracts"
+
+
+
+And that is it! You've deployed an ERC721 token contract using OpenZeppelin's contracts and libraries. Next, you can interact with your token contract via Remix, or add it to MetaMask.
+
+### Deploying an ERC1155 Token
+
+For this example, an ERC1155 token will be deployed to Pangolin. The final code used combines different contracts from OpenZeppelin:
+
+ - **ERC1155** — ERC1155 token implementation with the optional features from the base interface. Includes the supply mechanism with a `_mint` function but needs to be explicitly called from within the main contract
+ - **Pausable** — extension to allows pausing tokens transfer, mintings and burnings
+ - **Ownable.sol** — extension to restrict access to certain functions
+
+OpenZeppelin's ERC1155 token contract provides a `_mint` function that can only be called in the `constructor` function. Therefore, this example creates 1000 tokens with an ID of `0`, and 1 unique token with an ID of `1`.
+
+The first step is to go to [Remix](https://remix.ethereum.org/) and create a new file. For this example, the file name will be `ERC1155.sol`.
+
+As shown for the [ERC20 token](#deploying-an-erc20-token), you'll need to write the smart contract and compile it. For this example, the following code is used:
+
+```solidity
+pragma solidity ^0.8.0;
+
+import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
+import "@openzeppelin/contracts/access/Ownable.sol";
+import "@openzeppelin/contracts/security/Pausable.sol";
+
+contract MyToken is ERC1155, Ownable, Pausable {
+ constructor() ERC1155("Test") {
+ _mint(msg.sender, 0, 1000 * 10 ** 18, "");
+ _mint(msg.sender, 1, 1, "");
+ }
+
+ function setURI(string memory newuri) public onlyOwner {
+ _setURI(newuri);
+ }
+
+ function pause() public onlyOwner {
+ _pause();
+ }
+
+ function unpause() public onlyOwner {
+ _unpause();
+ }
+
+ function _beforeTokenTransfer(address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
+ internal
+ whenNotPaused
+ override
+ {
+ super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
+ }
+}
+```
+
+This ERC1155 token smart contract was extracted from the [Contract Wizard](#openzeppelin-contract-wizard), setting no `Base URI` and activating `Pausable` feature. The constructor function was modified to include the minting of both a fungible and a non-fungible token.
+
+With the contract compiled, head to the "Deploy & Run Transactions" tab. In here, you need to:
+
+ 1. Change the environment to "Injected Web3". This will use MetaMask's injected provider. Consequently, the contract will be deployed to whatever network MetaMask is connected to. MetaMask might show a pop-up outlining that Remix is trying to connect to your wallet
+ 2. Select the proper contract to deploy. In this example, it is the `MyToken` contract inside the `ERC1155.sol` file
+ 3. If everything is ready, click on the "Deploy" button. Review the transaction information in MetaMask and confirm it
+ 4. After a few seconds, the transaction should get confirmed, and you should see your contract under "Deployed Contracts"
+
+
+
+And that is it! You've deployed an ERC1155 token contract using OpenZeppelin's contracts and libraries. Next, you can interact with your token contract via Remix.
diff --git a/docs/builders/interact/remix.md b/docs/builders/interact/remix.md
new file mode 100644
index 00000000..bb023222
--- /dev/null
+++ b/docs/builders/interact/remix.md
@@ -0,0 +1,147 @@
+---
+title: Using Remix
+sidebar_position: 1
+description: Learn how to use one of the most popular Ethereum developer tools, the Remix IDE, to interact with a local Darwinia node.
+---
+
+# Using Remix to Deploy to Pangolin
+
+## Introduction
+
+Remix is one of the commonly used development environments for smart contracts on Ethereum. Given Darwinia’s Ethereum compatibility features, Remix can be used directly with a Darwinia development node or the Pangolin Node.
+
+This guide walks through the process of creating and deploying a Solidity-based smart contract to a Darwinia development node using the [Remix IDE](https://remix.ethereum.org/).
+
+:::note
+This tutorial was created using the v2.6.4 tag which is based on the v2.6.4 release of [Darwinia-Common](https://github.com/darwinia-network/darwinia-common/releases/tag/v2.6.4). The Darwinia platform and the [Frontier](https://github.com/paritytech/frontier) components it relies on for Substrate-based Ethereum compatibility are still under very active development.
+:::
+
+## Checking Prerequisites
+
+This guide assumes that you have a local Darwinia node running in `--dev` mode and that you have a [MetaMask](https://metamask.io/) installation configured to use this local node. You can find instructions for running a local Darwinia node [here](/builders/get-started/darwinia-dev/) and instructions to connect MetaMask to it [here](/dvm/wallets/dvm-metamask.md).
+
+If you followed the guides above, you should have a local Darwinia node which will begin to author blocks as transactions arrive:
+
+
+
+And you should have a MetaMask installation connected to your local Darwinia dev node with at least one account that has a balance. It should look something like this (expanded view):
+
+
+
+:::note
+Make sure you are connected to your Darwinia node and not another network!
+:::
+
+## Getting Started with Remix
+
+Now, let’s fire up Remix to exercise more advanced functionalities in Darwinia.
+
+Launch Remix by navigating to [https://remix.ethereum.org/](https://remix.ethereum.org/). In the main screen, under Environments, select Solidity to configure Remix for Solidity development, then navigate to the File Explorers view:
+
+
+
+We will create a new file to save the Solidity smart contract. Hit the + button under File Explorers and enter the name "MyToken.sol" in the popup dialog:
+
+
+
+Next, let's paste the following smart contract into the editor tab that comes up:
+
+```solidity
+pragma solidity ^0.7.0;
+
+import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.2.0-solc-0.7/contracts/token/ERC20/ERC20.sol';
+
+// This ERC-20 contract mints the specified amount of tokens to the contract creator.
+contract MyToken is ERC20 {
+ constructor(uint256 initialSupply) ERC20("MyToken", "MYTOK") {
+ _mint(msg.sender, initialSupply);
+ }
+}
+```
+
+This is a simple ERC-20 contract based on the current Open Zeppelin ERC-20 template. It creates MyToken with symbol MYTOK and mints the entirety of the initial supply to the creator of the contract.
+
+Once you have pasted the contract into the editor, it should look like this:
+
+
+
+Now, navigate to the compile sidebar option to press the “Compile MyToken.sol” button:
+
+
+
+You will see Remix download all of the Open Zeppelin dependencies and compile the contract.
+
+## Deploying a Contract to Darwinia Using Remix
+
+Now we can deploy the contract by navigating to the Deployment sidebar option. You need to change the topmost “Environment” dropdown from “JavaScript VM” to “Injected Web3.” This tells Remix to use the MetaMask injected provider, which will point it to your Darwinia development node. If you wanted to try this using the Pangolin Network, you would have to connect MetaMask to the Pangolin Network instead of your local development node.
+
+As soon as you select "Injected Web3", you will be prompted to allow Remix to connect to your MetaMask account.
+
+
+
+Press “Confirm” in Metamask to allow Remix to access the selected account.
+
+
+
+
+
+Back on Remix, you should see that the account you wish to use for deployment is now managed by MetaMask. Next to the Deploy button, let’s specify an initial supply of 8M tokens. Since this contract uses the default of 18 decimals, the value to put in the box is `8000000000000000000000000`.
+
+Once you have entered this value, select "Deploy."
+
+
+
+You will be prompted in MetaMask to confirm the contract deployment transaction.
+
+:::note
+If you have problems deploying any specific contract, you can try manually increasing the gas limit. You can do this under Settings -> Advanced -> Advanced Gas Controls = ON.
+:::
+
+After you press confirm and the deployment is complete, you will see the transaction listed in MetaMask. The contract will appear under Deployed Contracts in Remix.
+
+
+
+Once the contract is deployed, you can interact with it from within Remix.
+
+Drill down on the contract under “Deployed Contracts.” Clicking on name, symbol, and totalSupply should return “MyToken,” “MYTOK,” and “8000000000000000000000000” respectively. If you copy the address from which you deployed the contract and paste it into the balanceOf field, you should see the entirety of the balance of the ERC20 as belonging to that user. Copy the contract address by clicking the button next to the contract name and address.
+
+
+
+## Interacting with a Darwinia-based ERC-20 from MetaMask
+
+Now, open MetaMask to add the newly deployed ERC-20 tokens. Before doing so, make sure you have copied the contract's address from Remix. Back in MetaMask, click on “Add Token” as shown below. Make sure you are in the account that deployed the token contract.
+
+
+
+Paste the copied contract address into the “Custom Token” field. The “Token Symbol” and “Decimals of Precision” fields should be automatically populated.
+
+
+
+After hitting “Next,” you will need to confirm that you want to add these tokens to your MetaMask account.
+
+
+
+ Hit “Add Token” and you should see a balance of 8M MyTokens in MetaMask:
+
+
+
+Now we can send some of these ERC-20 tokens to the other account that we have set up in MetaMask. Hit “send” to initiate the transfer of 500 MyTokens and select the destination account.
+
+
+
+After hitting “next,” you will be asked to confirm (similar to what is pictured below).
+
+
+
+Hit “Confirm” and after the transaction is complete, you will see a confirmation and a reduction of the MyToken account balance from the sender account in MetaMask:
+
+
+
+If you own the account that you sent the tokens to, you can add the token asset to verify that the transfer arrived.
+
+
+
+If you encounter a failure while transferring tokens, you may need to increase the gas price and gas limit.
+
+
+
diff --git a/docs/builders/interact/truffle.md b/docs/builders/interact/truffle.md
new file mode 100644
index 00000000..1393703f
--- /dev/null
+++ b/docs/builders/interact/truffle.md
@@ -0,0 +1,357 @@
+---
+title: Using Truffle
+sidebar_position: 4
+description: Darwinia makes it incredibly easy to deploy a Solidity-based smart contract to a Darwinia node using Truffle. Learn how in this tutorial.
+---
+
+# Using Truffle to Deploy to Darwinia
+
+## Introduction
+
+This guide walks through the process of deploying a Solidity-based smart contract to a Darwinia node using [Truffle](https://www.trufflesuite.com/), a commonly used development tool for smart contracts on Ethereum. Given Darwinia’s Ethereum compatibility features, Truffle can be used directly with a Darwinia node.
+
+:::note
+This tutorial was created using the v2.6.4 tag which is based on the v2.6.4 release of [Darwinia-Common](https://github.com/darwinia-network/darwinia-common/releases/tag/v2.6.4). The Darwinia platform and the [Frontier](https://github.com/paritytech/frontier) components it relies on for Substrate-based Ethereum compatibility are still under very active development.
+
+The examples in this guide assumes you have a MacOS or Ubuntu 18.04-based environment and will need to be adapted accordingly for Windows.
+:::
+
+For this guide, you will need to have a Darwinia development node running in `--dev` mode. This can be done by either following the steps detailed [here](/builders/get-started/darwinia-dev/).
+
+## Checking Prerequisites
+
+import InstallNodeJs from '/snippets/text/common/install-nodejs.md';
+
+
+
+As of writing of this guide, the versions used were 16.0.0 and 7.10.0, respectively.
+
+Also, you will need the following:
+
+ - Have MetaMask installed and [connected to Darwinia](/dvm/wallets/dvm-metamask.md)
+ - Have an account with funds, which you can get from [Faucet](/builders/get-started/darwinia-pangolin/#get-tokens)
+
+Once all requirements have been met, you are ready to build with truffle.
+
+## Starting a Truffle Project
+
+To get started with the Truffle box, if you have Truffle installed globally, you can execute:
+
+```
+mkdir metacoin-box && cd metacoin-box
+truffle unbox metacoin
+```
+
+
+
+Nevertheless, the box also has Truffle as a dependency in case you do not want to have it installed globally. In such a case, you can directly clone the following repository:
+
+```
+git clone https://github.com/truffle-box/metacoin-box.git
+cd metacoin-box
+```
+
+:::note
+To create a bare Truffle project with no smart contracts included, use `truffle init`.
+:::
+
+Once this operation is completed, you'll now have a project structure with the following items:
+
+- `contracts/`: Directory for Solidity contracts
+- `migrations/`: Directory for scriptable deployment files
+- `test/`: Directory for test files for testing your application and contracts
+- `truffle-config.js`: Truffle configuration file
+
+### The Truffle Configuration File
+
+Navigate inside the directory to take a look at the `truffle-config.js` file (for the purpose of this guide, some information was removed):
+
+```js
+const HDWalletProvider = require('@truffle/hdwallet-provider');
+// Darwinia Development Node Private Key
+const privateKeyDev ='YOUR-PRIVATE-KEY-HERE';
+//...
+module.exports = {
+ networks: {
+ dev: {
+ provider: () => {
+ return new HDWalletProvider(privateKeyDev, 'http://localhost:9933/')
+ },
+ network_id: 43,
+ }
+ },
+ compilers: {
+ solc: {
+ version: "^0.6.7"
+ }
+ }
+};
+```
+
+After write config file, we need to install `@truffle/hdwallet-provider` package.
+```
+npm i @truffle/hdwallet-provider
+```
+
+Note that we are using `HD-Wallet-Provider` from Truffle as the Hierarchical Deterministic wallet. Also, we've defined a `dev` network that points to the development node provider URL, and the private key of the development account, which holds all funds in the development node, is included.
+
+For deployments to the Pangolin TestNet or Crab, you need to provide the private key of an address that holds funds. For Pangolin, you can create an account in MetaMask, fund it using the [TestNet faucet](/builders/get-started/darwinia-pangolin/#get-tokens), and export its private key.
+
+Below you can find network configurations for all of our networks:
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+
+
+```
+dev: {
+ provider: () => {
+ ...
+ return new HDWalletProvider(privateKeyDev, 'http://localhost:9933/') // Insert your private key here
+ },
+ network_id: 43,
+},
+```
+
+
+
+
+```
+pangolin: {
+ provider: () => {
+ ...
+ return new HDWalletProvider(privateKeyPangolin, 'http://pangolin-rpc.darwinia.network') // Insert your private key here
+ },
+ network_id: 43,
+},
+```
+
+
+
+
+```
+crab: {
+ provider: () => {
+ ...
+ return new HDWalletProvider(privateKeyCrab, 'http://crab-rpc.darwinia.network') // Insert your private key here
+ },
+ network_id: 44,
+},
+```
+
+
+
+
+## The Contract File
+
+There is also a MetaCoin contract included with the Truffle box:
+
+```solidity
+// SPDX-License-Identifier: MIT
+pragma solidity >=0.4.25 <0.7.0;
+
+import "./ConvertLib.sol";
+
+// This is just a simple example of a coin-like contract.
+// It is not standards compatible and cannot be expected to talk to other
+// coin/token contracts. If you want to create a standards-compliant
+// token, see: https://github.com/ConsenSys/Tokens. Cheers!
+
+contract MetaCoin {
+ mapping (address => uint) balances;
+
+ event Transfer(address indexed _from, address indexed _to, uint256 _value);
+
+ constructor() public {
+ balances[tx.origin] = 10000;
+ }
+
+ function sendCoin(address receiver, uint amount) public returns(bool sufficient) {
+ if (balances[msg.sender] < amount) return false;
+ balances[msg.sender] -= amount;
+ balances[receiver] += amount;
+ emit Transfer(msg.sender, receiver, amount);
+ return true;
+ }
+
+ function getBalanceInEth(address addr) public view returns(uint){
+ return ConvertLib.convert(getBalance(addr),2);
+ }
+
+ function getBalance(address addr) public view returns(uint) {
+ return balances[addr];
+ }
+}
+```
+
+If we take a look at the Truffle contract migration script under `migrations/2_deploy_contracts.js`, it contains the following:
+
+```javascript
+const ConvertLib = artifacts.require("ConvertLib");
+const MetaCoin = artifacts.require("MetaCoin");
+
+module.exports = function(deployer) {
+ deployer.deploy(ConvertLib);
+ deployer.link(ConvertLib, MetaCoin);
+ deployer.deploy(MetaCoin);
+};
+```
+
+## Deploying a Contract to Darwinia Using Truffle
+
+Before we can deploy our contracts, we must compile them. (We say "contracts" because normal Truffle deployments include the `Migrations.sol` contract.) You can do this with the following command:
+
+```
+truffle compile
+```
+
+If successful, you should see output like the following:
+
+```
+$ metacoin-box truffle compile
+
+Compiling your contracts...
+===========================
+✔ Fetching solc version list from solc-bin. Attempt #1
+✔ Downloading compiler. Attempt #1.
+> Compiling ./contracts/ConvertLib.sol
+> Compiling ./contracts/MetaCoin.sol
+> Compiling ./contracts/Migrations.sol
+✔ Fetching solc version list from solc-bin. Attempt #1
+> Artifacts written to /Users/echo/workspace/draft/code/metacoin-box/build/contracts
+> Compiled successfully using:
+ - solc: 0.6.12+commit.27d51765.Emscripten.clang
+```
+
+Now we are ready to deploy the compiled contracts. You can do this with the following command:
+
+
+
+
+```
+truffle migrate --network dev
+```
+
+
+
+
+```
+truffle migrate --network pangolin
+```
+
+
+
+
+```
+truffle migrate --network Crab
+```
+
+
+
+
+If successful, you will see deployment actions, including the address of the deployed contract:
+
+```
+$ metacoin-box truffle migrate --network pangolin
+
+Compiling your contracts...
+===========================
+✔ Fetching solc version list from solc-bin. Attempt #1
+> Everything is up to date, there is nothing to compile.
+
+
+
+Starting migrations...
+======================
+> Network name: 'pangolin'
+> Network id: 43
+> Block gas limit: 4294967295 (0xffffffff)
+
+
+1_initial_migration.js
+======================
+
+ Deploying 'Migrations'
+ ----------------------
+ > transaction hash: 0x1cf510a03023bd4842ed2fa6e901bad99445ca3caea952451350bc66b7fb3b5b
+ > Blocks: 2 Seconds: 13
+ > contract address: 0xe5C85b572c57F20e6FCA59b7b6B4D0d56B10f87c
+ > block number: 686236
+ > block timestamp: 1632915054
+ > account: 0xA4ADf2A419Fe24e7f6527F76AfBA5674BF9252f3
+ > balance: 93.900544511883035776
+ > gas used: 159195 (0x26ddb)
+ > gas price: 20 gwei
+ > value sent: 0 ETH
+ > total cost: 0.0031839 ETH
+
+
+ > Saving migration to chain.
+ > Saving artifacts
+ -------------------------------------
+ > Total cost: 0.0031839 ETH
+
+
+2_deploy_contracts.js
+=====================
+
+ Deploying 'ConvertLib'
+ ----------------------
+ > transaction hash: 0xa782ad8ee3cd9fd572adbb5ea3971f8f862959cb7826ea3b67c8df182e2a2cb9
+ > Blocks: 4 Seconds: 27
+ > contract address: 0x59Ef69D2Dc9b55461bF0BBCAA32b351d669A54b8
+ > block number: 686244
+ > block timestamp: 1632915102
+ > account: 0xA4ADf2A419Fe24e7f6527F76AfBA5674BF9252f3
+ > balance: 93.897784031883035776
+ > gas used: 95686 (0x175c6)
+ > gas price: 20 gwei
+ > value sent: 0 ETH
+ > total cost: 0.00191372 ETH
+
+
+ Linking
+ -------
+ * Contract: MetaCoin <--> Library: ConvertLib (at address: 0x59Ef69D2Dc9b55461bF0BBCAA32b351d669A54b8)
+
+ Deploying 'MetaCoin'
+ --------------------
+ > transaction hash: 0x245f3136b9044ef34541753fdf08cd2679ddde63ea93c5c4c37d72382bca727c
+ > Blocks: 4 Seconds: 21
+ > contract address: 0xD05FDEC15D2eEA9E13d07817b3C85bf1b500EB58
+ > block number: 686252
+ > block timestamp: 1632915150
+ > account: 0xA4ADf2A419Fe24e7f6527F76AfBA5674BF9252f3
+ > balance: 93.892056811883035776
+ > gas used: 286361 (0x45e99)
+ > gas price: 20 gwei
+ > value sent: 0 ETH
+ > total cost: 0.00572722 ETH
+
+
+ > Saving migration to chain.
+ > Saving artifacts
+ -------------------------------------
+ > Total cost: 0.00764094 ETH
+
+
+Summary
+=======
+> Total deployments: 3
+> Final cost: 0.01082484 ETH
+```
+
diff --git a/docs/builders/interact/waffle-mars.md b/docs/builders/interact/waffle-mars.md
new file mode 100644
index 00000000..8d843d03
--- /dev/null
+++ b/docs/builders/interact/waffle-mars.md
@@ -0,0 +1,428 @@
+---
+title: Using Waffle and Mars
+sidebar_position: 5
+description: Learn how to use Waffle and Mars to write, compile, test, and deploy Ethereum smart contracts on Pangolin.
+---
+
+# Using Waffle & Mars to Deploy to Pangolin
+
+## Introduction
+
+[Waffle](https://getwaffle.io/) is a library for compiling and testing smart contracts, and [Mars](https://github.com/EthWorks/Mars) is a deployment manager. Together, Waffle and Mars can be used to write, compile, test, and deploy Ethereum smart contracts. Since Darwinia is Ethereum compatible, Waffle and Mars can be used to deploy smart contracts to a Darwinia development node or the Pangolin.
+
+Waffle uses minimal dependencies, has syntax that is easy to learn and extend, and provides fast execution times when compiling and testing smart contracts. Furthermore, it is [TypeScript](https://www.typescriptlang.org/) compatible and uses [Chai matchers](https://ethereum-waffle.readthedocs.io/en/latest/matchers.html) to make tests easy to read and write.
+
+Mars provides a simple, TypeScript compatible framework for creating advanced deployment scripts and staying in sync with state changes. Mars focuses on infrastructure-as-code, allowing developers to specify how their smart contracts should be deployed and then using those specifications to automatically handle state changes and deployments.
+
+In this guide, you'll be creating a TypeScript project to write, compile, and test a smart contract using Waffle, then deploy it on to the Pangolin using Mars.
+
+## Checking Prerequisites
+
+import InstallNodeJs from '/snippets/text/common/install-nodejs.md';
+
+
+
+As of writing of this guide, the versions used were 16.0.0 and 7.10.0, respectively.
+
+Waffle and Mars can be used with a locally running Darwinia development node, but for the purposes of this guide, you will be deploying to Pangolin. Therefore, you will need a funded account for development.
+
+import DevAccount from '/snippets/text/metamask-local/dev-account.md';
+
+
+
+Once you've created an account you'll need to export the private key to be used in this guide. Before moving on, ensure your account has funds and, if needed, get `PRING` tokens from the [faucet](/builders/get-started/darwinia-pangolin/#get-tokens).
+
+## Create a TypeScript Project with Waffle & Mars
+
+To get started, you'll create a TypeScript project and install and configure a few dependencies.
+
+1. Create the project directory and change to it:
+```
+mkdir waffle-mars && cd waffle-mars
+```
+
+2. Initialize the project. Which will create a `package.json` in the directory:
+```
+npm init -y
+```
+
+3. Install the following dependencies:
+```
+npm install ethereum-waffle ethereum-mars ethers \
+@openzeppelin/contracts typescript ts-node chai \
+@types/chai mocha @types/mocha
+```
+
+- [Waffle](https://github.com/EthWorks/Waffle) - for writing, compiling, and testing smart contracts
+- [Mars](https://github.com/EthWorks/Mars) - for deploying smart contracts to Pangolin
+- [Ethers](https://github.com/ethers-io/ethers.js/) - for interacting with Pangolin's Ethereum API
+- [OpenZeppelin Contracts](https://github.com/OpenZeppelin/openzeppelin-contracts) - the contract you'll be creating will use OpenZeppelin's ERC20 base implementation
+- [TypeScript](https://github.com/microsoft/TypeScript) - the project will be a TypeScript project
+- [TS Node](https://github.com/TypeStrong/ts-node) - for executing the deployment script you'll create later in this guide
+- [Chai](https://github.com/chaijs/chai) - an assertion library used alongside Waffle for writing tests
+- [@types/chai](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/chai) - contains the type definitions for chai
+- [Mocha](https://github.com/mochajs/mocha) - a testing framework for writing tests alongside Waffle
+- [@types/mocha](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mocha) - contains the type definitions for mocha
+
+4. Create a [TypeScript configuration](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) file:
+```
+touch tsconfig.json
+```
+
+5. Add a basic TypeScript configuration:
+```
+{
+ "compilerOptions": {
+ "strict": true,
+ "target": "ES2019",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "module": "CommonJS",
+ "composite": true,
+ "sourceMap": true,
+ "declaration": true,
+ "noEmit": true
+ }
+}
+```
+
+Now, you should have a basic TypeScript project with the necessary dependencies to get started building with Waffle and Mars.
+## Add a Contract
+
+For this guide, you will create an ERC-20 contract that mints a specified amount of tokens to the contract creator. It's based on the Open Zeppelin ERC-20 template.
+
+1. Create a directory to store your contracts and a file for the smart contract:
+```
+mkdir contracts && cd contracts && touch MyToken.sol
+```
+
+2. Add the following contract to MyToken.sol:
+```solidity
+pragma solidity ^0.8.0;
+
+import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
+
+contract MyToken is ERC20 {
+ constructor() ERC20("MyToken", "MYTOK") {}
+
+ function initialize(uint initialSupply) public {
+ _mint(msg.sender, initialSupply);
+ }
+}
+```
+
+In this contract, you are creating an ERC20 token called MyToken with the symbol MYTOK, that allows you, as the contract creator, to mint as many MYTOKs as desired.
+
+## Use Waffle to Compile and Test
+
+### Compile with Waffle
+
+Now that you have written a smart contract, the next step is to use Waffle to compile it. Before diving into compiling your contract, you will need to configure Waffle.
+
+1. Go back to the root project directory and create a `waffle.json` file to configure Waffle:
+```
+cd .. && touch waffle.json
+```
+
+2. Edit the `waffle.json` to specify compiler configurations, the directory containing your contracts, and more. For this example, we'll use `solcjs` and the Solidity version you used for the contract, which is `0.8.7`:
+```json
+{
+ "compilerType": "solcjs", // Specifies compiler to use
+ "compilerVersion": "0.8.7", // Specifies version of the compiler
+ "compilerOptions": {
+ "optimizer": { // Optional optimizer settings
+ "enabled": true, // Enable optimizer
+ "runs": 20000 // Optimize how many times you want to run the code
+ }
+ },
+ "sourceDirectory": "./contracts", // Path to directory containing smart contracts
+ "outputDirectory": "./build", // Path to directory where Waffle saves compiler output
+ "typechainEnabled": true // Enable typed artifact generation
+}
+```
+
+3. Add a script to run Waffle in the `package.json`:
+```json
+"scripts": {
+ "build": "waffle"
+},
+```
+
+That is all you need to do to configure Waffle, now you're all set to compile the `MyToken` contract using the `build` script:
+
+```
+npm run build
+```
+
+```
+$ waffle-mars npm run build
+
+> waffle-mars@1.0.0 build
+> waffle
+```
+
+After compiling your contracts, Waffle stores the JSON output in the `build` directory. The contract in this guide is based on Open Zeppelin's ERC-20 template, so relevant ERC-20 JSON files will appear in the `build` directory too.
+
+### Test with Waffle
+
+Before deploying your contract and sending it off into the wild, you should test it first. Waffle provides an advanced testing framework and has plenty of tools to help you with testing.
+
+You'll be running tests against the Pangolin TestNet and will need the corresponding RPC URL to connect to it: `http://pangolin-rpc.darwinia.network`. Since you will be running tests against the TestNet, it might take a couple minutes to run all of the tests.
+
+1. Create a directory to contain your tests and a file to test your `MyToken` contract:
+```
+mkdir test && cd test && touch MyToken.test.ts
+```
+
+2. Open the `MyToken.test.ts` file and setup your test file to use Waffle's Solidity plugin and use Ethers custom JSON-RPC provider to connect to Pangolin:
+```typescript
+import { use, expect } from 'chai';
+import { Provider } from '@ethersproject/providers';
+import { solidity } from 'ethereum-waffle';
+import { ethers, Wallet } from 'ethers';
+import { MyToken, MyTokenFactory } from '../build/types';
+
+// Tell Chai to use Waffle's Solidity plugin
+use(solidity);
+
+describe ('MyToken', () => {
+ // Use custom provider to connect to Pangolin
+ let provider: Provider = new ethers.providers.JsonRpcProvider('http://pangolin-rpc.darwinia.network');
+ let wallet: Wallet;
+ let walletTo: Wallet;
+ let token: MyToken;
+
+ beforeEach(async () => {
+ // Logic for setting up the wallet and deploying MyToken will go here
+ });
+
+ // Tests will go here
+})
+```
+
+3. Before each test is run, you'll want to create wallets and connect them to the provider, use the wallets to deploy an instance of the `MyToken` contract, and then call the `initialize` function once with an initial supply of 10 tokens:
+```typescript
+ beforeEach(async () => {
+ const PRIVATE_KEY = ''
+ // Create a wallet instance using your private key & connect it to the provider
+ wallet = new Wallet(PRIVATE_KEY).connect(provider);
+
+ // Create a random account to transfer tokens to & connect it to the provider
+ walletTo = Wallet.createRandom().connect(provider);
+
+ // Use your wallet to deploy the MyToken contract
+ token = await new MyTokenFactory(wallet).deploy();
+
+ // Mint 10 tokens to the contract owner, which is you
+ let contractTransaction = await token.initialize(10);
+
+ // Wait until the transaction is confirmed before running tests
+ await contractTransaction.wait();
+ });
+```
+
+4. Now you can create your first test. The first test will check your initial balance to ensure you received the initial supply of 10 tokens. However, to follow good testing practices, write a failing test first:
+```typescript
+it('Mints the correct initial balance', async () => {
+ expect(await token.balanceOf(wallet.address)).to.equal(1); // This should fail
+});
+```
+
+5. Before you can run your first test, you'll need to go back to the root direction and add a `.mocharc.json` Mocha configuration file:
+```
+cd .. && touch .mocharc.json
+```
+
+6. Now edit the `.mocharc.json` file to configure Mocha:
+```json
+{
+ "require": "ts-node/register/transpile-only", // Use ts-node to transpile the code for tests
+ "timeout": 600000, // Set timeout to 10 minutes
+ "extension": "test.ts" // Specify extension for test files
+}
+```
+
+7. You'll also need to add a script in the `package.json` to run your tests:
+```json
+"scripts": {
+ "build": "waffle",
+ "test": "mocha"
+},
+```
+
+8. You're all set to run the tests, simply use the `test` script you just created and run:
+```
+npm run test
+```
+Please note that it could take a few minutes to process because the tests are running against Pangolin, but if all worked as expected, you should have one failing test.
+
+9. Next, you can go back and edit the test to check for 10 tokens:
+```typescript
+it('Mints the correct initial balance', async () => {
+ expect(await token.balanceOf(wallet.address)).to.equal(10); // This should pass
+});
+```
+10. If you run the tests again, you should now see one passing test:
+```
+npm run test
+```
+
+11. You've tested the ability to mint tokens, next you'll test the ability to transfer the minted tokens. If you want to write a failing test first again that is up to, however the final test should look like this:
+```typescript
+it('Should transfer the correct amount of tokens to the destination account', async () => {
+ // Send the destination wallet 7 tokens
+ await (await token.transfer(walletTo.address, 7)).wait();
+
+ // Expect the destination wallet to have received the 7 tokens
+ expect(await token.balanceOf(walletTo.address)).to.equal(7);
+});
+```
+
+Congratulations, you should now have two passing tests! Altogether, your test file should look like this:
+```typescript
+import { use, expect } from 'chai';
+import { Provider } from '@ethersproject/providers';
+import { solidity } from 'ethereum-waffle';
+import { ethers, Wallet } from 'ethers';
+import { MyToken, MyTokenFactory } from '../build/types';
+
+use(solidity);
+
+describe ('MyToken', () => {
+ let provider: Provider = new ethers.providers.JsonRpcProvider('http://pangolin-rpc.darwinia.network');
+ let wallet: Wallet;
+ let walletTo: Wallet;
+ let token: MyToken;
+
+ beforeEach(async () => {
+ const PRIVATE_KEY = ''
+ wallet = new Wallet(PRIVATE_KEY).connect(provider);
+ walletTo = Wallet.createRandom().connect(provider);
+ token = await new MyTokenFactory(wallet).deploy();
+ let contractTransaction = await token.initialize(10);
+ await contractTransaction.wait();
+ });
+
+ it('Mints the correct initial balance', async () => {
+ expect(await token.balanceOf(wallet.address)).to.equal(10);
+ });
+
+ it('Should transfer the correct amount of tokens to the destination account', async () => {
+ await (await token.transfer(walletTo.address, 7)).wait();
+ expect(await token.balanceOf(walletTo.address)).to.equal(7);
+ });
+})
+```
+
+If you want to write more tests on your own, you could consider testing transfers from accounts without any funds or transfers from accounts without enough funds.
+
+## Use Mars to Deploy to Pangolin
+
+After you compile your contracts and before deployment, you will have to generate contract artifacts for Mars. Mars uses the contract artifacts for typechecks in deployments. Then you'll need to create a deployment script and deploy the `MyToken` smart contract.
+
+Remember, you will be deploying to Pangolin and will need to use the TestNet RPC URL: `http://pangolin-rpc.darwinia.network`.
+
+The deployment will be broken up into three sections: [generate artifacts](#generate-artifacts), [create a deployment script](#create-a-deployment-script), and [deploy with Mars](#deploy-with-mars).
+
+### Generate Artifacts
+
+Artifacts need to be generated for Mars so that typechecks are enabled within deployment scripts.
+
+1. Update existing script to run Waffle in the `package.json` to include Mars:
+```json
+"scripts": {
+ "build": "waffle && mars",
+ "test": "mocha"
+},
+```
+
+2. Generate the artifacts and create the `artifacts.ts` file needed for deployments:
+```
+npm run build
+```
+
+```
+$ waffle-mars npm run build
+
+> waffle-mars@1.0.0 build
+> waffle && mars
+```
+
+If you open the `build` directory, you should now see an `artifacts.ts` file containing the artifact data needed for deployments. To continue on with the deployment process, you'll need to write a deployment script. The deployment script will be used to tell Mars which contract to deploy, to what network, and which account is to be used to trigger the deployment.
+
+### Create a Deployment Script
+
+Now you need to configure the deployment for the `MyToken` contract to the Pangolin TestNet.
+
+In this step, you'll create the deployment script which will define how the contract should be deployed. Mars offers a `deploy` function that you can pass options to such as the private key of the account to deploy the contract, the network to deploy to, and more. Inside of the `deploy` function is where the contracts to be deployed are defined. Mars has a `contract` function that accepts the `name`, `artifact`, and `constructorArgs`. This function will be used to deploy the `MyToken` contract with an initial supply of 10 MYTOKs.
+
+
+1. Create a `src` directory to contain your deployment scripts and create the script to deploy the `MyToken` contract:
+```
+mkdir src && cd src && touch deploy.ts
+```
+
+2. In `deploy.ts`, use Mars' `deploy` function to create a script to deploy to Pangolin using your account's private key:
+```javascript
+import { deploy } from 'ethereum-mars';
+
+const privateKey = "";
+deploy({network: 'http://pangolin-rpc.darwinia.network', privateKey},(deployer) => {
+ // Deployment logic will go here
+});
+```
+
+3. Set up the `deploy` function to deploy the `MyToken` contract created in the previous steps:
+```javascript
+import { deploy, contract } from 'ethereum-mars';
+import { MyToken } from '../build/artifacts';
+
+const privateKey = "";
+deploy({network: 'http://pangolin-rpc.darwinia.network', privateKey}, () => {
+ contract('myToken', MyToken);
+});
+```
+
+4. Add a deploy script to the `scripts` object in the `package.json`:
+```json
+ "scripts": {
+ "build": "waffle && mars",
+ "test": "mocha",
+ "deploy": "ts-node src/deploy.ts"
+ },
+```
+
+So far, you should have created a deployment script in `deploy.ts` that will deploy the `MyToken` contract to Pangolin, and added the ability to easily call the script and deploy the contract.
+
+### Deploy with Mars
+
+You've configured the deployment, now it's time to actually deploy to Pangolin.
+
+1. Deploy the contract using the script you just created:
+```
+npm run deploy
+```
+
+2. In your Terminal, Mars will prompt you to press `ENTER` to send your transaction:
+
+
+If successful, you should see details about your transaction including it's hash, the block it was included in, and it's address.
+
+```
+$ waffle-mars npm run deploy
+
+
+> waffle-mars@1.0.0 deploy
+> ts-node src/deploy.ts
+
+Transaction: Deploy myToken
+ Fee: $19.24, Ξ0.006553245235595322
+ Balance: $275588.88, Ξ93.85932584491775371
+ Sending ...
+ Hash: 0xa1be3385b7c761e145992f0f0d419546379856e6a35e0acc0275fdc5fa3f75ea
+ Block: 686677
+ Address: 0x9e41aa68a1e59b049A13D14281A9d39197F30036
+```
+
+Congratulations! You've deployed a contract to Pangolin using Waffle and Mars!
diff --git a/docs/builders/tools/_category_.json b/docs/builders/tools/_category_.json
new file mode 100644
index 00000000..5ecd522f
--- /dev/null
+++ b/docs/builders/tools/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Tools",
+ "position": 3
+}
diff --git a/docs/builders/tools/eth-libraries/_category_.json b/docs/builders/tools/eth-libraries/_category_.json
new file mode 100644
index 00000000..8aa3dd71
--- /dev/null
+++ b/docs/builders/tools/eth-libraries/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Eth Libraries",
+ "position": 1
+}
diff --git a/docs/builders/tools/eth-libraries/etherjs.md b/docs/builders/tools/eth-libraries/etherjs.md
new file mode 100644
index 00000000..4b7c4579
--- /dev/null
+++ b/docs/builders/tools/eth-libraries/etherjs.md
@@ -0,0 +1,81 @@
+---
+title: Ethers.js
+sidebar_position: 1
+description: Follow this tutorial to learn how to use the Ethereum EtherJS Library to deploy Solidity smart contracts to Pangolin.
+---
+# Ethers.js JavaScript Library
+
+## Introduction
+
+The [ethers.js](https://docs.ethers.io/) library provides a set of tools to interact with Ethereum Nodes with JavaScript, similar to web3.js. Darwinia has an Ethereum-like API available that is fully compatible with Ethereum-style JSON RPC invocations. Therefore, developers can leverage this compatibility and use the ethers.js library to interact with a Darwinia node as if they were doing so on Ethereum. You can read more about ethers.js on this [blog post](https://medium.com/l4-media/announcing-ethers-js-a-web3-alternative-6f134fdd06f3).
+
+## Setup Ethers.js with Pangolin
+
+To get started with the ethers.js library, install it using the following command:
+
+```
+npm install ethers
+```
+
+Once done, the simplest setup to start using the library and its methods is the following:
+
+```js
+const ethers = require('ethers');
+
+// Variables definition
+const privKey = '0xPRIVKEY';
+
+// Define Provider
+const provider = new ethers.providers.StaticJsonRpcProvider('RPC_URL', {
+ chainId: ChainId,
+ name: 'NETWORK_NAME'
+});
+
+// Create Wallet
+let wallet = new ethers.Wallet(privKey, provider);
+```
+
+Different methods are available inside `provider` and `wallet`. Depending on which network you want to connect to, you can set the `RPC_URL` to the following values:
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+
+
+```
+- RPC_URL: http://localhost:9933/
+- ChainId: 43
+- NETWORK_NAME: development
+```
+
+
+
+
+```
+- RPC_URL: http://pangolin-rpc.darwinia.network
+- ChainId: 43
+- NETWORK_NAME: Pangolin
+```
+
+
+
+
+```
+- RPC_URL: http://crab-rpc.darwinia.network
+- ChainID: 44
+- NETWORK_NAME: Crab
+```
+
+
+
+
+## Tutorials
+
+If you are interested in a more detailed step-by-step guide, you can go to our specific tutorials on using ethers.js on Pangolin to [send a transaction](/builders/interact/eth-libraries/send-transaction/) or [deploy a contract](/builders/interact/eth-libraries/deploy-contract/).
diff --git a/docs/builders/tools/eth-libraries/web3js.md b/docs/builders/tools/eth-libraries/web3js.md
new file mode 100644
index 00000000..c93fcc18
--- /dev/null
+++ b/docs/builders/tools/eth-libraries/web3js.md
@@ -0,0 +1,38 @@
+---
+title: Web3.js
+sidebar_position: 2
+description: Follow this tutorial to learn how to use the Ethereum Web3 JavaScript Library to deploy Solidity smart contracts to Pangolin.
+---
+# Web3.js JavaScript Library
+
+## Introduction
+
+[Web3.js](https://web3js.readthedocs.io/) is a set of libraries that allow developers to interact with Ethereum nodes using HTTP, IPC, or WebSocket protocols with JavaScript. Darwinia has an Ethereum-like API available that is fully compatible with Ethereum-style JSON RPC invocations. Therefore, developers can leverage this compatibility and use the web3.js library to interact with a Darwinia node as if they were doing so on Ethereum.
+
+## Setup Web3.js with Pangolin
+
+To get started with the web3.js library, we first need to install it using the following command:
+
+```
+npm install web3
+```
+
+Once done, the simplest setup to start using the library and its methods is the following:
+
+```js
+const Web3 = require('web3');
+
+//Create web3 instance
+const web3 = new Web3('RPC_URL');
+```
+
+Depending on which network you want to connect to, you can set the `RPC_URL` to the following values:
+
+ - Darwinia development node: `http://localhost:9933/`
+ - Pangolin TestNet: `http://pangolin-rpc.darwinia.network`
+ - Crab: `http://crab-rpc.darwinia.network`
+
+## Tutorials
+
+If you are interested in a more detailed step-by-step guide, go to our specific tutorials about using web3.js on Pangolin to [send a transaction](/builders/interact/eth-libraries/send-transaction/) or [deploy a contract](/builders/interact/eth-libraries/deploy-contract/).
+
diff --git a/docs/builders/tools/eth-libraries/web3py.md b/docs/builders/tools/eth-libraries/web3py.md
new file mode 100644
index 00000000..7b5dc959
--- /dev/null
+++ b/docs/builders/tools/eth-libraries/web3py.md
@@ -0,0 +1,37 @@
+---
+title: Web3.py
+sidebar_position: 3
+description: Follow this tutorial to learn how to use the Ethereum Web3 Python Library to deploy Solidity smart contracts to Pangolin.
+---
+# Web3.py Python Library
+
+## Introduction
+
+[Web3.py](https://web3py.readthedocs.io/) is a set of libraries that allow developers to interact with Ethereum nodes using HTTP, IPC, or WebSocket protocols with Python. Darwinia has an Ethereum-like API available that is fully compatible with Ethereum-style JSON RPC invocations. Therefore, developers can leverage this compatibility and use the web3.py library to interact with a node as if they were doing so on Ethereum.
+
+## Setup Web3.py with Pangolin
+
+To get started with the web3.py library, install it using the following command:
+
+```
+pip3 install web3
+```
+
+Once done, the simplest setup to start using the library and its methods is the following:
+
+```py
+from web3 import Web3
+
+web3 = Web3(Web3.HTTPProvider('RPC_URL'))
+```
+
+Depending on which network you want to connect to, you can set the `RPC_URL` to the following values:
+
+ - Darwinia development node: `http://localhost:9933/`
+ - Pangolin TestNet: `http://pangolin-rpc.darwinia.network`
+ - Crab: `http://crab-rpc.darwinia.network`
+
+## Tutorials
+
+If you are interested in a more detailed step-by-step guide, go to our specific tutorials about using web3.py on Pangolin to [send a transaction](/builders/interact/eth-libraries/send-transaction/) or [deploy a contract](/builders/interact/eth-libraries/deploy-contract/).
+
diff --git a/docs/builders/tools/explorers.md b/docs/builders/tools/explorers.md
new file mode 100644
index 00000000..2e0ffc36
--- /dev/null
+++ b/docs/builders/tools/explorers.md
@@ -0,0 +1,44 @@
+---
+title: Block Explorers
+sidebar_position: 9
+description: An overview of the currently available block explorers that may be used to navigate the Substrate and Ethereum layers of the Pangolin TestNet.
+---
+# Block Explorers
+
+## Introduction
+
+Block explorers can be thought of as search engines for the blockchain. They allow users to search information such as balances, contracts, and transactions. More advanced block explorers even offer indexing capabilities, which enable them to provide a complete set of information, such as ERC20 tokens in the network. They might even offer API services to access it via external services.
+
+### PolkadotJS (Dev Node - TestNet)
+
+Polkadot JS Apps uses the WebSocket endpoint to interact with the Network. To connect it to a Darwinia development node, you can follow the steps in [this tutorial](/builders/get-started/darwinia-dev/#connecting-to-darwinia-apps). The default port for this is `9944`.
+
+
+
+To view and interact with Pangolin's substrate layer, go to [this URL](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fpangolin-rpc.darwinia.network#/explorer). This is the Polkadot JS Apps pointing to the TestNet. You can find more information in [this page](/builders/get-started/darwinia-dev/#connecting-to-darwinia-apps).
+
+
+
+### Subscan
+
+[Subscan](https://crab.subscan.io/) is a powerful, user-friendly multi-chain browser that adds support for DVM smart contract solutions now.
+
+#### Preparation
+
+Switch network and select the network for which you want to query data.
+
+
+
+#### Get transaction information
+
+Enter the DVM transaction hash in the search box and click `Search`.
+
+
+
+
+
+#### Get account information
+
+
+
+As shown above, the relationship between the DVM account and the Substrate account, the account balance, the staking and the transaction history can be clearly displayed.
diff --git a/docs/builders/tools/hardhat.md b/docs/builders/tools/hardhat.md
new file mode 100644
index 00000000..8fa882a7
--- /dev/null
+++ b/docs/builders/tools/hardhat.md
@@ -0,0 +1,69 @@
+---
+title: Hardhat
+sidebar_position: 5
+description: Learn how to configure Hardhat to add a local Darwinia development node and the Pangolin TestNet as networks for testing and deploying Solidity smart contracts.
+---
+
+# Hardhat
+
+## Introduction
+
+[Hardhat](https://hardhat.org/) is a popular development framework for compiling, testing, and deploying Solidity smart contracts. Since Darwinia is Ethereum compatible, with a few lines of extra configuration, you can use Hardhat as you normally would to develop on Pangolin.
+
+## Configure Hardhat to Connect to Pangolin
+
+To get started with Hardhat you must have an npm project. If you do not yet have one, to create one you can run:
+
+```
+npm init
+```
+
+Once you have a npm project, install Hardhat:
+
+```
+npm install hardhat
+```
+
+Then to create a Hardhat config file in your project, run:
+
+```
+npx hardhat
+```
+
+In your `hardhat.config.js` file, add network configurations for a Darwinia development node and the Pangolin TestNet:
+
+```javascript
+// Darwinia Development Node Private Key
+const privateKeyDev = 'YOUR-PRIVATE-KEY-HERE';
+// Pangolin Private Key
+const privateKeyPangolin = "YOUR-PRIVATE-KEY-HERE";
+// Crab Private Key - Note: This is for example purposes only. Never store your private keys in a JavaScript file.
+const privateKeyCrab = "YOUR-PRIVATE-KEY-HERE";
+
+module.exports = {
+ networks: {
+ // Darwinia Development Node
+ dev: {
+ url: 'http://localhost:9933/',
+ chainId: 43,
+ accounts: [privateKeyDev]
+ },
+ // Pangolin TestNet
+ pangolin: {
+ url: 'http://pangolin-rpc.darwinia.network',
+ chainId: 43,
+ accounts: [privateKeyPangolin]
+ },
+ // Crab
+ crab: {
+ url: 'http://crab-rpc.darwinia.network',
+ chainId: 44,
+ accounts: [privateKeyCrab]
+ },
+ },
+};
+```
+
+## Tutorial
+
+If you are interested in a more detailed step-by-step guide, check out our specific tutorial about using [Hardhat](/builders/interact/hardhat/) with Pangolin.
diff --git a/docs/builders/tools/mars.md b/docs/builders/tools/mars.md
new file mode 100644
index 00000000..a83118eb
--- /dev/null
+++ b/docs/builders/tools/mars.md
@@ -0,0 +1,38 @@
+---
+title: Mars
+sidebar_position: 8
+description: Learn how to configure Mars for deploying Solidity smart contracts to either a locally running Darwinia development node or the Pangolin TestNet.
+---
+
+# Mars
+
+## Introduction
+
+[Mars](https://github.com/EthWorks/Mars) is a new infrastructure-as-code tool for deploying Solidity smart contracts. Mars makes writing advanced deployment scripts a breeze and handles state change for you, making sure your deployments are always up-to-date. Since Darwinia is Ethereum compatible, you can use Mars as you normally would with Ethereum to develop on Pangolin. All you have to do is change the network you wish to deploy to.
+
+## Configure Mars to Connect to Pangolin
+
+Assuming you already have a JavaScript or TypeScript project, install Mars:
+
+```
+npm install ethereum-mars
+```
+
+To configure Mars to deploy to a Darwinia development node or the Pangolin TestNet, within your deployment scripts add the following network configurations:
+
+```typescript
+import { deploy } from 'ethereum-mars';
+const privateKey = "";
+// For Darwinia development node
+deploy({network: 'http://localhost:9933', privateKey},(deployer) => {
+ // Deployment logic will go here
+});
+// For Pangolin
+deploy({network: 'http://pangolin-rpc.darwinia.network', privateKey},(deployer) => {
+ // Deployment logic will go here
+});
+```
+
+## Tutorial
+
+If you are interested in a more detailed step-by-step guide on how to use Mars, go to our specific tutorial about using [Waffle & Mars](/builders/interact/waffle-mars/) on Pangolin,.
diff --git a/docs/builders/tools/openzeppelin.md b/docs/builders/tools/openzeppelin.md
new file mode 100644
index 00000000..0a082ba3
--- /dev/null
+++ b/docs/builders/tools/openzeppelin.md
@@ -0,0 +1,32 @@
+---
+title: OpenZeppelin
+sidebar_position: 2
+description: Learn how to use OpenZeppelin products on Pangolin thanks to its Ethereum compatibility features
+---
+
+# OpenZeppelin
+
+## Introduction
+
+OpenZeppelin is well known in the Ethereum developer community as their set of audited smart contracts and libraries are a standard in the industry. For example, most of the tutorials that show developers how to deploy an ERC20 token use OpenZeppelin contracts.
+
+You can find more information about OpenZeppelin in their [website](https://openzeppelin.com/) or [documentation site](https://docs.openzeppelin.com/openzeppelin/).
+
+As part of its Ethereum compatibility features, OpenZeppelin products can be seamlessly used on Pangolin. This page will provide information on different OpenZeppelin solutions that you can test.
+
+## OpenZeppelin on Pangolin
+
+Currently, the following OpenZeppelin products/solutions work on the different networks available on Pangolin:
+
+| **Product** | |**Darwinia Dev Node**| |**Pangolin TestNet**|
+| :-------------------: | :-: | :-----------------: | :-: | :--------------: |
+| Contracts & Libraries | | ✓ | | ✓ |
+| Contract Wizard | | ✓ | | ✓ |
+| Defender | | X | | X |
+
+You will find a corresponding tutorial for each product in the following links:
+
+ - [**Contract Wizard**](/builders/interact/oz-remix/#openzeppelin-contract-wizard) — where you'll find a guide on how to use OpenZeppelin web-based wizard to create different token contracts with different functionalities
+ - [**Contracts & Libraries**](/builders/interact/oz-remix/#deploying-openzeppelin-contracts-on-pangolin) — where you'll find tutorials to deploy the most common token contracts using OpenZeppelin's templates: ERC20, ERC721 and ERC1155
+ - **Defender** — where you'll find a guide on how to use OpenZeppelin Defender to manage your smart contracts in the Pangolin TestNet
+
diff --git a/docs/builders/tools/precompiles.md b/docs/builders/tools/precompiles.md
new file mode 100644
index 00000000..443de405
--- /dev/null
+++ b/docs/builders/tools/precompiles.md
@@ -0,0 +1,173 @@
+---
+title: Precompiled Contracts
+sidebar_position: 10
+description: Learn how to use precompiled contracts on Pangolin, the Pangolin TestNet that is unique for its complete Ethereum compatibility.
+---
+
+# Precompiled Contracts
+
+## Introduction
+
+Another feature added with the release of Pangolin and Crab Networks is the inclusion of some [precompiled contracts](https://docs.klaytn.com/smart-contract/precompiled-contracts) that are natively available on Ethereum.
+
+Four precompiles are currently included, including: ecrecover, sha256, ripemd-160, and the identity function.
+In this guide, we will explain how to use and/or verify these precompiles.
+
+## Checking Prerequisites
+
+import InstallNodeJs from '/snippets/text/common/install-nodejs.md';
+
+
+
+As of writing of this guide, the versions used were 16.0.0 and 7.10.0, respectively. We will also need to install the Web3 package by executing:
+
+```
+npm install --save web3
+```
+
+To verify the installed version of Web3, you can use the `ls` command:
+
+```
+npm ls web3
+```
+As of writing this guide, the version used was 1.3.0. We will be also using [Remix](/builders/tools/remix/), connecting it to the Pangolin TestNet via [MetaMask](/dvm/wallets/dvm-metamask.md).
+
+## Verify Signatures with ECRECOVER
+
+The main function of this precompile is to verify the signature of a message. In general terms, you feed `ecrecover` the transaction's signature values and it returns an address. The signature is verified if the address returned is the same as the public address that sent the transaction.
+
+Let's jump into a small example to showcase how to leverage this precompiled function. To do so we need to retrieve the transaction's signature values (v, r, s). Therefore, we'll sign and retrieve the signed message where these values are:
+
+```solidity
+const Web3 = require('web3');
+
+// Provider
+const web3 = new Web3('http://pangolin-rpc.darwinia.network');
+
+// Address and Private Key
+const address = '0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b';
+const pk1 = '99B3C12287537E38C90A9219D4CB074A89A16E9CDB20BF85728EBD97C343E342';
+const msg = web3.utils.sha3('supercalifragilisticexpialidocious');
+
+async function signMessage(pk) {
+ try {
+ // Sign and get Signed Message
+ const smsg = await web3.eth.accounts.sign(msg, pk);
+ console.log(smsg);
+ } catch (error) {
+ console.error(error);
+ }
+}
+
+signMessage(pk1);
+```
+
+This code will return the following object in the terminal:
+
+```js
+{
+ message: '0xc2ae6711c7a897c75140343cde1cbdba96ebbd756f5914fde5c12fadf002ec97',
+ messageHash: '0xc51dac836bc7841a01c4b631fa620904fc8724d7f9f1d3c420f0e02adf229d50',
+ v: '0x1b',
+ r: '0x44287513919034a471a7dc2b2ed121f95984ae23b20f9637ba8dff471b6719ef',
+ s: '0x7d7dc30309a3baffbfd9342b97d0e804092c0aeb5821319aa732bc09146eafb4',
+ signature: '0x44287513919034a471a7dc2b2ed121f95984ae23b20f9637ba8dff471b6719ef7d7dc30309a3baffbfd9342b97d0e804092c0aeb5821319aa732bc09146eafb41b'
+}
+```
+With the necessary values, we can go to Remix to test the precompiled contract. Note that this can also be verified with the Web3 JS library, but in our case, we'll go to Remix to be sure that it is using the precompiled contract on the blockchain. The Solidity code we can use to verify the signature is the following:
+
+```solidity
+pragma solidity ^0.7.0;
+
+contract ECRECOVER{
+ address addressTest = 0x12Cb274aAD8251C875c0bf6872b67d9983E53fDd;
+ bytes32 msgHash = 0xc51dac836bc7841a01c4b631fa620904fc8724d7f9f1d3c420f0e02adf229d50;
+ uint8 v = 0x1b;
+ bytes32 r = 0x44287513919034a471a7dc2b2ed121f95984ae23b20f9637ba8dff471b6719ef;
+ bytes32 s = 0x7d7dc30309a3baffbfd9342b97d0e804092c0aeb5821319aa732bc09146eafb4;
+
+ function verify() public view returns(bool) {
+ // Use ECRECOVER to verify address
+ return (ecrecover(msgHash, v, r, s) == (addressTest));
+ }
+}
+```
+
+Using the [Remix compiler and deployment](/builders/interact/remix/) and with [MetaMask pointing to Pangolin](/dvm/wallets/dvm-metamask.md), we can deploy the contract and call the `verify()` method that returns _true_ if the address returned by `ecrecover` is equal to the address used to sign the message (related to the private key and needs to be manually set in the contract).
+
+## Hashing with SHA256
+
+This hashing function returns the SHA256 hash from the given data. To test this precompile, you can use this [online tool](https://md5calc.com/hash/sha256) to calculate the SHA256 hash of any string you want. In our case, we'll do so with `Hello World!`. We can head directly to Remix and deploy the following code, where the calculated hash is set for the `expectedHash` variable:
+
+```solidity
+pragma solidity ^0.7.0;
+
+contract Hash256{
+ bytes32 public expectedHash = 0x7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069;
+
+ function calculateHash() internal pure returns (bytes32) {
+ string memory word = 'Hello World!';
+ bytes32 hash = sha256(bytes (word));
+
+ return hash;
+ }
+
+ function checkHash() public view returns(bool) {
+ return (calculateHash() == expectedHash);
+ }
+}
+
+```
+Once the contract is deployed, we can call the `checkHash()` method that returns _true_ if the hash returned by `calculateHash()` is equal to the hash provided.
+
+## Hashing with RIPEMD-160
+
+This hashing function returns a RIPEMD-160 hash from the given data. To test this precompile, you can use this [online tool](https://md5calc.com/hash/ripemd160) to calculate the RIPEMD-160 hash of any string. In our case, we'll do so again with `Hello World!`. We'll reuse the same code as before, but use the `ripemd160` function. Note that it returns a `bytes20` type variable:
+
+```solidity
+pragma solidity ^0.7.0;
+
+contract HashRipmd160{
+ bytes20 public expectedHash = hex'8476ee4631b9b30ac2754b0ee0c47e161d3f724c';
+
+ function calculateHash() internal pure returns (bytes20) {
+ string memory word = 'Hello World!';
+ bytes20 hash = ripemd160(bytes (word));
+
+ return hash;
+ }
+
+ function checkHash() public view returns(bool) {
+ return (calculateHash() == expectedHash);
+ }
+}
+```
+With the contract deployed, we can call the `checkHash()` method that returns _true_ if the hash returned by `calculateHash()` is equal to the hash provided.
+
+## The Identity Function
+
+Also known as datacopy, this function serves as a cheaper way to copy data in memory. The Solidity compiler does not support it, so it needs to be called with inline assembly. The [following code](https://docs.klaytn.com/smart-contract/precompiled-contracts#address-0x-04-datacopy-data) (adapted to Solidity), can be used to call this precompiled contract. We can use this [online tool](https://web3-type-converter.onbrn.com/) to get bytes from any string, as this is the input of the method `callDataCopy()`.
+
+```solidity
+pragma solidity ^0.7.0;
+
+contract Identity{
+
+ bytes public memoryStored;
+
+ function callDatacopy(bytes memory data) public returns (bytes memory) {
+ bytes memory result = new bytes(data.length);
+ assembly {
+ let len := mload(data)
+ if iszero(call(gas(), 0x04, 0, add(data, 0x20), len, add(result,0x20), len)) {
+ invalid()
+ }
+ }
+
+ memoryStored = result;
+
+ return result;
+ }
+}
+```
+With the contract deployed, we can call the `callDataCopy()` method and verify if `memoryStored` matches the bytes that you pass in as an input of the function.
diff --git a/docs/builders/tools/pubsub.md b/docs/builders/tools/pubsub.md
new file mode 100644
index 00000000..dce523e4
--- /dev/null
+++ b/docs/builders/tools/pubsub.md
@@ -0,0 +1,238 @@
+---
+title: Events Subscription
+sidebar_position: 11
+description: Use Ethereum-like publish-subscribe functionality to subscribe to specific events on Darwinia's Ethereum-compatible chain.
+---
+
+# Subscribe to Events in Pangolin
+
+## Introduction
+The ability to subscribe to Ethereum-style events was supported by Pangolin. In this guide, we will outline the subscription types available and current limitations.
+
+## Checking Prerequisites
+The examples in this guide are based on a MacOS environment. You will also need the following:
+
+ - Have MetaMask installed and [connected to Pangolin](/dvm/wallets/dvm-metamask.md)
+ - Have an account with funds. You can get this from [Faucet](/builders/get-started/darwinia-pangolin/#get-tokens)
+ - Deploy your own ERC-20 token on Pangolin. You can do following [our Remix tutorial](/builders/interact/remix/), while first pointing MetaMask to Pangolin
+
+import InstallNodeJs from '/snippets/text/common/install-nodejs.md';
+
+
+
+As of writing of this guide, the versions used were 16.0.0 and 7.10.0, respectively. We will also need to install the Web3 package by executing:
+
+```
+npm install --save web3
+```
+
+To verify the installed version of Web3, you can use the `ls` command:
+
+```
+npm ls web3
+```
+
+As of writing this guide, the version used was 1.3.0.
+
+## Subscribing to Event Logs in Pangolin
+Any contract that follows the ERC-20 token standard emits an event related to a transfer of tokens, that is, `event Transfer(address indexed from, address indexed to, uint256 value)`. For this example, we will subscribe to the logs of such events. Using the web3.js library, we need the following piece of code:
+
+```js
+const Web3 = require('web3');
+const web3 = new Web3('wss://pangolin-rpc.darwinia.network');
+
+web3.eth.subscribe('logs', {
+ address: 'ContractAddress',
+ topics: ['0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef']
+}, (error, result) => {
+ if (error)
+ console.error(error);
+})
+ .on("connected", function (subscriptionId) {
+ console.log(subscriptionId);
+ })
+ .on("data", function (log) {
+ console.log(log);
+ });
+```
+
+Note that we are connecting to the WebSocket endpoint of Pangolin. We use the `web3.eth.subscribe(‘logs’, options [, callback])` method to subscribe to the logs, filtered by the given options. In our case, the options are the contract’s address where the events are emitted from and the topics used to describe the event. More information about topics can be found in [this Medium post](https://medium.com/mycrypto/understanding-event-logs-on-the-ethereum-blockchain-f4ae7ba50378). If no topics are included, you subscribe to all events emitted by the contract. In order to only filter the Transfer event, we need to include the signature of the event, calculated as:
+
+```js
+EventSignature = keccak256(Transfer(address,address,uint256))
+```
+
+The result of the calculation is shown in the previous code snippet. We’ll return to filtering by topics later on. The rest of the code handles the callback function. Once we execute this code, we’ll get a subscription ID, and the terminal will wait for any event through that subscription:
+
+```
+$ event node contracts-events.js
+0x4d4c476b6759683667557170434f6276
+```
+
+Next, an ERC-20 token transfer will be sent with the following parameters:
+
+ - From address: 0xA4ADf2A419Fe24e7f6527F76AfBA5674BF9252f3
+ - To address: 0xF712eEa0FC84D94b7f0ACc14bB3F248BdB454cF9
+ - Value (tokens): 1000000000000000000 - that is 1 with 18 zeros
+
+Once we send the transaction, the log of the event emitted by the transaction will appear in the terminal:
+```
+$ event node contracts-events.js
+0x4d4c476b6759683667557170434f6276
+{
+ address: '0x0883474d63bBC730c34Cccb5269a1c0f1a7F1310',
+ blockHash: '0xc966b7495399dfaf499827de46fa4b9733d22edfee8008246898656e377111da',
+ blockNumber: 687284,
+ data: '0x0000000000000000000000000000000000000000000000000de0b6b3a7640000',
+ logIndex: 0,
+ removed: false,
+ topics: [
+ '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
+ '0x000000000000000000000000a4adf2a419fe24e7f6527f76afba5674bf9252f3',
+ '0x000000000000000000000000f712eea0fc84d94b7f0acc14bb3f248bdb454cf9'
+ ],
+ transactionHash: '0x2cde426491b264b366eaa6cc850672ebf1fac0996a80f8e035cba73c5edf3db0',
+ transactionIndex: 0,
+ transactionLogIndex: '0x0',
+ id: 'log_e350b838'
+}
+```
+
+
+Let's break down the response received. Our target event sends two pieces of indexed information: the `from` and `to` addresses (in that order), which are treated like topics. The other piece of data shared by our event is the number of tokens, which is not indexed. Therefore, there is a total of three topics (the maximum is four), which correspond to the opcode LOG3:
+
+
+Consequently, you can see that the `from` and `to` addresses are contained inside the topics returned by the logs. Ethereum addresses are 40 hex characters long (1 hex character is 4 bits, hence 160 bits or H160 format). Thus, the extra 24 zeros are needed to fill the gap to H256, which is 64 hex characters long.
+
+Unindexed data is returned in the `data` field of the logs, but this is encoded in bytes32/hex. To decode it we can use, for example, this [online tool](https://web3-type-converter.onbrn.com/), and verify that the `data` is in fact 1 (plus 18 zeros).
+
+If the event returns multiple unindexed values, they will be appended one after the other in the same order the event emits them. Therefore, each value is then obtained by deconstructing data into separate 32 bytes (or 64 hex character long) pieces.
+
+### Using Wildcards and Conditional Formatting
+Using the same example as in the previous section, lets subscribe to the events of the token contract with the following code:
+
+```js
+const Web3 = require('web3');
+const web3 = new Web3('wss://pangolin-rpc.darwinia.network');
+
+web3.eth
+ .subscribe(
+ 'logs',
+ {
+ address: 'ContractAddress',
+ topics: [
+ null,
+ [
+ '0x000000000000000000000000a4adf2a419fe24e7f6527f76afba5674bf9252f3',,
+ '0x000000000000000000000000f712eea0fc84d94b7f0acc14bb3f248bdb454cf9',
+ ],
+ ],
+ },
+ (error, result) => {
+ if (error) console.error(error);
+ }
+ )
+ .on('connected', function (subscriptionId) {
+ console.log(subscriptionId);
+ })
+ .on('data', function (log) {
+ console.log(log);
+ });
+```
+
+Here, by using the wildcard null in place for the event signature, we filter to listen to all events emitted by the contract that we subscribed to. But with this configuration, we can also use a second input field (`topic_1`) to define a filter by address as mentioned before. In the case of our subscription, we are notifying that we want to only receive events where `topic_1` is one of the addresses we are providing. Note that the addresses need to be in H256 format. For example, the address `0xA4ADf2A419Fe24e7f6527F76AfBA5674BF9252f3` needs to be entered as `0x000000000000000000000000a4adf2a419fe24e7f6527f76afba5674bf9252f3`. As before, the output of this subscription will display the event signature in `topic_0` to tell us which event was emitted by the contract.
+
+```
+$ event node contracts-events.js
+{
+ address: '0x0883474d63bBC730c34Cccb5269a1c0f1a7F1310',
+ blockHash: '0x4d38a4253cf565a969612a19274c7b4acce3d8e8dbf445187a0c4e9ed9fd9510',
+ blockNumber: 687689,
+ data: '0x0000000000000000000000000000000000000000000000000de0b6b3a7640000',
+ logIndex: 0,
+ removed: false,
+ topics: [
+ '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
+ '0x000000000000000000000000a4adf2a419fe24e7f6527f76afba5674bf9252f3',
+ '0x000000000000000000000000f712eea0fc84d94b7f0acc14bb3f248bdb454cf9'
+ ],
+ transactionHash: '0xe179e187a7e60a96801ab39dd215807ab61066136cd4c8c0ff2a9a91ba208dd2',
+ transactionIndex: 0,
+ transactionLogIndex: '0x0',
+ id: 'log_c985230f'
+}
+{
+ address: '0x0883474d63bBC730c34Cccb5269a1c0f1a7F1310',
+ blockHash: '0xc966b7495399dfaf499827de46fa4b9733d22edfee8008246898656e377111da',
+ blockNumber: 687284,
+ data: '0x0000000000000000000000000000000000000000000000000de0b6b3a7640000',
+ logIndex: 0,
+ removed: false,
+ topics: [
+ '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
+ '0x000000000000000000000000a4adf2a419fe24e7f6527f76afba5674bf9252f3',
+ '0x000000000000000000000000f712eea0fc84d94b7f0acc14bb3f248bdb454cf9'
+ ],
+ transactionHash: '0x2cde426491b264b366eaa6cc850672ebf1fac0996a80f8e035cba73c5edf3db0',
+ transactionIndex: 0,
+ transactionLogIndex: '0x0',
+ id: 'log_e350b838'
+}
+```
+
+As shown, after we provided the two addresses with conditional formatting, we received two logs with the same subscription ID. Events emitted by transactions from different addresses will not throw any logs to this subscription.
+
+This example showed how we could subscribe to just the event logs of a specific contract, but the web3.js library provides other subscription types that we’ll go over in the following sections.
+
+## Subscribe to Incoming Pending Transactions
+In order to subscribe to pending transactions, we can use the `web3.eth.subscribe('pendingTransactions', [, callback])` method, implementing the same callback function to check for the response. This is much simpler than our previous example, and it returns the transaction hash of the pending transactions.
+
+```
+$ event node pending-tx.js
+0x4a767a6c61566e63587077346f665a71
+0x1dcc68d6e6b66e885c765f4733909d642ba53ad6354d62d8823145184645fcad
+0x9bdc01fef632bbd4ef48d47751d3d255e8dc7f90fe530db70d32ea755af16a9c
+```
+
+
+We can verify that this transaction hash is the same as that shown in MetaMask (or Remix).
+
+## Subscribe to Incoming Block Headers
+Another type available under the Web3.js library is to subscribe to new block headers. To do so, we use the `web3.eth.subscribe('newBlockHeaders' [, callback])` method, implementing the same callback function to check for the response. This subscription provides incoming block headers and can be used to track changes in the blockchain.
+
+```
+$ event node block-headers.js
+0x47586b513475396a74543274414b725a
+{
+ author: '0x07c0a51e0d88ede9d531f165e370013b648e6b62',
+ difficulty: '0',
+ extraData: '0x',
+ gasLimit: 4294967295,
+ gasUsed: 0,
+ hash: '0x49a51bc4d07f4715c124ecb3bb0ab3e0afdddc22b2048d45dd2e679931f8f223',
+ logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
+ miner: '0x07C0A51e0D88Ede9D531f165E370013b648e6b62',
+ number: 687807,
+ parentHash: '0xdc7c74b5ef125737f5f68fa1ef6e51874efbb9811f13f43f14086bfd6ecbd804',
+ receiptsRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
+ sealFields: [
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
+ '0x0000000000000000'
+ ],
+ sha3Uncles: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347',
+ size: 514,
+ stateRoot: '0xbb7843482f08c6010df7eb7e9e55b445a6d5c5ea451e1ba3b8873bd6518326f9',
+ timestamp: 1632924588000,
+ transactionsRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421'
+}
+```
+
+Note that only one block header is shown in the image. These messages are displayed for every block produced so they can fill up the terminal quite fast.
+
+## Check if a Node is Synchronized with the Network
+With pub/sub it is also possible to check whether a particular node you are subscribed to is currently synchronized with the network. For that, we can leverage the `web3.eth.subscribe('syncing' [, callback])` method, implementing the same callback function to check for the response. This subscription will return an object when the node is synced with the network.
+
+
+## Current Limitations
+The pub/sub implementation in [Frontier](https://github.com/paritytech/frontier) is still in active development. This first version allows DApp developers (or users in general) to subscribe to specific event types, but there are still some limitations. You may have noticed from previous examples that some of the fields are not showing proper information with the current version released, and that is because certain properties are yet to be supported by Frontier.
+
diff --git a/docs/builders/tools/remix.md b/docs/builders/tools/remix.md
new file mode 100644
index 00000000..9d0f53cf
--- /dev/null
+++ b/docs/builders/tools/remix.md
@@ -0,0 +1,43 @@
+---
+title: Remix
+sidebar_position: 4
+description: Learn how to use one of the most popular Ethereum developer tools, the Remix IDE, to interact with Darwinia.
+---
+
+# Remix
+
+## Introduction
+
+Another tool developers can use to interact with Pangolin is the [Remix IDE](https://remix.ethereum.org/), one of the most commonly used development environments for smart contracts on Ethereum. It provides a web-based solution to quickly compile and deploy Solidity and Vyper based code to either a local VM or, more interestingly, an external Web3 provider, such as MetaMask. By combining both tools, one can get started very swiftly with Pangolin.
+
+## Deploying a Contract to Pangolin
+
+To demonstrate how you can leverage [Remix](https://remix.ethereum.org/) to deploy smart contracts to Pangolin, we will use the following basic contract:
+
+```solidity
+pragma solidity ^0.7.5;
+contract SimpleContract{
+ string public text;
+
+ constructor(string memory _input) {
+ text = _input;
+ }
+}
+```
+
+Once you've compiled the contract and are ready to deploy you can navigate to the "Deploy & Run Transactions" tab in Remix and follow these steps:
+
+1. Set the Remix environment to "Injected Web3"
+2. Set your account and ensure you have funds. For Pangolin, you can use our [TestNet faucet](/builders/get-started/darwinia-pangolin/#get-tokens)
+3. Pass in `Test Contract` as input to the contructor function and hit "Deploy"
+4. MetaMask will pop-up and show the information regarding the transaction, which you'll need to sign by clicking "Confirm"
+
+
+
+Once the transaction is included, the contract appears in the "Deployed Contracts" section on Remix. In there, we can interact with the functions available from our contract.
+
+
+
+## Tutorial
+
+If you are interested in a more detailed step-by-step guide, go to our specific tutorials about [using Remix](/builders/interact/remix/) with Pangolin.
diff --git a/docs/builders/tools/truffle.md b/docs/builders/tools/truffle.md
new file mode 100644
index 00000000..78ce0cb9
--- /dev/null
+++ b/docs/builders/tools/truffle.md
@@ -0,0 +1,68 @@
+---
+title: Truffle
+sidebar_position: 6
+description: Learn how to configure Truffle to add a local Darwinia development node and the Pangolin TestNet as networks for testing and deploying Solidity smart contracts.
+---
+
+# Truffle
+
+## Introduction
+
+[Truffle](https://www.trufflesuite.com/truffle) is a popular development framework for compiling, testing, and deploying Solidity smart contracts. Since Pangolin is Ethereum compatible, with a few lines of extra configuration, you can use Truffle as you normally would with Ethereum to develop on Pangolin.
+
+## Configure Truffle to Connect to Pangolin
+
+If you haven't yet, you'll want to globally install Truffle:
+
+```
+npm install -g truffle
+```
+
+In your `truffle-config.js` file, add network configurations for a Darwinia development node and the Pangolin TestNet:
+
+```javascript
+const HDWalletProvider = require('@truffle/hdwallet-provider');
+// Darwinia Development Node Private Key
+const privateKeyDev = 'YOUR-PRIVATE-KEY-HERE';
+// Pangolin Private Key
+const privateKeyPangolin = "YOUR-PRIVATE-KEY-HERE";
+// Crab Private Key - Note: This is for example purposes only. Never store your private keys in a JavaScript file.
+const privateKeyCrab = "YOUR-PRIVATE-KEY-HERE";
+
+module.exports = {
+ networks: {
+ // Darwinia Development Node
+ dev: {
+ provider: () => {
+ return new HDWalletProvider(privateKeyDev, 'http://localhost:9933/')
+ },
+ network_id: 43,
+ },
+ // Pangolin TestNet
+ pangolin: {
+ provider: () => {
+ return new HDWalletProvider(
+ privateKeyPangolin,
+ 'http://pangolin-rpc.darwinia.network'
+ );
+ },
+ network_id: 43,
+ },
+ // Crab
+ crab: {
+ provider: () => {
+ return new HDWalletProvider(
+ privateKeyCrab,
+ 'http://crab-rpc.darwinia.network'
+ );
+ },
+ network_id: 44,
+ }
+ },
+};
+```
+
+
+## Tutorial
+
+If you are interested in a more detailed step-by-step guide, go to our specific tutorial about [using Truffle](/builders/interact/truffle/) with Pangolin.
diff --git a/docs/builders/tools/waffle.md b/docs/builders/tools/waffle.md
new file mode 100644
index 00000000..4231779d
--- /dev/null
+++ b/docs/builders/tools/waffle.md
@@ -0,0 +1,59 @@
+---
+title: Waffle
+sidebar_position: 7
+description: Learn how to configure Waffle for testing Solidity smart contracts to either a locally running Darwinia development node or the Pangolin TestNet.
+---
+
+# Waffle
+
+## Introduction
+
+[Waffle](https://www.getwaffle.io/) is a popular development framework for testing Solidity smart contracts. Since Pangolin is Ethereum compatible, with a few lines of extra configuration, you can use Waffle as you normally would with Ethereum to develop on Pangolin.
+
+## Configure Waffle to Connect to Pangolin
+
+Assuming you already have a JavaScript or TypeScript project, install Waffle:
+
+```
+npm install ethereum-waffle
+```
+
+To configure Waffle to run tests against a Darwinia development node or the Pangolin TestNet, within your tests create a custom provider and add network configurations:
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+
+
+
+```js
+describe ('Test Contract', () => {
+ // Use custom provider to connect to Pangolin or Darwinia development node
+ const pangolinProvider = new ethers.providers.JsonRpcProvider('http://pangolin-rpc.darwinia.network');
+ const devProvider = new ethers.providers.JsonRpcProvider('http://localhost:9933');
+})
+```
+
+
+
+
+```typescript
+describe ('Test Contract', () => {
+ // Use custom provider to connect to Pangolin or Darwinia development node
+ const pangolinProvider: Provider = new ethers.providers.JsonRpcProvider('http://pangolin-rpc.darwinia.network');
+ const devProvider: Provider = new ethers.providers.JsonRpcProvider('http://localhost:9933');
+})
+```
+
+
+
+
+## Tutorial
+
+If you are interested in a more detailed step-by-step guide on how to use Waffle, go to our specific tutorial about using [Waffle & Mars](/builders/interact/waffle-mars/) on Pangolin.
diff --git a/docs/crab-network/_category_.json b/docs/crab-network/_category_.json
new file mode 100644
index 00000000..eef9c21e
--- /dev/null
+++ b/docs/crab-network/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Crab Network",
+ "position": 1
+}
diff --git a/docs/crab-home.md b/docs/crab-network/crab-home.md
similarity index 99%
rename from docs/crab-home.md
rename to docs/crab-network/crab-home.md
index 45dc943e..ea8659e8 100644
--- a/docs/crab-home.md
+++ b/docs/crab-network/crab-home.md
@@ -2,6 +2,7 @@
id: crab-home
title: Darwinia Crab Network
sidebar_label: Crab Network
+sidebar_position: 1
slug: /
---
diff --git a/docs/crab-parameters.md b/docs/crab-network/crab-parameters.md
similarity index 99%
rename from docs/crab-parameters.md
rename to docs/crab-network/crab-parameters.md
index 8341b987..7637ceb6 100644
--- a/docs/crab-parameters.md
+++ b/docs/crab-network/crab-parameters.md
@@ -2,6 +2,7 @@
id: crab-parameters
title: Crab Network Parameters
sidebar_label: Parameters
+sidebar_position: 3
---
> This page intends to reflect current network configurations, it reflects the [runtime file](https://github.com/darwinia-network/darwinia-common/blob/master/bin/node-template/runtime/src/lib.rs), which is still a work in progress.
diff --git a/docs/crab-tools.md b/docs/crab-network/crab-tools.md
similarity index 94%
rename from docs/crab-tools.md
rename to docs/crab-network/crab-tools.md
index df88c9e0..40fa7749 100644
--- a/docs/crab-tools.md
+++ b/docs/crab-network/crab-tools.md
@@ -2,6 +2,7 @@
id: crab-tools
title: Tools
sidebar_label: Tools
+sidebar_position: 2
---
## Wallet
diff --git a/docs/crab-tut-governance.md b/docs/crab-tut-governance.md
deleted file mode 100644
index 5011f820..00000000
--- a/docs/crab-tut-governance.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-id: crab-tut-governance
-title: How to participate in governance
-sidebar_label: Participate in governance
----
-
-TBD
\ No newline at end of file
diff --git a/docs/crab-tut-relayer.md b/docs/crab-tut-relayer.md
deleted file mode 100644
index 168336e7..00000000
--- a/docs/crab-tut-relayer.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-id: crab-tut-relayer
-title: How to become a relayer
-sidebar_label: Become a relayer
----
-
-TBD
\ No newline at end of file
diff --git a/docs/crab-tuts.md b/docs/crab-tuts.md
deleted file mode 100644
index ae6986a7..00000000
--- a/docs/crab-tuts.md
+++ /dev/null
@@ -1,15 +0,0 @@
----
-id: crab-tut
-title: Tutorials List
-sidebar_label: Tutorials
----
-## Staking
-- Become a Nominator [View Guide](crab-tut-nominator)
-- Run a Node [View Guide](crab-tut-node)
-- Become a Validator [View Guide](crab-tut-validator)
-- Participate in Governance [View Guide](crab-tut-governance)
-- Become a Relayer [View Guide](crab-tut-relayer)
-
-## Other
-- Create an Account [View Guide](crab-tut-create-account)
-- Claim your CRING (test coin) [View Guide](crab-tut-claim-cring)
diff --git a/docs/dvm-explorer.md b/docs/dvm-explorer.md
deleted file mode 100644
index 847558ca..00000000
--- a/docs/dvm-explorer.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-id: dvm-explorer
-title: DVM Explorer
-sidebar_label: Explorer
----
-
-[Subscan](https://crab.subscan.io/) is a powerful, user-friendly multi-chain browser that adds support for DVM smart contract solutions now.
-
-## Preparation
-
-Switch network and select the network for which you want to query data.
-
-
-
-## Get transaction information
-
-Enter the DVM transaction hash in the search box and click `Search`.
-
-
-
-
-
-## Get account information
-
-
-
-As shown above, the relationship between the DVM account and the Substrate account, the account balance, the staking and the transaction history can be clearly displayed.
diff --git a/docs/dvm-metamask.md b/docs/dvm-metamask.md
deleted file mode 100644
index 242ca205..00000000
--- a/docs/dvm-metamask.md
+++ /dev/null
@@ -1,47 +0,0 @@
----
-id: dvm-metamask
-title: Metamask
-sidebar_label: Metamask
----
-
-Since the DVM and the Ethereum virtual machine are compatible in the underlying specifications, users can use the wallets from the existing Ethereum ecosystem to manage their assets. Here we will introduce how to use Metamask.
-
-### Connect with Metamask
-
-1. Install the Metamask plugin, download and install it yourself.
-2. Add a custom network, here is an example of adding a Pangolin test network, different networks have different configuration parameters.
-
-
-
-
-
-The different network configuration are as follows.
-
-| Network | RPC URL | ChainId | Currency| Block Explorer URL |
-| ---------| ------------------------------------ | -------| --------|---------- |
-| Pangolin | http://pangolin-rpc.darwinia.network | 43 | PRING | https://pangolin.subscan.io/ |
-| Crab | http://crab-rpc.darwinia.network | 44 | CRING | https://crab.subscan.io/ |
-
-
-
-### Transfer
-
-Demonstrating how to use Metamask to transfer and query transactions in a DVM on the Pangolin test network.
-
-1. Click `Send` and enter the transfer parameters.
-
-
-
-
-2. Click `Confirm` to send transaction.
-
-
-
-3. The transfer executed successfully.
-
-
-
-4. View details of the transaction execution in your browser.
-
-
-
diff --git a/docs/dvm-remix.md b/docs/dvm-remix.md
deleted file mode 100644
index 16cda1ed..00000000
--- a/docs/dvm-remix.md
+++ /dev/null
@@ -1,53 +0,0 @@
----
-id: dvm-remix
-title: Remix
-sidebar_label: Remix
----
-
-Since the DVM and the Ethereum virtual machine are compatible in the underlying specifications, users can use the the existing contract development tools of Ethereum ecosystem. Here we will introduce how to use Remix to execute contracts.
-
-## Prepare a contract
-
-```js
-pragma solidity ^0.6.0;
-
-contract Incrementer {
- uint256 public number;
-
- function increment(uint256 _value) public {
- number = number + _value;
- }
-
- function reset() public {
- number = 0;
- }
-}
-```
-
-Click on `Compile` to compile the program and make sure it compiles successfully.
-
-
-
-## Connect to Metamask
-
-Remix can use a DVM account on Metamask and deploy the contract directly to the corresponding network. Note that DVM accounts need to be bound to Metamask first, see [Using Metamask with DVM accounts](dvm-metamask). ENVIRONMENT Select `Injected Web3`, select the DVM account in the Metamask pop-up window and click `Next`.
-
-
-
-## Execute the contract
-
-Once you have successfully connected to Metamask, click `Deploy` to deploy the contract and the console will display the execution process of the transaction.
-
-
-
-When the contract is successfully deployed, Click `number` to make a contract call, which returns 0.
-
-
-
-Click `increment` to make another call.
-
-
-
-Click `number` again to make a contract call, and the result is 5 now.
-
-
diff --git a/docs/dvm-web3-contract.md b/docs/dvm-web3-contract.md
deleted file mode 100644
index 3df5964a..00000000
--- a/docs/dvm-web3-contract.md
+++ /dev/null
@@ -1,306 +0,0 @@
----
-id: dvm-web3-contract
-title: Web3 Contract
-sidebar_label: Web3 Contract
----
-
-## Preparations
-
-1. Install Node.js
-
-```sh
-$ sudo apt install -y nodejs
-```
-
-2. install web3, solc package
-
-```sh
-$ mkdir incrementer && cd incrementer/
-$ npm init --yes
-$ npm install --save web3
-$ npm install --save solc@0.6.10
-```
-
-3. The project layout as follows:
-
-```sh
-$ ls incrementer/
-compile.js deploy.js get.js Incrementer.sol increment.js node_modules/ package.json package-lock.json reset.js
-```
-
-## Play with contract
-
-A simple solidity contract demo.
-
-```js
-// Incrementer.sol
-pragma solidity ^0.6.0;
-
-contract Incrementer {
- uint256 public number;
-
- constructor(uint256 _initialNumber) public {
- number = _initialNumber;
- }
-
- function increment(uint256 _value) public {
- number = number + _value;
- }
-
- function reset() public {
- number = 0;
- }
-}
-```
-
-### Deploy contract
-
-```js
-// compile.js
-const path = require('path');
-const fs = require('fs');
-const solc = require('solc');
-
-// Compile contract
-const contractPath = path.resolve(__dirname, 'Incrementer.sol');
-const source = fs.readFileSync(contractPath, 'utf8');
-const input = {
- language: 'Solidity',
- sources: {
- 'Incrementer.sol': {
- content: source,
- },
- },
- settings: {
- outputSelection: {
- '*': {
- '*': ['*'],
- },
- },
- },
-};
-
-const tempFile = JSON.parse(solc.compile(JSON.stringify(input)));
-const contractFile = tempFile.contracts['Incrementer.sol']['Incrementer'];
-module.exports = contractFile;
-```
-
-```js
-// deploy.js
-const Web3 = require('web3');
-const contractFile = require('./compile');
-
-// Initialization
-const bytecode = contractFile.evm.bytecode.object;
-const abi = contractFile.abi;
-const privKey =
- '99B3C12287537E38C90A9219D4CB074A89A16E9CDB20BF85728EBD97C343E342'; // Genesis private key
-const address = '0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b';
-const web3 = new Web3('http://localhost:9933');
-
-// Deploy contract
-const deploy = async () => {
- console.log('Attempting to deploy from account:', address);
-
- const incrementer = new web3.eth.Contract(abi);
-
- const incrementerTx = incrementer.deploy({
- data: bytecode,
- arguments: [5],
- });
-
- const createTransaction = await web3.eth.accounts.signTransaction(
- {
- from: address,
- data: incrementerTx.encodeABI(),
- gas: '4294967295',
- },
- privKey
- );
-
- const createReceipt = await web3.eth.sendSignedTransaction(
- createTransaction.rawTransaction
- );
- console.log('Contract deployed at address', createReceipt.contractAddress);
- };
-
- deploy();
-```
-
-Deploy contract using the command:
-
-```sh
-$ node deploy.js
-```
-
-The output:
-
-```sh
-Attempting to deploy from account: 0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b
-Contract deployed at address 0x5c4242beB94dE30b922f57241f1D02f36e906915
-```
-
-The contract address `0x5c4242beB94dE30b922f57241f1D02f36e906915`.
-
-### Get number
-
-```js
-// get.js
-const Web3 = require('web3');
-const { abi } = require('./compile');
-
-// Initialization
-const address = '0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b';
-const web3 = new Web3('http://localhost:9933');
-const contractAddress = '0x5c4242beB94dE30b922f57241f1D02f36e906915';
-
-// Contract Call
-const incrementer = new web3.eth.Contract(abi, contractAddress);
-const get = async () => {
- console.log(`Making a call to contract at address ${contractAddress}`);
- const data = await incrementer.methods
- .number()
- .call();
- console.log(`The current number stored is: ${data}`);
-};
-
-get();
-```
-
-Run command below:
-
-```sh
-$ node get.js
-```
-
-The output:
-
-```sh
-Making a call to contract at address 0x5c4242beB94dE30b922f57241f1D02f36e906915
-The current number stored is: 5
-```
-
-### Set number
-
-```js
-// increment.js
-const Web3 = require('web3');
-const { abi } = require('./compile');
-
-// Initialization
-const privKey =
- '99B3C12287537E38C90A9219D4CB074A89A16E9CDB20BF85728EBD97C343E342'; // Genesis private key
-const address = '0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b';
-const web3 = new Web3('http://localhost:9933');
-const contractAddress = '0x5c4242beB94dE30b922f57241f1D02f36e906915';
-const _value = 3;
-
-// Contract Tx
-const incrementer = new web3.eth.Contract(abi);
-const encoded = incrementer.methods.increment(_value).encodeABI();
-
-const increment = async () => {
- console.log(
- `Calling the increment by ${_value} function in contract at address ${contractAddress}`
- );
- const createTransaction = await web3.eth.accounts.signTransaction(
- {
- from: address,
- to: contractAddress,
- data: encoded,
- gas: '4294967295',
- },
- privKey
- );
-
- const createReceipt = await web3.eth.sendSignedTransaction(
- createTransaction.rawTransaction
- );
- console.log(`Tx successfully with hash: ${createReceipt.transactionHash}`);
-};
-
-increment();
-```
-
-Run command:
-
-```sh
-$ node increment.js
-```
-
-The output:
-
-```sh
-Calling the increment by 3 function in contract at address 0x5c4242beB94dE30b922f57241f1D02f36e906915
-Tx successfully with hash: 0x259078d1eefb40b9859748e2116c5bed04360583d5309e9d6947458bb5e1d0f9
-```
-
-Get the number value:
-
-```sh
-$ node get.js
-Making a call to contract at address 0x5c4242beB94dE30b922f57241f1D02f36e906915
-The current number stored is: 8
-```
-
-### Reset number
-
-```js
-// reset.js
-const Web3 = require('web3');
-const { abi } = require('./compile');
-
-// Initialization
-const privKey =
- '99B3C12287537E38C90A9219D4CB074A89A16E9CDB20BF85728EBD97C343E342'; // Genesis private key
-const address = '0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b';
-const web3 = new Web3('http://localhost:9933');
-const contractAddress = '0x5c4242beB94dE30b922f57241f1D02f36e906915';
-
-// Contract Tx
-const incrementer = new web3.eth.Contract(abi);
-const encoded = incrementer.methods.reset().encodeABI();
-
-const reset = async () => {
- console.log(
- `Calling the reset function in contract at address ${contractAddress}`
- );
- const createTransaction = await web3.eth.accounts.signTransaction(
- {
- from: address,
- to: contractAddress,
- data: encoded,
- gas: '4294967295',
- },
- privKey
- );
-
- const createReceipt = await web3.eth.sendSignedTransaction(
- createTransaction.rawTransaction
- );
- console.log(`Tx successfully with hash: ${createReceipt.transactionHash}`);
-};
-
-reset();
-```
-
-Run command:
-
-```sh
-$ node reset.js
-```
-
-The output:
-
-```sh
-Calling the reset function in contract at address 0x5c4242beB94dE30b922f57241f1D02f36e906915
-Tx successfully with hash: 0x79b8b47ba82e271cd6e105b07743f2a2f470b5fa923a0c97d7f75ce3a3bcceac
-```
-
-Get the number value:
-
-```sh
-$ node get.js
-Making a call to contract at address 0x5c4242beB94dE30b922f57241f1D02f36e906915
-The current number stored is: 0
-```
\ No newline at end of file
diff --git a/docs/dvm-web3-transfer.md b/docs/dvm-web3-transfer.md
deleted file mode 100644
index 7b0da16b..00000000
--- a/docs/dvm-web3-transfer.md
+++ /dev/null
@@ -1,124 +0,0 @@
----
-id: dvm-web3-transfer
-title: Web3 Transfer
-sidebar_label: Web3 Transfer
----
-
-## Preparations
-
-1. Install Nodejs
-
-```sh
-$ sudo apt install -y nodejs
-```
-
-2. install web3 package
-
-```sh
-$ mkdir transaction && cd transaction/
-$ npm init --yes
-$ npm install --save web3
-```
-
-3. The project layout as follows:
-
-```sh
-$ ls transaction/
-balance.js node_modules/ package.json package-lock.json transaction.js
-```
-
-## Get balance
-
-```js
-// balance.js
-const Web3 = require('web3');
-
-// Variables definition
-const addressFrom = '0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b';
-const addressTo = '0xAa01a1bEF0557fa9625581a293F3AA7770192632';
-const web3 = new Web3('http://localhost:9933');
-
-// Balance call
-const balances = async () => {
- const balanceFrom = web3.utils.fromWei(
- await web3.eth.getBalance(addressFrom),
- 'ether'
- );
- const balanceTo = await web3.utils.fromWei(
- await web3.eth.getBalance(addressTo),
- 'ether'
- );
-
- console.log(`The balance of ${addressFrom} is: ${balanceFrom} PRING.`);
- console.log(`The balance of ${addressTo} is: ${balanceTo} PRING.`);
-};
-
-balances();
-```
-
-The output:
-
-```sh
-$ node balance.js
-The balance of 0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b is: 123.45678900000000009 PRING.
-The balance of 0xAa01a1bEF0557fa9625581a293F3AA7770192632 is: 0 PRING.
-```
-
-## Transfer
-
-Make a transaction to Transfer 50 PRING from `0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b` to `0xAa01a1bEF0557fa9625581a293F3AA7770192632`.
-
-```js
-// transfer.js
-const Web3 = require('web3');
-
-// Variables definition
-const privKey =
- '99B3C12287537E38C90A9219D4CB074A89A16E9CDB20BF85728EBD97C343E342';
-const addressFrom = '0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b';
-const addressTo = '0xAa01a1bEF0557fa9625581a293F3AA7770192632';
-const web3 = new Web3('http://localhost:9933');
-
-// Create transaction
-const deploy = async () => {
- console.log(
- `Attempting to send transaction from ${addressFrom} to ${addressTo}`
- );
-
- const createTransaction = await web3.eth.accounts.signTransaction(
- {
- from: addressFrom,
- to: addressTo,
- value: web3.utils.toWei('50', 'ether'),
- gas: '5000000000',
- },
- privKey
- );
-
- const createReceipt = await web3.eth.sendSignedTransaction(
- createTransaction.rawTransaction
- );
-
- console.log(
- `Transaction successful with hash: ${createReceipt.transactionHash}`
- );
-
-}
-
-deploy();
-```
-
-The output:
-
-```sh
-$ node transaction.js
-Attempting to send transaction from 0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b to 0xAa01a1bEF0557fa9625581a293F3AA7770192632
-Transaction successful with hash: 0xaccfb5438c6927c6c32adc640394600f5dda183ea82683dc5a9feddc64b5d438
-```
-
-Get balances again:
-
-```sh
-The balance of 0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b is: 73.45678900000000009 PRING.
-The balance of 0xAa01a1bEF0557fa9625581a293F3AA7770192632 is: 50 PRING.
-```
diff --git a/docs/dvm/_category_.json b/docs/dvm/_category_.json
new file mode 100644
index 00000000..76bf7e83
--- /dev/null
+++ b/docs/dvm/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "DVM",
+ "position": 4
+}
diff --git a/docs/dvm-eco.md b/docs/dvm/dvm-eco.md
similarity index 97%
rename from docs/dvm-eco.md
rename to docs/dvm/dvm-eco.md
index 9fbe2580..c9a81593 100644
--- a/docs/dvm-eco.md
+++ b/docs/dvm/dvm-eco.md
@@ -2,6 +2,7 @@
id: dvm-eco
title: Ecosystem
sidebar_label: Ecosystem
+sidebar_position: 4
---
With the DVM smart contract solution, smart contract projects in the ethereum ecosystem can be easily migrated to the Crab Network. To encourage more community developers to build applications on DVM, Darwinia launched the [Grant Program](https://github.com/darwinia-network/collaboration/blob/master/grant/README.md) and [Bounty Program](https://github.com/darwinia-network/collaboration/blob/master/bounty/README.md).
diff --git a/docs/dvm-intro.md b/docs/dvm/dvm-intro.md
similarity index 96%
rename from docs/dvm-intro.md
rename to docs/dvm/dvm-intro.md
index c50b7615..36fcfeac 100644
--- a/docs/dvm-intro.md
+++ b/docs/dvm/dvm-intro.md
@@ -2,6 +2,7 @@
id: dvm-intro
title: DVM Introduction
sidebar_label: Introduction
+sidebar_position: 1
---
Darwinia Network has been working on the cross-chain area with the aim of interconnecting multiple chains, and Darwinia Network also wants to help existing blockchain applications migrate more easily between different networks.
diff --git a/docs/dvm/overview/_category_.json b/docs/dvm/overview/_category_.json
new file mode 100644
index 00000000..fbe9f1ee
--- /dev/null
+++ b/docs/dvm/overview/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Overview",
+ "position": 2
+}
diff --git a/docs/dvm-address.md b/docs/dvm/overview/dvm-address.md
similarity index 94%
rename from docs/dvm-address.md
rename to docs/dvm/overview/dvm-address.md
index a4d67897..5571f95e 100644
--- a/docs/dvm-address.md
+++ b/docs/dvm/overview/dvm-address.md
@@ -2,6 +2,7 @@
id: dvm-address
title: DVM Address
sidebar_label: Address
+sidebar_position: 1
---
The Crab Network and the Pangolin testnet use the account address format based on the [SS58 Address](https://substrate.dev/docs/en/knowledgebase/advanced/ss58-address-format). In order to be compatible with the ethereum smart contract ecosystem, a second address format is introduced on top of the existing network, namely DVM address.
@@ -20,4 +21,4 @@ The rules for address conversion are shown in the following diagram:
Address conversion can be done by using the [Web Apps](https://apps.darwinia.network/#/account) tool. Click on `Toolbox` > `DVM Address`, enter the address of the DVM account to be converted.
-
+
diff --git a/docs/dvm-system-contract.md b/docs/dvm/overview/dvm-system-contract.md
similarity index 99%
rename from docs/dvm-system-contract.md
rename to docs/dvm/overview/dvm-system-contract.md
index fa48ba90..b46e230e 100644
--- a/docs/dvm-system-contract.md
+++ b/docs/dvm/overview/dvm-system-contract.md
@@ -2,6 +2,7 @@
id: dvm-system-contract
title: DVM System contract
sidebar_label: System contract
+sidebar_position: 2
---
System contract is a special smart contract with a fixed contract address, similar to an ethereum pre-compiled contract.
diff --git a/docs/dvm/wallets/_category_.json b/docs/dvm/wallets/_category_.json
new file mode 100644
index 00000000..9f0647f9
--- /dev/null
+++ b/docs/dvm/wallets/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Wallets",
+ "position": 3
+}
diff --git a/docs/dvm-apps.md b/docs/dvm/wallets/dvm-apps.md
similarity index 83%
rename from docs/dvm-apps.md
rename to docs/dvm/wallets/dvm-apps.md
index 09b6b971..c61a372d 100644
--- a/docs/dvm-apps.md
+++ b/docs/dvm/wallets/dvm-apps.md
@@ -2,13 +2,14 @@
id: dvm-apps
title: Apps
sidebar_label: Apps
+sidebar_position: 1
---
As every DVM account has a corresponding Substrate address, the balance of a DVM account can be checked at [Web Apps](https://apps.darwinia.network/#/account).
## Address Conversion
-The way to generate the corresponding Substrate address of a DVM account. See [address conversion](dvm-address).
+The way to generate the corresponding Substrate address of a DVM account. See [address conversion](/dvm/overview/dvm-address.md).
For example, the DVM account address `0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b` has a Substrate address `2qSbd2umtD4KmV2X6UEyn3zQ6jFT13jZEybLwc3hn5kiMmeD`.
@@ -19,4 +20,4 @@ Click on `Toolbox` > `RPC Requests` > `balances` and enter:
- accountId: Substrate account id
- tokentype: 0 for RING balance, 1 for KTON balance
-
+
diff --git a/docs/dvm/wallets/dvm-metamask.md b/docs/dvm/wallets/dvm-metamask.md
new file mode 100644
index 00000000..b8cf5fe5
--- /dev/null
+++ b/docs/dvm/wallets/dvm-metamask.md
@@ -0,0 +1,95 @@
+---
+id: dvm-metamask
+title: Metamask
+sidebar_label: Metamask
+sidebar_position: 2
+---
+
+The DVM account address format is consistent with the Ethereum account address format and the generation method. The difference is that each DVM account address corresponds to a unique Substrate account address. In other words, the DVM address is first an Ethereum address, but it also corresponds to a Substrate address in addition to the Ethereum address. Currently, you can use the Apps tool to generate the Stustrate address corresponding to the DVM address. Since the DVM and the Ethereum virtual machine are compatible in the underlying specifications, users can use the wallets from the existing Ethereum ecosystem to manage their assets, such as Metamask.
+
+### Connect with Metamask
+
+1. Install the Metamask plugin, download and install it yourself.
+2. Add a custom network, here is an example of adding a Pangolin test network, different networks have different configuration parameters.
++ Click `Custom RPC`.
+
+
+
++ Add Pangolin Test Network configuration parameters.
+
+
+
++ After the connection is successful, as shown in the figure below.
+
+
+
+The different network configuration are as follows.
+
+| Network | RPC URL | ChainID | Currency| Block Explorer URL |
+| ---------| ------------------------------------ | -------| --------|---------- |
+| Pangolin | http://pangolin-rpc.darwinia.network | 43 | PRING | https://pangolin.subscan.io/ |
+| Crab | http://crab-rpc.darwinia.network | 44 | CRAB | https://crab.subscan.io/ |
+
+### Address Conversion
+
+Use Apps tool to generate the Stustrate address corresponding to the DVM address.
+1. Copy the DVM address.
+
+
+
+2. Address conversion can be done by using the [Apps](https://apps.darwinia.network/#/toolbox/dvmaddress) tool. Click on `Toolbox`, `DVM Address`, enter the address of the copied DVM account.
+
+
+
+3. This address is the only Substrate address corresponding to the DVM address. Click the upper right corner to copy the Substrate address.
+
+
+
+4. You can apply for the test token from the Faucet through the generated Substrate address. For details, please refer to the following.
+
+### Apply for the test token
+
+1. Join the Telegram group named ["Darwinia Faucet Official"](https://t.me/darwiniafaucet_official).
+
+2. Send `/faucet@darwinia_faucet_bot`.
+
+
+
+3. Send `Faucet`+ the copied Substrate address corresponding to the DVM account address.
+
+
+
+4. You can open the link of the Darwinia_bot to check the transaction on Subscan.
+
+
+
+
+5. Since this Substrate address corresponds to a specific DVM address, when the test token is sent to the Substrate address, the corresponding DVM address can be managed through Metamask to achieve the purpose of managing this Substrate address.
+
+
+
+6. When querying the DVM address through Subscan, you can see its corresponding Substrate address at the same time.
+
+
+
+### Transfer
+
+Demonstrating how to use Metamask to transfer and query transactions in a DVM on the Pangolin test network.
+
+1. Click `Send` and enter the transfer parameters.
+
+
+
+
+2. Click `Confirm` to send transaction.
+
+
+
+3. The transfer executed successfully.
+
+
+
+4. View details of the transaction execution in your browser.
+
+
+
\ No newline at end of file
diff --git a/docs/dvm/wallets/smart-app/_category_.json b/docs/dvm/wallets/smart-app/_category_.json
new file mode 100644
index 00000000..b5644c0e
--- /dev/null
+++ b/docs/dvm/wallets/smart-app/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Smart App",
+ "position": 3
+}
diff --git a/docs/dvm-deposit.md b/docs/dvm/wallets/smart-app/dvm-deposit.md
similarity index 62%
rename from docs/dvm-deposit.md
rename to docs/dvm/wallets/smart-app/dvm-deposit.md
index e1c3cc36..75d3d249 100644
--- a/docs/dvm-deposit.md
+++ b/docs/dvm/wallets/smart-app/dvm-deposit.md
@@ -2,13 +2,14 @@
id: dvm-deposit
title: Deposit to a DVM address
sidebar_label: Deposit
+sidebar_position: 2
---
It is an action of transferring assets from a Substrate account to a DVM account. The receiving address is the Substrate address of the DVM account.
## Preparation
-You should have a DVM account to receive `PRING/PKTON`, if not, please use Metamask to generate one. See [How to use Metamask](dvm-metamask).
+You should have a DVM account to receive `PRING/PKTON`, if not, please use Metamask to generate one. See [How to use Metamask](/dvm/wallets/dvm-metamask.md).
## Deposit
@@ -16,46 +17,46 @@ You should have a DVM account to receive `PRING/PKTON`, if not, please use Metam
Click [Smart App](https://smart.darwinia.network/) -> `Connect Wallet` to connect to the account in Polkadot Js.
-
+
Select the account that you want to transfer assets from and click `Confirm`. Free `PRING` can be got at [Element](https://app.element.io/?pk_vid=6961ca0f7c45f8bf16052310122d2437#/room/#darwinia:matrix.org).
-
+
Once the Substrate account has been successfully connected.
-
+
Enter the DVM account address your prepared and the amount to be transfered and click on `Confirm`. The DVM account in the example is `0xB3A77a84E132465530cdb5738203eb00215D780b`
-
+
Click `Next`.
-
+
Click `Confirm`.
-
+
Enter your password in the Polkadot Js, sign and send the transaction.
-
+
## Check transaction
See transaction execution result in Subscan.
-
-
+
+
## Check if the transfer is successful
Check the balance in Subscan:
-
+
Check the balance in Metamask:
-
+
diff --git a/docs/dvm-smart-app.md b/docs/dvm/wallets/smart-app/dvm-smart-app.md
similarity index 76%
rename from docs/dvm-smart-app.md
rename to docs/dvm/wallets/smart-app/dvm-smart-app.md
index 9a0668c0..5f162cfd 100644
--- a/docs/dvm-smart-app.md
+++ b/docs/dvm/wallets/smart-app/dvm-smart-app.md
@@ -2,6 +2,7 @@
id: dvm-smart-app
title: Smart App
sidebar_label: Overview
+sidebar_position: 1
---
The [Smart App](https://smart.darwinia.network/) is a wallet that provides a user-friendly solution for transferring assets between DVM account and Substrate accounts
@@ -12,5 +13,5 @@ The Smart App currently only supports the Crab and Pangolin networks(the default
Take the example of switching to the Crab network:
-
-
+
+
diff --git a/docs/dvm-withdraw.md b/docs/dvm/wallets/smart-app/dvm-withdraw.md
similarity index 67%
rename from docs/dvm-withdraw.md
rename to docs/dvm/wallets/smart-app/dvm-withdraw.md
index f557dda5..39bb4474 100644
--- a/docs/dvm-withdraw.md
+++ b/docs/dvm/wallets/smart-app/dvm-withdraw.md
@@ -2,6 +2,7 @@
id: dvm-withdraw
title: Withdraw from a DVM address
sidebar_label: Withdraw
+sidebar_position: 3
---
It is an action of transferring assets from a DVM account to a Substrate account.
@@ -16,31 +17,31 @@ You should have a Substrate account to receive `PRING/PKTON`.
Open [Smart App](https://smart.darwinia.network/), and set `From` to `Smart` and `To` to `Substrate`.
-
+
Select the DVM account(the balance of this account should not be empty).
-
+
Once the association has been successfully established, like this:
-
+
Enter the address of your Substrate account prepared before, here is `2rPQTYLVvDToHK9efx9XMNZiAZ8uBYA3JJTdzqaTE9JynmsG`.
-
+
Click `Confirm` and then `Next`.
-
+
And then click the `Confirm` to sign and send the transaction.
-
+
## Check if the transfer is successful
Check your balance in Subscan:
-
+
diff --git a/docs/kusama-auction/_category_.json b/docs/kusama-auction/_category_.json
new file mode 100644
index 00000000..056f2988
--- /dev/null
+++ b/docs/kusama-auction/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Kusama Auction",
+ "position": 3
+}
diff --git a/docs/crab-crowdloan-howto-gateio.md b/docs/kusama-auction/crab-crowdloan-howto-gateio.md
similarity index 74%
rename from docs/crab-crowdloan-howto-gateio.md
rename to docs/kusama-auction/crab-crowdloan-howto-gateio.md
index 40b8e9cd..e95f5f68 100644
--- a/docs/crab-crowdloan-howto-gateio.md
+++ b/docs/kusama-auction/crab-crowdloan-howto-gateio.md
@@ -2,18 +2,19 @@
id: crab-crowdloan-howto-gateio
title: Contribute in Gateio
sidebar_label: Contribute in Gateio
+sidebar_position: 6
---
1. Open the Gateio mobile app and click "Join KSM Slot Auction!".
- 
+ 
2. Select "CRING" and click to see the project details.
- 
+ 
3. Fill in the quantity of KSM on this page and click "Subscribe".
- 
+ 
4. After the auction is over, the rewards will be issued directly in the Gateio, and users can see the rewards in the Gateio.
diff --git a/docs/crab-crowdloan-howto-hotbit.md b/docs/kusama-auction/crab-crowdloan-howto-hotbit.md
similarity index 76%
rename from docs/crab-crowdloan-howto-hotbit.md
rename to docs/kusama-auction/crab-crowdloan-howto-hotbit.md
index be6f6b9c..e5ef61fe 100644
--- a/docs/crab-crowdloan-howto-hotbit.md
+++ b/docs/kusama-auction/crab-crowdloan-howto-hotbit.md
@@ -2,16 +2,17 @@
id: crab-crowdloan-howto-hotbit
title: Contribute in Hotbit
sidebar_label: Contribute in Hotbit
+sidebar_position: 7
---
1. Go to https://www.hotbit.io/slotauction
- 
+ 
2. Select "Crab (CRING) Slot#1", select "Participate" and enter a certain amount of KSM.
- 
+ 
3. After the auction is over, the rewards will be issued directly in the Hotbit, and users can see the rewards in the Hotbit.
\ No newline at end of file
diff --git a/docs/crab-crowdloan-howto-math.md b/docs/kusama-auction/crab-crowdloan-howto-math.md
similarity index 81%
rename from docs/crab-crowdloan-howto-math.md
rename to docs/kusama-auction/crab-crowdloan-howto-math.md
index b1d3cc18..7664304c 100644
--- a/docs/crab-crowdloan-howto-math.md
+++ b/docs/kusama-auction/crab-crowdloan-howto-math.md
@@ -2,14 +2,15 @@
id: crab-crowdloan-howto-math
title: Contribute in Math Cloud Wallet
sidebar_label: Contribute in Math Cloud Wallet
+sidebar_position: 5
---
1. Go to https://cloud.mathwallet.xyz/#/auction
- 
+ 
2. Select "Darwinia Crab", click to enter the project details, directly fill in the amount of KSM on this page and click "Contribute".
- 
+ 
3. After the auction is over, the rewards will be issued directly in the Math Cloud Wallet, and users can see the rewards in the Math Cloud Wallet.
diff --git a/docs/crab-crowdloan-howto-okex.md b/docs/kusama-auction/crab-crowdloan-howto-okex.md
similarity index 88%
rename from docs/crab-crowdloan-howto-okex.md
rename to docs/kusama-auction/crab-crowdloan-howto-okex.md
index 0e34241d..d98a8fd2 100644
--- a/docs/crab-crowdloan-howto-okex.md
+++ b/docs/kusama-auction/crab-crowdloan-howto-okex.md
@@ -2,6 +2,7 @@
id: crab-crowdloan-howto-okex
title: Contribute in OKEx
sidebar_label: Contribute in OKEx
+sidebar_position: 4
---
@@ -9,21 +10,21 @@ sidebar_label: Contribute in OKEx
1. Visit the web version [OKEx](https://www.okex.com/) and go to "Finance" > "Earn" > "Parachain Slot Auction":
- 
+ 
2. Select "Crab Network" and click "Vote", enter the number of KSMs you want to contribute and confirm your vote:
- 
+ 
## Method 2: Join Crowdloan through OKEx mobile application
1. Open OKEx app and go to "Assets" > "Finance" > "Earn" > "Parachain Slot Auction":
- 
+ 
2. Select "Crab Network" and click click "Vote", enter the number of KSMs you want to contribute and confirm your vote:
- 
+ 
> **Important 1**: We have set aside 25% of CRING and 1% of RING token supplies for Kusama PLO over the next 10 years. We will bid for 8 periods of one slot for 48 weeks to ensure that the stability of the network is not affected. Considering the instability of the first few slots, we plan to join the slot auction in the 4th round of.
diff --git a/docs/crab-crowdloan-howto-polkadotjs.md b/docs/kusama-auction/crab-crowdloan-howto-polkadotjs.md
similarity index 81%
rename from docs/crab-crowdloan-howto-polkadotjs.md
rename to docs/kusama-auction/crab-crowdloan-howto-polkadotjs.md
index 47bd8a44..64d27032 100644
--- a/docs/crab-crowdloan-howto-polkadotjs.md
+++ b/docs/kusama-auction/crab-crowdloan-howto-polkadotjs.md
@@ -2,6 +2,7 @@
id: crab-crowdloan-howto-polkadotjs
title: Contribute through Polkadot.{js}
sidebar_label: Contribute through Polkadot.{js}
+sidebar_position: 3
---
Before participating in the crowdloan via Polkadot.{js}, please make sure that you have:
@@ -18,16 +19,16 @@ Before participating in the crowdloan via Polkadot.{js}, please make sure that y
1. Click "Network" in the toolbar > select "Parachains" > click "Crowdloan".
- 
+ 
2. Select "Crab Network" in "ongoing" and click "Contribute".
- 
+ 
3. Enter the amount of KSM you want to contribute, and click "Contribute".
- 
+ 
4. Finally, sign the transaction.
- 
\ No newline at end of file
+ 
\ No newline at end of file
diff --git a/docs/crab-crowdloan-howto-unstaking.md b/docs/kusama-auction/crab-crowdloan-howto-unstaking.md
similarity index 82%
rename from docs/crab-crowdloan-howto-unstaking.md
rename to docs/kusama-auction/crab-crowdloan-howto-unstaking.md
index b8405141..93cd9e29 100644
--- a/docs/crab-crowdloan-howto-unstaking.md
+++ b/docs/kusama-auction/crab-crowdloan-howto-unstaking.md
@@ -2,6 +2,7 @@
id: crab-crowdloan-howto-unstaking
title: Unstaking Your KSM Tokens on Polkadot.{js} Extension
sidebar_label: Unstaking
+sidebar_position: 2
---
You will need to unstake your KSM tokens prior to bonding them to the crowdloan module. For recently unstaked KSM tokens, Kusama has a delayed exit period (7 days), which serves as cooldown. During this period, you will not be able to transfer your tokens.
@@ -11,28 +12,28 @@ You will need to unstake your KSM tokens prior to bonding them to the crowdloan
1. Open [Polkadot{.js}](https://polkadot.js.org/apps/) and connect to the Kusama network. Then in the navigation bar at the top of the page, click on "Network" dropdown and select "Staking".
- 
+ 
2. Click on "Account actions" in the white sub-header towards the top of the screen. Then click "Stop" (towards the right of the screen) on the account that you'd like to unstake.
- 
+ 
3. Click on "Sign and Submit" in the bottom right corner to authorize the transaction. Your browser extension will prompt you to enter your password and sign the transaction. You have now stopped nominating, but your tokens remain bonded.
- 
+ 
4. To unbond your tokens, click the ellipses (three dots) on the right-hand side of the page and click on "Unbond funds".
- 
+ 
5. Enter the amount you'd like to unbond and then click on "Unbond". Then sign and submit the transaction.
- 
+ 
6. If done successfully, there should be a clock icon next the amount you requested to be unbonded. You can hover over the icon to see how much longer until the tokens are fully unlocked, which is approximately 7 days. Once the 7 days have passed, click on "Withdraw unbonded funds". This will make your KSM transferable. Even though it says "withdraw", they won't be leaving your account.
- 
+ 
7. You can return to "My Accounts" and select the dropdown next to balance to see that your KSM is now transferable.
- 
\ No newline at end of file
+ 
\ No newline at end of file
diff --git a/docs/crab-crowdloan.md b/docs/kusama-auction/crab-crowdloan.md
similarity index 98%
rename from docs/crab-crowdloan.md
rename to docs/kusama-auction/crab-crowdloan.md
index c15a7698..581e0bae 100644
--- a/docs/crab-crowdloan.md
+++ b/docs/kusama-auction/crab-crowdloan.md
@@ -2,6 +2,7 @@
id: crab-crowdloan
title: Kusama Parachain Slot Auction Crowdloan
sidebar_label: Crowdloan
+sidebar_position: 1
---
Kusama allows parachains to source KSM for their parachain bids in a decentralized crowdloan.
@@ -83,7 +84,7 @@ Participants will be able to reclaim their KSM in one of two ways:
- If the auction was not successful, then this retirement phase will begin at the crowdloan's configured end, and participants can likewise withdraw their KSM (at the end of the light purple bar, which is the crab's first crowdloan ).
-
+
[More details in Kusama website](https://kusama.network/auctions)
diff --git a/docs/pangolin-home.md b/docs/pangolin-home.md
deleted file mode 100644
index af1aa15b..00000000
--- a/docs/pangolin-home.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-id: pangolin-home
-title: Pangolin Testnet
-sidebar_label: Pangolin Testnet
----
-
-Pangolin is the test network of Darwinia and Crab network.
-
-## Features
-
-- Test the latest technology.
-- Compatible with Ethereum Virtual Machine.
-- Compatible with Ethereum contract infrastructure Metamask, Remix, etc.
-- Smart contracts supporting solidity language.
-- May be reset
-
-Developers can apply for free `PRING`s for test in [Element](https://app.element.io/?pk_vid=6961ca0f7c45f8bf16052310122d2437#/room/#darwinia:matrix.org).
\ No newline at end of file
diff --git a/docs/tutorials/_category_.json b/docs/tutorials/_category_.json
new file mode 100644
index 00000000..c57773eb
--- /dev/null
+++ b/docs/tutorials/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Tutorials",
+ "position": 2
+}
diff --git a/docs/crab-tut-claim-cring.md b/docs/tutorials/crab-tut-claim-cring.md
similarity index 87%
rename from docs/crab-tut-claim-cring.md
rename to docs/tutorials/crab-tut-claim-cring.md
index 559ad1bb..c9ab4ef3 100644
--- a/docs/crab-tut-claim-cring.md
+++ b/docs/tutorials/crab-tut-claim-cring.md
@@ -2,6 +2,7 @@
id: crab-tut-claim-cring
title: Claim Airdropped CRING
sidebar_label: Claim Airdropped CRING
+sidebar_position: 2
---
## Airdrop
@@ -43,11 +44,11 @@ Please select the following signature tools and download according to the usage
3. Select the network you want to query (Ethereum / TRON) and click [Search]. (The Ethereum network is used as an example below)
-
+
4. Get query results
-
+
### Claim CRING Airdrop
@@ -57,31 +58,31 @@ Please select the following signature tools and download according to the usage
3. Select the network you want to query (Ethereum / TRON) and click [Claim]. (The Ethereum network is used as an example below)
-
+
4. Fill in the Darwinia Crab address that accepts CRING. After confirming that it is correct, click [Submit].
>️ If there is no Darwinia Crab address, please refer to the generation method: [How to create Crab account](crab-tut-create-account)
-
+
5. Sign through mobile wallet or browser plug-in (signature does not consume fees)
-
+
6. After successfully obtaining the signature information, click [Copy Signature]. (Please pay attention to save the signature information, it is recommended not to close this page temporarily before successfully receiving the airdrop)
-
+
7. Open [Darwinia wallet - Claim](https://apps.darwinia.network#/claims):, Select the address just received to receive the airdrop and click [Continue].
-
+
8. Paste the signature information just generated in the `CRING Claim Tool`, and click [Confirm claim]-[Redeem]-[Submit]
-
+
9. After successful receipt, you will receive the following prompt. At this time, it means your airdrop has been successfully received, you can check the balance in [Darwinia Wallet-Account](https://apps.darwinia.network#/accounts) or [subscan](https://crab.subscan.io/).
-
+
## Contact Us
diff --git a/docs/crab-tut-create-account.md b/docs/tutorials/crab-tut-create-account.md
similarity index 90%
rename from docs/crab-tut-create-account.md
rename to docs/tutorials/crab-tut-create-account.md
index aa0fc936..7170357a 100644
--- a/docs/crab-tut-create-account.md
+++ b/docs/tutorials/crab-tut-create-account.md
@@ -2,27 +2,28 @@
id: crab-tut-create-account
title: Create an Account
sidebar_label: Create an Account
+sidebar_position: 1
---
There are mainly three ways to generate a Crab account, you can choose either one based on your preference. Once your account is created and you have your account `secret phrase` or `secret seed`, you can migrate your account from various medium by importing your account.
## 1. Crab Web Wallet
-
+
Enter [Crab Web Wallet](https://apps.darwinia.network), you can see two buttons "Add Account" and "Restore JSON" in the "Account" column.
-
+
**New account**
Click "Add Account", after setting the basic account information, click the "Save" button. (By default, only "mnemonic", "private key" need to be switched)
-
+
Click the "Create and Backup Account" button to back up the account "json file"
-
+
> Be sure to back up `mnemonics, private keys, json files`, etc. When backing up the json file, please keep the password safe. If the password is lost, the address cannot be restored through the json file, but it can be re-imported through the mnemonic word and private key.
@@ -30,14 +31,14 @@ Click the "Create and Backup Account" button to back up the account "json file"
If you have created an account before and backed up a json file, you can directly select "Restore JSON".
-
-
+
+
**Restore account via "Mnemonic"**
If you forget the password of the JSON file, you can use the "mnemonic word" to recover it. Click "Add Account" to replace the mnemonic with the original account's mnemonic. (The name and password can be reset)
-
+
**Generate Vanity account**
@@ -46,7 +47,7 @@ If you need to generate a Darwinia wallet account containing specific letters, y
- Click [Vanity], fill in the conditions you need to filter
-
+
`Search for` Type here what you would like your address to contain. This tool will generate the keys and show the associated addresses that best match your search. You can use \"?\" as a wildcard for a character.": "",
@@ -56,11 +57,11 @@ If you need to generate a Darwinia wallet account containing specific letters, y
- Click [Start generation], after waiting for the account to be generated, click [+] to select your favorite account for backup.
-
+
- Click [Save], according to your usage habits, choose to back up the original seed or json file
-
+
> Be sure to back up `mnemonics, private keys, json files`, etc. When backing up the json file, please keep the password safe. If the password is lost, the address cannot be restored through the json file, but it can be re-imported through the mnemonic word and private key.
@@ -72,17 +73,17 @@ If you need to generate a Darwinia wallet account containing specific letters, y
The browser plugin is available for both [Google Chrome](https://chrome.google.com/webstore/detail/polkadot%7Bjs%7D-extension/mopnmbcafieddcagagdcbnhejhlodfdd?hl=en) and [FireFox](https://addons.mozilla.org/en-US/firefox/addon/polkadot-js-extension).
-
+
**New Account**
Click the extension to open the "Account Management" dialog box, click the "Create New Account" button, and then follow the instructions.
-
+
-
+
-
+
> Make sure to keep the mnemonics safe.
@@ -92,7 +93,7 @@ Now we will ensure that the addresses are displayed as Darwinia mainnet addresse
Click on "Options" at the top of the plugin window. Select `Crab Network` or `Substrate` in "Display Address Format for" dropdown box.
-
+
> Crab Network share the same `Network ID` as `Substrate`, if you need to choose a network when generating an account, use `substrate` as the same effect as `crab network`.
diff --git a/docs/crab-tut-exchange.md b/docs/tutorials/crab-tut-exchange.md
similarity index 99%
rename from docs/crab-tut-exchange.md
rename to docs/tutorials/crab-tut-exchange.md
index 543ace70..5e887ce5 100644
--- a/docs/crab-tut-exchange.md
+++ b/docs/tutorials/crab-tut-exchange.md
@@ -2,6 +2,7 @@
id: crab-tut-exchange
title: Exchange Access Guide
sidebar_label: Exchange Access Guide
+sidebar_position: 5
---
## Basic Informations
diff --git a/docs/crab-tut-node.md b/docs/tutorials/crab-tut-node.md
similarity index 98%
rename from docs/crab-tut-node.md
rename to docs/tutorials/crab-tut-node.md
index 035c4f81..93b8b76c 100644
--- a/docs/crab-tut-node.md
+++ b/docs/tutorials/crab-tut-node.md
@@ -2,6 +2,7 @@
id: crab-tut-node
title: How to run a node
sidebar_label: Running a node
+sidebar_position: 3
---
## Initial Setup
diff --git a/docs/tutorials/staking/_category_.json b/docs/tutorials/staking/_category_.json
new file mode 100644
index 00000000..88b1946d
--- /dev/null
+++ b/docs/tutorials/staking/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Staking",
+ "position": 4
+}
diff --git a/docs/crab-tut-nominator.md b/docs/tutorials/staking/crab-tut-nominator.md
similarity index 87%
rename from docs/crab-tut-nominator.md
rename to docs/tutorials/staking/crab-tut-nominator.md
index 83bce592..59cc3199 100644
--- a/docs/crab-tut-nominator.md
+++ b/docs/tutorials/staking/crab-tut-nominator.md
@@ -2,10 +2,11 @@
id: crab-tut-nominator
title: How to become a nominator
sidebar_label: Become a nominator
+sidebar_position: 2
---
> - Staking is a consensus mechanism based on PoS (Proof of Stake / Proof of Stake). Token holders obtain rewards and benefits through pledge, voting, delegation, and locking.
-> - Before participating in staking, please make sure you have at least **1** Crab address. If you hold more tokens or have higher security requirements, it is recommended to prepare **2** Crab addresses. If there is no address, please refer to: [How to create an account](crab-tut-create-account.md).
+> - Before participating in staking, please make sure you have at least **1** Crab address. If you hold more tokens or have higher security requirements, it is recommended to prepare **2** Crab addresses. If there is no address, please refer to: [How to create an account](/tutorials/crab-tut-create-account.md).
> - A small amount of CRING must be prepared in Crab Network's address as fee.
@@ -13,11 +14,11 @@ sidebar_label: Become a nominator
Enter [Darwinia Wallet](https://apps.darwinia.network) and lick the `Staking` column on the left , Click `Start staking`
-
+
Fill in the staking parameters
-
+
`Stash account` Account for stashing tokens. Tokens participating in staking will come from this account. The operations of this account are mostly related to changes in stash.
@@ -35,7 +36,7 @@ Fill in the staking parameters
After filling in the staking parameters, please click `bond` and `submit`
-
+
## Nominate a validator
@@ -43,19 +44,19 @@ After filling in the staking parameters, please click `bond` and `submit`
After completing the staking parameters, click `Nominate` on this page
-
+
Choose your favorite validator
-
+
Sign and submit
-
+
View information about nominated validators
-
+
> The operation of nominating validators will take effect from the next era, and it is normal to temporarily delay.
@@ -75,7 +76,7 @@ The tokens' statuses are following:
There are other operations in staking for the following purposes:
-
+
`Stop nomination` Cancels all nominees.
@@ -91,7 +92,7 @@ There are other operations in staking for the following purposes:
> Please note: 56 era (about 56 days) will be saved, and you will not be able to claim it if it expires.
-
+
`Claim Reward` Manually claim the reward, and the reward will be distributed in units of era.
@@ -109,7 +110,7 @@ There are other operations in staking for the following purposes:
`Set nominees` Re-nominate validator
-`Change session key` If you want to upgrade to become a validator, you need to fill in this item. [How to become a validator](crab-tut-validator.md)
+`Change session key` If you want to upgrade to become a validator, you need to fill in this item. [How to become a validator](/tutorials/staking/crab-tut-validator.md)
`Set on-chain identity` Set your personal information, such as display, legal name, email, website, twitter and riot. Other users can view this information and contact you.
diff --git a/docs/crab-tut-validator.md b/docs/tutorials/staking/crab-tut-validator.md
similarity index 92%
rename from docs/crab-tut-validator.md
rename to docs/tutorials/staking/crab-tut-validator.md
index 20da96d6..d91642d0 100644
--- a/docs/crab-tut-validator.md
+++ b/docs/tutorials/staking/crab-tut-validator.md
@@ -2,10 +2,11 @@
id: crab-tut-validator
title: How to become a validator
sidebar_label: Become a validator
+sidebar_position: 1
---
> - Staking is a consensus mechanism based on PoS (Proof of Stake / Proof of Stake). Token holders obtain rewards and benefits through pledge, voting, delegation, and locking.
-> - Before participating in staking, please make sure you have at least **1** Crab address. If you hold more tokens or have higher security requirements, it is recommended to prepare **2** Crab addresses. If there is no address, please refer to: [How to create an account](crab-tut-create-account.md).
+> - Before participating in staking, please make sure you have at least **1** Crab address. If you hold more tokens or have higher security requirements, it is recommended to prepare **2** Crab addresses. If there is no address, please refer to: [How to create an account](../crab-tut-create-account.md).
> - A small amount of CRING must be prepared in Crab Network's address as fee.
### Run your validator node
@@ -67,11 +68,11 @@ The result is what you need when setting the session key.
Enter [Crab Wallet](https://apps.darwinia.network) and click the `Staking` column on the left , Click `Start staking`.
-
+
Fill in the staking parameters
-
+
` Stash account` Account for stashing tokens. Tokens participating in staking will come from this account. The operations of this account are mostly related to changes in stash.
@@ -89,7 +90,7 @@ Fill in the staking parameters
After filling in the staking parameters, please click `bond` and `submit`
-
+
### To be Validator
@@ -97,27 +98,27 @@ Click `Set session keys` on this page, completing the generated session keys and
> The session key must be filled with real data, otherwise it will result in missing blocks and be slashed.
-
+
After confirming, click `sign and submit`
> The identities of the validator and the nominator are mutually exclusive and cannot coexist. If you are running a validator, you need to cancel the validator before proceeding with the nomination.
-
+
Click `validate` and set the validator parameters
`Reward commission percentage` Set the proportion of the node's priority distribution of income, the range is 0-100. (Example: If a 5% reward commission is set, this node will first receive 5% of the node's revenue, and the remaining 95% of the node's revenue will be distributed in proportion to the amount of mortgages validated by the validator and nominator; Validator's income = node reward commission + mortgage reward share)
-
+
After confirming, click `sign and submit`
-
+
Go to `staking scan` to view information about validators
-
+
> The operation of validate will take effect after the first epoch of the next era. Prior to this, the validator will be in the [waiting] list.
@@ -147,7 +148,7 @@ $ docker run -it \
There are other operations in staking for the following purposes:
-
+
`Stop nomination` Cancels all nominees.
@@ -163,7 +164,7 @@ There are other operations in staking for the following purposes:
> Please note: 56 era (about 56 days) will be saved, and you will not be able to claim it if it expires.
-
+
`Claim Reward` Manually claim the reward, and the reward will be distributed in units of era.
diff --git a/docusaurus.config.js b/docusaurus.config.js
index 58a57d02..d0717df7 100644
--- a/docusaurus.config.js
+++ b/docusaurus.config.js
@@ -13,6 +13,9 @@ module.exports = {
organizationName: 'darwinia-network', // Usually your GitHub org/user name.
projectName: 'crab-docs', // Usually your repo name.
themeConfig: {
+ prism: {
+ additionalLanguages: ['solidity'],
+ },
colorMode: {
// disableSwitch: true,
defaultMode: 'light',
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/assets/crowdloan/okex2.jpg b/i18n/zh-CN/docusaurus-plugin-content-docs/current/assets/crowdloan/okex2.png
similarity index 100%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/assets/crowdloan/okex2.jpg
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/assets/crowdloan/okex2.png
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-rpc.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/builders/interact/dvm-rpc.md
similarity index 98%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-rpc.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/builders/interact/dvm-rpc.md
index b15dfba2..ac9cf9fa 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-rpc.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/builders/interact/dvm-rpc.md
@@ -2,6 +2,7 @@
id: dvm-rpc
title: DVM Rpc
sidebar_label: RPC 列表
+sidebar_position: 0
---
> 注: 当前已实现的 RPC 接口和以太坊保持一致,部分接口还未实现。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-network/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-network/_category_.json
new file mode 100644
index 00000000..eef9c21e
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-network/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Crab Network",
+ "position": 1
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-home.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-network/crab-home.md
similarity index 99%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-home.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-network/crab-home.md
index a7cbdc58..053bcc3a 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-home.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-network/crab-home.md
@@ -2,6 +2,7 @@
id: crab-home
title: Crab 网络
sidebar_label: Crab 网络
+sidebar_position: 1
slug: /
---
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-parameters.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-network/crab-parameters.md
similarity index 99%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-parameters.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-network/crab-parameters.md
index e645f9da..108f54ec 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-parameters.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-network/crab-parameters.md
@@ -2,6 +2,7 @@
id: crab-parameters
title: 网络参数
sidebar_label: 网络参数
+sidebar_position: 3
---
> 本节内容旨在说明 Crab 网络的一些关键参数, 全部参数请查询 [Runtime File Setting](https://github.com/darwinia-network/darwinia/blob/master/runtime/crab/src/lib.rs)。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tools.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-network/crab-tools.md
similarity index 94%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tools.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-network/crab-tools.md
index e28ef860..10370ef2 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tools.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-network/crab-tools.md
@@ -2,6 +2,7 @@
id: crab-tools
title: 工具集
sidebar_label: 工具集
+sidebar_position: 2
---
## 钱包
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tuts.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tuts.md
deleted file mode 100644
index ae6986a7..00000000
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tuts.md
+++ /dev/null
@@ -1,15 +0,0 @@
----
-id: crab-tut
-title: Tutorials List
-sidebar_label: Tutorials
----
-## Staking
-- Become a Nominator [View Guide](crab-tut-nominator)
-- Run a Node [View Guide](crab-tut-node)
-- Become a Validator [View Guide](crab-tut-validator)
-- Participate in Governance [View Guide](crab-tut-governance)
-- Become a Relayer [View Guide](crab-tut-relayer)
-
-## Other
-- Create an Account [View Guide](crab-tut-create-account)
-- Claim your CRING (test coin) [View Guide](crab-tut-claim-cring)
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-remix.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-remix.md
index 8b6cc301..4cd6436c 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-remix.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-remix.md
@@ -26,29 +26,29 @@ contract Incrementer {
示例合约程序如上图所示,点击 `Compile`,调试程序,保证编译成功。
-
+
## 连接 Metamask
Remix 可以关联 Metamask 上的 DVM 账户,并直接部署合约到对应的网络中。需要注意的是,DVM 账户需要提前绑定 Metamask, 请参考 [DVM 账户使用 Metamask](dvm-metamask)。 ENVIRONMENT 选择 `Injected Web3`,弹出的 Metamask 窗口中选择关联的 DVM 账户,点击 `Next`。
-
+
## 合约操作
连接 Metamask 成功后,点击 `Deploy` 部署合约,控制台会显示交易的执行情况。
-
+
合约部署成功后,执行 `number` 进行合约调用,此时的返回结果为 0。
-
+
执行 `increment` 合约,如下图所示:
-
+
再次执行 `number` 进行合约调用,返回结果为 5。
-
+
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/_category_.json
new file mode 100644
index 00000000..76bf7e83
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "DVM",
+ "position": 4
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-eco.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/dvm-eco.md
similarity index 97%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-eco.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/dvm-eco.md
index bc4ff2ad..3c452e05 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-eco.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/dvm-eco.md
@@ -2,6 +2,7 @@
id: dvm-eco
title: 生态
sidebar_label: 生态
+sidebar_position: 4
---
通过 DVM 智能合约解决方案,以太坊生态中的智能合约项目可以零成本的迁移到达尔文网络中,在新的架构平台上开展业务,
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/dvm-intro.md
similarity index 95%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-intro.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/dvm-intro.md
index 3b19d570..d2ce6c4b 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-intro.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/dvm-intro.md
@@ -2,6 +2,7 @@
id: dvm-intro
title: DVM 介绍
sidebar_label: 介绍
+sidebar_position: 1
---
达尔文网络一直在跨链领域精耕细作,致力于多链互联互通,达尔文网络也希望能够助力现有区块链应用在不同网络之间更轻易地迁移。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/overview/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/overview/_category_.json
new file mode 100644
index 00000000..fbe9f1ee
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/overview/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Overview",
+ "position": 2
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-address.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/overview/dvm-address.md
similarity index 94%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-address.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/overview/dvm-address.md
index 0f23a968..21758f7f 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-address.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/overview/dvm-address.md
@@ -2,6 +2,7 @@
id: dvm-address
title: DVM 账户
sidebar_label: DVM 账户
+sidebar_position: 1
---
达尔文网络是基于 Substrate 开发的跨链网络,账户地址格式基于 [SS58 Address](https://substrate.dev/docs/en/knowledgebase/advanced/ss58-address-format) 模型。为了兼容以太坊智能合约生态,在现有网络基础上,引入第二种地址格式,即
@@ -21,4 +22,4 @@ DVM 账户地址和以太坊账户地址格式,生成方式均一致,每一
目前使用 [Web Apps](https://apps.darwinia.network/#/account) 的工具完成地址转换,点击左侧 `工具箱`,然后 `DVM 地址`, 输入待转换的 DVM 账户地址即可。
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-system-contract.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/overview/dvm-system-contract.md
similarity index 99%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-system-contract.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/overview/dvm-system-contract.md
index 7dda4f93..ee4aea30 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-system-contract.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/overview/dvm-system-contract.md
@@ -2,6 +2,7 @@
id: dvm-system-contract
title: DVM 系统合约
sidebar_label: 系统合约
+sidebar_position: 2
---
系统合约是一种特殊的用户智能合约,拥有固定的合约地址,类似于以太坊预编译合约。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/_category_.json
new file mode 100644
index 00000000..9f0647f9
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Wallets",
+ "position": 3
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-apps.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/dvm-apps.md
similarity index 85%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-apps.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/dvm-apps.md
index f1b35eba..9ad4b3df 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-apps.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/dvm-apps.md
@@ -2,13 +2,14 @@
id: dvm-apps
title: Apps
sidebar_label: Apps
+sidebar_position: 1
---
因为 DVM 账户和 Substrate 账户存在一一对应关系,所以可以在 [Web Apps](https://apps.darwinia.network/#/account) 查询 DVM 账户余额。
## 地址转换
-根据 DVM 账户地址,生成对应的 Substrate 账户地址。见 [地址转换](dvm-address)。
+根据 DVM 账户地址,生成对应的 Substrate 账户地址。见 [地址转换](/dvm/overview/dvm-address.md)。
例如,DVM 账户地址 `0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b` 对应的 Substrate 账户地址为 `2qSbd2umtD4KmV2X6UEyn3zQ6jFT13jZEybLwc3hn5kiMmeD`。
@@ -19,4 +20,4 @@ sidebar_label: Apps
- accountId: 待查询余额的 Substrate 账户
- tokentype: 0 查询账户 RING 余额,1 表示查询账户 KTON 余额
-
+
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-metamask.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/dvm-metamask.md
similarity index 74%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-metamask.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/dvm-metamask.md
index e19fa562..97754803 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-metamask.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/dvm-metamask.md
@@ -2,6 +2,7 @@
id: dvm-metamask
title: 使用 Metamask
sidebar_label: Metamask
+sidebar_position: 2
---
由于 DVM 和以太坊虚拟机在底层范式保持一致,用户可以使用现有以太坊生态中的钱包管理资产,接下来介绍如何使用 Metamask。
@@ -11,9 +12,9 @@ sidebar_label: Metamask
1. 安装 Metamask 插件,自行下载安装。
2. 添加自定义网络,这里以添加 Pangolin 测试网络为例,不同网络配置参数不同。
-
+
-
+
不同网络连接参数如下:
@@ -24,7 +25,7 @@ sidebar_label: Metamask
连接成功后,如下图所示。
-
+
### 转账
@@ -32,18 +33,18 @@ sidebar_label: Metamask
1. 单击 `Send`,输入转账参数。
-
-
+
+
2. 确认发送交易。
-
+
3. 交易完成。
-
+
4. 在浏览器中查看交易执行的细节。
-
-
+
+
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/smart-app/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/smart-app/_category_.json
new file mode 100644
index 00000000..b5644c0e
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/smart-app/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Smart App",
+ "position": 3
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-deposit.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/smart-app/dvm-deposit.md
similarity index 63%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-deposit.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/smart-app/dvm-deposit.md
index 5bea0d33..ab43d3a1 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-deposit.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/smart-app/dvm-deposit.md
@@ -2,13 +2,14 @@
id: dvm-deposit
title: DVM 账户充值
sidebar_label: DVM 账户充值
+sidebar_position: 2
---
DVM 账户充值指的是用户将 Substrate 账户资产转移到 DVM 账户中的过程。本质上,是给 DVM 账户地址关联的 Substrate 账户地址转账。
## 准备
-准备一个接收 `PRING/PKTON` 的 DVM 账户,可以用 Metamask 生成。见 [如何使用 Metamask](dvm-metamask)。
+准备一个接收 `PRING/PKTON` 的 DVM 账户,可以用 Metamask 生成。见 [如何使用 Metamask](/dvm/wallets/dvm-metamask.md)。
## 充值
@@ -16,45 +17,45 @@ DVM 账户充值指的是用户将 Substrate 账户资产转移到 DVM 账户中
打开 [Smart App](https://smart.darwinia.network/) -> `连接钱包`,关联 Polkadot Js 中的账户。
-
+
选择一个余额不为 0 的账户,点击 `确定`。免费 `PRING` 在 [Element](https://app.element.io/?pk_vid=6961ca0f7c45f8bf16052310122d2437#/room/#darwinia:matrix.org) 申请即可。
-
+
关联 Substrate 账户成功后,如下图所示:
-
+
输入提前准备的 DVM 账户,以及充值金额,点击 `确认转账`。示例中的 DVM 账户为 `0xa3503704240f764cf91faBa1775754B42fd2040F`。
-
+
检查并勾选后两项,选择 `下一步`。
-
+
点击 `确定`。
-
+
在跳出的 Polkadot Js 窗口内输入密码,签名并发送交易。
-
+
## 查看交易
点击 Substrate 账户详情,在 Subscan 中查看交易执行结果。
-
-
+
+
## 确认到账
Subscan 中查看账户余额:
-
+
Metamask 中查看账户余额:
-
+
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-smart-app.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/smart-app/dvm-smart-app.md
similarity index 73%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-smart-app.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/smart-app/dvm-smart-app.md
index 4038be8b..534f0012 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-smart-app.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/smart-app/dvm-smart-app.md
@@ -2,6 +2,7 @@
id: dvm-smart-app
title: Smart App
sidebar_label: 概述
+sidebar_position: 1
---
[Smart App](https://smart.darwinia.network/) 是达尔文自主研发的钱包,提供用户友好的 DVM 账户和 Substrate 账户之间的资产转移方案。
@@ -12,5 +13,5 @@ sidebar_label: 概述
以切换到 Crab 网络为例:
-
-
+
+
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-withdraw.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/smart-app/dvm-withdraw.md
similarity index 67%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-withdraw.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/smart-app/dvm-withdraw.md
index 3d936c5b..088b65d1 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm-withdraw.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/dvm/wallets/smart-app/dvm-withdraw.md
@@ -2,6 +2,7 @@
id: dvm-withdraw
title: DVM 账户提取
sidebar_label: DVM 账户提取
+sidebar_position: 3
---
DVM 账户提款指的是将 DVM 账户中的资产转账到 Substrate 地址的过程。
@@ -16,30 +17,30 @@ DVM 账户提款指的是将 DVM 账户中的资产转账到 Substrate 地址的
打开 [Smart App](https://smart.darwinia.network/),点击圈中箭头,设置为从 Smart 到 Substrate。
-
+
在跳出的 Metamask 窗口中,选择关联的 DVM 账户(该账户余额不为空)。
-
+
关联成功后,如下图所示:
-
+
输入提前准备的 Substrate 账户地址,如 `2ru6GFH1tWhHcxMQ2zpQ8DW7GhQYcdZ9sFnoEp98NyhjBimK`。
-
+
点击 `确认转账`。
-
+
检查并勾选后两项,选择 `下一步`,在 Metamask 弹出框中选择 `确认`,签名发送交易。
-
+
## 确认到账
在 Subscan 中根据 Substrate 账户地址查询余额:
-
+
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/_category_.json
new file mode 100644
index 00000000..056f2988
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Kusama Auction",
+ "position": 3
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-gateio.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-gateio.md
similarity index 71%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-gateio.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-gateio.md
index 39f5e4ab..d3cd9530 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-gateio.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-gateio.md
@@ -2,18 +2,19 @@
id: crab-crowdloan-howto-gateio
title: Gate.io 教程
sidebar_label: Gate.io 教程
+sidebar_position: 6
---
1. 打开 Gate.io 手机 App, 点击 “质押 KSM”。
- 
+ 
2. 选择 “CRING”,点击进入项目详情。
- 
+ 
3. 在该页面中填写KSM的数额并点击 “立即参与” 即可。
- 
+ 
4. 竞拍结束后,奖励将直接在 Gate 中发放,用户可在 Gate 中查看奖励。
\ No newline at end of file
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-hotbit.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-hotbit.md
similarity index 83%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-hotbit.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-hotbit.md
index 74b86c44..0407e5df 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-hotbit.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-hotbit.md
@@ -2,16 +2,17 @@
id: crab-crowdloan-howto-hotbit
title: Hotbit 教程
sidebar_label: Hotbit 教程
+sidebar_position: 7
---
1. 点击进入 Hotbit 插槽拍卖页面:https://www.hotbit.io/slotauction
- 
+ 
2. 选择 "Crab (CRING) Slot#1",选择 "点击参与" 并输入一定数量的 KSM 即可。
- 
+ 
3. 用户在 Hotbit 为 Darwinia Crab 锁仓,Hotbit 将代替用户进行链上投票。如果项目拍中,Hotbit 将代替用户领取并发送项目奖励给用户。若项目未拍中,Hotbit 则将用户资产从链上取回,返还给用户并发放众贷期间的奖励。
\ No newline at end of file
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-math.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-math.md
similarity index 80%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-math.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-math.md
index c56b8f02..70452ef5 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-math.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-math.md
@@ -2,14 +2,15 @@
id: crab-crowdloan-howto-math
title: 麦子钱包 教程
sidebar_label: 麦子钱包 教程
+sidebar_position: 5
---
1. 点击快速访问麦子钱包插槽竞拍页面:https://cloud.mathwallet.xyz/#/auction
- 
+ 
2. 选择 “Darwinia Crab”,点击进入项目详情,在该页面中直接填写KSM的数额并点击 “Contribute” 即可。
- 
+ 
3. 竞拍结束后,奖励将直接在麦子云钱包中发放,用户可在麦子云钱包中查看奖励。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-okex.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-okex.md
similarity index 88%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-okex.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-okex.md
index 7f8bd02f..bfc594a8 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-okex.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-okex.md
@@ -2,27 +2,28 @@
id: crab-crowdloan-howto-okex
title: OKEx 教程
sidebar_label: OKEx 教程
+sidebar_position: 4
---
## 方式一:通过网页版 OKEx 加入众贷(Crowdloan)
1.访问网页版[OKEx](https://www.okex.com/ ),点击"金融业务" > "赚币" > "平行链插槽竞拍"。
- 
+ 
2.选择 “Crab Network”,点击“投票”,输入想要锁定的 KSM 数量并确认投票。
- 
+ 
## 方式二:通过手机移动端 OKEx 加入众贷(Crowdloan)
1.打开手机移动端OKEx,点击“资产” > “金融业务” > “赚币” > “平行链插槽竞拍”。
- 
+ 
2.选择 “Crab Network”,点击“投票”,输入想要锁定的 KSM 数量并确认投票。
- 
+ 
> **重要提示**:我们将使用**25% 的 CRING 以及 1% 的 RING** 将用于支持未来 10 年 Crab 网络在 Kusama 上平行链插槽拍卖。我们将一次性竞拍一个插槽的 8 个 周期,为期 48 周,以保证网络的运行的稳定性不受影响。考虑到前几个插槽有一定不稳定性因素影响,我们计划在**第 4 轮开始进行插槽竞拍。**
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-polkadotjs.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-polkadotjs.md
similarity index 80%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-polkadotjs.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-polkadotjs.md
index c99c1297..3bab282c 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-polkadotjs.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-polkadotjs.md
@@ -2,6 +2,7 @@
id: crab-crowdloan-howto-polkadotjs
title: 通过 Polkadot.{js} 参与众贷
sidebar_label: 通过 Polkadot.{js} 参与众贷
+sidebar_position: 3
---
在通过 Polkadot.{js} 参与众筹之前,请确保你已经:
@@ -14,16 +15,16 @@ sidebar_label: 通过 Polkadot.{js} 参与众贷
1. 打开 [Polkadot.{js}](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkusama-rpc.polkadot.io#/parachains/crowdloan),并确保在 "Network" > "Parachains" > "Crowdloan" 中.
- 
+ 
2. 在"ongoing"中找到 "Darwinia Crab" 然后点击 "Contribute".
- 
+ 
3. 选择你用来参与的账户,并在弹框中输入你想要参与的数量, 然后点击 "Contribute".
- 
+ 
4. 最后签名并发送交易
- 
\ No newline at end of file
+ 
\ No newline at end of file
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-unstaking.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-unstaking.md
similarity index 78%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-unstaking.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-unstaking.md
index 4d8e25b9..16be0f95 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan-howto-unstaking.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan-howto-unstaking.md
@@ -2,6 +2,7 @@
id: crab-crowdloan-howto-unstaking
title: Unstaking 你的 KSM
sidebar_label: Unstaking 你的 KSM
+sidebar_position: 2
---
在将您的 KSM 参与到众贷之前,您需要先取消 Staking。 对于刚刚解开 Staking 的 KSM 代币,Kusama 有一个延迟期(7 天)。 在此期间,您将无法转账您的代币。
@@ -11,28 +12,28 @@ sidebar_label: Unstaking 你的 KSM
1. 打开 [Polkadot{.js}](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkusama-rpc.polkadot.io#/staking/actions) ,然后进入"Network" > "Staking"。
- 
+ 
2. 进入 "Account actions". 然后在你想要进行unstake的账户的右边点击 "Stop" 。
- 
+ 
3. 点击右下角的“Sign and Submit”,对交易进行授权。 您的浏览器扩展程序将提示您输入密码并签署交易。到这里,您就已经停止nominate了,但您的代币仍是绑定状态。
- 
+ 
4. 要 unbond 您的代币,请单击页面右侧的省略号(三个点),然后单击“Unbond funds”。
- 
+ 
5. 输入您想要解除绑定的金额,然后点击“Unbond”。 然后签名并提交交易。
- 
+ 
6. 如果成功完成,您要求解绑的金额旁边应该有一个时钟图标。 您可以将鼠标悬停在该图标上以查看代币完全解锁所需的时间,大约为 7 天。 7 天过后,才能点击“Withdraw unbonded funds”。 这将使您的 KSM 可转账。
- 
+ 
7. 您可以返回 “My accounts” 并选择 “balance” 旁边的下拉菜单,以查看您的 KSM 现在都多少可以转账。
- 
\ No newline at end of file
+ 
\ No newline at end of file
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan.md
similarity index 98%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan.md
index 1883f03d..c3fe5b92 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-crowdloan.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/kusama-auction/crab-crowdloan.md
@@ -2,6 +2,7 @@
id: crab-crowdloan
title: Kusama 平行链拍卖众贷
sidebar_label: 众贷
+sidebar_position: 1
---
Kusama 允许平行链以去中心化的方式筹集 KSM。
@@ -87,7 +88,7 @@ KSM 持有者可以将其通证锁定在 Crowdloan 上一段时间(48周),
- 如果拍卖不成功,那么这个退出阶段将在众筹配置结束时开始,参与者同样可以撤回他们的 KSM(在浅紫色条的末尾,这是 Crab 的第一个众筹)。
-
+
[如果想了解众贷的更多细节,请看](https://kusama.network/auctions)
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/_category_.json
new file mode 100644
index 00000000..c57773eb
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Tutorials",
+ "position": 2
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-claim-cring.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/crab-tut-claim-cring.md
similarity index 83%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-claim-cring.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/crab-tut-claim-cring.md
index c2397178..d15eb5ba 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-claim-cring.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/crab-tut-claim-cring.md
@@ -2,6 +2,7 @@
id: crab-tut-claim-cring
title: 空投
sidebar_label: 空投
+sidebar_position: 2
---
## 空投计划
@@ -33,11 +34,11 @@ Darwinia 官方已于 2020年3月20日13:50(GMT +8:00),对 RING & DOT 的
2. 选择想要查询的网络(以太坊/波场),点击 `查询`。(下文以以太坊网络为例)
-
+
1. 获得查询结果
-
+
### 领取 CRING 空投
@@ -45,31 +46,31 @@ Darwinia 官方已于 2020年3月20日13:50(GMT +8:00),对 RING & DOT 的
2. 选择想要查询的网络(以太坊/波场),点击「领取」。(下文以以太坊网络为例)
-
+
3. 填写接受 CRING 的 Darwinia Crab 地址,确认无误后,点击「提交」。
-
+
4. 通过浏览器插件签名(签名不消耗燃料费)
-
+
5. 成功获取签名信息,点击复制。(请注意保存签名信息,建议在成功接收空投前,暂时不关闭本页面)
-
+
6. 打开 [达尔文钱包-认领模块]():,选中刚刚填写的接收空投的地址,点击「继续」。
-
+
7. 将刚刚在 CRING Claim Tool 中生成的签名信息贴入,依次点击 `确定认领` > `领取` > `签名`
-
+
8. 领取成功后,您将收到如下提示。这时就代表您的空投已成功领取,可以到 [达尔文钱包-账户]() 或 [subscan]()中查看账户余额信息。
-
+
- 如果您在领取空投的过程中遇到其他问题,请加入我们的社群交流。
- 微信公众号:DarwiniaNetwork
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-create-account.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/crab-tut-create-account.md
similarity index 89%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-create-account.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/crab-tut-create-account.md
index e8006c8d..ac699045 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-create-account.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/crab-tut-create-account.md
@@ -2,6 +2,7 @@
id: crab-tut-create-account
title: 创建账户
sidebar_label: 创建账户
+sidebar_position: 1
---
创建 Crab 帐户的方法有多种,您可以根据自己的喜好选择其中一种。如果您之前创建过帐户,则可直接通过 “助记词/私钥/JSON 文件” 等恢复/导入账户。
@@ -10,17 +11,17 @@ sidebar_label: 创建账户
进入 [Crab Web Wallet](https://apps.darwinia.network),可在`账户` 栏看到 `添加账号` 和 `使用JSON恢复` 两个按钮。
-
+
**新建账号**
点击 `添加账号`,在设置完账户基本信息后,点击 `保存` 按钮。(默认只显示“助记词“,”私钥“需切换)
-
+
点击 `创建并且备份账户` 按钮,备份该账户“JSON 文件”
-
+
> 务必备份好`助记词、私钥、JSON文件`等。备份 JSON 文件时,请注意保管密码,密码丢失将无法通过 JSON 文件恢复地址,但可通过助记词、私钥重新导入。
@@ -28,22 +29,22 @@ sidebar_label: 创建账户
如之前创建过账号,且备份有 JSON 文件,可直接选择 `使用JSON恢复`。
-
+
-
+
**通过 `助记词` 恢复账号**
如忘记 JSON 文件密码,可通过 `助记词` 进行恢复。点击 `添加账号`,将助记词替换成原先账户的助记词即可。(名称和密码均可重新设置)
-
+
**生成自定义账号**
如您需要生成一个包含特定字母的 Darwinia 钱包账号,可参考一下教程:
> 此类账号多用于从水龙头领取空投的工作量证明,或者处于记忆和美观的需要。
- 点击「美化账号」,填写您需要筛选的条件
-
+
`搜索` 在此处输入您希望包含的地址,该工具将生成密钥并显示与您的搜索最匹配的关联地址。
@@ -53,11 +54,11 @@ sidebar_label: 创建账户
- 点击 `开始生成`,等待账户生成,点击 `+` 选择您心仪的账户进行备份。
-
+
- 点击 `保存`,根据你的使用习惯,选择备份原始种子或 JSON 文件
-
+
> 务必备份好`助记词、私钥、JSON文件`等。备份 JSON 文件时,请注意保管密码,密码丢失将无法通过 JSON 文件恢复地址,但可通过助记词、私钥重新导入。
@@ -68,17 +69,17 @@ sidebar_label: 创建账户
浏览器插件可用于 [Google Chrome](https://chrome.google.com/webstore/detail/polkadot%7Bjs%7D-extension/mopnmbcafieddcagagdcbnhejhlodfdd?hl=en) and [FireFox](https://addons.mozilla.org/en-US/firefox/addon/polkadot-js-extension).
-
+
**新建账户**
单击扩展程序打开 “帐户管理” 对话框,单击 `创建新帐户` 按钮,然后按照说明进行操作。
-
+
-
+
-
+
> 确保将助记词安全保管。
@@ -86,7 +87,7 @@ sidebar_label: 创建账户
现在,我们将确保这些地址显示为 Crab 网络 地址。您的地址将根据网络选择而有所不同。单击插件窗口顶部的 “选项”。在 “显示地址格式为” 下拉框中选择 “Substrate”。
-
+
> Crab网络与Substrate共享相同的`Network ID`,如果在生成帐户时需要选择网络,请选择`Substrate`。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-exchange.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/crab-tut-exchange.md
similarity index 99%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-exchange.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/crab-tut-exchange.md
index bc1e1247..c1e69cec 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-exchange.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/crab-tut-exchange.md
@@ -2,6 +2,7 @@
id: crab-tut-exchange
title: 操作指南
sidebar_label: 交易所接入
+sidebar_position: 5
---
## 基本信息
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-node.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/crab-tut-node.md
similarity index 98%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-node.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/crab-tut-node.md
index 11a00358..f8ec4a04 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-node.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/crab-tut-node.md
@@ -2,6 +2,7 @@
id: crab-tut-node
title: 如何运行一个全节点
sidebar_label: 运行节点
+sidebar_position: 3
---
## 环境准备
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/staking/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/staking/_category_.json
new file mode 100644
index 00000000..88b1946d
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/staking/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Staking",
+ "position": 4
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-nominator.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/staking/crab-tut-nominator.md
similarity index 89%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-nominator.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/staking/crab-tut-nominator.md
index 6102e2f8..398710d9 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-nominator.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/staking/crab-tut-nominator.md
@@ -2,6 +2,7 @@
id: crab-tut-nominator
title: 如何成为投票人
sidebar_label: 成为投票人
+sidebar_position: 2
---
> - Staking 是基于 PoS(Proof of Stake/权益证明)的共识机制,代币持有人通过质押、投票、委托和锁定等行为获取收益。
@@ -12,11 +13,11 @@ sidebar_label: 成为投票人
进入 [Crab Web Wallet](https://apps.darwinia.network),点击左侧 `抵押` 栏目,点击 `开始 staking`
-
+
填写 Staking 参数
-
+
`资金账户` 保管资金的账号,参与 Staking 的代币将来自这个账户,此账户的操作多与资金变动相关。
@@ -34,7 +35,7 @@ sidebar_label: 成为投票人
填写好 Staking 参数后,请点击 `冻结`,签名并提交
-
+
## 提名验证人
@@ -42,19 +43,19 @@ sidebar_label: 成为投票人
完成 Staking 参数后,在本页面点击 `提名`
-
+
选择合适的验证人,并点击 `提名`
-
+
签名并提交
-
+
返回 `抵押` 处,查看已提名验证人的相关信息
-
+
> 提名验证人的操作结果,会在下一个 era 开始时生效,暂时延迟为正常现象。
@@ -74,7 +75,7 @@ sidebar_label: 成为投票人
Staking 还有一些其他操作,感兴趣的朋友,可以自行探索,列举如下:
-
+
`停止提名` 取消所有投票。
@@ -90,7 +91,7 @@ Staking 还有一些其他操作,感兴趣的朋友,可以自行探索,列
> 注意:收益会保存 56 个 era(约 56 天),超期将无法领取。
-
+
`领取收益` 手动领取已获得的收益,收益将以 era 为单位发放。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-validator.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/staking/crab-tut-validator.md
similarity index 91%
rename from i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-validator.md
rename to i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/staking/crab-tut-validator.md
index 15557f1a..1219d9a5 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/crab-tut-validator.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/staking/crab-tut-validator.md
@@ -2,10 +2,11 @@
id: crab-tut-validator
title: 如何成为验证人
sidebar_label: 成为验证人
+sidebar_position: 1
---
> - Staking 是基于 PoS(Proof of Stake/权益证明)的共识机制,代币持有人通过质押、投票、委托和锁定等行为获取收益。
-> - 在参与 Staking 之前,请确保有至少拥有 **1** 个 Crab 地址,如果您持有较多代币或对安全性要求较高,建议准备 **2** 个 Crab 地址。没有地址请参考:[如何创建账户](crab-tut-create-account.md)。
+> - 在参与 Staking 之前,请确保有至少拥有 **1** 个 Crab 地址,如果您持有较多代币或对安全性要求较高,建议准备 **2** 个 Crab 地址。没有地址请参考:[如何创建账户](/tutorials/crab-tut-create-account.md)。
> - Crab 地址内需准备少许 CRING,作为交易手续费。
### 运行验证人节点
@@ -68,11 +69,11 @@ result 就是新生成的属于该节点的 session keys。下面会用到。
进入 [Darwinia Web Wallet](https://apps.darwinia.network),点击左侧 `抵押` 栏目,点击 `开始 Staking`
-
+
填入参数
-
+
`资金账户` 保管资金的账号,参与 Staking 的代币将来自这个账户,此账户的操作多与资金变动相关。
@@ -90,7 +91,7 @@ result 就是新生成的属于该节点的 session keys。下面会用到。
填写好 Staking 参数后,请点击 `冻结`,签名并提交
-
+
### 参选验证人
@@ -98,11 +99,11 @@ result 就是新生成的属于该节点的 session keys。下面会用到。
> session keys 务必填写真实数据,否则会导致漏块,从而收到经济惩罚。
-
+
确认无误后,点击「签名并提交」
-
+
> 验证人和提名人的身份是互斥的,不可并存。如果您正在提名其他验证人,需要取消提名操作后,再进行后续的操作。
@@ -110,15 +111,15 @@ result 就是新生成的属于该节点的 session keys。下面会用到。
`奖励佣金百分比` 设置本节点优先分配收益的比重,范围为 **0-100%**。(例:如设置了 **5%** 的奖励佣金,本节点将优先获得节点收益的 **5%**,剩下 **95%** 的节点收益,将依据验证人和投票人抵押的金额,按比例分配;也就是说,`验证人的收益 = 节点奖励佣金 + 抵押奖励分成`)
-
+
确认无误后,点击 `签名并提交`
-
+
去 `浏览器` 查看当前验证人的相关信息
-
+
> 参选验证人后会进入「候选」队列,在进入下一个 era 的时刻参与选举。
@@ -148,7 +149,7 @@ result 就是新生成的属于该节点的 session keys。下面会用到。
Staking 还有一些其他操作,感兴趣的朋友,可以自行探索,列举如下:
-
+
`停止提名` 取消所有投票。
@@ -164,7 +165,7 @@ Staking 还有一些其他操作,感兴趣的朋友,可以自行探索,列
> 请注意:收益会保存 **56** 个 era(约 **56** 天),超期将无法领取。
-
+
`领取收益` 手动领取已获得的收益,收益将以 era 为单位发放。
diff --git a/package.json b/package.json
index 8e13e5e0..eb232ac6 100644
--- a/package.json
+++ b/package.json
@@ -3,24 +3,28 @@
"version": "0.0.0",
"private": true,
"scripts": {
- "docusaurus": "docusaurus",
- "start": "docusaurus start",
- "build": "docusaurus build",
- "swizzle": "docusaurus swizzle",
- "deploy": "docusaurus deploy",
- "clear": "docusaurus clear",
- "serve": "docusaurus serve",
- "write-translations": "docusaurus write-translations",
- "write-heading-ids": "docusaurus write-heading-ids"
+ "docusaurus": "npx docusaurus",
+ "start": "npx docusaurus start",
+ "build": "npx docusaurus build",
+ "swizzle": "npx docusaurus swizzle",
+ "deploy": "npx docusaurus deploy",
+ "clear": "npx docusaurus clear",
+ "serve": "npx docusaurus serve",
+ "write-translations": "npx docusaurus write-translations",
+ "write-heading-ids": "npx docusaurus write-heading-ids"
},
"dependencies": {
- "@docusaurus/core": "2.0.0-alpha.71",
- "@docusaurus/preset-classic": "2.0.0-alpha.71",
+ "@docusaurus/core": "2.0.0-beta.6 ",
+ "@docusaurus/preset-classic": "2.0.0-beta.6",
"@mdx-js/react": "^1.6.21",
+ "@metamask/detect-provider": "^1.2.0",
+ "antd": "^4.16.13",
"clsx": "^1.1.1",
- "docusaurus-plugin-sass": "^0.1.12",
+ "docusaurus-plugin-sass": "^0.2.1",
+ "raw-loader": "^4.0.2",
"react": "^17.0.1",
- "react-dom": "^17.0.1"
+ "react-dom": "^17.0.1",
+ "sass": "^1.42.1"
},
"browserslist": {
"production": [
diff --git a/sidebars.js b/sidebars.js
index 199be44a..d1cb3808 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -1,79 +1,68 @@
module.exports = {
- firstSidebar: {
- "Crab Network": [
- 'crab-home',
- 'crab-tools',
- 'crab-parameters'
- ],
+ autogeneratedSidebar: [
+ {
+ type: 'autogenerated',
+ dirName: '.',
+ }
+ ],
+ // firstSidebar: {
+ // "Crab Network": [
+ // 'crab-home',
+ // 'crab-tools',
+ // 'crab-parameters'
+ // ],
- 'Tutorials': [
- 'crab-tut-create-account',
- 'crab-tut-claim-cring',
- 'crab-tut-node',
- {
- 'Staking': [
- 'crab-tut-validator',
- 'crab-tut-nominator'
- ]
- },
- 'crab-tut-exchange'
- ],
+ // 'Tutorials': [
+ // 'crab-tut-create-account',
+ // 'crab-tut-claim-cring',
+ // 'crab-tut-node',
+ // {
+ // 'Staking': [
+ // 'crab-tut-validator',
+ // 'crab-tut-nominator'
+ // ]
+ // },
+ // 'crab-tut-exchange'
+ // ],
- "Kusama Auction": [
- 'crab-crowdloan',
- 'crab-crowdloan-howto-unstaking',
- 'crab-crowdloan-howto-polkadotjs',
- 'crab-crowdloan-howto-okex',
- 'crab-crowdloan-howto-math',
- 'crab-crowdloan-howto-gateio',
- 'crab-crowdloan-howto-hotbit'
- ],
-
- "DVM": [
- 'dvm-intro',
- {
- 'Overview': [
- 'dvm-address',
- 'dvm-system-contract'
- ]
- },
- {
- 'Wallets': [
- 'dvm-apps',
- 'dvm-metamask',
- {
- 'Smart App':[
- 'dvm-smart-app',
- 'dvm-deposit',
- 'dvm-withdraw'
- ]
- }
- ]
- },
- 'dvm-explorer',
- {
- 'Interaction': [
- 'dvm-rpc',
- {
- 'Contract': [
- 'dvm-remix',
- 'dvm-web3-contract',
- 'dvm-web3-transfer'
- ]
- }
- ]
- },
- 'dvm-eco'
- ],
-
- 'Pangolin Testnet': [
- 'pangolin-home',
- {
- 'Bridges': [
- 'pangolin-bridge-ropsten'
- ]
- }
- ]
- },
+ // "Kusama Auction": [
+ // 'crab-crowdloan',
+ // 'crab-crowdloan-howto-unstaking',
+ // 'crab-crowdloan-howto-polkadotjs',
+ // 'crab-crowdloan-howto-okex',
+ // 'crab-crowdloan-howto-math',
+ // 'crab-crowdloan-howto-gateio',
+ // 'crab-crowdloan-howto-hotbit'
+ // ],
+ // "DVM": [
+ // 'dvm-intro',
+ // {
+ // 'Overview': [
+ // 'dvm-address',
+ // 'dvm-system-contract'
+ // ]
+ // },
+ // {
+ // 'Wallets': [
+ // 'dvm-apps',
+ // 'dvm-metamask',
+ // {
+ // 'Smart App':[
+ // 'dvm-smart-app',
+ // 'dvm-deposit',
+ // 'dvm-withdraw'
+ // ]
+ // }
+ // ]
+ // },
+ // 'dvm-eco',
+ // ],
+ // 'Builders':[
+ // {
+ // type: 'autogenerated',
+ // dirName: 'builders', // Generate sidebar slice from docs/builders
+ // },
+ // ]
+ // },
};
diff --git a/src/component/ConnectWalletButton/index.tsx b/src/component/ConnectWalletButton/index.tsx
new file mode 100644
index 00000000..ff617fd4
--- /dev/null
+++ b/src/component/ConnectWalletButton/index.tsx
@@ -0,0 +1,150 @@
+import React, { useRef, useState } from 'react';
+import clsx from 'clsx';
+
+import { Modal, Button, notification } from "antd";
+import detectEthereumProvider from '@metamask/detect-provider';
+
+import styles from './styles.module.scss';
+
+interface AddEthereumChainParameter {
+ chainId: string; // A 0x-prefixed hexadecimal string
+ chainName: string;
+ nativeCurrency: {
+ name: string;
+ symbol: string; // 2-6 characters long
+ decimals: 18;
+ };
+ rpcUrls: string[];
+ blockExplorerUrls?: string[];
+ iconUrls?: string[]; // Currently ignored.
+}
+
+const chainsParameter: AddEthereumChainParameter[] = [
+ {
+ chainId: '0x2b',
+ chainName: 'Pangolin',
+ nativeCurrency: {
+ name: 'PRING',
+ symbol: 'PRING',
+ decimals: 18,
+ },
+ rpcUrls: ['https://pangolin-rpc.darwinia.network/'],
+ blockExplorerUrls: ['https://pangolin.subscan.io/'],
+ },
+ {
+ chainId: '0x2c',
+ chainName: 'Crab',
+ nativeCurrency: {
+ name: 'CRAB',
+ symbol: 'CRAB',
+ decimals: 18,
+ },
+ rpcUrls: ['https://crab-rpc.darwinia.network/'],
+ blockExplorerUrls: ['https://crab.subscan.io/'],
+ }
+];
+
+const ellipsisAddress = (address: string): string => {
+ return `${address.substr(0, 6)}...${address.substring(address.length-4)}`
+};
+
+type Props = {
+ className?: string;
+}
+
+const ConnectWalletButton: React.FC = ({ className }) => {
+ const provider = useRef();
+ const [connected, setConnected] = useState<{index: number; account: string; chainName: string} | null>(null);
+ const [isVisible, setIsVisible] = useState(false);
+
+ const handleConnectClick = () => {
+ setIsVisible(true);
+ };
+
+ const handleSelectChainClick = async (index: number) => {
+ if (!provider.current) {
+ provider.current = await detectEthereumProvider();
+ }
+
+ if (provider.current) {
+ const chainParameter = chainsParameter[index];
+ try {
+ const ret = await provider.current.request({
+ method: 'wallet_switchEthereumChain',
+ params: [{ chainId: chainParameter.chainId }],
+ });
+ if (!ret) {
+ const accounts = await provider.current.request({ method: 'eth_requestAccounts' });
+ setConnected({ index, account: accounts[0], chainName: chainParameter.chainName });
+ }
+ } catch (switchError) {
+ if (switchError.code === 4902) {
+ try {
+ const ret = await provider.current.request({
+ method: 'wallet_addEthereumChain',
+ params: [{
+ chainId: chainParameter.chainId,
+ chainName: chainParameter.chainName,
+ nativeCurrency: chainParameter.nativeCurrency,
+ rpcUrls: [...chainParameter.rpcUrls],
+ blockExplorerUrls: [...chainParameter.blockExplorerUrls],
+ }],
+ });
+ if (!ret) {
+ const accounts = await provider.current.request({ method: 'eth_requestAccounts' });
+ setConnected({ index, account: accounts[0], chainName: chainParameter.chainName });
+ }
+ } catch (addError) {
+ notification.error({
+ message: 'Oops, something wrong',
+ description: (addError as Error).message,
+ });
+ }
+ } else {
+ notification.error({
+ message: 'Oops, something wrong',
+ description: (switchError as Error).message,
+ });
+ }
+ }
+ } else {
+ notification.info({
+ message: 'Oops, something is not quite right.',
+ description:
It looks like MetaMask hasn't been installed. Please install MetaMask and try again.