Skip to content

Commit

Permalink
[Cosmos]: Expose bech32 address prefix via FFI
Browse files Browse the repository at this point in the history
* Implement missing TX compiler for Cosmos chains
* TODO: Fix TWAnyAddressData
  • Loading branch information
satoshiotomakan committed Nov 14, 2023
1 parent 9b8c3b8 commit d75f178
Show file tree
Hide file tree
Showing 25 changed files with 371 additions and 132 deletions.
50 changes: 35 additions & 15 deletions rust/chains/tw_cosmos/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@
// terms governing use, modification, and redistribution, is contained in the
// file LICENSE at the root of the source code distribution tree.

use std::str::FromStr;
use tw_coin_entry::coin_context::CoinContext;
use tw_coin_entry::coin_entry::{CoinEntry, PublicKeyBytes, SignatureBytes};
use tw_coin_entry::derivation::Derivation;
use tw_coin_entry::error::AddressResult;
use tw_coin_entry::modules::json_signer::NoJsonSigner;
use tw_coin_entry::modules::message_signer::NoMessageSigner;
use tw_coin_entry::modules::plan_builder::NoPlanBuilder;
use tw_coin_entry::prefix::NoPrefix;
use tw_cosmos_sdk::address::{Address, CosmosAddress};
use tw_cosmos_sdk::address::{Address, Bech32Prefix};
use tw_cosmos_sdk::context::StandardCosmosContext;
use tw_cosmos_sdk::modules::compiler::tw_compiler::TWTransactionCompiler;
use tw_cosmos_sdk::modules::signer::tw_signer::TWSigner;
use tw_keypair::tw;
use tw_proto::Cosmos::Proto;
Expand All @@ -22,7 +23,7 @@ use tw_proto::TxCompiler::Proto as CompilerProto;
pub struct CosmosEntry;

impl CoinEntry for CosmosEntry {
type AddressPrefix = NoPrefix;
type AddressPrefix = Bech32Prefix;
type Address = Address;
type SigningInput<'a> = Proto::SigningInput<'a>;
type SigningOutput = Proto::SigningOutput<'static>;
Expand All @@ -31,44 +32,63 @@ impl CoinEntry for CosmosEntry {
type PlanBuilder = NoPlanBuilder;
type MessageSigner = NoMessageSigner;

#[inline]
fn parse_address(
&self,
coin: &dyn CoinContext,
address: &str,
_prefix: Option<Self::AddressPrefix>,
prefix: Option<Self::AddressPrefix>,
) -> AddressResult<Self::Address> {
Address::from_str_with_coin(coin, address)
Address::from_str_with_coin_and_prefix(coin, address.to_string(), prefix)
}

#[inline]
fn parse_address_unchecked(
&self,
_coin: &dyn CoinContext,
address: &str,
) -> AddressResult<Self::Address> {
Address::from_str(address)
}

#[inline]
fn derive_address(
&self,
coin: &dyn CoinContext,
public_key: tw::PublicKey,
_derivation: Derivation,
_prefix: Option<Self::AddressPrefix>,
prefix: Option<Self::AddressPrefix>,
) -> AddressResult<Self::Address> {
Address::with_public_key_coin_context(coin, &public_key)
Address::with_public_key_coin_context(coin, &public_key, prefix)
}

#[inline]
fn sign(&self, coin: &dyn CoinContext, input: Self::SigningInput<'_>) -> Self::SigningOutput {
TWSigner::<StandardCosmosContext>::sign(coin, input)
}

#[inline]
fn preimage_hashes(
&self,
_coin: &dyn CoinContext,
_input: Self::SigningInput<'_>,
coin: &dyn CoinContext,
input: Self::SigningInput<'_>,
) -> Self::PreSigningOutput {
todo!()
TWTransactionCompiler::<StandardCosmosContext>::preimage_hashes(coin, input)
}

#[inline]
fn compile(
&self,
_coin: &dyn CoinContext,
_input: Self::SigningInput<'_>,
_signatures: Vec<SignatureBytes>,
_public_keys: Vec<PublicKeyBytes>,
coin: &dyn CoinContext,
input: Self::SigningInput<'_>,
signatures: Vec<SignatureBytes>,
public_keys: Vec<PublicKeyBytes>,
) -> Self::SigningOutput {
todo!()
TWTransactionCompiler::<StandardCosmosContext>::compile(
coin,
input,
signatures,
public_keys,
)
}
}
51 changes: 36 additions & 15 deletions rust/chains/tw_native_evmos/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
// file LICENSE at the root of the source code distribution tree.

use crate::context::NativeEvmosContext;
use std::str::FromStr;
use tw_coin_entry::coin_context::CoinContext;
use tw_coin_entry::coin_entry::{CoinEntry, PublicKeyBytes, SignatureBytes};
use tw_coin_entry::derivation::Derivation;
use tw_coin_entry::error::AddressResult;
use tw_coin_entry::modules::json_signer::NoJsonSigner;
use tw_coin_entry::modules::message_signer::NoMessageSigner;
use tw_coin_entry::modules::plan_builder::NoPlanBuilder;
use tw_coin_entry::prefix::NoPrefix;
use tw_cosmos_sdk::address::{Address, CosmosAddress};
use tw_cosmos_sdk::address::{Address, Bech32Prefix};
use tw_cosmos_sdk::context::StandardCosmosContext;
use tw_cosmos_sdk::modules::compiler::tw_compiler::TWTransactionCompiler;
use tw_cosmos_sdk::modules::signer::tw_signer::TWSigner;
use tw_keypair::tw;
use tw_proto::Cosmos::Proto;
Expand All @@ -22,7 +24,7 @@ use tw_proto::TxCompiler::Proto as CompilerProto;
pub struct NativeEvmosEntry;

impl CoinEntry for NativeEvmosEntry {
type AddressPrefix = NoPrefix;
type AddressPrefix = Bech32Prefix;
type Address = Address;
type SigningInput<'a> = Proto::SigningInput<'a>;
type SigningOutput = Proto::SigningOutput<'static>;
Expand All @@ -31,44 +33,63 @@ impl CoinEntry for NativeEvmosEntry {
type PlanBuilder = NoPlanBuilder;
type MessageSigner = NoMessageSigner;

#[inline]
fn parse_address(
&self,
coin: &dyn CoinContext,
address: &str,
_prefix: Option<Self::AddressPrefix>,
prefix: Option<Self::AddressPrefix>,
) -> AddressResult<Self::Address> {
Address::from_str_with_coin(coin, address)
Address::from_str_with_coin_and_prefix(coin, address.to_string(), prefix)
}

#[inline]
fn parse_address_unchecked(
&self,
_coin: &dyn CoinContext,
address: &str,
) -> AddressResult<Self::Address> {
Address::from_str(address)
}

#[inline]
fn derive_address(
&self,
coin: &dyn CoinContext,
public_key: tw::PublicKey,
_derivation: Derivation,
_prefix: Option<Self::AddressPrefix>,
prefix: Option<Self::AddressPrefix>,
) -> AddressResult<Self::Address> {
Address::with_public_key_coin_context(coin, &public_key)
Address::with_public_key_coin_context(coin, &public_key, prefix)
}

#[inline]
fn sign(&self, coin: &dyn CoinContext, input: Self::SigningInput<'_>) -> Self::SigningOutput {
TWSigner::<NativeEvmosContext>::sign(coin, input)
}

#[inline]
fn preimage_hashes(
&self,
_coin: &dyn CoinContext,
_input: Self::SigningInput<'_>,
coin: &dyn CoinContext,
input: Self::SigningInput<'_>,
) -> Self::PreSigningOutput {
todo!()
TWTransactionCompiler::<StandardCosmosContext>::preimage_hashes(coin, input)
}

#[inline]
fn compile(
&self,
_coin: &dyn CoinContext,
_input: Self::SigningInput<'_>,
_signatures: Vec<SignatureBytes>,
_public_keys: Vec<PublicKeyBytes>,
coin: &dyn CoinContext,
input: Self::SigningInput<'_>,
signatures: Vec<SignatureBytes>,
public_keys: Vec<PublicKeyBytes>,
) -> Self::SigningOutput {
todo!()
TWTransactionCompiler::<StandardCosmosContext>::compile(
coin,
input,
signatures,
public_keys,
)
}
}
47 changes: 34 additions & 13 deletions rust/chains/tw_native_injective/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
// file LICENSE at the root of the source code distribution tree.

use crate::context::NativeInjectiveContext;
use std::str::FromStr;
use tw_coin_entry::coin_context::CoinContext;
use tw_coin_entry::coin_entry::{CoinEntry, PublicKeyBytes, SignatureBytes};
use tw_coin_entry::derivation::Derivation;
use tw_coin_entry::error::AddressResult;
use tw_coin_entry::modules::json_signer::NoJsonSigner;
use tw_coin_entry::modules::message_signer::NoMessageSigner;
use tw_coin_entry::modules::plan_builder::NoPlanBuilder;
use tw_coin_entry::prefix::NoPrefix;
use tw_cosmos_sdk::address::{Address, CosmosAddress};
use tw_cosmos_sdk::address::{Address, Bech32Prefix, CosmosAddress};
use tw_cosmos_sdk::context::StandardCosmosContext;
use tw_cosmos_sdk::modules::compiler::tw_compiler::TWTransactionCompiler;
use tw_cosmos_sdk::modules::signer::tw_signer::TWSigner;
use tw_keypair::tw;
use tw_proto::Cosmos::Proto;
Expand All @@ -22,7 +24,7 @@ use tw_proto::TxCompiler::Proto as CompilerProto;
pub struct NativeInjectiveEntry;

impl CoinEntry for NativeInjectiveEntry {
type AddressPrefix = NoPrefix;
type AddressPrefix = Bech32Prefix;
type Address = Address;
type SigningInput<'a> = Proto::SigningInput<'a>;
type SigningOutput = Proto::SigningOutput<'static>;
Expand All @@ -31,6 +33,7 @@ impl CoinEntry for NativeInjectiveEntry {
type PlanBuilder = NoPlanBuilder;
type MessageSigner = NoMessageSigner;

#[inline]
fn parse_address(
&self,
coin: &dyn CoinContext,
Expand All @@ -40,35 +43,53 @@ impl CoinEntry for NativeInjectiveEntry {
Address::from_str_with_coin(coin, address)
}

#[inline]
fn parse_address_unchecked(
&self,
_coin: &dyn CoinContext,
address: &str,
) -> AddressResult<Self::Address> {
Address::from_str(address)
}

#[inline]
fn derive_address(
&self,
coin: &dyn CoinContext,
public_key: tw::PublicKey,
_derivation: Derivation,
_prefix: Option<Self::AddressPrefix>,
prefix: Option<Self::AddressPrefix>,
) -> AddressResult<Self::Address> {
Address::with_public_key_coin_context(coin, &public_key)
Address::with_public_key_coin_context(coin, &public_key, prefix)
}

#[inline]
fn sign(&self, coin: &dyn CoinContext, input: Self::SigningInput<'_>) -> Self::SigningOutput {
TWSigner::<NativeInjectiveContext>::sign(coin, input)
}

#[inline]
fn preimage_hashes(
&self,
_coin: &dyn CoinContext,
_input: Self::SigningInput<'_>,
coin: &dyn CoinContext,
input: Self::SigningInput<'_>,
) -> Self::PreSigningOutput {
todo!()
TWTransactionCompiler::<StandardCosmosContext>::preimage_hashes(coin, input)
}

#[inline]
fn compile(
&self,
_coin: &dyn CoinContext,
_input: Self::SigningInput<'_>,
_signatures: Vec<SignatureBytes>,
_public_keys: Vec<PublicKeyBytes>,
coin: &dyn CoinContext,
input: Self::SigningInput<'_>,
signatures: Vec<SignatureBytes>,
public_keys: Vec<PublicKeyBytes>,
) -> Self::SigningOutput {
todo!()
TWTransactionCompiler::<StandardCosmosContext>::compile(
coin,
input,
signatures,
public_keys,
)
}
}
10 changes: 8 additions & 2 deletions rust/tw_any_coin/src/any_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ impl AnyAddress {
prefix: Option<AddressPrefix>,
) -> AddressResult<AnyAddress> {
let (ctx, entry) = coin_dispatcher(coin).map_err(|_| AddressError::UnknownCoinType)?;
let address = entry.normalize_address(&ctx, address, prefix)?;
entry.validate_address(&ctx, address, prefix)?;
let address = entry.normalize_address(&ctx, address)?;
Ok(AnyAddress { coin, address })
}

Expand All @@ -56,8 +57,13 @@ impl AnyAddress {
/// Returns underlying data (public key or key hash).
#[inline]
pub fn get_data(&self) -> AddressResult<Data> {
// TODO
println!(
"AnyAddress::get_data() coin={} address={}",
self.coin, self.address
);
let (ctx, entry) = coin_dispatcher(self.coin).map_err(|_| AddressError::UnknownCoinType)?;
entry.address_to_data(&ctx, &self.address, None)
entry.address_to_data(&ctx, &self.address)
}

/// Returns the address string representation.
Expand Down
Loading

0 comments on commit d75f178

Please sign in to comment.