LedgerHQ / app-stellar

Stellar app for Ledger Nano S
Apache License 2.0
15 stars 23 forks source link

Cannot sign InvokeHostFunction operations with Ledger Nano S #82

Closed sieg-i closed 4 months ago

sieg-i commented 7 months ago

Hello,

has anybody successfully created a smart contract using Ledger Nano S for signing the transaction object? I'm trying to create the contract from a dapp and when calling Ledger SDK's str.signTransaction to sign the transaction then instead of being asked to approve it on the ledger app I receive the error "Ledger device: UNKNOWN_ERROR (0xb005)".

A standard payment operation can be signed on the Ledger app successfully though, also signing the very same transaction with other wallets like Freighter or Albedo works fine as well. So maybe it's a limitation of the stellar ledger app or the ledger SDK.

import Transport from "@ledgerhq/hw-transport-webusb";
import Str from "@ledgerhq/hw-app-str";
import {
  Account,
  Address,
  Asset,
  BASE_FEE,
  Networks,
  Operation,
  SorobanRpc,
  Transaction,
  TransactionBuilder,
  sign,
  xdr,
} from '@stellar/stellar-sdk';
import { Buffer } from 'buffer';

const sorobanRpc = new SorobanRpc.Server('https://soroban-testnet.stellar.org');    

// get the first ledger account for signing
const transport = await Transport.create();
const str = new Str(transport);
const keyPath = "44'/148'/0'";
const key = await str.getPublicKey(keyPath);
const senderAddress = key.publicKey;
const account = await sorobanRpc.getAccount(senderAddress);

// helper for creating wasm hash
function hexToRawBytes(hexString: string): ArrayBuffer {
  const byteArray = new Uint8Array(hexString.length / 2);
  for (let i = 0; i < hexString.length; i += 2) {
    byteArray[i / 2] = parseInt(hexString.substr(i, 2), 16);
  }
  return byteArray.buffer;
}

// hash of the already installed WASM code on TESTNET
const wasmHashHex = "7f7c3e89d2380f6e8e43eb418657436c491581cf2acbaa9ae4853a21c26bf859";
const wasmHash = hexToRawBytes(wasmHashHex);

// signing of this InvokeHostFunction operation fails later on the Ledger Nano app
const createCustomContractOp = Operation.createCustomContract({
  wasmHash: Buffer.from(wasmHash),
  address: Address.fromString(senderAddress),
  salt: crypto.getRandomValues(Buffer.alloc(32)),
});

// transaction object for it
const createContractTrx: Transaction = new TransactionBuilder(account, {
      fee: BASE_FEE,
      networkPassphrase: Networks.TESTNET
    })
      .addOperation(createCustomContractOp)
      .setTimeout(30)
      .build();

// signing of this payment operation works on the Ledger Nano app
const paymentTrx = new TransactionBuilder(account, { fee: BASE_FEE, networkPassphrase: Networks.TESTNET })
  .addOperation(Operation.payment({
      source: account.accountId(),
      destination: 'GC47QO37WB42X3L4KCRWUBFAIEK35JB5RE6KZABDROVV7UF6C2MN75XL',
      amount: '1',
      asset: Asset.native()
  }))
  .setTimeout(30)
  .build();

let works = await str.signTransaction(keyPath, paymentTrx.signatureBase());  // signing of payment transaction works
console.log(works);

let fails = await str.signTransaction(keyPath, createContractTrx.signatureBase());  // this fails with error "Ledger device: UNKNOWN_ERROR (0xb005)"
overcat commented 7 months ago

Hi @sieg-i, I will be releasing a preview version in the community soon.

sieg-i commented 7 months ago

Just noticed in #81 that there seems to be missing support for Soroban transactions atm, unfortunately.

overcat commented 7 months ago

Hi @sieg-i, fyi https://github.com/lightsail-network/app-stellar/blob/develop/sideloading.md