Skip to content

Commit

Permalink
chore: update near-ledger to 0.5.0 (#309)
Browse files Browse the repository at this point in the history
- [x] check out and build old version of near-cli-rs
([revision](https://github.com/near/near-cli-rs/tree/0f484b5053f12f3baba66cda5a82252bee916913)
before [blind signature
pull](#259) )
  - [x] near 0.7.2
- [x] test a normal tx on `app-near`: ok
https://explorer.near.org/transactions/HSE5jFuKvrDYeaxEqd445PwVsahcYgXV6kZQQY5uDsj2
    - [x] test a long tx  on `app-near`: error 
        ```bash
        `near` CLI has a new update available 0.7.2 →  0.8.1
        To update `near` CLI use: near extensions self-update
        Error:
0: Error occurred while signing the transaction:
APDUExchangeError("Unknown Ledger APDU retcode: 27024")

        ❯ pcalc 27024
27024 0x6990 0y110100110010000

        ❯ rg 0x6990
        workdir/app-near/src/constants.h
        37:#define SW_BUFFER_OVERFLOW 0x6990
        ```
- [x] test a long tx on `app-near-rs`: ok
https://nearblocks.io/txns/5yzwbUckGSWMyYj8hbG3jJjHWLef5atkzc2fiVrf8Loy
- [x] current pr near 0.8.1
- [x] test a normal tx on `app-near`: ok
https://nearblocks.io/txns/5Ptbx3iGykXKQpxYBhR9YUa5BCmS6jGjyLiE7oGYGXKN
  - [x] test a long tx on `app-near` : error
      ```bash
      Error:
0: Error occurred while signing the transaction:
APDUExchangeError("Ledger APDU retcode: 0x6990")
      ```
- [x] test a long tx on `app-near-rs`: ok
https://nearblocks.io/txns/2duat1ripdAxtHJjuNyNT7ZNd6adADs8LGMZ6VsV9FDm
  - [x] test a deploy contract tx 
- [x] on `app-near-rs`: ok
https://nearblocks.io/txns/GV6Y9TcTMhqBUoYL6M6BxkeCXXkEe8TfmLJCVx64U7ME#
      ```bash
      Unsigned transaction:
signer_id:
1b11b3b31673033936ad07bddc01f9da27d974811e480fb197c799e23480a489
receiver_id:
1b11b3b31673033936ad07bddc01f9da27d974811e480fb197c799e23480a489
      actions:
         -- deploy contract DC1KnvBEyPhBzBxCBarMgY9ZN68krg449Dk8AxARU2QN
      ...
      ```
- [x]
https://nearblocks.io/address/1b11b3b31673033936ad07bddc01f9da27d974811e480fb197c799e23480a489#contract
    - [x] on `app-near`: error, same behaviour as long tx  (12288 bytes)
      ```bytes
      12288   ./examples/adder/res/adder.wasm
      ```
  • Loading branch information
dj8yfo authored Mar 14, 2024
1 parent ffdfb1f commit 62d6f3a
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 82 deletions.
5 changes: 3 additions & 2 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 @@ -66,7 +66,7 @@ bytesize = "1.1.0"
prettytable = "0.10.0"
textwrap = "0.16.1"

near-ledger = { version = "0.4.0", optional = true }
near-ledger = { version = "0.5.0", optional = true }

near-crypto = "0.20.1"
near-primitives = "0.20.1"
Expand Down
9 changes: 7 additions & 2 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,8 +563,13 @@ pub fn print_unsigned_transaction(transaction: &crate::commands::PrepopulatedTra
"--", "create account:", &transaction.receiver_id
)
}
near_primitives::transaction::Action::DeployContract(_) => {
eprintln!("{:>5} {:<20}", "--", "deploy contract")
near_primitives::transaction::Action::DeployContract(code) => {
let code_hash = CryptoHash::hash_bytes(&code.code);
eprintln!(
"{:>5} {:<70}",
"--",
format!("deploy contract {:?}", code_hash)
)
}
near_primitives::transaction::Action::FunctionCall(function_call_action) => {
eprintln!("{:>5} {:<20}", "--", "function call:");
Expand Down
87 changes: 10 additions & 77 deletions src/transaction_signature_options/sign_with_ledger/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
use color_eyre::eyre::{ContextCompat, WrapErr};
use inquire::{CustomType, Select};
use inquire::CustomType;
use near_ledger::NEARLedgerError;
use near_primitives::borsh;
use slip10::BIP32Path;

use crate::common::JsonRpcClientExt;
use crate::common::RpcQueryResponseExt;

const SW_BUFFER_OVERFLOW: &str = "0x6990";
const ERR_OVERFLOW_MEMO: &str = "Buffer overflow on Ledger device occured. \
Transaction is too large for signature. \
This is resolved in https://github.com/dj8yfo/app-near-rs . \
The status is tracked in `About` section.";

#[derive(Debug, Clone, interactive_clap::InteractiveClap)]
#[interactive_clap(input_context = crate::commands::TransactionContext)]
#[interactive_clap(output_context = SignLedgerContext)]
Expand Down Expand Up @@ -37,77 +43,8 @@ pub struct SignLedgerContext {
on_after_sending_transaction_callback:
crate::transaction_signature_options::OnAfterSendingTransactionCallback,
}
const BLIND_SIGN_MEMO: &str = "Blind signature means that transaction is prepared by CLI, but cannot be reviewed on the Ledger device. \
In order to be absolutely sure that the transaction you are signing is not forged, take the constructed transaction, \
verify its content using NEAR CLI on another host or use any other tool capable of displaying unsigned NEAR transactions, \
and confirm that the SHA256 hash matches the one displayed above and another identical one, that will be displayed on your Ledger device after confirming the prompt. \
Following helper command on NEAR CLI can be used:";

impl SignLedgerContext {
fn input_blind_agree() -> color_eyre::eyre::Result<bool> {
let options: Vec<&str> = vec!["Yes", "No"];

Ok(
Select::new("Do you agree to continue with blind signature? ", options)
.prompt()
.map(|selected| selected == "Yes")?,
)
}

fn blind_sign_subflow(
hash: near_primitives::hash::CryptoHash,
hd_path: BIP32Path,
unsigned_transaction: near_primitives::transaction::Transaction,
) -> color_eyre::eyre::Result<near_crypto::Signature> {
eprintln!("\n\nBuffer overflow on Ledger device occured. Transaction is too large for normal signature.");
eprintln!("\nThe following is Base58-encoded SHA-256 hash of unsigned transaction:");
eprintln!("{}", hash);

eprintln!(
"\nUnsigned transaction (serialized as base64):\n{}\n",
crate::types::transaction::TransactionAsBase64::from(unsigned_transaction)
);
eprintln!("{}", BLIND_SIGN_MEMO);
eprintln!(
"$ {} transaction print-transaction unsigned\n\n",
crate::common::get_near_exec_path()
);

eprintln!("Make sure to enable blind sign in NEAR app's settings on Ledger device\n");
let agree = Self::input_blind_agree()?;
if agree {
eprintln!(
"Confirm transaction blind signing on your Ledger device (HD Path: {})",
hd_path,
);
let result = near_ledger::blind_sign_transaction(hash, hd_path);
let signature = result.map_err(|err| {
match err {
near_ledger::NEARLedgerError::BlindSignatureDisabled => {
color_eyre::Report::msg("Blind signature is disabled in NEAR app's settings on Ledger device".to_string())
},
near_ledger::NEARLedgerError::BlindSignatureNotSupported => {
color_eyre::Report::msg("Blind signature is not supported by the version of NEAR app installed on Ledger device. \
Version of the app with the feature available is tracked in https://github.com/LedgerHQ/app-near/pull/32".to_string())
},
err => {
color_eyre::Report::msg(format!(
"Error occurred while signing the transaction: {:?}",
err
))
}
}
})?;
let signature =
near_crypto::Signature::from_parts(near_crypto::KeyType::ED25519, &signature)
.wrap_err("Signature is not expected to fail on deserialization")?;

Ok(signature)
} else {
Err(color_eyre::Report::msg("signing with ledger aborted"))
}
}

pub fn from_previous_context(
previous_context: crate::commands::TransactionContext,
scope: &<SignLedger as interactive_clap::ToInteractiveClapContextScope>::InteractiveClapContextScope,
Expand Down Expand Up @@ -170,12 +107,8 @@ impl SignLedgerContext {
near_crypto::Signature::from_parts(near_crypto::KeyType::ED25519, &signature)
.wrap_err("Signature is not expected to fail on deserialization")?
}
Err(near_ledger::NEARLedgerError::BufferOverflow { transaction_hash }) => {
Self::blind_sign_subflow(
transaction_hash,
seed_phrase_hd_path,
unsigned_transaction.clone(),
)?
Err(NEARLedgerError::APDUExchangeError(msg)) if msg.contains(SW_BUFFER_OVERFLOW) => {
return Err(color_eyre::Report::msg(ERR_OVERFLOW_MEMO));
}
Err(near_ledger_error) => {
return Err(color_eyre::Report::msg(format!(
Expand Down

0 comments on commit 62d6f3a

Please sign in to comment.