Files
hash-wallet/cw_bitcoin/lib/hardware/litecoin_ledger_service.dart
Konstantin UllrichandGitHub 8b76391a2e LCW-1128-Add-support-for-Trezor (#2565)
* feat: add support for Trezor hardware wallet integration Restore Wallets

* feat: add Trezor hardware wallet support, implement RLP decoding utility, and update transaction signing logic

* feat: add bitcoin trezor signing

* chore: update Trezor Connect dependency to specific commit hash in pubspec_base.yaml

* feat: add trezor support for litecoin

* feat: add colorFilter for device manufacturer icons to align with theme styles

* refactor: optimize Trezor callback handling

* feat: add BitBox and Trezor support for Bitcoin and Litecoin, update transaction signing logic, and improve modularity in hardware wallet services

* refactor: simplify constructor assertions in `BaseBottomSheetWidget` and cleanup Trezor chainId handling logic

* feat: conditionally render device manufacturers based on platform and hide SeedSigner for now
2025-10-11 02:12:27 +03:00

89 lines
3.3 KiB
Dart

import 'dart:async';
import 'dart:typed_data';
import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:blockchain_utils/blockchain_utils.dart';
import 'package:cw_bitcoin/electrum_wallet.dart';
import 'package:cw_bitcoin/hardware/bitcoin_hardware_wallet_service.dart';
import 'package:cw_bitcoin/psbt/transaction_builder.dart';
import 'package:cw_bitcoin/utils.dart';
import 'package:cw_core/hardware/hardware_account_data.dart';
import 'package:cw_core/hardware/hardware_wallet_service.dart';
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
import 'package:ledger_litecoin/ledger_litecoin.dart';
class LitecoinLedgerService extends HardwareWalletService with BitcoinHardwareWalletService, LitecoinHardwareWalletService {
LitecoinLedgerService(this.ledgerConnection)
: litecoinLedgerApp = LitecoinLedgerApp(ledgerConnection);
final LedgerConnection ledgerConnection;
final LitecoinLedgerApp litecoinLedgerApp;
@override
Future<List<HardwareAccountData>> getAvailableAccounts({int index = 0, int limit = 5}) async {
await litecoinLedgerApp.getVersion();
final accounts = <HardwareAccountData>[];
final indexRange = List.generate(limit, (i) => i + index);
final xpubVersion = Bip44Conf.litecoinMainNet.altKeyNetVer;
for (final i in indexRange) {
final derivationPath = "m/84'/2'/$i'";
final xpub = await litecoinLedgerApp.getXPubKey(
accountsDerivationPath: derivationPath,
xPubVersion: int.parse(hex.encode(xpubVersion.public), radix: 16));
final hd = Bip32Slip10Secp256k1.fromExtendedKey(xpub, xpubVersion).childKey(Bip32KeyIndex(0));
final address = generateP2WPKHAddress(hd: hd, index: 0, network: LitecoinNetwork.mainnet);
accounts.add(HardwareAccountData(
address: address,
accountIndex: i,
derivationPath: derivationPath,
xpub: xpub,
));
}
return accounts;
}
@override
Future<String> signLitecoinTransaction({
required List<BitcoinBaseOutput> outputs,
required List<PSBTReadyUtxoWithAddress> inputs,
required Map<String, PublicKeyWithDerivationPath> publicKeys,
}) {
final readyInputs = <LedgerTransaction>[];
for (final utxo in inputs) {
final publicKeyAndDerivationPath = publicKeys[utxo.ownerDetails.address.pubKeyHash()]!;
readyInputs.add(LedgerTransaction(
rawTx: utxo.rawTx,
outputIndex: utxo.utxo.vout,
ownerPublicKey: Uint8List.fromList(hex.decode(publicKeyAndDerivationPath.publicKey)),
ownerDerivationPath: publicKeyAndDerivationPath.derivationPath,
));
}
// Check if we have the key to one of the output addresses to hide change on the device
String? changePath;
for (final output in outputs) {
final maybeChangePath = publicKeys[(output as BitcoinOutput).address.pubKeyHash()];
if (maybeChangePath != null) changePath ??= maybeChangePath.derivationPath;
}
return litecoinLedgerApp.createTransaction(
inputs: readyInputs,
outputs: outputs
.map((e) => TransactionOutput.fromBigInt((e as BitcoinOutput).value,
Uint8List.fromList(e.address.toScriptPubKey().toBytes())))
.toList(),
changePath: changePath,
sigHashType: 0x01,
additionals: ["bech32"],
isSegWit: true,
useTrustedInputForSegwit: true);
}
}