-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'ian/update-sdk-docs' (#388)
update sdk docs for v0.43.0
- Loading branch information
Showing
14 changed files
with
536 additions
and
539 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,13 @@ | ||
import Expandable from '../../components/Expandable'; | ||
import { Callout } from 'nextra-theme-docs' | ||
|
||
# The Namada SDK | ||
|
||
The Namada software development kit (SDK) can be found in the `namada` repo under the path [`namada/crates](https://github.com/anoma/namada/tree/main/crates/sdk). The SDK is written in Rust and can be used to interact with the Namada blockchain, by constructing transactions, signing them, and submitting them to the network. | ||
The Namada software development kit (SDK) can be found in the `namada` repo under the path [`namada/crates/sdk`](https://github.com/anoma/namada/tree/main/crates/sdk). | ||
The SDK is written in Rust and can be used to interact with the Namada blockchain by constructing transactions, signing them, and submitting them to the network. | ||
|
||
## Quick Start | ||
This section explains some basic operations using the SDK with example code. | ||
|
||
A good starting point to see the SDK in use is to check-out the [namada interface](https://github.com/anoma/namada/tree/main/crates/sdk) repo. This repo contains a simple web application that uses the SDK to interact with the Namada blockchain. However, it is important to note the added complexity arising from the application integrating javascript using [wasm-bindgen](https://rustwasm.github.io/docs/wasm-bindgen/), which is not necessary. | ||
|
||
## Installation | ||
|
||
The Namada SDK can be installed by creating a new Rust project and adding the following to the `Cargo.toml` file: | ||
|
||
|
||
<Expandable> | ||
|
||
```toml | ||
[package] | ||
name = "namada-sdk-example" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
clap = { version = "4.4.2", features = ["derive", "env"] } | ||
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_sdk = { git = "https://github.com/anoma/namada", rev = "v0.31.8", default-features = false, features = ["tendermint-rpc", "std", "async-send", "download-params", "rand"] } | ||
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"] } | ||
``` | ||
|
||
</Expandable> | ||
|
||
|
||
Once the sdk is installed, you can use it to interact with the Namada blockchain. | ||
|
||
## Table of contents | ||
|
||
- [Setting up a client](./sdk/setting-up-a-client.mdx) | ||
- [Setting up a wallet](./sdk/setting-up-a-wallet.mdx) | ||
- [Constructing transfers](./sdk/constructing-transfers.mdx) | ||
<Callout type="info"> | ||
Read the following sections in order, as they may refer to variables, imports or actions taken in previous sections. | ||
</Callout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,12 @@ | ||
{ | ||
"setting-up-a-client" : "Setting up a client", | ||
"setup": "Project setup", | ||
"context": "Chain context", | ||
"query": "Querying", | ||
"setting-up-a-wallet" : "Setting up a wallet", | ||
"generating-accounts": "Generating accounts", | ||
"constructing-transfers" : "Constructing transfers", | ||
"shielded-sync": "Shielded sync", | ||
"shielded-transfers": "Shielded transfers", | ||
"proof-of-stake" : "Proof of stake transactions", | ||
"governance" : "Governance", | ||
"interface-integration" : "Integrating with the interface" | ||
"governance" : "Governance" | ||
} |
109 changes: 37 additions & 72 deletions
109
packages/docs/pages/integrating-with-namada/sdk/constructing-transfers.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,81 +1,46 @@ | ||
# Constructing transfers | ||
|
||
Now that we have the wallet and client set up, we can create the environment necessary for constructing transfers. | ||
This can be a bit tricky, but the below boilerplate code should do the trick: | ||
The following imports will be needed in order to generate transfers: | ||
The SDK provides methods for constructing, signing, and submitting transactions to the chain. These are accessed through the [Chain Context](./context.mdx) object. | ||
|
||
```rust | ||
use namada_sdk::args::InputAmount; | ||
``` | ||
|
||
After the user has [generated an account](./generating-accounts.mdx) and created the appropriate struct, it is not too difficult to construct and submit transfer transactions. | ||
### Preparation | ||
|
||
```rust | ||
let mut namada = NamadaImpl::new(&http_client, &mut wallet, &mut shielded_ctx, &NullIo) | ||
.await | ||
.expect("unable to construct Namada object") | ||
.chain_id(ChainId::from_str("public-testnet-14.5d79b6958580").unwrap()); | ||
// Transfer the given amount of native tokens from the source account to the | ||
// destination account. | ||
async fn gen_transfer( | ||
namada: &impl Namada, | ||
source: &Account, | ||
destination: &Account, | ||
amount: InputAmount, | ||
) -> std::result::Result<ProcessTxResponse, namada_sdk::error::Error> { | ||
let mut transfer_tx_builder = namada | ||
.new_transfer( | ||
TransferSource::Address(Address::from(&source.public_key)), | ||
TransferTarget::Address(Address::from(&destination.public_key)), | ||
namada.native_token(), | ||
amount, | ||
) | ||
.signing_keys(vec![source.public_key.clone()]); | ||
let (mut transfer_tx, signing_data, _epoch) = transfer_tx_builder | ||
.build(namada) | ||
.await | ||
.expect("unable to build transfer"); | ||
namada | ||
.sign(&mut transfer_tx, args: &transfer_tx_builder.tx, signing_data, with: default_sign, user_data: ()) | ||
.await | ||
.expect("unable to sign reveal pk tx"); | ||
namada.submit(transfer_tx, &transfer_tx_builder.tx).await | ||
} | ||
``` | ||
Let's assume we have two accounts—Alice and Bob—[added to the wallet](./setting-up-a-wallet.mdx) as in the previous section | ||
and that Alice's account already contains sufficient funds. | ||
|
||
Other transactions can be constructed in a similar fashion. | ||
|
||
## Shielded transfers | ||
|
||
In order to make the transfer shielded, we need to the only difference is to use shielded addresses and keys instead of transparent ones. | ||
|
||
It is important to use the shielded extended `SpendingKey` as the source. | ||
### Transparent Transfers | ||
The following code will build a `transparent-transfer` tx that sends 1 NAM from Alice to Bob, then sign it and submit | ||
it to the chain. | ||
|
||
```rust | ||
use std::str::FromStr; | ||
use namada_sdk::{ | ||
masp::{ | ||
PaymentAddress, | ||
TransferSource, | ||
TransferTarget, | ||
}, | ||
masp_primitives::zip32::ExtendedSpendingKey, | ||
key::common::PublicKey, | ||
use namada_sdk::args::TxTransparentTransferData; | ||
use namada_sdk::args::InputAmount; | ||
use namada_sdk::signing::default_sign; | ||
|
||
// Prepare the tx arguments | ||
let data = TxTransparentTransferData { | ||
source: sdk.wallet().await.find_address("alice".to_string()).expect("Invalid alias").into_owned(), | ||
target: sdk.wallet().await.find_address("bob".to_string()).expect("Invalid alias").into_owned(), | ||
token: sdk.native_token(), | ||
amount: InputAmount::from_str("1").expect("Invalid amount"), | ||
}; | ||
|
||
// Make sure to replace "secret-ex" with an actual Namada extended spending key | ||
let source = ExtendedSpendingKey::from_str("secret-ex").unwrap(); | ||
// Make sure to replace "payment-addr-ex" with an actual Namada payment address | ||
let destination = PaymentAddress::from_str("payment-addr-ex").unwrap(); | ||
// Make sure to replace "public-key" with an actual Namada public key | ||
let fee_payer = PublicKey::from_str("public-key"); | ||
let amount = /* Needed amount here */; | ||
let mut transfer_tx_builder = namada | ||
.new_transfer( | ||
TransferSource::ExtendedSpendingKey(source.into()), | ||
TransferTarget::PaymentAddress(destination), | ||
namada.native_token(), | ||
amount, | ||
) | ||
.signing_keys(vec![fee_payer]); | ||
``` | ||
// Build the tx | ||
let mut transfer_tx_builder = sdk | ||
.new_transparent_transfer(vec![data]) | ||
.signing_keys(vec![alice_acct.public_key.clone()]); | ||
let (mut transfer_tx, signing_data) = transfer_tx_builder | ||
.build(&sdk) | ||
.await | ||
.expect("unable to build transfer"); | ||
|
||
// Sign the tx | ||
sdk.sign(&mut transfer_tx, &transfer_tx_builder.tx, signing_data, default_sign, ()) | ||
.await | ||
.expect("unable to sign transparent-transfer tx"); | ||
|
||
// Submit the signed tx to the ledger for execution | ||
match sdk.submit(transfer_tx, &transfer_tx_builder.tx).await { | ||
Ok(res) => println!("Tx result: {:?}", res), | ||
Err(e) => println!("Tx error: {:?}", e) | ||
} | ||
``` |
85 changes: 85 additions & 0 deletions
85
packages/docs/pages/integrating-with-namada/sdk/context.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { Callout } from 'nextra-theme-docs'; | ||
|
||
# Initializing the Chain Context | ||
|
||
To begin working with the SDK, the first step is to initialize a 'Chain Context'. This is an instance of the | ||
[`NamadaImpl struct`](https://github.com/anoma/namada/blob/main/crates/sdk/src/lib.rs#L659), which allows us to access | ||
wallet storage, shielded context storage, and the RPC endpoint of our full node. | ||
|
||
The Chain Context object also provides methods for common operations like querying the chain, constructing, signing, | ||
and submitting transactions. | ||
|
||
To create the Chain Context, we'll need the RPC url of a synced full node. | ||
|
||
### Code | ||
|
||
First, import our dependencies: | ||
```rust | ||
use tokio; | ||
use std::str::FromStr; | ||
use namada_sdk::{args::TxBuilder, io::NullIo, masp::fs::FsShieldedUtils, wallet::fs::FsWalletUtils, NamadaImpl, chain::ChainId}; | ||
use tendermint_rpc::{HttpClient, Url}; | ||
``` | ||
|
||
Next, we'll create the required helper objects. | ||
|
||
Instantiate an http client for interacting with the full node: | ||
```rust | ||
let url = Url::from_str("http://127.0.0.1:26657").expect("Invalid RPC address"); | ||
let http_client = HttpClient::new(url).unwrap(); | ||
``` | ||
|
||
Set up wallet storage for our addresses and keys: | ||
```rust | ||
let wallet = FsWalletUtils::new("./sdk-wallet".into()); | ||
``` | ||
|
||
Set up shielded context storage for the current state of the shielded pool: | ||
```rust | ||
let shielded_ctx = FsShieldedUtils::new("./masp".into()); | ||
``` | ||
|
||
Create an IO object to capture the input/output streams. Since we don't need to | ||
capture anything, we'll use `NullIo` | ||
```rust | ||
let null_io = NullIo; | ||
``` | ||
|
||
Now we're ready to instantiate our Chain Context: | ||
```rust | ||
let sdk = NamadaImpl::new(http_client, wallet, shielded_ctx, null_io) | ||
.await | ||
.expect("unable to initialize Namada context") | ||
.chain_id(ChainId::from_str("local-net.b8f955720ab").unwrap()); | ||
``` | ||
|
||
### Full Example: | ||
|
||
```rust | ||
use tokio; | ||
use std::str::FromStr; | ||
use namada_sdk::{args::TxBuilder, io::NullIo, masp::fs::FsShieldedUtils, rpc, wallet::fs::FsWalletUtils, Namada, NamadaImpl, chain::ChainId}; | ||
use tendermint_rpc::{HttpClient, Url}; | ||
|
||
#[tokio::main] | ||
async fn main() { | ||
|
||
let url = Url::from_str("http://127.0.0.1:26657").expect("Invalid RPC address"); | ||
let http_client = HttpClient::new(url).unwrap(); | ||
|
||
let wallet = FsWalletUtils::new("./sdk-wallet".into()); | ||
let shielded_ctx = FsShieldedUtils::new("./masp".into()); | ||
let null_io = NullIo; | ||
|
||
let sdk = NamadaImpl::new(http_client, wallet, shielded_ctx, null_io) | ||
.await | ||
.expect("unable to initialize Namada context") | ||
.chain_id(ChainId::from_str("local-net.b8f955720ab").unwrap()); | ||
} | ||
``` | ||
The paths provided when creating `wallet` and `shielded_ctx` are the directories where the shielded context data and `wallet.toml` will be | ||
saved to/read from. | ||
|
||
<Callout type="info"> | ||
All following pages in this section assume you have already created a Chain Context with the name `sdk`. | ||
</Callout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.