mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 01:11:10 +00:00
Complete rebrand: Polkadot→Pezkuwi, Substrate→Bizinikiwi
- Replace PolkadotConfig with PezkuwiConfig - Replace SubstrateConfig with BizinikiwConfig - Rename config module files (polkadot.rs→pezkuwi.rs, substrate.rs→bizinikiwi.rs) - Update all documentation and examples - All 165 files updated, cargo check passes
This commit is contained in:
@@ -4,7 +4,7 @@ This example shows how to expose a small piece of Subxt functionality, in our ca
|
||||
|
||||
## Overview
|
||||
|
||||
- We want to let non-Rust clients interact with any Substrate-based node (Polkadot in this example) via a tiny FFI layer.
|
||||
- We want to let non-Rust clients interact with any Bizinikiwi-based node (Pezkuwi in this example) via a tiny FFI layer.
|
||||
- Instead of exposing Subxt’s full, Rust-centric API, we build a thin **facade crate** that:
|
||||
1. Calls Subxt under the hood
|
||||
2. Exposes just the functions we need via `pub extern "C" fn …`
|
||||
@@ -15,7 +15,7 @@ flowchart LR
|
||||
subgraph Rust side
|
||||
subxt[Subxt Public API]
|
||||
facade[Facade crate]
|
||||
node[Substrate node]
|
||||
node[Bizinikiwi node]
|
||||
cabi[C ABI library]
|
||||
subxt --> facade
|
||||
facade --> node
|
||||
@@ -46,14 +46,14 @@ which does a single balance transfer and returns 0 on success, –1 on error.
|
||||
- Rust toolchain (with cargo)
|
||||
- Python 3
|
||||
- Node.js (for the JS example. Version 19 worked on my M2 Mac, but version 22 did not, so YMMV).
|
||||
- A running Substrate node (Polkadot) on ws://127.0.0.1:8000. One can use Chopsticks for a quick local Polkadot node:
|
||||
- A running Bizinikiwi node (Pezkuwi) on ws://127.0.0.1:8000. One can use Chopsticks for a quick local Pezkuwi node:
|
||||
|
||||
```shell
|
||||
npx @acala-network/chopsticks \
|
||||
--config=https://raw.githubusercontent.com/AcalaNetwork/chopsticks/master/configs/polkadot.yml
|
||||
--config=https://raw.githubusercontent.com/AcalaNetwork/chopsticks/master/configs/pezkuwi.yml
|
||||
```
|
||||
|
||||
Or, if you have a `substrate-node` binary, just run `substrate-node --dev --rpc-port 8000`.
|
||||
Or, if you have a `bizinikiwi-node` binary, just run `bizinikiwi-node --dev --rpc-port 8000`.
|
||||
- In our Python and Javascript files, we introduce a **dest** variable that represents the destination account for the transfer, we gave it a hard coded value (Bob's account public key) from the running Chopsticks node. Feel free to change it to any other account, or better yet, make it generic!
|
||||
|
||||
If you run into any issues running the Node version, I found that I needed to run `brew install python-setuptools` too.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use hex::decode;
|
||||
use std::{ffi::CStr, os::raw::c_char, sync::OnceLock};
|
||||
use pezkuwi_subxt::{OnlineClient, PolkadotConfig, dynamic::Value, ext::scale_value::Composite, tx};
|
||||
use pezkuwi_subxt::{OnlineClient, PezkuwiConfig, dynamic::Value, ext::scale_value::Composite, tx};
|
||||
use pezkuwi_subxt_signer::sr25519::dev;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
@@ -35,7 +35,7 @@ pub extern "C" fn do_transfer(dest_hex: *const c_char, amount: u64) -> i32 {
|
||||
|
||||
// Spin up (or reuse) our Tokio runtime and connect:
|
||||
let client = tokio_rt().block_on(async {
|
||||
OnlineClient::<PolkadotConfig>::from_url("ws://127.0.0.1:8000")
|
||||
OnlineClient::<PezkuwiConfig>::from_url("ws://127.0.0.1:8000")
|
||||
.await
|
||||
.unwrap()
|
||||
});
|
||||
|
||||
@@ -7,40 +7,40 @@ This example showcases working with Subxt and Zombienet to try out connecting to
|
||||
|
||||
### 1. Install `zombienet`
|
||||
|
||||
[Zombienet](https://github.com/paritytech/zombienet) is a tool for quickly spinning up a (local) blockchain
|
||||
[Zombienet](https://github.com/pezkuwichain/zombienet) is a tool for quickly spinning up a (local) blockchain
|
||||
network. We will use it to start up a local Asset Hub for us.
|
||||
|
||||
Please follow the install guide in the [zombienet github repo](https://github.com/paritytech/zombienet) to
|
||||
Please follow the install guide in the [zombienet github repo](https://github.com/pezkuwichain/zombienet) to
|
||||
install it.
|
||||
|
||||
### 2. `polkadot`
|
||||
### 2. `pezkuwi`
|
||||
|
||||
We need a relay chain. Build the polkadot binary from the [polkadot github repo](https://github.com/paritytech/polkadot)
|
||||
We need a relay chain. Build the pezkuwi binary from the [pezkuwi github repo](https://github.com/pezkuwichain/pezkuwi)
|
||||
and install it in your path:
|
||||
|
||||
```txt
|
||||
git clone https://github.com/paritytech/polkadot.git
|
||||
cd polkadot
|
||||
git clone https://github.com/pezkuwichain/pezkuwi.git
|
||||
cd pezkuwi
|
||||
cargo install --path .
|
||||
```
|
||||
|
||||
### 3. `polkadot-parachain`
|
||||
### 3. `pezkuwi-parachain`
|
||||
|
||||
The Asset Hub is part of the [cumulus github repo](https://github.com/paritytech/cumulus), an SDK for developing
|
||||
parachains. Building the cumulus workspace produces a binary called `polkadot-parachain` which can be used to run
|
||||
The Asset Hub is part of the [pezcumulus github repo](https://github.com/pezkuwichain/pezcumulus), an SDK for developing
|
||||
parachains. Building the pezcumulus workspace produces a binary called `pezkuwi-parachain` which can be used to run
|
||||
Asset Hub nodes.
|
||||
|
||||
```txt
|
||||
git clone https://github.com/paritytech/cumulus.git
|
||||
cd cumulus
|
||||
cargo install --path polkadot-parachain
|
||||
git clone https://github.com/pezkuwichain/pezcumulus.git
|
||||
cd pezcumulus
|
||||
cargo install --path pezkuwi-parachain
|
||||
```
|
||||
|
||||
### 4. Run the parachain locally
|
||||
|
||||
With these binaries installed, Zombienet can now get the parachain running locally from a configuration file, `asset-hub-zombienet.toml`
|
||||
in this case. We need to have at least 2 validator nodes running via the `polkadot` binary, and an Asset Hub node running via the
|
||||
`polkadot-parachain` binary. Zombienet starts these up, and gets the parachain registered with the validator nodes for us. To do that,
|
||||
in this case. We need to have at least 2 validator nodes running via the `pezkuwi` binary, and an Asset Hub node running via the
|
||||
`pezkuwi-parachain` binary. Zombienet starts these up, and gets the parachain registered with the validator nodes for us. To do that,
|
||||
run:
|
||||
|
||||
```txt
|
||||
@@ -49,8 +49,8 @@ zombienet -p native spawn asset-hub-zombienet.toml
|
||||
|
||||
Zombienet uses Kubernetes by default, but we can use it without Kubernetes by providing the `-p native` flag.
|
||||
|
||||
You might have noticed that we use `chain = "rococo-local"` in the `asset-hub-zombienet.toml` file for the relay chain. This is just to
|
||||
make the epoch time shorter and should have no effect on your interactions with the parachain. Polkadot / Kusama / Rococo have different
|
||||
You might have noticed that we use `chain = "pezkuwichain-local"` in the `asset-hub-zombienet.toml` file for the relay chain. This is just to
|
||||
make the epoch time shorter and should have no effect on your interactions with the parachain. Pezkuwi / Kusama / Pezkuwichain have different
|
||||
epoch times of `24h` / `2h` / `2min` respectively.
|
||||
|
||||
### 5. Run the example
|
||||
@@ -69,10 +69,10 @@ To run our example code.
|
||||
We can obtain the metadata for Statemint via the [subxt cli](https://crates.io/crates/subxt-cli) tool, like so:
|
||||
|
||||
```txt
|
||||
subxt metadata --url wss://polkadot-asset-hub-rpc.polkadot.io:443 > statemint_metadata.scale
|
||||
subxt metadata --url wss://pezkuwi-asset-hub-rpc.pezkuwi.io:443 > statemint_metadata.scale
|
||||
```
|
||||
|
||||
It is important to explicitly specify the port as `443`.
|
||||
|
||||
One way to find a suitable URL to obtain this from is by looking through the sidebar on [Polkadot.js](https://polkadot.js.org/apps/)
|
||||
One way to find a suitable URL to obtain this from is by looking through the sidebar on [Pezkuwi.js](https://pezkuwi.js.org/apps/)
|
||||
to find the Asset Hub entry, and seeing which RPC node URLs it uses.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[relaychain]
|
||||
default_image = "docker.io/parity/polkadot:latest"
|
||||
default_command = "polkadot"
|
||||
default_image = "docker.io/parity/pezkuwi:latest"
|
||||
default_command = "pezkuwi"
|
||||
default_args = ["-lparachain=debug"]
|
||||
|
||||
chain = "rococo-local"
|
||||
chain = "pezkuwichain-local"
|
||||
|
||||
[[relaychain.nodes]]
|
||||
name = "alice"
|
||||
@@ -15,11 +15,11 @@ validator = true
|
||||
|
||||
[[parachains]]
|
||||
id = 100
|
||||
chain = "asset-hub-polkadot-local"
|
||||
chain = "asset-hub-pezkuwi-local"
|
||||
|
||||
[parachains.collator]
|
||||
name = "collator01"
|
||||
image = "docker.io/parity/polkadot-parachain:latest"
|
||||
image = "docker.io/parity/pezkuwi-parachain:latest"
|
||||
ws_port = 42069
|
||||
command = "polkadot-parachain"
|
||||
command = "pezkuwi-parachain"
|
||||
args = ["-lparachain=debug"]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use pezkuwi_subxt::{
|
||||
PolkadotConfig,
|
||||
PezkuwiConfig,
|
||||
utils::{AccountId32, MultiAddress},
|
||||
OnlineClient,
|
||||
};
|
||||
@@ -8,9 +8,9 @@ use pezkuwi_subxt_signer::sr25519::dev::{self};
|
||||
#[pezkuwi_subxt::subxt(runtime_metadata_path = "statemint_metadata.scale")]
|
||||
pub mod statemint {}
|
||||
|
||||
// PolkadotConfig or SubstrateConfig will suffice for this example at the moment,
|
||||
// but PolkadotConfig is a little more correct, having the right `Address` type.
|
||||
type StatemintConfig = PolkadotConfig;
|
||||
// PezkuwiConfig or BizinikiwConfig will suffice for this example at the moment,
|
||||
// but PezkuwiConfig is a little more correct, having the right `Address` type.
|
||||
type StatemintConfig = PezkuwiConfig;
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn main() {
|
||||
|
||||
@@ -8,11 +8,11 @@ To run the app locally we first install Trunk, a WASM bundler:
|
||||
cargo install --locked trunk
|
||||
```
|
||||
|
||||
You need to have a local polkadot/substrate node with it's JSON-RPC HTTP server running at 127.0.0.1:9933 in order for the examples to be working.
|
||||
If you have a `polkadot` binary already, running this should be sufficient:
|
||||
You need to have a local pezkuwi/bizinikiwi node with it's JSON-RPC HTTP server running at 127.0.0.1:9933 in order for the examples to be working.
|
||||
If you have a `pezkuwi` binary already, running this should be sufficient:
|
||||
|
||||
```
|
||||
polkadot --dev
|
||||
pezkuwi --dev
|
||||
```
|
||||
|
||||
Then, in another terminal, run the app locally with:
|
||||
@@ -23,4 +23,4 @@ trunk serve --open
|
||||
|
||||
# signing example
|
||||
|
||||
For the signing example, we use the `@polkadot/extension-dapp` NPM package to talk to wallets loaded as browser extensions. In order to sign and submit the transaction using the `polkadot --dev` node we spawned above, you'll need to create a dev account in your wallet of choice. Use the recovery phrase `bottom drive obey lake curtain smoke basket hold race lonely fit walk` and the derivation path `//Alice` to create a dev account that can be used.
|
||||
For the signing example, we use the `@pezkuwi/extension-dapp` NPM package to talk to wallets loaded as browser extensions. In order to sign and submit the transaction using the `pezkuwi --dev` node we spawned above, you'll need to create a dev account in your wallet of choice. Use the recovery phrase `bottom drive obey lake curtain smoke basket hold race lonely fit walk` and the derivation path `//Alice` to create a dev account that can be used.
|
||||
@@ -1,7 +1,7 @@
|
||||
use anyhow::anyhow;
|
||||
use futures::FutureExt;
|
||||
|
||||
use pezkuwi_subxt::{OnlineClient, PolkadotConfig};
|
||||
use pezkuwi_subxt::{OnlineClient, PezkuwiConfig};
|
||||
|
||||
use pezkuwi_subxt::config::DefaultExtrinsicParamsBuilder;
|
||||
use pezkuwi_subxt::ext::codec::{Decode, Encode};
|
||||
@@ -9,14 +9,14 @@ use pezkuwi_subxt::tx::Payload as _;
|
||||
use pezkuwi_subxt::tx::SubmittableTransaction;
|
||||
use pezkuwi_subxt::utils::{AccountId32, MultiSignature};
|
||||
|
||||
use crate::services::{extension_signature_for_extrinsic, get_accounts, polkadot, Account};
|
||||
use crate::services::{extension_signature_for_extrinsic, get_accounts, pezkuwi, Account};
|
||||
use web_sys::HtmlInputElement;
|
||||
use yew::prelude::*;
|
||||
|
||||
pub struct SigningExamplesComponent {
|
||||
message: String,
|
||||
remark_call_bytes: Vec<u8>,
|
||||
online_client: Option<OnlineClient<PolkadotConfig>>,
|
||||
online_client: Option<OnlineClient<PezkuwiConfig>>,
|
||||
stage: SigningStage,
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ impl SigningExamplesComponent {
|
||||
/// # Panics
|
||||
/// panics if self.online_client is None.
|
||||
fn set_message(&mut self, message: String) {
|
||||
let remark_call = polkadot::tx().system().remark(message.as_bytes().to_vec());
|
||||
let remark_call = pezkuwi::tx().system().remark(message.as_bytes().to_vec());
|
||||
let online_client = self.online_client.as_ref().unwrap();
|
||||
let remark_call_bytes = remark_call
|
||||
.encode_call_data(&online_client.metadata())
|
||||
@@ -51,18 +51,18 @@ pub enum SigningStage {
|
||||
|
||||
pub enum SubmittingStage {
|
||||
Initial {
|
||||
signed_extrinsic: SubmittableTransaction<PolkadotConfig, OnlineClient<PolkadotConfig>>,
|
||||
signed_extrinsic: SubmittableTransaction<PezkuwiConfig, OnlineClient<PezkuwiConfig>>,
|
||||
},
|
||||
Submitting,
|
||||
Success {
|
||||
remark_event: polkadot::system::events::ExtrinsicSuccess,
|
||||
remark_event: pezkuwi::system::events::ExtrinsicSuccess,
|
||||
},
|
||||
Error(anyhow::Error),
|
||||
}
|
||||
|
||||
pub enum Message {
|
||||
Error(anyhow::Error),
|
||||
OnlineClientCreated(OnlineClient<PolkadotConfig>),
|
||||
OnlineClientCreated(OnlineClient<PezkuwiConfig>),
|
||||
ChangeMessage(String),
|
||||
RequestAccounts,
|
||||
ReceivedAccounts(Vec<Account>),
|
||||
@@ -70,11 +70,11 @@ pub enum Message {
|
||||
SignWithAccount(usize),
|
||||
ReceivedSignature(
|
||||
MultiSignature,
|
||||
SubmittableTransaction<PolkadotConfig, OnlineClient<PolkadotConfig>>,
|
||||
SubmittableTransaction<PezkuwiConfig, OnlineClient<PezkuwiConfig>>,
|
||||
),
|
||||
SubmitSigned,
|
||||
ExtrinsicFinalized {
|
||||
remark_event: polkadot::system::events::ExtrinsicSuccess,
|
||||
remark_event: pezkuwi::system::events::ExtrinsicSuccess,
|
||||
},
|
||||
ExtrinsicFailed(anyhow::Error),
|
||||
}
|
||||
@@ -85,7 +85,7 @@ impl Component for SigningExamplesComponent {
|
||||
type Properties = ();
|
||||
|
||||
fn create(ctx: &Context<Self>) -> Self {
|
||||
ctx.link().send_future(OnlineClient::<PolkadotConfig>::new().map(|res| {
|
||||
ctx.link().send_future(OnlineClient::<PezkuwiConfig>::new().map(|res| {
|
||||
match res {
|
||||
Ok(online_client) => Message::OnlineClientCreated(online_client),
|
||||
Err(err) => Message::Error(anyhow!("Online Client could not be created. Make sure you have a local node running:\n{err}")),
|
||||
@@ -131,7 +131,7 @@ impl Component for SigningExamplesComponent {
|
||||
|
||||
self.stage = SigningStage::Signing(account.clone());
|
||||
|
||||
let remark_call = polkadot::tx()
|
||||
let remark_call = pezkuwi::tx()
|
||||
.system()
|
||||
.remark(self.message.as_bytes().to_vec());
|
||||
|
||||
@@ -258,7 +258,7 @@ impl Component for SigningExamplesComponent {
|
||||
| SigningStage::EnterMessage
|
||||
| SigningStage::CreatingOnlineClient => html!(<></>),
|
||||
_ => {
|
||||
let _remark_call = polkadot::tx()
|
||||
let _remark_call = pezkuwi::tx()
|
||||
.system()
|
||||
.remark(self.message.as_bytes().to_vec());
|
||||
html!(
|
||||
@@ -321,7 +321,7 @@ impl Component for SigningExamplesComponent {
|
||||
}
|
||||
SigningStage::SelectAccount(accounts) => {
|
||||
if accounts.is_empty() {
|
||||
html!(<div>{"No Web3 extension accounts found. Install Talisman or the Polkadot.js extension and add an account."}</div>)
|
||||
html!(<div>{"No Web3 extension accounts found. Install Talisman or the Pezkuwi.js extension and add an account."}</div>)
|
||||
} else {
|
||||
html!(
|
||||
<>
|
||||
@@ -394,8 +394,8 @@ impl Component for SigningExamplesComponent {
|
||||
}
|
||||
|
||||
async fn submit_wait_finalized_and_get_extrinsic_success_event(
|
||||
extrinsic: SubmittableTransaction<PolkadotConfig, OnlineClient<PolkadotConfig>>,
|
||||
) -> Result<polkadot::system::events::ExtrinsicSuccess, anyhow::Error> {
|
||||
extrinsic: SubmittableTransaction<PezkuwiConfig, OnlineClient<PezkuwiConfig>>,
|
||||
) -> Result<pezkuwi::system::events::ExtrinsicSuccess, anyhow::Error> {
|
||||
let events = extrinsic
|
||||
.submit_and_watch()
|
||||
.await?
|
||||
@@ -404,10 +404,10 @@ async fn submit_wait_finalized_and_get_extrinsic_success_event(
|
||||
|
||||
let events_str = format!("{:?}", &events);
|
||||
web_sys::console::log_1(&events_str.into());
|
||||
for event in events.find::<polkadot::system::events::ExtrinsicSuccess>() {
|
||||
for event in events.find::<pezkuwi::system::events::ExtrinsicSuccess>() {
|
||||
web_sys::console::log_1(&format!("{:?}", event).into());
|
||||
}
|
||||
|
||||
let success = events.find_first::<polkadot::system::events::ExtrinsicSuccess>()?;
|
||||
let success = events.find_first::<pezkuwi::system::events::ExtrinsicSuccess>()?;
|
||||
success.ok_or(anyhow!("ExtrinsicSuccess not found in events"))
|
||||
}
|
||||
|
||||
@@ -4,24 +4,24 @@ use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use std::fmt::Write;
|
||||
use pezkuwi_subxt::ext::codec::{Compact, Encode};
|
||||
use pezkuwi_subxt::{self, OnlineClient, PolkadotConfig};
|
||||
use pezkuwi_subxt::{self, OnlineClient, PezkuwiConfig};
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use yew::{AttrValue, Callback};
|
||||
|
||||
#[pezkuwi_subxt::subxt(runtime_metadata_path = "../../artifacts/polkadot_metadata_small.scale")]
|
||||
pub mod polkadot {}
|
||||
#[pezkuwi_subxt::subxt(runtime_metadata_path = "../../artifacts/pezkuwi_metadata_small.scale")]
|
||||
pub mod pezkuwi {}
|
||||
|
||||
pub(crate) async fn fetch_constant_block_length() -> Result<String, pezkuwi_subxt::Error> {
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
let constant_query = polkadot::constants().system().block_length();
|
||||
let api = OnlineClient::<PezkuwiConfig>::new().await?;
|
||||
let constant_query = pezkuwi::constants().system().block_length();
|
||||
|
||||
let value = api.constants().at(&constant_query)?;
|
||||
Ok(format!("{value:?}"))
|
||||
}
|
||||
|
||||
pub(crate) async fn fetch_events_dynamically() -> Result<Vec<String>, pezkuwi_subxt::Error> {
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
let api = OnlineClient::<PezkuwiConfig>::new().await?;
|
||||
let events = api.events().at_latest().await?;
|
||||
let mut event_strings = Vec::<String>::new();
|
||||
for event in events.iter() {
|
||||
@@ -38,7 +38,7 @@ pub(crate) async fn fetch_events_dynamically() -> Result<Vec<String>, pezkuwi_su
|
||||
pub(crate) async fn subscribe_to_finalized_blocks(
|
||||
cb: Callback<AttrValue>,
|
||||
) -> Result<(), pezkuwi_subxt::Error> {
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
let api = OnlineClient::<PezkuwiConfig>::new().await?;
|
||||
// Subscribe to all finalized blocks:
|
||||
let mut blocks_sub = api.blocks().subscribe_finalized().await?;
|
||||
while let Some(block) = blocks_sub.next().await {
|
||||
@@ -54,7 +54,7 @@ pub(crate) async fn subscribe_to_finalized_blocks(
|
||||
let bytes_hex = format!("0x{}", hex::encode(ext.bytes()));
|
||||
|
||||
// See the API docs for more ways to decode extrinsics:
|
||||
let decoded_ext = ext.as_root_extrinsic::<polkadot::Call>();
|
||||
let decoded_ext = ext.as_root_extrinsic::<pezkuwi::Call>();
|
||||
|
||||
writeln!(output, " Extrinsic #{idx}:").ok();
|
||||
writeln!(output, " Bytes: {bytes_hex}").ok();
|
||||
@@ -117,12 +117,12 @@ fn encode_then_hex<E: Encode>(input: &E) -> String {
|
||||
format!("0x{}", hex::encode(input.encode()))
|
||||
}
|
||||
|
||||
/// communicates with JavaScript to obtain a signature for the `partial_extrinsic` via a browser extension (e.g. polkadot-js or Talisman)
|
||||
/// communicates with JavaScript to obtain a signature for the `partial_extrinsic` via a browser extension (e.g. pezkuwi-js or Talisman)
|
||||
///
|
||||
/// Some parameters are hard-coded here and not taken from the partial_extrinsic itself (mortality_checkpoint, era, tip).
|
||||
pub async fn extension_signature_for_extrinsic(
|
||||
call_data: &[u8],
|
||||
api: &OnlineClient<PolkadotConfig>,
|
||||
api: &OnlineClient<PezkuwiConfig>,
|
||||
account_nonce: u64,
|
||||
account_source: String,
|
||||
account_address: String,
|
||||
|
||||
Reference in New Issue
Block a user