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 - Update to SDK changes in namada v0.18.1 #327

Merged
merged 2 commits into from
Jul 10, 2023
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
16 changes: 8 additions & 8 deletions packages/shared/lib/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/shared/lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ gloo-utils = { version = "0.1.5", features = ["serde"] }
js-sys = "0.3.60"
masp_primitives = { git = "https://github.com/anoma/masp", rev = "9320c6b69b5d2e97134866871e960f0a31703813" }
masp_proofs = { git = "https://github.com/anoma/masp", rev = "9320c6b69b5d2e97134866871e960f0a31703813", default-features = false, features = ["local-prover"] }
namada = { git = "https://github.com/anoma/namada", version = "0.18.0", default-features = false, features = ["abciplus", "namada-sdk"] }
namada = { git = "https://github.com/anoma/namada", version = "0.18.1", default-features = false, features = ["abciplus", "namada-sdk"] }
prost = "0.9.0"
prost-types = "0.9.0"
rand = "0.8.5"
Expand Down
195 changes: 172 additions & 23 deletions packages/shared/lib/src/sdk/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
use namada::ledger::{
masp::ShieldedContext,
wallet::{Store, Wallet},
};
use wasm_bindgen::{prelude::wasm_bindgen, JsError, JsValue};

use crate::utils::to_js_result;
use crate::{
rpc_client::HttpClient,
sdk::masp::WebShieldedUtils,
utils::{set_panic_hook, to_bytes},
};
use borsh::BorshSerialize;
use namada::{
ledger::{
args,
masp::ShieldedContext,
signing,
wallet::{Store, Wallet},
},
proto::{Section, Signature, Tx},
types::{key::common::PublicKey, key::common::SecretKey as SK, key::ed25519::SecretKey},
};
use std::str::FromStr;
use wasm_bindgen::{prelude::wasm_bindgen, JsError, JsValue};

pub mod masp;
mod tx;
Expand Down Expand Up @@ -87,28 +95,126 @@ impl Sdk {
wallet::add_spending_key(&mut self.wallet, xsk, password, alias)
}

pub async fn submit_bond(
async fn submit_reveal_pk(
&mut self,
tx_msg: &[u8],
password: Option<String>,
args: &args::Tx,
mut tx: Tx,
pk: &PublicKey,
) -> Result<(), JsError> {
let args = tx::bond_tx_args(tx_msg, password)?;
// Build a transaction to reveal the signer of this transaction
let reveal_pk = namada::ledger::tx::build_reveal_pk(
&self.client,
&mut self.wallet,
args::RevealPk {
tx: args.clone(),
public_key: pk.clone(),
},
)
.await?;

// Sign and submit reveal pk
if let Some((mut rtx, _, pk)) = reveal_pk {
// Sign the reveal public key transaction with the fee payer
signing::sign_tx(&mut self.wallet, &mut rtx, &args, &pk).await?;
// Submit the reveal public key transaction first
namada::ledger::tx::process_tx(&self.client, &mut self.wallet, &args, rtx).await?;
// Update the stateful PoW challenge of the outer transaction
#[cfg(not(feature = "mainnet"))]
signing::update_pow_challenge(&self.client, &args, &mut tx, &pk, false).await;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We most likely have to add "mainnet" feature to Cargo.toml and to the release/mainnet builds. Worth asking someone about this flag :)

}

Ok(())
}

/// Sign and submit transactions
async fn sign_and_process_tx(
&mut self,
args: args::Tx,
mut tx: Tx,
pk: PublicKey,
) -> Result<(), JsError> {
// Submit a reveal pk tx if necessary
self.submit_reveal_pk(&args, tx.clone(), &pk).await?;

namada::ledger::tx::submit_bond(&mut self.client, &mut self.wallet, args)
// Sign tx
signing::sign_tx(&mut self.wallet, &mut tx, &args, &pk)
.await
.map_err(|e| JsError::from(e))
.map_err(JsError::from)?;

// Submit tx
namada::ledger::tx::process_tx(&self.client, &mut self.wallet, &args, tx)
.await
.map_err(JsError::from)?;

Ok(())
}

pub async fn submit_unbond(
/// Contruct transfer data for external signers, returns byte array
pub async fn build_transfer(&mut self, tx_msg: &[u8]) -> Result<JsValue, JsError> {
let args = tx::transfer_tx_args(tx_msg, None, None)?;

let transfer = namada::ledger::tx::build_transfer(
&self.client,
&mut self.wallet,
&mut self.shielded_ctx,
args.clone(),
)
.await
.map_err(JsError::from)?;

let bytes = transfer.0.try_to_vec().map_err(JsError::from)?;

to_js_result(bytes)
}

// Append signatures and return tx bytes
pub fn sign_tx(
&self,
tx_bytes: &[u8],
data_key: String,
header_key: String,
) -> Result<JsValue, JsError> {
let mut tx: Tx = Tx::try_from(tx_bytes).map_err(JsError::from)?;
let data_secret = SecretKey::from_str(&data_key).map_err(JsError::from)?;
let header_secret = SecretKey::from_str(&header_key).map_err(JsError::from)?;

// Sign over the transaction data
tx.add_section(Section::Signature(Signature::new(
vec![*tx.data_sechash(), *tx.code_sechash()],
&SK::Ed25519(data_secret),
)));

tx.protocol_filter();

// Then sign over the bound wrapper
tx.add_section(Section::Signature(Signature::new(
tx.sechashes(),
&SK::Ed25519(header_secret),
)));

let bytes = tx.try_to_vec().map_err(|e| JsError::from(e))?;
to_js_result(Vec::from(bytes))
}

/// Submit signed transfer tx
pub async fn submit_signed_transfer(
&mut self,
pk: String,
tx_msg: &[u8],
password: Option<String>,
tx_bytes: &[u8],
) -> Result<(), JsError> {
let args = tx::unbond_tx_args(tx_msg, password)?;
let transfer_tx = Tx::try_from(tx_bytes).map_err(|e| JsError::from(e))?;
let args = tx::transfer_tx_args(tx_msg, None, None).map_err(|e| JsError::from(e))?;
let pk = PublicKey::from_str(&pk).map_err(JsError::from)?;

self.submit_reveal_pk(&args.tx, transfer_tx.clone(), &pk)
.await?;

namada::ledger::tx::submit_unbond(&mut self.client, &mut self.wallet, args)
namada::ledger::tx::process_tx(&self.client, &mut self.wallet, &args.tx, transfer_tx)
.await
.map_err(|e| JsError::from(e))
.map_err(JsError::from)?;

Ok(())
}

pub async fn submit_transfer(
Expand All @@ -118,14 +224,18 @@ impl Sdk {
xsk: Option<String>,
) -> Result<(), JsError> {
let args = tx::transfer_tx_args(tx_msg, password, xsk)?;
namada::ledger::tx::submit_transfer(
let (tx, _, pk, _, _) = namada::ledger::tx::build_transfer(
&self.client,
&mut self.wallet,
&mut self.shielded_ctx,
args,
args.clone(),
)
.await
.map_err(|e| JsError::from(e))
.map_err(JsError::from)?;

self.sign_and_process_tx(args.tx, tx, pk).await?;

Ok(())
}

pub async fn submit_ibc_transfer(
Expand All @@ -135,9 +245,48 @@ impl Sdk {
) -> Result<(), JsError> {
let args = tx::ibc_transfer_tx_args(tx_msg, password)?;

namada::ledger::tx::submit_ibc_transfer(&self.client, &mut self.wallet, args)
.await
.map_err(|e| JsError::from(e))
let (tx, _, pk) =
namada::ledger::tx::build_ibc_transfer(&self.client, &mut self.wallet, args.clone())
.await
.map_err(JsError::from)?;

self.sign_and_process_tx(args.tx, tx, pk).await?;

Ok(())
}

pub async fn submit_bond(
&mut self,
tx_msg: &[u8],
password: Option<String>,
) -> Result<(), JsError> {
let args = tx::bond_tx_args(tx_msg, password)?;

let (tx, _, pk) =
namada::ledger::tx::build_bond(&mut self.client, &mut self.wallet, args.clone())
.await
.map_err(JsError::from)?;

self.sign_and_process_tx(args.tx, tx, pk).await?;

Ok(())
}

pub async fn submit_unbond(
&mut self,
tx_msg: &[u8],
password: Option<String>,
) -> Result<(), JsError> {
let args = tx::unbond_tx_args(tx_msg, password)?;

let (tx, _, pk, _) =
namada::ledger::tx::build_unbond(&mut self.client, &mut self.wallet, args.clone())
.await
.map_err(JsError::from)?;

self.sign_and_process_tx(args.tx, tx, pk).await?;

Ok(())
}
}

Expand Down
14 changes: 13 additions & 1 deletion packages/shared/lib/src/sdk/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use namada::{
types::{
address::Address,
chain::ChainId,
key::common::PublicKey as PK,
key::ed25519::PublicKey,
masp::{ExtendedSpendingKey, PaymentAddress, TransferSource, TransferTarget},
token::{Amount, DenominatedAmount, Denomination},
transaction::GasLimit,
Expand All @@ -20,6 +22,7 @@ pub struct TxMsg {
fee_amount: u64,
gas_limit: u64,
chain_id: String,
public_key: Option<String>,
}

#[derive(BorshSerialize, BorshDeserialize)]
Expand Down Expand Up @@ -175,6 +178,7 @@ pub fn transfer_tx_args(
))),
},
}?;

let native_token = Address::from_str(&native_token)?;
let token = Address::from_str(&token)?;
let amount_str = amount.to_string();
Expand Down Expand Up @@ -275,8 +279,8 @@ fn tx_msg_into_args(tx_msg: TxMsg, password: Option<String>) -> Result<args::Tx,
token,
fee_amount,
gas_limit,
// TODO: remove all the unused tx codes
chain_id,
public_key,
} = tx_msg;

let token = Address::from_str(&token)?;
Expand All @@ -289,6 +293,13 @@ fn tx_msg_into_args(tx_msg: TxMsg, password: Option<String>) -> Result<args::Tx,

let password = password.map(|pwd| zeroize::Zeroizing::new(pwd));
let gas_limit = Amount::from(gas_limit);
let public_key = match public_key {
Some(v) => {
let pk = PublicKey::from_str(&v).map_err(JsError::from)?;
Some(PK::Ed25519(pk))
}
_ => None,
};

let args = args::Tx {
dry_run: false,
Expand All @@ -306,6 +317,7 @@ fn tx_msg_into_args(tx_msg: TxMsg, password: Option<String>) -> Result<args::Tx,
signing_key: None,
signer: None,
tx_reveal_code_path: PathBuf::from("tx_reveal_pk.wasm"),
verification_key: public_key,
password,
};
Ok(args)
Expand Down
23 changes: 14 additions & 9 deletions packages/types/src/tx/schema/tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@ export class TxMsgValue {
fee_amount: BN;
gas_limit: BN;
chain_id: string;
public_key?: string;

constructor(properties: TxProps | SchemaObject<typeof TxMsgSchema>) {
this.token = properties.token;
this.fee_amount = 'feeAmount' in properties ?
new BN(properties.feeAmount.toString()) :
properties.fee_amount;
this.gas_limit = 'gasLimit' in properties ?
new BN(properties.gasLimit.toString()) :
properties.gas_limit;
this.chain_id = 'chainId' in properties ?
properties.chainId :
properties.chain_id;
this.fee_amount =
"feeAmount" in properties
? new BN(properties.feeAmount.toString())
: properties.fee_amount;
this.gas_limit =
"gasLimit" in properties
? new BN(properties.gasLimit.toString())
: properties.gas_limit;
this.chain_id =
"chainId" in properties ? properties.chainId : properties.chain_id;
this.public_key =
"publicKey" in properties ? properties.publicKey : undefined;
}
}

Expand All @@ -31,6 +35,7 @@ export const TxMsgSchema = [
["fee_amount", "u64"],
["gas_limit", "u64"],
["chain_id", "string"],
["public_key", { kind: "option", type: "string" }],
],
},
] as const; // needed for SchemaObject to deduce types correctly
1 change: 1 addition & 0 deletions packages/types/src/tx/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type TxProps = {
feeAmount: BigNumber;
gasLimit: BigNumber;
chainId: string;
publicKey?: string;
};

export type TransferProps = {
Expand Down
Loading