Skip to content

Commit

Permalink
update icons
Browse files Browse the repository at this point in the history
  • Loading branch information
Pana committed Nov 6, 2024
1 parent e828ae5 commit 8e4bfac
Show file tree
Hide file tree
Showing 25 changed files with 297 additions and 9 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ ledger/
# Build directory
build/
.vscode
compile.sh
compile.sh
.DS_Store
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ path = ["44'/503'"]
name = "Conflux"

[package.metadata.ledger.nanox]
icon = "crab_14x14.gif"
icon = "icons/cfx_14.gif"

[package.metadata.ledger.nanosplus]
icon = "crab_14x14.gif"
icon = "icons/cfx_14.gif"

[package.metadata.ledger.stax]
icon = "crab_32x32.gif"
icon = "icons/cfx_32.gif"

[package.metadata.ledger.flex]
icon = "crab_40x40.gif"
icon = "icons/cfx_40.gif"
Binary file removed crab.gif
Binary file not shown.
Binary file removed crab_14x14.gif
Binary file not shown.
28 changes: 28 additions & 0 deletions docs/APDU.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Application Protocol Data Unit (APDU)

The communication protocol used by [BOLOS](https://ledger.readthedocs.io/en/latest/bolos/overview.html) to exchange [APDU](https://en.wikipedia.org/wiki/Smart_card_application_protocol_data_unit) is very close to [ISO 7816-4](https://www.iso.org/standard/77180.html) with a few differences:

- `Lc` length is always exactly 1 byte
- No `Le` field in APDU command
- Maximum size of APDU command is 260 bytes: 5 bytes of header + 255 bytes of data
- Maximum size of APDU response is 260 bytes: 258 bytes of response data + 2 bytes of status word

Status words tend to be similar to common [APDU responses](https://www.eftlab.com/knowledge-base/complete-list-of-apdu-responses/) in the industry.

## Command APDU

| Field name | Length (bytes) | Description |
| --- | --- | --- |
| CLA | 1 | Instruction class - indicates the type of command |
| INS | 1 | Instruction code - indicates the specific command |
| P1 | 1 | Instruction parameter 1 for the command |
| P2 | 1 | Instruction parameter 2 for the command |
| Lc | 1 | The number of bytes of command data to follow (a value from 0 to 255) |
| CData | var | Command data with `Lc` bytes |

## Response APDU

| Field name | Length (bytes) | Description |
| --- | --- | --- |
| RData | var | Reponse data (can be empty) |

Check failure on line 27 in docs/APDU.md

View workflow job for this annotation

GitHub Actions / Check misspellings

Reponse ==> Response
| SW | 2 | Status word containing command processing status (e.g. `0x9000` for success) |
245 changes: 245 additions & 0 deletions docs/COMMANDS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
## GET_APP_INFO

#### Request format

| CLA | INS | P1 | P2 | Lc |
| ------ | ------ | ------ | ------ | ------ |
| `0xe0` | `0x01` | `0x00` | `0x00` | `0x00` |

##### Request payload

None.

#### Response format

| Description | Length |
| ------------- | ------ |
| Flags | 1 |
| Major version | 1 |
| Minor version | 1 |
| Patch version | 1 |

Flags: `b000000YX`

- `X`: blind signing enabled
- `Y`: detailed display enabled

#### Examples

**Command**: `e001000000`

| CLA | INS | P1 | P2 | Lc |
| ------ | ------ | ------ | ------ | ------ |
| `0xe0` | `0x01` | `0x00` | `0x00` | `0x00` |

**Response**: `03000002 9000`, blind signing enabled, detailed display enabled, application version: `0.0.2`.

## GET_PUBLIC_KEY

#### Request format

| CLA | INS | P1 | P2 | Lc | Le |
| ---- | ---- | --------------------- | ----------------------- | -------- | -------- |
| `E0` | `02` | `00`: no display | `00`: no chain code | variable | variable |
| | | `01`: display address | `01`: return chain code | | |

##### Request payload

| Description | Length |
| ------------------------------------------------ | ------ |
| Number of BIP 32 derivations to perform (max 10) | 1 |
| First derivation index (big endian) | 4 |
| ... | 4 |
| Last derivation index (big endian) | 4 |
| Chain ID (required when `P1 == 01`) | 4 |

#### Response format

| Description | Length |
| ----------------------- | ------ |
| Public key length | 1 |
| Uncompressed public key | var |
| Chain code length | 1 |
| Chain code | var |

#### Examples

**Command**: `e002000015058000002c800001f7800000000000000000000000`

| CLA | INS | P1 | P2 | Lc | Le |
| ------ | ------ | ------ | ------ | ------ | ------------------------------------------------------------- |
| `0xe0` | `0x02` | `0x00` | `0x00` | `0x15` | `0x05 0x8000002c 0x800001f7 0x80000000 0x00000000 0x00000000` |

`44'/503'/0'/0/0` is encoded as `0x05 0x8000002c 0x800001f7 0x80000000 0x00000000 0x00000000`.

**Response**: `41 047b88d05ba40b8e6ed961b526ab68c7051d2a8602862c788f84416cc37e9c0a5c4213b20660a6591cd53ad81d5b68499acb835ac7a08c88e18bf8f4998061eb4a 9000`

---

**Command**: `e002000115058000002c800001f7800000000000000000000000`

| CLA | INS | P1 | P2 | Lc | Le |
| ------ | ------ | ------ | ------ | ------ | ------------------------------------------------------------- |
| `0xe0` | `0x02` | `0x00` | `0x01` | `0x15` | `0x05 0x8000002c 0x800001f7 0x80000000 0x00000000 0x00000000` |

**Response**: `41 047b88d05ba40b8e6ed961b526ab68c7051d2a8602862c788f84416cc37e9c0a5c4213b20660a6591cd53ad81d5b68499acb835ac7a08c88e18bf8f4998061eb4a 20 20b19d018f0bf5264aa6a0953a22d2cc432205fc022adfeb0160b1cad0b4ab8b 9000`

---

**Command**: `e002010019058000002c800001f780000000000000000000000000000405`

| CLA | INS | P1 | P2 | Lc | Le |
| ------ | ------ | ------ | ------ | ------ | ------------------------------------------------------------------------ |
| `0xe0` | `0x02` | `0x01` | `0x00` | `0x19` | `0x05 0x8000002c 0x800001f7 0x80000000 0x00000000 0x00000000 0x00000405` |

Notice the chain ID (`0x00000405 ~ 1029`, aka mainnet) at the end.

**Response**: `41 047b88d05ba40b8e6ed961b526ab68c7051d2a8602862c788f84416cc37e9c0a5c4213b20660a6591cd53ad81d5b68499acb835ac7a08c88e18bf8f4998061eb4a 9000`

---

**Command**: `e002010119058000002c800001f780000000000000000000000000000405`

| CLA | INS | P1 | P2 | Lc | Le |
| ------ | ------ | ------ | ------ | ------ | ------------------------------------------------------------------------ |
| `0xe0` | `0x02` | `0x01` | `0x01` | `0x19` | `0x05 0x8000002c 0x800001f7 0x80000000 0x00000000 0x00000000 0x00000405` |

**Response**: `41 047b88d05ba40b8e6ed961b526ab68c7051d2a8602862c788f84416cc37e9c0a5c4213b20660a6591cd53ad81d5b68499acb835ac7a08c88e18bf8f4998061eb4a 20 20b19d018f0bf5264aa6a0953a22d2cc432205fc022adfeb0160b1cad0b4ab8b 9000`

## SIGN_TX

#### Request format

| CLA | INS | P1 | P2 | Lc | Le |
| ---- | ---- | --------------------------------------- | ---- | -------- | -------- |
| `e0` | `03` | `00`: first transaction data block | `00` | variable | variable |
| | | `80`: subsequent transaction data block | | | |

##### Request payload

First data block:

| Description | Length |
| ------------------------------------------------ | ------ |
| Number of BIP 32 derivations to perform (max 10) | 1 |
| First derivation index (big endian) | 4 |
| ... | 4 |
| Last derivation index (big endian) | 4 |
| RLP data chunk | var |

Subsequent data blocks:

| Description | Length |
| -------------- | ------ |
| RLP data chunk | var |

#### **Response** format

| Description | Length |
| ----------- | ------ |
| v | 1 |
| r | 32 |
| s | 32 |

#### Examples

**Command**: `e003000041058000002c800001f7800000000000000000000000eb1284561f61b9831e84809410109fc8df283027b6285cc889f5aa624eac1f55843b9aca0081800182040580`

| CLA | INS | P1 | P2 | Lc | Le |
| ------ | ------ | ------ | ------ | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `0xe0` | `0x03` | `0x00` | `0x00` | `0x41` | `0x05 0x8000002c 0x800001f7 0x80000000 0x00000000 0x00000000 0xeb1284561f61b9831e84809410109fc8df283027b6285cc889f5aa624eac1f55843b9aca0081800182040580` |

`44'/503'/0'/0/0` is encoded as `0x05 0x8000002c 0x800001f7 0x80000000 0x00000000 0x00000000`.

`0xeb1284561f61b9831e84809410109fc8df283027b6285cc889f5aa624eac1f55843b9aca0081800182040580` is the RLP encoded list `["0x12", "0x561f61b9", "0x1e8480", "0x10109fC8DF283027b6285cc889F5aA624EaC1F55", "0x3b9aca00", "0x80", "0x1", "0x405", "0x"]` which represents the following transaction:

```js
{
nonce: 18,
gasPrice: 1444897209,
gasLimit: 2000000,
to: '0x10109fC8DF283027b6285cc889F5aA624EaC1F55',
value: 1000000000,
storageLimit: 128,
epochHeight: 1,
chainId: 1029,
data: '0x
}
```
**Response**: `00 f9071161c2dbc19dabf54d14d42944cecacf61943a9898f4f64c8aa6d23a58b6 64ea364f092d23d7a94388f2f43cf54a86fe644d221e822210fde413d406ebb6 9000`
---
The same transaction sent in two chunks:
**Command**: `e00300002b058000002c800001f7800000000000000000000000eb1284561f61b9831e84809410109fc8df283027b628`
| CLA | INS | P1 | P2 | Lc | Le |
| ------ | ------ | ------ | ------ | ------ | ------------------------------------------------------------------------------------------------------------ |
| `0xe0` | `0x03` | `0x00` | `0x00` | `0x2b` | `0x05 0x8000002c 0x800001f7 0x80000000 0x00000000 0x00000000 0xeb1284561f61b9831e84809410109fc8df283027b628` |
**Response**: `9000`
**Command**: `e0038000165cc889f5aa624eac1f55843b9aca0081800182040580`
| CLA | INS | P1 | P2 | Lc | Le |
| ------ | ------ | ------ | ------ | ------ | ------------------------------------------------ |
| `0xe0` | `0x03` | `0x80` | `0x00` | `0x16` | `0x5cc889f5aa624eac1f55843b9aca0081800182040580` |
**Response**: `00 f9071161c2dbc19dabf54d14d42944cecacf61943a9898f4f64c8aa6d23a58b6 64ea364f092d23d7a94388f2f43cf54a86fe644d221e822210fde413d406ebb6 9000`
## SIGN_PERSONAL
#### Request format
| CLA | INS | P1 | P2 | Lc | Le |
| ---- | ---- | --------------------------- | ---- | -------- | -------- |
| `e0` | `04` | `00`: first data block | `00` | variable | variable |
| | | `80`: subsequent data block | | | |
##### Request payload
First data block:
| Description | Length |
| ------------------------------------------------ | ------ |
| Number of BIP 32 derivations to perform (max 10) | 1 |
| First derivation index (big endian) | 4 |
| ... | 4 |
| Last derivation index (big endian) | 4 |
| Chain ID | 4 |
| Message length | 4 |
| Message chunk | var |
Subsequent data blocks:
| Description | Length |
| ------------- | ------ |
| Message chunk | var |
#### **Response** format
| Description | Length |
| ----------- | ------ |
| v | 1 |
| r | 32 |
| s | 32 |
#### Examples
**Command**: `e00400002a058000002c800001f7800000000000000000000000000004050000000d48656c6c6f2c20776f726c6421`
| CLA | INS | P1 | P2 | Lc | Le |
| ------ | ------ | ------ | ------ | ------ | ---------------------------------------------------------------------------------------------------------------- |
| `0xe0` | `0x04` | `0x00` | `0x00` | `0x2a` | `0x05 0x8000002c 0x800001f7 0x80000000 0x00000000 0x00000000 0x00000405 0x0000000d 0x48656c6c6f2c20776f726c6421` |
`44'/503'/0'/0/0` is encoded as `0x05 0x8000002c 0x800001f7 0x80000000 0x00000000 0x00000000`.
`0x00000405` stands for chain ID 1029 (Conflux mainnet).
`0x0000000d` is the length of the subsequent message (13 bytes).
`0x48656c6c6f2c20776f726c6421` is the message `"Hello, world!"` hex-encoded.
**Response**: `00 07954c638fc7de7cdc26c69633ad0202f8a20842b49508baa3e63166961b517a 70b2e651babb1566ae53f8c1ff40c8b5426366e0d5d2de2b0fae9ed2209de53e 9000`
Binary file added icons/cfx_14.gif
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 icons/cfx_16.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Binary file added icons/cfx_32_1.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Binary file added icons/cfx_40_1.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Binary file added icons/cfx_64_1.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/app_ui/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub fn ui_display_pk(addr: &[u8]) -> Result<bool, AppSW> {
#[cfg(any(target_os = "stax", target_os = "flex"))]
{
// Load glyph from 64x64 4bpp gif file with include_gif macro. Creates an NBGL compatible glyph.
const FERRIS: NbglGlyph = NbglGlyph::from_include(include_gif!("crab_64x64.gif", NBGL));
const FERRIS: NbglGlyph = NbglGlyph::from_include(include_gif!("icons/cfx_64.gif", NBGL));
// Display the address confirmation screen.
Ok(NbglAddressReview::new()
.glyph(&FERRIS)
Expand Down
4 changes: 2 additions & 2 deletions src/app_ui/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ fn ui_about_menu(comm: &mut Comm) -> Event<Instruction> {

#[cfg(not(any(target_os = "stax", target_os = "flex")))]
pub fn ui_menu_main(comm: &mut Comm) -> Event<Instruction> {
const APP_ICON: Glyph = Glyph::from_include(include_gif!("crab.gif"));
const APP_ICON: Glyph = Glyph::from_include(include_gif!("icons/cfx_16.gif"));
let pages = [
// The from trait allows to create different styles of pages
// without having to use the new() function.
Expand All @@ -75,7 +75,7 @@ pub fn ui_menu_main(comm: &mut Comm) -> Event<Instruction> {
#[cfg(any(target_os = "stax", target_os = "flex"))]
pub fn ui_menu_main(_: &mut Comm) -> NbglHomeAndSettings {
// Load glyph from 64x64 4bpp gif file with include_gif macro. Creates an NBGL compatible glyph.
const FERRIS: NbglGlyph = NbglGlyph::from_include(include_gif!("crab_64x64.gif", NBGL));
const FERRIS: NbglGlyph = NbglGlyph::from_include(include_gif!("icons/cfx_64.gif", NBGL));

let settings_strings = [["Display Memo", "Allow display of transaction data."]];
let mut settings: Settings = Default::default();
Expand Down
2 changes: 1 addition & 1 deletion src/app_ui/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pub fn ui_display_tx(tx: &Transaction) -> Result<bool, AppSW> {
#[cfg(any(target_os = "stax", target_os = "flex"))]
{
// Load glyph from 64x64 4bpp gif file with include_gif macro. Creates an NBGL compatible glyph.
const FERRIS: NbglGlyph = NbglGlyph::from_include(include_gif!("crab_64x64.gif", NBGL));
const FERRIS: 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()
Expand Down
6 changes: 6 additions & 0 deletions src/handlers/personal_sign.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use crate::AppSW;

pub fn handler_personal_sign() -> Result<(), AppSW> {
// todo
Ok(())
}
8 changes: 8 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ mod handlers {
pub mod get_public_key;
pub mod get_version;
pub mod sign_tx;
pub mod personal_sign;
}
mod cfx_addr;
mod consts;
Expand All @@ -40,6 +41,7 @@ use handlers::{
get_public_key::handler_get_public_key,
get_version::handler_get_version,
sign_tx::{handler_sign_tx, TxContext},
personal_sign::handler_personal_sign,
};
use ledger_device_sdk::io::{ApduHeader, Comm, Reply, StatusWords};
#[cfg(feature = "pending_review_screen")]
Expand Down Expand Up @@ -98,6 +100,7 @@ pub enum Instruction {
GetAppName,
GetPubkey { display: bool },
SignTx { chunk: u8, more: bool },
PersonalSign { chunk: u8, more: bool },
}

impl TryFrom<ApduHeader> for Instruction {
Expand Down Expand Up @@ -128,6 +131,10 @@ impl TryFrom<ApduHeader> for Instruction {
more: value.p2 == P2_SIGN_TX_MORE,
})
}
(7, 0, 0) => Ok(Instruction::PersonalSign{
chunk: 0,
more: false,
}),
(3..=6, _, _) => Err(AppSW::WrongP1P2),
(_, _, _) => Err(AppSW::InsNotSupported),
}
Expand Down Expand Up @@ -214,5 +221,6 @@ fn handle_apdu(comm: &mut Comm, ins: &Instruction, ctx: &mut TxContext) -> Resul
Instruction::GetVersion => handler_get_version(comm),
Instruction::GetPubkey { display } => handler_get_public_key(comm, *display),
Instruction::SignTx { chunk, more } => handler_sign_tx(comm, *chunk, *more, ctx),
Instruction::PersonalSign {chunk: _, more: _} => handler_personal_sign(),
}
}
Binary file modified tests/snapshots/nanosp/test_app_mainmenu/00000.png
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 modified tests/snapshots/nanosp/test_sign_tx_long_tx/00005.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/snapshots/nanosp/test_sign_tx_refused/00007.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/snapshots/nanosp/test_sign_tx_short_tx/00005.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 8e4bfac

Please sign in to comment.