Skip to content

Commit

Permalink
Merge pull request #15 from Conflux-Chain/fixLedgerFeedback
Browse files Browse the repository at this point in the history
Fix ledger feedback
  • Loading branch information
Pana authored Jan 7, 2025
2 parents d5d3f8f + 03f390c commit 2be8d52
Show file tree
Hide file tree
Showing 283 changed files with 278 additions and 52 deletions.
8 changes: 4 additions & 4 deletions 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 Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ authors = ["Conflux Foundation"]
edition = "2021"

[dependencies]
ledger_device_sdk = "1.18.4"
ledger_device_sdk = "1.19.1"
include_gif = "1.2.0"
hex = { version = "0.4.3", default-features = false, features = ["serde", "alloc"] }
# numtoa = "0.2.4"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/account-add-ledger-guide.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/account-add-success.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/account-add.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/account-management.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/fluent-home.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/fluent-send-tx.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/ledger-blind-sign.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/ledger-conflux-ready.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/ledger-live.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/ledger-review-tx-amount.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/ledger-review-tx-data.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/ledger-review-tx-reject.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/ledger-review-tx-to.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/ledger-review-tx1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/ledger-setting-1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/ledger-setting-2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/tx-history-entry.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/how-to-use/imgs/tx-history.jpg
Binary file added docs/how-to-use/imgs/tx-rejected.jpg
Binary file added docs/how-to-use/imgs/wait-for-sign.jpg
112 changes: 112 additions & 0 deletions docs/how-to-use/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# How To Use Your Ledger Device With The Conflux Fluent Wallet

## Introduction

A Ledger Device is a hardware wallet that is considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users. This guide will help you to connect your Ledger device to the Conflux Fluent Wallet. The Conflux Fluent Wallet enables you to Send and Receive CFX and tokens issued on Conflux network.

## Quick Links

- Before You Start, Make Sure
- Video Guide
- Install The Conflux App
- Connecting to the Conflux Fluent Wallet
- View Account Balance
- Receiving CFX in the Conflux Fluent Wallet
- Sending CFX in the Conflux Fluent Wallet
- Support

## Before You Start, Make Sure

1. You’ve initialized your Ledger Device.
2. The latest firmware is installed (Ledger Nano S Plus).
3. Ledger Live is ready to use.
4. Install the latest version of [Conflux Fluent Wallet](https://fluentwallet.com/) (above 2.8.0)
![](./imgs/fluent-home.jpg)

## Video Guide

https://youtu.be/QaDE8k57dGQ

## Install The Conflux App

1. Open the Manager ("My Ledger") in Ledger Live.
2. Connect and unlock your Ledger Device.
3. If asked, follow the onscreen instructions and Allow Ledger Manager.
4. Find Conflux in the app catalog.
![](./imgs/ledger-live.jpg)
5. Click the Install button.
1. An installation window will appear.
2. Your device will display Processing…
3. The app installation is confirmed.
4. ![](./imgs/ledger-conflux-installed.jpg)
6. Close Ledger Live.

## Connecting to the Conflux Fluent Wallet

1. First, connect and unlock your Ledger Device.
2. Open the Conflux App on your Ledger Device
![](./imgs/ledger-conflux-ready.jpg)
3. Open the Conflux Fluent Wallet Application.
4. Open settings(top right) and choose the "Account Management" option.
![](./imgs/account-management.jpg)
5. Click the "Add Account" button.
![](./imgs/account-add.jpg)
6. Choose hardware wallet and make your hardware wallet ready.
![](./imgs/account-add-choose-hardware.jpg)
![](./imgs/account-add-ledger-guide.jpg)
7. Choose address and Click Import button
![](./imgs/fluent-import-choose-address.jpg)
8. Success
![](./imgs/account-add-success.jpg)

## View Account Balance

Your account balance is shown on the asset list of the Fluent Wallet, including CFX and tokens issued on the Conflux network.

![](./imgs/ledger-account-with-balance.jpg)

## Receiving CFX in the Conflux Fluent Wallet

You can get your Receive address by simply `copying the address to the clipboard` or by `scanning the QR Code`.

The copy icon and QR code icon are located on the right side of the address.

## Sending CFX in the Conflux Fluent Wallet

1. Click the `Send` button on the Fluent Wallet.
2. Fill in the recipient address, choose token to send and fill in amount to send.
![](./imgs/fluent-send-tx.jpg)
3. Click the `Next` button. And confirm the transaction on your Ledger Device.
![](./imgs/ledger-review-tx1.jpg)
![](./imgs/ledger-review-tx-amount.jpg)
![](./imgs/ledger-review-tx-gas-fee.jpg)
![](./imgs/ledger-review-tx-to.jpg)
![](./imgs/ledger-review-tx-data.jpg)
![](./imgs/ledger-review-tx-approve.jpg)
![](./imgs/ledger-review-tx-reject.jpg)
4. If everything is correct, in the `Approve` page, click both left and right buttons on your Ledger Device to confirm the transaction.
5. The transaction is now sent and you can view it in the transaction history.
![](./imgs/tx-history-entry.jpg)
![](./imgs/tx-history.jpg)
6. If you are sending tokens, you need to enable the "Blind Signing" in the Ledger Device.
![](./imgs/ledger-setting-2.jpg)
Click both left and right buttons on your Ledger Device to enable the "Blind Signing".
![](./imgs/ledger-setting-1.jpg)
7. A blind signing warning will appear when you send tokens.
![](./imgs/ledger-review-tx-blind-sign.jpg)

## FAQs

1. Which Ledger Devices are supported?
- Ledger Nano S Plux
- Ledger Nano X
- Ledger Flex
- Ledger Stax
2. Which version of the Fluent Wallet is supported?
- Fluent Wallet version 2.8.0 and above.

## Support

Emial: build@confluxnetwork.org

Github Issue: https://github.com/Conflux-Chain/app-conflux/issues
91 changes: 72 additions & 19 deletions src/app_ui/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,44 @@
* limitations under the License.
*****************************************************************************/
use crate::cfx_addr::{cfx_addr_encode, Network};
use crate::types::Transaction;
use crate::settings::Settings;
use crate::types::{Transaction, U256};
use crate::AppSW;

#[cfg(not(any(target_os = "stax", target_os = "flex")))]
use ledger_device_sdk::ui::{
bitmaps::{CROSSMARK, EYE, VALIDATE_14},
gadgets::{Field, MultiFieldReview},
bitmaps::{CROSSMARK, EYE, VALIDATE_14, WARNING},
gadgets::{clear_screen, Field, MultiFieldReview, Page},
};

#[cfg(any(target_os = "stax", target_os = "flex"))]
use crate::settings::Settings;
#[cfg(any(target_os = "stax", target_os = "flex"))]
use include_gif::include_gif;
#[cfg(any(target_os = "stax", target_os = "flex"))]
use ledger_device_sdk::nbgl::{Field, NbglGlyph, NbglReview};
use ledger_device_sdk::nbgl::{Field, NbglChoice, NbglGlyph, NbglReview};

use alloc::format;
use alloc::{format, vec};

/// Displays a transaction and returns true if user approved it.
///
/// This method can return [`AppSW::TxDisplayFail`] error if the coin name length is too long.
/// This method can return [`AppSW::TxDisplayFail`] error
///
/// # Arguments
///
/// * `tx` - Transaction to be displayed for validation
pub fn ui_display_tx(tx: &Transaction) -> Result<bool, AppSW> {
let fully_decoded = tx.fully_decoded();

let value_str = tx.value.cfx_str().ok_or(AppSW::TxDisplayFail)?;
let value_with_unit = format!("CFX {}", value_str);
let value_with_unit = format!("{} CFX", value_str);

let network = Network::from_network_id(tx.chain_id);
let to_str = cfx_addr_encode(&*tx.to, network).map_err(|_e| AppSW::AddrDisplayFail)?;
let data_str = format!("0x{}", hex::encode(tx.data.clone()).to_uppercase());

let fee_str = tx.max_gas_fee().cfx_str().ok_or(AppSW::TxDisplayFail)?;
let fee_with_unit = format!("{} CFX", fee_str);

// Define transaction review fields
let my_fields = [
let mut my_fields = vec![
Field {
name: "Amount",
value: value_with_unit.as_str(),
Expand All @@ -58,14 +62,51 @@ pub fn ui_display_tx(tx: &Transaction) -> Result<bool, AppSW> {
value: to_str.as_str(),
},
Field {
name: "Data",
value: data_str.as_str(),
name: "Max Gas Fees",
value: fee_with_unit.as_str(),
},
];

// If max storage fee is not zero, add it to the review fields
let storage_fee_str = tx.max_storage_fee().cfx_str().ok_or(AppSW::TxDisplayFail)?;
let storage_fee_with_unit = format!("{} CFX", storage_fee_str);
if tx.max_storage_fee() > U256::zero() {
my_fields.push(Field {
name: "Max Storage Fees",
value: storage_fee_with_unit.as_str(),
});
}

// If data is not empty, add it to the review fields
let data_str = format!("0x{}", hex::encode(tx.data.clone()).to_uppercase());
if !tx.data.is_empty() {
my_fields.push(Field {
name: "Data",
value: data_str.as_str(),
});
}

let settings: Settings = Default::default();

// Create transaction review
#[cfg(not(any(target_os = "stax", target_os = "flex")))]
{
if !fully_decoded && settings.get_element(0)? == 0 {
// show warning and return
let warning =
Page::from((["Blind signing must", "be enabled in Settings"], &CROSSMARK));
clear_screen();
warning.place_and_wait();
return Ok(false);
}

if !fully_decoded {
// show warning
let warning = Page::from((["Blind", "Signing"], &WARNING));
clear_screen();
warning.place_and_wait();
}

let my_review = MultiFieldReview::new(
&my_fields,
&["Review ", "Transaction"],
Expand All @@ -75,28 +116,40 @@ pub fn ui_display_tx(tx: &Transaction) -> Result<bool, AppSW> {
"Reject",
Some(&CROSSMARK),
);

Ok(my_review.show())
}

#[cfg(any(target_os = "stax", target_os = "flex"))]
{
if !fully_decoded && settings.get_element(0)? == 0 {
let _confirmed = NbglChoice::new().show(
"This transaction cannot be clear-signed",
"Enable blind signing in the settings to sign this transaction.",
"Go to settings",
"Reject transaction",
);
return Ok(false);
}
// Load glyph from 64x64 4bpp gif file with include_gif macro. Creates an NBGL compatible glyph.
const CFX: NbglGlyph = NbglGlyph::from_include(include_gif!("icons/cfx_64.gif", NBGL));
// Create NBGL review. Maximum number of fields and string buffer length can be customised
// with constant generic parameters of NbglReview. Default values are 32 and 1024 respectively.
let review: NbglReview = NbglReview::new()
let mut review: NbglReview = NbglReview::new()
.titles(
"Review transaction\nto send CFX",
"",
"Sign transaction\nto send CFX",
)
.glyph(&CFX);

// If first setting switch is disabled do not display the transaction data
let settings: Settings = Default::default();
if settings.get_element(1)? == 0 {
Ok(review.show(&my_fields[0..2]))
if !fully_decoded {
review = review.blind();
}

// If second setting switch is disabled do not display the transaction data
if settings.get_element(1)? == 0 && !tx.data.is_empty() {
let field_len = my_fields.len() - 1;
Ok(review.show(&my_fields[0..field_len]))
} else {
Ok(review.show(&my_fields))
}
Expand Down
1 change: 1 addition & 0 deletions src/cfx_addr/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub fn convert_bits(
pad: bool,
) -> Result<Vec<u8>, &'static str> {
assert!(inbits <= 8 && outbits <= 8);
#[allow(clippy::manual_div_ceil)]
let num_bytes = (data.len() * inbits as usize + outbits as usize - 1) / outbits as usize;
let mut ret = Vec::with_capacity(num_bytes);
let mut acc: u16 = 0; // accumulator of bits
Expand Down
5 changes: 5 additions & 0 deletions src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,8 @@ pub const EXPONENT_SMALLEST_UNIT: usize = 18;
pub const APP_FLAG_BLIND_SIGNING_ENABLED: u8 = 0x01;

pub const APP_FLAG_DETAILED_DISPLAY_ENABLED: u8 = 0x02;

/**
* One CFX that can be paid for storage.
*/
pub const STORAGE_OF_ONE_CFX: u64 = 1024;
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#![no_std]
#![no_main]
#![allow(static_mut_refs)]
#![allow(unexpected_cfgs)]

mod utils;
mod app_ui {
Expand Down
4 changes: 2 additions & 2 deletions src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ impl Settings {
#[inline(never)]
#[allow(unused)]
pub fn get_mut(&mut self) -> &mut AtomicStorage<[u8; SETTINGS_SIZE]> {
return unsafe { DATA.get_mut() };
unsafe { DATA.get_mut() }
}

#[inline(never)]
#[allow(unused)]
pub fn get_ref(&mut self) -> &AtomicStorage<[u8; SETTINGS_SIZE]> {
return unsafe { DATA.get_ref() };
unsafe { DATA.get_ref() }
}

#[allow(unused)]
Expand Down
20 changes: 20 additions & 0 deletions src/types/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,26 @@ impl Decodable for H256 {
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Address(pub [u8; ADDRRESS_BYTES_LEN]);

impl Address {
pub fn address_type(&self) -> u8 {
self.0[0] & 0xf0
}

pub fn is_user_address(&self) -> bool {
self.address_type() == 0x10
}

#[allow(unused)]
pub fn is_contract_address(&self) -> bool {
self.address_type() == 0x80
}

#[allow(unused)]
pub fn is_builtin_address(&self) -> bool {
self.address_type() == 0x00
}
}

impl Decodable for Address {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
rlp.decoder()
Expand Down
Loading

0 comments on commit 2be8d52

Please sign in to comment.