Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore!: documented all the builders. #39

Merged
merged 5 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions examples/nft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ async fn main() {
let network = near_workspaces::sandbox().await.unwrap();
let nft = network.dev_create_account().await.unwrap();
let account = network.dev_create_account().await.unwrap();
let account2 = network.dev_create_account().await.unwrap();
let network = NetworkConfig::from(network);

let nft_signer = Signer::new(Signer::from_workspace(&nft)).unwrap();
Expand Down Expand Up @@ -65,7 +66,7 @@ async fn main() {
println!("Account has {}", tokens.data.first().unwrap().token_id);

Tokens::account(account.id().clone())
.send_to(nft.id().clone())
.send_to(account2.id().clone())
.nft(nft.id().clone(), "1".to_string())
.unwrap()
.with_signer(nft_signer.clone())
Expand All @@ -83,13 +84,13 @@ async fn main() {

assert!(tokens.data.is_empty());

let tokens = Tokens::account(nft.id().clone())
let tokens = Tokens::account(account2.id().clone())
.nft_assets(nft.id().clone())
.unwrap()
.fetch_from(&network)
.await
.unwrap();

assert_eq!(tokens.data.len(), 1);
println!("nft has {}", tokens.data.first().unwrap().token_id);
println!("account 2 has {}", tokens.data.first().unwrap().token_id);
}
36 changes: 31 additions & 5 deletions src/account/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ pub struct CreateAccountBuilder {
}

impl CreateAccountBuilder {
/// Create an NEAR account and fund it by your own
///
/// You can only create an sub-account of your own account or sub-account of the linkdrop account ([near](https://nearblocks.io/address/near) on mainnet , [testnet](https://testnet.nearblocks.io/address/testnet) on testnet)
pub fn fund_myself(
self,
signer_account_id: AccountId,
Expand Down Expand Up @@ -85,13 +88,14 @@ impl CreateAccountBuilder {
}))
}

pub fn sponsor_by_faucet_service(
self,
account_id: AccountId,
) -> PublicKeyProvider<CreateAccountByFaucet, Infallible> {
/// Create an account sponsored by faucet service
///
/// This is a way to create an account without having to fund it. It works only on testnet.
/// You can only create an sub-account of the [testnet](https://testnet.nearblocks.io/address/testnet) account
pub fn sponsor_by_faucet_service(self) -> PublicKeyProvider<CreateAccountByFaucet, Infallible> {
akorchyn marked this conversation as resolved.
Show resolved Hide resolved
PublicKeyProvider::new(Box::new(move |public_key| {
Ok(CreateAccountByFaucet {
new_account_id: account_id,
new_account_id: self.account_id,
public_key,
})
}))
Expand All @@ -105,11 +109,24 @@ pub struct CreateAccountByFaucet {
}

impl CreateAccountByFaucet {
/// Sends the account creation request to the default testnet faucet service.
akorchyn marked this conversation as resolved.
Show resolved Hide resolved
///
/// The account will be created as a sub-account of the [testnet](https://testnet.nearblocks.io/address/testnet) account
pub async fn send_to_testnet_faucet(self) -> Result<Response, FaucetError> {
akorchyn marked this conversation as resolved.
Show resolved Hide resolved
let testnet = NetworkConfig::testnet();
self.send_to_config_faucet(&testnet).await
}

/// Sends the account creation request to the faucet service specified in the network config.
/// This way you can specify your own faucet service.
///
/// The function sends the request in the following format:
/// ```json
/// {
/// "newAccountId": "new_account_id",
/// "newAccountPublicKey": "new_account_public_key"
/// }
/// ```
pub async fn send_to_config_faucet(
self,
config: &NetworkConfig,
Expand All @@ -122,6 +139,15 @@ impl CreateAccountByFaucet {
self.send_to_faucet(faucet_service_url).await
}

/// Sends the account creation request to the faucet service specified by the URL.
///
/// The function sends the request in the following format:
/// ```json
/// {
/// "newAccountId": "new_account_id",
/// "newAccountPublicKey": "new_account_public_key"
/// }
/// ```
pub async fn send_to_faucet(self, url: &Url) -> Result<Response, FaucetError> {
akorchyn marked this conversation as resolved.
Show resolved Hide resolved
let mut data = std::collections::HashMap::new();
data.insert("newAccountId", self.new_account_id.to_string());
Expand Down
180 changes: 180 additions & 0 deletions src/account/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ mod create;
pub struct Account(pub AccountId);

impl Account {
/// Prepares a query to fetch the [Data](crate::Data)<[AccountView](near_primitives::views::AccountView)> with the account information for the given account ID.
///
/// ## Example
/// ```rust,no_run
/// use near_api::*;
///
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// let account_info = Account("alice.testnet".parse()?).view().fetch_from_testnet().await?;
/// println!("Account: {:?}", account_info);
/// # Ok(())
akorchyn marked this conversation as resolved.
Show resolved Hide resolved
/// # }
/// ```
pub fn view(&self) -> QueryBuilder<AccountViewHandler> {
let request = near_primitives::views::QueryRequest::ViewAccount {
account_id: self.0.clone(),
Expand All @@ -45,6 +57,23 @@ impl Account {
)
}

/// Prepares a query to fetch the [Data](crate::Data)<[AccessKeyView](near_primitives::views::AccessKeyView)> with the access key information for the given account public key.
///
/// ## Example
/// ```rust,no_run
/// use near_api::*;
/// use near_crypto::PublicKey;
/// use std::str::FromStr;
///
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// let access_key = Account("alice.testnet".parse()?)
akorchyn marked this conversation as resolved.
Show resolved Hide resolved
/// .access_key(PublicKey::from_str("ed25519:H4sIAAAAAAAAA+2X0Q6CMBAAtVlJQgYAAAA=")?)
/// .fetch_from_testnet()
/// .await?;
/// println!("Access key: {:?}", access_key);
/// # Ok(())
/// # }
/// ```
pub fn access_key(&self, signer_public_key: PublicKey) -> QueryBuilder<AccessKeyHandler> {
let request = near_primitives::views::QueryRequest::ViewAccessKey {
account_id: self.0.clone(),
Expand All @@ -57,6 +86,18 @@ impl Account {
)
}

/// Prepares a query to fetch the [AccessKeyList](near_primitives::views::AccessKeyList) list of access keys for the given account ID.
///
/// ## Example
/// ```rust,no_run
/// use near_api::*;
///
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// let access_keys = Account("alice.testnet".parse()?).list_keys().fetch_from_testnet().await?;
akorchyn marked this conversation as resolved.
Show resolved Hide resolved
/// println!("Access keys: {:?}", access_keys);
/// # Ok(())
/// # }
/// ```
pub fn list_keys(&self) -> QueryBuilder<AccessKeyListHandler> {
let request = near_primitives::views::QueryRequest::ViewAccessKeyList {
account_id: self.0.clone(),
Expand All @@ -68,6 +109,25 @@ impl Account {
)
}

/// Adds a new access key to the given account ID.
///
/// ## Example
/// ```rust,no_run
/// use near_api::*;
/// use near_primitives::account::AccessKeyPermission;
/// use near_crypto::PublicKey;
/// use std::str::FromStr;
///
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// let pk = PublicKey::from_str("ed25519:H4sIAAAAAAAAA+2X0Q6CMBAAtVlJQgYAAAA=")?;
/// let result: near_primitives::views::FinalExecutionOutcomeView = Account("alice.testnet".parse()?)
/// .add_key(AccessKeyPermission::FullAccess, pk)
/// .with_signer(Signer::new(Signer::from_ledger())?)
/// .send_to_testnet()
/// .await?;
/// # Ok(())
/// # }
/// ```
pub fn add_key(
&self,
permission: AccessKeyPermission,
Expand All @@ -84,6 +144,22 @@ impl Account {
)
}

/// Deletes an access key from the given account ID.
///
/// ## Example
/// ```rust,no_run
/// use near_api::*;
/// use near_crypto::PublicKey;
/// use std::str::FromStr;
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// let result: near_primitives::views::FinalExecutionOutcomeView = Account("alice.testnet".parse()?)
/// .delete_key(PublicKey::from_str("ed25519:H4sIAAAAAAAAA+2X0Q6CMBAAtVlJQgYAAAA=")?)
/// .with_signer(Signer::new(Signer::from_ledger())?)
/// .send_to_testnet()
/// .await?;
/// # Ok(())
/// # }
/// ```
pub fn delete_key(&self, public_key: PublicKey) -> ConstructTransaction {
ConstructTransaction::new(self.0.clone(), self.0.clone()).add_action(
near_primitives::transaction::Action::DeleteKey(Box::new(DeleteKeyAction {
Expand All @@ -92,6 +168,23 @@ impl Account {
)
}

/// Deletes multiple access keys from the given account ID.
///
/// ## Example
/// ```rust,no_run
/// use near_api::*;
/// use near_crypto::PublicKey;
/// use std::str::FromStr;
///
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// let result: near_primitives::views::FinalExecutionOutcomeView = Account("alice.testnet".parse()?)
/// .delete_keys(vec![PublicKey::from_str("ed25519:H4sIAAAAAAAAA+2X0Q6CMBAAtVlJQgYAAAA=")?])
/// .with_signer(Signer::new(Signer::from_ledger())?)
/// .send_to_testnet()
/// .await?;
/// # Ok(())
/// # }
/// ```
pub fn delete_keys(&self, public_keys: Vec<PublicKey>) -> ConstructTransaction {
let actions = public_keys
.into_iter()
Expand All @@ -105,6 +198,27 @@ impl Account {
ConstructTransaction::new(self.0.clone(), self.0.clone()).add_actions(actions)
}

/// Deletes the account with the given beneficiary ID. The account balance will be transfered to the beneficiary.
///
/// Please note that this action is irreversible. Also, you have to understand that another person could potentially
/// re-create the account with the same name and pretend to be you on other websites that use your account ID as a unique identifier.
/// (near.social, devhub proposal, etc)
///
/// Do not use it unless you understand the consequences.
///
/// ## Example
/// ```rust,no_run
/// use near_api::*;
///
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// let result: near_primitives::views::FinalExecutionOutcomeView = Account("alice.testnet".parse()?)
/// .delete_account_with_beneficiary("bob.testnet".parse()?)
/// .with_signer(Signer::new(Signer::from_ledger())?)
/// .send_to_testnet()
/// .await?;
/// # Ok(())
/// # }
/// ```
pub fn delete_account_with_beneficiary(
&self,
beneficiary_id: AccountId,
Expand All @@ -116,6 +230,72 @@ impl Account {
)
}

/// Creates a new account builder for the given account ID.
///
/// ## Creating account sponsored by faucet service
///
akorchyn marked this conversation as resolved.
Show resolved Hide resolved
/// This is a way to create an account without having to fund it. It works only on testnet.
/// The account should be created as a sub-account of the [testnet](https://testnet.nearblocks.io/address/testnet) account
///
/// ```rust,no_run
/// use near_api::*;
///
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// let secret = near_api::signer::generate_secret_key()?;
/// let result: reqwest::Response = Account::create_account("alice.testnet".parse()?)
/// .sponsor_by_faucet_service()
/// .public_key(secret.public_key())?
/// .send_to_testnet_faucet()
/// .await?;
/// // You have to save the secret key somewhere safe
/// std::fs::write("secret.key", secret.to_string())?;
/// # Ok(())
/// # }
/// ```
///
/// ## Creating sub-account of the linkdrop root account funded by your own NEAR and signed by your account
///
/// There is a few linkdrop root accounts that you can use to create sub-accounts.
/// * For mainnet, you can use the [near](https://explorer.near.org/accounts/near) account.
/// * For testnet, you can use the [testnet](https://testnet.nearblocks.io/address/testnet) account.
///
/// ```rust,no_run
/// use near_api::*;
///
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// let secret = near_api::signer::generate_secret_key()?;
/// let bob_signer = Signer::new(Signer::from_seed_phrase("lucky barrel fall come bottom can rib join rough around subway cloth ", None)?)?;
/// let result: near_primitives::views::FinalExecutionOutcomeView = Account::create_account("alice.testnet".parse()?)
/// .fund_myself("bob.testnet".parse()?, NearToken::from_near(1))
/// .public_key(secret.public_key())?
/// .with_signer(bob_signer)
/// .send_to_testnet()
/// .await?;
/// # Ok(())
/// # }
/// ```
///
/// ## Creating sub-account of your own account funded by your NEAR
///
/// You can create only one level deep of sub-accounts.
///
/// E.g you are `alice.testnet`, you can't create `sub.sub.alice.testnet`, but you can create `sub.alice.testnet`.
/// Though, 'sub.alice.testnet' can create sub-accounts of its own.
/// ```rust,no_run
/// use near_api::*;
///
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// let secret = near_api::signer::generate_secret_key()?;
/// let bob_signer = Signer::new(Signer::from_seed_phrase("lucky barrel fall come bottom can rib join rough around subway cloth ", None)?)?;
/// let result: near_primitives::views::FinalExecutionOutcomeView = Account::create_account("subaccount.bob.testnet".parse()?)
/// .fund_myself("bob.testnet".parse()?, NearToken::from_near(1))
/// .public_key(secret.public_key())?
/// .with_signer(bob_signer)
/// .send_to_testnet()
/// .await?;
/// # Ok(())
/// # }
/// ```
pub const fn create_account(account_id: AccountId) -> CreateAccountBuilder {
CreateAccountBuilder { account_id }
}
Expand Down
Loading
Loading