Skip to content

Commit

Permalink
Merge pull request #308 from anoma/bengt/light-sdk
Browse files Browse the repository at this point in the history
draft light sdk
  • Loading branch information
bengtlofgren authored Mar 4, 2024
2 parents 3c2978c + ef45918 commit 510e83f
Show file tree
Hide file tree
Showing 10 changed files with 567 additions and 1 deletion.
4 changes: 3 additions & 1 deletion packages/docs/pages/integrating-with-namada/_meta.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"sdk" : "Using the SDK"
"sdk" : "Using the SDK",
"light-sdk": "Using the Light SDK",
"indexer": "Using the Indexer"
}
14 changes: 14 additions & 0 deletions packages/docs/pages/integrating-with-namada/light-sdk.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Callout } from 'nextra-theme-docs';

# The Namada Light SDK

The namada light sdk was developed to provide a simple way to interact with the Namada API.
It provides pre-built functions that can be used in a more "out of the box" way than the SDK, but still requires some knowledge of the API.

This documentation aims to provide that knowledge.

## Sections

- [Setup](./light-sdk/setup.mdx)
- [Usage](./light-sdk/usage.mdx)
- [Examples](./light-sdk/examples.mdx)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"setup": "Setup",
"usage": "Usage",
"examples": "Examples"
}
40 changes: 40 additions & 0 deletions packages/docs/pages/integrating-with-namada/light-sdk/examples.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Example usage of the Light SDK

## Setup

```rust
let CHAIN_ID = "shielded-expedition.88f17d1d14";
let tendermint_addr = "http://localhost:26657";
```

## Transactions

### Transfer

```rust
let source_address = namada_light_sdk::namada_sdk::address::Address::from_str("tnam1v4ehgw36xq6ngs3ng5crvdpngg6yvsecx4znjdfegyurgwzzx4pyywfexuuyys69gc6rzdfnryrntx").unwrap(); // replace with a valid source address
let target_address = namada_light_sdk::namada_sdk::address::Address::from_str("tnam1v4ehgw36xq6ngs3ng5crvdpngg6yvsecx4znjdfegyurgwzzx4pyywfexuuyys69gc6rzdfnryrntx").unwrap(); // replace with a valid target address
let token_address = namada_light_sdk::reading::blocking::query_native_token(tendermint_addr).unwrap();
let amount = namada_light_sdk::namada_sdk::token::DenominatedAmount::from_str("10000").unwrap();
// Construct the raw transaction struct
let transfer = Transfer::new(
source_address,
target_address,
token_address,
amount,
None,
None,
global_args
);
// In order to broadcast the transaction, it must be signed. This is difficult at the moment and more docs will be provided soon.
// For now, the wallet must be created and the tx args may be left empty. The signing data and sign function must be provided, along with the user data.
let signature = namada_light_sdk::namada_sdk::signing::sign_tx(wallet, args, tx, signing_data, sign, user_data)
transfer = transfer.attach_signatures(signer, signature);
transfer = transfer.attach_fee(fee, denominated_amount, fee_payer, epoch, gas_limit);
transfer = transfer.attach_fee_signature(signer, signature);

// Once signed and the fee_payer and signature is added, the payload can be retrieved and broadcasted
let transfer_tx = transfer.payload()
let response = namada_light_sdk::writing::blocking::broadcast_tx(tendermint_addr, transfer_tx).unwrap();
```

44 changes: 44 additions & 0 deletions packages/docs/pages/integrating-with-namada/light-sdk/setup.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Importing the Light SDK

The Light SDK can be imported into your project using the following line in your `cargo.toml` file.

```toml
[package]
name = "namada-light-sdk-starter"
version = "0.1.0"
edition = "2021"

[dependencies]
async-std = "1.11.0"
futures = "0.3.28"
getrandom = { version = "0.2" }
rand = {version = "0.8", default-features = false}
rand_core = {version = "0.6", default-features = false}
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0.107"
namada_light_sdk = { git = "https://github.com/anoma/namada.git", rev = "v0.31.8"} # The feature `asynchronous` is used by default. For the `blocking` feature, add the features = ["blocking"] line.
tendermint-config = "0.34.0"
tendermint-rpc = { version = "0.34.0", features = ["http-client"]}
tokio = {version = "1.8.2", default-features = false}
tempfile = "3.8.0"
async-trait = "0.1.74"
markdown-gen = "1.2.1"
reqwest = "0.11.22"
minio = "0.1.0"
itertools = "0.12.0"

[build-dependencies]
vergen = { version = "8.0.0", features = ["build", "git", "gitcl"] }
```

## Asynchronous vs blocking

The light sdk is compartmentalized into two features: `asynchronous` and `blocking`. The `asynchronous` feature is used by default. For the `blocking` feature, add the `features = ["blocking"]` line to the `namada_light_sdk` dependency in your `cargo.toml` file.

```toml
...
namada_light_sdk = { git = "https://github.com/anoma/namada.git", rev = "v0.31.8", features = ["blocking"]}
...
```

These features differ in the way that they interact with the protocol. The `asynchronous` feature uses the `async-std` runtime, while the `blocking` feature uses the `tokio` runtime. The `asynchronous` feature is recommended for new projects, as it is more efficient and easier to work with.
25 changes: 25 additions & 0 deletions packages/docs/pages/integrating-with-namada/light-sdk/usage.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Callout } from 'nextra-theme-docs'

# Using the Light SDK

The light sdk exposes the following modules:

```rust
pub mod reading; // exposes queries to retrieve data from a Namada node
pub mod transaction; // contains functions to construct all the transactions currently supported by the protocol
pub mod writing; // exposes functions to send data to a Namada node
pub use namada_sdk; // exposes the namada_sdk module for low level interactions with the Namada node
```

The functions exposed by each of these modules (excluding `namada_sdk`) are described in the following sections.

- [Reading](./usage/reading.mdx)
- [Transaction](./usage/transactions.mdx)
- [Writing](./usage/writing.mdx)







Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"reading": "Reading",
"transactions": "Transactions",
"writing": "Writing"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
## Reading

The reading module exposes the following functions:

```rust
pub fn query_native_token(tendermint_addr: &str) -> Result<Address, Error>{...}
/// Query the last committed block, if any.
pub fn query_block(tendermint_addr: &str) -> Result<Option<LastBlock>, Error>{...}
/// Query the results of the last committed block
pub fn query_results(tendermint_addr: &str) -> Result<Vec<BlockResults>, Error> {...}
/// Get a properly denominated amount of a token
pub fn denominate_amount(tendermint_addr: &str, amount: u64, token: &str) -> Result<DenominatedAmount, Error> {...}
```
Each of these functions returns a Result type, which can be used to handle errors.
The `tendermint_addr` parameter is the address of the Namada node to query. For local nodes, this is usually `http://localhost:26657`.

It also exposes the following modules that contain their own functions within them:

```rust
pub mod account;
pub mod governance;
pub mod pgf;
pub mod pos;
pub mod tx;
```

### Account
The account module exposes the following functions:

```rust

// Query token amount of owner
pub fn get_token_balance(tendermint_addr: &str, token: &Address, owner: &Address) -> Result<token::Amount, Error> {...}

// Check if the address exists on chain
pub fn known_address(tendermint_addr: &str, address: &Address) -> Result<bool, Error> {...}

// Query the account substorage space of an address
pub fn get_account_info(tendermint_addr: &str, owner: &Address) -> Result<Option<Account>, Error> {...}

// Query if the public_key is revealed
pub fn is_public_key_revealed(tendermint_addr: &str, owner: &Address) -> Result<bool, Error> {...}

// Query an account substorage at a specific index
pub fn get_public_key_at(tendermint_addr: &str, owner: &Address, index: u8) -> Result<Option<common::PublicKey>, Error> {...}
```

### Governance

```rust

// Query proposal by Id
pub fn query_proposal_by_id( tendermint_addr: &str, proposal_id: u64,) -> Result<Option<StorageProposal>, Error> {...}

// Get the givernance parameters
pub fn query_governance_parameters(tendermint_addr: &str,) -> Result<GovernanceParameters, Error> {...}

// Get the givernance parameters
pub fn query_proposal_votes(tendermint_addr: &str, proposal_id: u64,) -> Result<Vec<Vote>, Error> {...}
```

### Pgf

```rust
// Check if the given address is a pgf steward.
pub fn is_steward(tendermint_addr: &str,address: &Address,) -> Result<bool, Error> {...}
```

### Pos

```rust
// Query the epoch of the last committed block
pub fn query_epoch(tendermint_addr: &str) -> Result<Epoch, Error> {...}

// Query the epoch of the given block height, if it exists.
pub fn query_epoch_at_height(tendermint_addr: &str, height: BlockHeight) -> Result<Option<Epoch>, Error> {...}

// Check if the given address is a known validator
pub fn is_validator(tendermint_addr: &str, address: &Address) -> Result<bool, Error> {...}

// Check if a given address is a known delegator
pub fn is_delegator(tendermint_addr: &str, address: &Address) -> Result<bool, Error> {...}

// Check if a given address is a known delegator at the given epoch
pub fn is_delegator_at(tendermint_addr: &str, address: &Address, epoch: Epoch) -> Result<bool, Error> {...}

// Get the set of consensus keys registered in the network
pub fn get_consensus_keys(tendermint_addr: &str) -> Result<BTreeSet<common::PublicKey>, Error> {...}

// Get the PoS parameters
pub fn get_pos_params(tendermint_addr: &str) -> Result<PosParams, Error> {...}

// Get all validators in the given epoch
pub fn get_all_validators(tendermint_addr: &str, epoch: Epoch) -> Result<HashSet<Address>, Error> {...}

// Get the total staked tokens in the given epoch
pub fn get_total_staked_tokens(tendermint_addr: &str, epoch: Epoch) -> Result<token::Amount, Error> {...}

// Get the given validator's stake at the given epoch
pub fn get_validator_stake(tendermint_addr: &str, epoch: Epoch, validator: &Address) -> Result<token::Amount, Error> {...}

// Query and return a validator's state
pub fn get_validator_state(tendermint_addr: &str, validator: &Address, epoch: Option<Epoch>) -> Result<Option<ValidatorState>, Error> {...}

// Get the delegator's delegation
pub fn get_delegators_delegation(tendermint_addr: &str, address: &Address) -> Result<HashSet<Address>, Error> {...}

// Get the delegator's delegation at some epoch
pub fn get_delegators_delegation_at(tendermint_addr: &str, address: &Address, epoch: Epoch) -> Result<HashMap<Address, token::Amount>, Error> {...}

// Query and return validator's commission rate and max commission rate change per epoch
pub fn query_commission_rate(tendermint_addr: &str, validator: &Address, epoch: Option<Epoch>) -> Result<Option<CommissionPair>, Error> {...}

// Query and return validator's metadata, including the commission rate and max commission rate change
pub fn query_metadata(tendermint_addr: &str, validator: &Address, epoch: Option<Epoch>) -> Result<(Option<ValidatorMetaData>, Option<CommissionPair>), Error> {...}

// Query and return the incoming redelegation epoch for a given pair of source validator and delegator, if there is any
pub fn query_incoming_redelegations(tendermint_addr: &str, src_validator: &Address, delegator: &Address) -> Result<Option<Epoch>, Error> {...}

// Query a validator's bonds for a given epoch
pub fn query_bond(tendermint_addr: &str, source: &Address, validator: &Address, epoch: Option<Epoch>) -> Result<token::Amount, Error> {...}

// Query withdrawable tokens in a validator account for a given epoch
pub fn query_withdrawable_tokens(tendermint_addr: &str, bond_source: &Address, validator: &Address, epoch: Option<Epoch>) -> Result<token::Amount, Error> {...}

// Query all unbonds for a validator, applying slashes
pub fn query_unbond_with_slashing(tendermint_addr: &str, source: &Address, validator: &Address) -> Result<HashMap<(Epoch, Epoch), token::Amount>, Error> {...}

// Get the bond amount at the given epoch
pub fn get_bond_amount_at(tendermint_addr: &str, delegator: &Address, validator: &Address, epoch: Epoch) -> Result<token::Amount, Error> {...}

// Get bonds and unbonds with all details (slashes and rewards, if any) grouped by their bond IDs
pub fn bonds_and_unbonds(tendermint_addr: &str, source: &Option<Address>, validator: &Option<Address>) -> Result<BondsAndUnbondsDetails, Error> {...}

// Get bonds and unbonds with all details (slashes and rewards, if any) grouped by their bond IDs, enriched with extra information calculated from the data
pub fn enriched_bonds_and_unbonds(tendermint_addr: &str, current_epoch: Epoch, source: &Option<Address>, validator: &Option<Address>) -> Result<EnrichedBondsAndUnbondsDetails, Error> {...}
```

### Tx

```rust
/// Call the corresponding `tx_event_query` RPC method, to fetch
/// the current status of a transation.
pub fn query_tx_events(tendermint_addr: &str, tx_hash: &str,) -> Result<Option<Event>, Error> {...}

/// Dry run a transaction
pub fn dry_run_tx(tendermint_addr: &str, tx_bytes: Vec<u8>) -> Result<TxResult, Error> {...}

/// Lookup the full response accompanying the specified transaction event
pub fn query_tx_response(tendermint_addr: &str, tx_hash: &str) -> Result<TxResponse, Error> {...}

/// Query the status of a given transaction.
pub fn query_tx_status(tendermint_addr: &str, tx_hash: &str) -> Result<Event, Error> {...}
```
Loading

0 comments on commit 510e83f

Please sign in to comment.