pub mod calls;
pub mod error;
pub mod listener;
mod rpc;
pub mod storage;
pub mod voucher;
use crate::{EventListener, ws::WSAddress};
use error::*;
use gear_node_wrapper::{Node, NodeInstance};
use gsdk::{
Api, ProgramStateChanges, UserMessageSentFilter, UserMessageSentSubscription,
ext::sp_runtime::AccountId32, signer::Signer,
};
use sp_core::{H256, sr25519};
use std::{borrow::Cow, ffi::OsStr, sync::Arc, time::Duration};
#[derive(Clone)]
pub struct GearApi(Signer, Option<Arc<NodeInstance>>);
impl GearApi {
pub const DEFAULT_SURI: &str = "//Alice";
pub const fn builder<'a>() -> GearApiBuilder<'a> {
GearApiBuilder {
api: Api::builder(),
suri: None,
}
}
pub async fn init(address: WSAddress) -> Result<Self> {
Self::init_with(address, "//Alice").await
}
pub async fn init_with(address: WSAddress, suri: impl AsRef<str>) -> Result<Self> {
Self::builder()
.suri(suri.as_ref())
.uri(address.url())
.build()
.await
}
pub fn with(self, suri: impl AsRef<str>) -> Result<Self> {
let mut suri = suri.as_ref().splitn(2, ':');
Ok(Self(
self.0
.change(suri.next().expect("Infallible"), suri.next())?,
self.1,
))
}
pub async fn dev() -> Result<Self> {
Self::init(WSAddress::dev()).await
}
pub async fn dev_from_path(path: impl AsRef<OsStr>) -> Result<Self> {
let node = Node::from_path(path.as_ref())?.spawn()?;
let api = Self::init(node.address.into()).await?;
Ok(Self(api.0, Some(Arc::new(node))))
}
pub async fn vara_dev_from_path(path: impl AsRef<OsStr>) -> Result<Self> {
let node = Node::from_path(path.as_ref())?.arg("--validator").spawn()?;
let api = Self::init(node.address.into()).await?;
Ok(Self(api.0, Some(Arc::new(node))))
}
pub fn print_node_logs(&mut self) {
if let Some(node) = self.1.as_mut() {
Arc::get_mut(node)
.expect("Unable to mutate `Node`")
.logs()
.expect("Unable to read logs");
}
}
pub async fn vara_testnet() -> Result<Self> {
Self::init(WSAddress::vara_testnet()).await
}
pub async fn vara() -> Result<Self> {
Self::init(WSAddress::vara()).await
}
pub async fn subscribe(&self) -> Result<EventListener> {
let events = self.0.api().subscribe_finalized_blocks().await?;
Ok(EventListener(events))
}
pub async fn subscribe_program_state_changes(
&self,
program_ids: Option<Vec<H256>>,
) -> Result<ProgramStateChanges> {
self.0
.api()
.subscribe_program_state_changes(program_ids)
.await
.map_err(Into::into)
}
pub async fn subscribe_user_message_sent(
&self,
filter: UserMessageSentFilter,
) -> Result<UserMessageSentSubscription> {
self.0
.api()
.subscribe_user_message_sent(filter)
.await
.map_err(Into::into)
}
pub fn set_nonce(&mut self, nonce: u64) {
self.0.set_nonce(nonce)
}
pub async fn rpc_nonce(&self) -> Result<u64> {
self.0
.api()
.tx()
.account_nonce(self.0.account_id())
.await
.map_err(Into::into)
}
pub fn account_id(&self) -> &AccountId32 {
self.0.account_id()
}
}
impl From<Signer> for GearApi {
fn from(signer: Signer) -> Self {
Self(signer, None)
}
}
impl From<Api> for GearApi {
fn from(api: Api) -> Self {
Signer::new(api, "//Alice", None)
.expect("//Alice always works")
.into()
}
}
impl From<(Api, sr25519::Pair)> for GearApi {
fn from((api, signer): (Api, sr25519::Pair)) -> Self {
Signer::from((api, signer.into())).into()
}
}
impl From<GearApi> for Signer {
fn from(api: GearApi) -> Self {
api.0
}
}
#[derive(Debug, Clone, Default)]
pub struct GearApiBuilder<'a> {
api: gsdk::ApiBuilder<'a>,
suri: Option<Cow<'a, str>>,
}
impl<'a> GearApiBuilder<'a> {
pub fn timeout(mut self, timeout: Duration) -> Self {
self.api = self.api.timeout(timeout);
self
}
pub fn suri(mut self, suri: impl Into<Cow<'a, str>>) -> Self {
self.suri = Some(suri.into());
self
}
pub fn uri(mut self, uri: impl Into<Cow<'a, str>>) -> Self {
self.api = self.api.uri(uri);
self
}
pub async fn build(self) -> Result<GearApi> {
let mut suri = self
.suri
.as_ref()
.map_or(GearApi::DEFAULT_SURI, Cow::as_ref)
.splitn(2, ':');
let api = self.api.build().await?;
Ok(GearApi(
api.signer(suri.next().expect("Infallible"), suri.next())?,
None,
))
}
}