Skip to content

Commit

Permalink
feat: add generate ibc shielding memo to the sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
emccorson committed Oct 4, 2024
1 parent 4b1a33a commit 4549176
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 12 deletions.
27 changes: 20 additions & 7 deletions apps/namadillo/src/App/Ibc/IbcTransfer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Coin } from "@cosmjs/launchpad";
import { coin, coins } from "@cosmjs/proto-signing";
import {
MsgTransferEncodeObject,
QueryClient,
SigningStargateClient,
StargateClient,
Expand Down Expand Up @@ -289,14 +290,26 @@ const submitIbcTransfer = async (
gas: "222000",
};

const response = await client.sendIbcTokens(
const timeoutTimestampNanoseconds =
BigInt(Math.floor(Date.now() / 1000) + 60) * BigInt(1_000_000_000);

const transferMsg: MsgTransferEncodeObject = {
typeUrl: "/ibc.applications.transfer.v1.MsgTransfer",
value: {
sourcePort: "transfer",
sourceChannel: channelId,
sender: source,
receiver: target,
token: coin(amount, token),
timeoutHeight: undefined,
timeoutTimestamp: timeoutTimestampNanoseconds,
memo,
},
};

const response = await client.signAndBroadcast(
source,
target,
coin(amount, token),
"transfer",
channelId,
undefined, // timeout height
Math.floor(Date.now() / 1000) + 60, // timeout timestamp
[transferMsg],
fee,
`${sourceChainId}->Namada`
);
Expand Down
25 changes: 25 additions & 0 deletions packages/sdk/src/tx/tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
WrapperTxProps,
} from "@namada/types";
import { ResponseSign } from "@zondax/ledger-namada";
import BigNumber from "bignumber.js";
import { WasmHash } from "../rpc";

/**
Expand Down Expand Up @@ -472,6 +473,30 @@ export class Tx {
};
}

/**
* Generate the memo needed for peforming an IBC transfer to a Namada shielded
* address.
* @async
* @param target - the Namada shielded address to send tokens to
* @param token - the token to transfer
* @param amount - the amount to transfer
* @param channelId - the IBC channel ID on the Namada side
* @returns promise that resolves to the shielding memo
*/
generateIbcShieldingMemo(
target: string,
token: string,
amount: BigNumber,
channelId: string
): Promise<string> {
return this.sdk.generate_ibc_shielding_memo(
target,
token,
amount.toString(),
channelId
);
}

/**
* Return the inner tx hashes from the provided tx bytes
* @param bytes - Uint8Array
Expand Down
55 changes: 50 additions & 5 deletions packages/shared/lib/src/sdk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,32 @@ use namada_sdk::eth_bridge::bridge_pool::build_bridge_pool_tx;
use namada_sdk::hash::Hash;
use namada_sdk::io::NamadaIo;
use namada_sdk::key::{common, ed25519, SigScheme};
use namada_sdk::masp::ShieldedContext;
use namada_sdk::masp::{ShieldedContext};
use namada_sdk::rpc::{query_epoch, InnerTxResult};
use namada_sdk::signing::SigningTxData;
use namada_sdk::string_encoding::Format;
use namada_sdk::tx::{
build_batch, build_bond, build_claim_rewards, build_ibc_transfer, build_redelegation,
build_reveal_pk, build_shielded_transfer, build_shielding_transfer, build_transparent_transfer,
build_unbond, build_unshielding_transfer, build_vote_proposal, build_withdraw,
data::compute_inner_tx_hash, either::Either, process_tx, ProcessTxResponse, Tx,
data::compute_inner_tx_hash, either::Either, process_tx, ProcessTxResponse,
Tx, gen_ibc_shielding_transfer
};
use namada_sdk::wallet::{Store, Wallet};
use namada_sdk::{Namada, NamadaImpl};
use namada_sdk::{Namada, NamadaImpl, PaymentAddress, TransferTarget};
use namada_sdk::args::{InputAmount, GenIbcShieldingTransfer, Query, TxExpiration};
use namada_sdk::ibc::core::host::types::identifiers::{ChannelId, PortId};
use namada_sdk::ibc::convert_masp_tx_to_ibc_memo;
use namada_sdk::token::DenominatedAmount;
use namada_sdk::tendermint_rpc::Url;
use std::str::FromStr;
use wasm_bindgen::{prelude::wasm_bindgen, JsError, JsValue};

/// Represents the Sdk public API.
#[wasm_bindgen]
pub struct Sdk {
namada: NamadaImpl<HttpClient, wallet::JSWalletUtils, masp::JSShieldedUtils, WebIo>,
rpc_url: String
}

#[wasm_bindgen]
Expand All @@ -47,7 +54,7 @@ impl Sdk {
#[wasm_bindgen(constructor)]
pub fn new(url: String, native_token: String, path_or_db_name: String) -> Self {
set_panic_hook();
let client: HttpClient = HttpClient::new(url);
let client: HttpClient = HttpClient::new(url.clone());
let wallet: Wallet<wallet::JSWalletUtils> = Wallet::new(
wallet::JSWalletUtils::new_utils(&path_or_db_name),
Store::default(),
Expand All @@ -63,7 +70,10 @@ impl Sdk {
Address::from_str(&native_token).unwrap(),
);

Sdk { namada }
Sdk {
namada,
rpc_url: url
}
}

pub async fn has_masp_params() -> Result<JsValue, JsValue> {
Expand Down Expand Up @@ -475,6 +485,41 @@ impl Sdk {
common::SigScheme::verify_signature(&public_key, &signed_hash, &sig).map_err(JsError::from)
}

pub async fn generate_ibc_shielding_memo(
&self,
target: &str,
token: String,
amount: &str,
channel_id: &str
) -> Result<JsValue, JsError> {
let ledger_address = Url::from_str(&self.rpc_url).expect("RPC URL is a valid URL");
let target = TransferTarget::PaymentAddress(
PaymentAddress::from_str(target).expect("target is a valid shielded address")
);
let amount = InputAmount::Unvalidated(
DenominatedAmount::from_str(amount).expect("amount is valid")
);
let channel_id = ChannelId::from_str(channel_id).expect("channel ID is valid");

let args = GenIbcShieldingTransfer {
query: Query { ledger_address },
output_folder: None,
target,
token,
amount,
port_id: PortId::transfer(),
channel_id,
expiration: TxExpiration::Default
};

if let Some(masp_tx) = gen_ibc_shielding_transfer(&self.namada, args).await? {
let memo = convert_masp_tx_to_ibc_memo(&masp_tx);
to_js_result(memo)
} else {
Err(JsError::new("Generating ibc shielding transfer generated nothing"))
}
}

fn serialize_tx_result(
&self,
tx: Tx,
Expand Down

0 comments on commit 4549176

Please sign in to comment.