Skip to content

Commit

Permalink
Problem: missing support for defi-wallet (fix #469) (#470)
Browse files Browse the repository at this point in the history
defiwallet fix
fix signing for defiwallet

fix clippy

remove test_fetch function

remove legacy code

run cargo test

use runtime env

fix warning

change log
  • Loading branch information
leejw51crypto authored Apr 23, 2024
1 parent c4bdafa commit fe74aa9
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 50 deletions.
12 changes: 3 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,9 @@ jobs:
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-stable-${{ hashFiles('**/Cargo.lock') }}
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- name: Generate code coverage
run: cargo llvm-cov --all-features --all --lcov --output-path lcov.info
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
files: ./lcov.info
fail_ci_if_error: true
- name: Run tests
run: cargo test --all-features --all

fmt:
name: cargo fmt
runs-on: ubuntu-latest
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Changelog
## [Unreleased]

## [v0.0.25-alpha] - 2024-4-23
- support defi-wallet

## [v0.0.24-alpha] - 2023-12-4
- fix walletconnect 2.0 send_tx
- add from_address for walletconnect 2.0 sendtx
Expand Down
20 changes: 0 additions & 20 deletions extra-cpp-bindings/src/wallectconnectregistry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,26 +198,6 @@ mod test {
assert_eq!(wallets.len(), 20);
}

#[test]
fn test_fetch_new_no_cache() {
let reg = Registry::fetch_new(None);
assert!(reg.is_ok());
}

#[test]
fn test_fetch_new_with_cache() {
let mut dir = std::env::temp_dir();
let tmpfile = format!("{}.json", uuid::Uuid::new_v4());
dir.push(tmpfile);
println!("{:?}", dir);

let reg = Registry::fetch_new(Some(dir.clone()));
assert!(reg.is_ok());

let reg = Registry::load_cached(Some(dir));
assert!(reg.is_ok());
}

#[test]
fn test_load_cached() {
let reg = Registry::load_cached(Some(PathBuf::from("./not_exists.json")));
Expand Down
2 changes: 0 additions & 2 deletions integration_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,5 @@ $PWD/demo/build/examples/get_tokens_blocking
$PWD/demo/build/examples/get_token_transfers_blocking
$PWD/demo/build/examples/create_payment
$PWD/demo/build/examples/wallet_connect
$PWD/demo/build/examples/get_token_holders
$PWD/demo/build/examples/new_wallet
$PWD/demo/build/examples/restore_wallet
$PWD/demo/build/examples/get_wallet
36 changes: 20 additions & 16 deletions wallet-connect/examples/web3_v2.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
use defi_wallet_connect::v2::WCMiddleware;
use ethers::abi::Address;
use ethers::core::types::transaction::eip2718::TypedTransaction;
use ethers::prelude::*;
use eyre::Result;
use image::Luma;
use qrcode::QrCode;
use std::fs;
use std::io;
use std::io::Write;
//use ethers::ethers_providers::Middleware;
use defi_wallet_connect::v2::WCMiddleware;
use ethers::prelude::*;

use std::str::FromStr;

use defi_wallet_connect::v2::{Client, ClientOptions, Metadata, RequiredNamespaces, SessionInfo};
use std::error::Error;
use std::io::BufRead;

const RPC_URL: &str = env!("MY_RPC_URL");
const CHAIN_ID: &str = env!("MY_CHAIN_ID");
const FROM_ADDRESS: &str = env!("MY_FROM_ADDRESS");
const TO_ADDRESS: &str = env!("MY_TO_ADDRESS");

#[derive(Debug, Default)]
pub struct WalletConnectTxCommon {
pub gas_limit: String, // decimal string, "1"
Expand All @@ -43,7 +37,9 @@ pub struct WalletConnectTxEip155 {
async fn make_client(
callback_sender: Option<tokio::sync::mpsc::UnboundedSender<String>>,
) -> Result<Client, relay_client::Error> {
let mychain = format!("eip155:{}", CHAIN_ID);
let chain_id = std::env::var("MY_CHAIN_ID").expect("MY_CHAIN_ID not set");
let mychain = format!("eip155:{}", chain_id);

let opts = ClientOptions {
relay_server: "wss://relay.walletconnect.com".parse().expect("url"),
project_id: std::env::args().skip(1).next().expect("project_id"),
Expand Down Expand Up @@ -200,7 +196,6 @@ pub async fn send_eip155_transaction_blocking(
.await
.map_err(|e| eyre::eyre!("send_typed_transaction error {}", e.to_string()))?;

//Ok(tx_bytes.0.to_vec())
Ok(tx_bytes.0.to_vec())
}

Expand All @@ -225,7 +220,8 @@ async fn send_ethereum_transaction(
let from_address = Address::from_str(from)?;
let to_address = Address::from_str(to)?;

let provider = Provider::<Http>::try_from(RPC_URL)?;
let rpc_url = std::env::var("MY_RPC_URL").expect("MY_RPC_URL not set");
let provider = Provider::<Http>::try_from(rpc_url.as_str())?;
let chain_id = provider.get_chainid().await?;
let nonce = provider.get_transaction_count(from_address, None).await?;
// Construct the transaction
Expand Down Expand Up @@ -296,18 +292,23 @@ async fn main() -> Result<(), Box<dyn Error>> {
}

if test_sign_tx {
let from_address = std::env::var("MY_FROM_ADDRESS").expect("MY_FROM_ADDRESS not set");
let to_address = std::env::var("MY_TO_ADDRESS").expect("MY_TO_ADDRESS not set");

// convert fromaddress to 20 fixed byte array
let fromaddress = Address::from_str(&FROM_ADDRESS)?;
let fromaddress = Address::from_str(&from_address)?;

let txinfo = WalletConnectTxEip155 {
common: WalletConnectTxCommon {
chainid: CHAIN_ID.parse::<u64>()?,
chainid: std::env::var("MY_CHAIN_ID")
.expect("MY_CHAIN_ID not set")
.parse::<u64>()?,
gas_limit: "21000".into(),
gas_price: "1000000000".into(),
nonce: "0".into(),
nonce: "".into(),
web3api_url: "".into(),
},
to: TO_ADDRESS.into(),
to: to_address.into(),
data: vec![],
value: "1000".into(),
};
Expand All @@ -331,10 +332,13 @@ async fn main() -> Result<(), Box<dyn Error>> {
}

if test_send_tx {
let from_address = std::env::var("MY_FROM_ADDRESS").expect("MY_FROM_ADDRESS not set");
let to_address = std::env::var("MY_TO_ADDRESS").expect("MY_TO_ADDRESS not set");

let amount = U256::from_dec_str("1000012345678912")?; // 1 ETH for example

let tx_hash =
send_ethereum_transaction(&mut client, FROM_ADDRESS, TO_ADDRESS, amount).await?;
send_ethereum_transaction(&mut client, &from_address, &to_address, amount).await?;

println!("Transaction sent with hash: {:?}", tx_hash);
}
Expand Down
1 change: 0 additions & 1 deletion wallet-connect/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ mod aead;
/// wrapper around the symmetric key
mod key;

pub use aead::*;
pub use key::*;
27 changes: 27 additions & 0 deletions wallet-connect/src/v2/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use async_trait::async_trait;
use ethers::prelude::PendingTransaction;
use ethers::types::transaction::eip2718::TypedTransaction;
use ethers::types::BlockId;
use ethers::types::U256;
use ethers::{
prelude::{
Address, Bytes, JsonRpcClient, Middleware, MiddlewareError, NameOrAddress, Provider,
Expand Down Expand Up @@ -242,6 +243,21 @@ fn append_hex(s: String) -> String {
}
}

// tx_bytes is 32 bytes, for defi-wallet , it's txhash
fn make_defiwallet_signature(tx_bytes: &[u8]) -> Option<Signature> {
// print hex of tx_bytes
if tx_bytes.len() == 32 {
let r = U256::from_big_endian(tx_bytes);
let s = U256::zero();
let v = 0;
// r: 32 bytes, s: 32bytes, v: 1 bytes
let sig = Signature { r, s, v };
Some(sig)
} else {
None
}
}

#[async_trait]
impl Middleware for WCMiddleware<Provider<Client>> {
type Error = WCError<Provider<Client>>;
Expand All @@ -268,6 +284,9 @@ impl Middleware for WCMiddleware<Provider<Client>> {
}
if let Some(data) = tx.data() {
tx_obj.insert("data", format!("0x{}", hex::encode(data)));
} else {
// need for defi wallet, otherwise user rejection error
tx_obj.insert("data", "0x".to_string());
}
if let Some(gas) = tx.gas() {
// gas not working for webwallet
Expand Down Expand Up @@ -299,6 +318,14 @@ impl Middleware for WCMiddleware<Provider<Client>> {
))));
}

if tx_rlp.as_raw().len() == 32 {
// It's not RLP-encoded
return make_defiwallet_signature(tx_rlp.as_raw()).ok_or_else(|| {
WCError::ClientError(ClientError::Eyre(eyre!(
"failed to decode defiwallet tx-hash signature"
)))
});
}
let first_byte = tx_rlp.as_raw()[0];
// TODO: check that the decoded request matches the typed transaction content here? or a new `sign_transaction` function that returns both request+signature?
if first_byte <= 0x7f {
Expand Down
2 changes: 1 addition & 1 deletion wallet-connect/src/v2/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ impl JsonRpcClient for Connector {
.required_namespaces
.eip155
.chains
.get(0)
.first()
.map(ToOwned::to_owned)
.unwrap_or_else(|| "eip155:25".to_owned());
// release the lock
Expand Down
2 changes: 1 addition & 1 deletion wallet-connect/src/v2/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ pub struct WcSessionProposeResponse {
pub struct WcSessionSettle {
relay: Relay,
pub namespaces: Namespaces,
#[serde(rename = "requiredNamespaces")]
#[serde(rename = "requiredNamespaces", default)]
required_namespaces: RequiredNamespaces,
pub controller: Peer,
expiry: i64,
Expand Down

0 comments on commit fe74aa9

Please sign in to comment.