Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@ledgerhq/hw-app-btc

Package Overview
Dependencies
Maintainers
18
Versions
437
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ledgerhq/hw-app-btc - npm Package Compare versions

Comparing version 10.1.2-nightly.0 to 10.2.0-nightly.1

tests/newops/isPathNormal.test.ts

6

CHANGELOG.md
# @ledgerhq/hw-app-btc
## 10.2.0-nightly.1
### Minor Changes
- [#5675](https://github.com/LedgerHQ/ledger-live/pull/5675) [`5fdd5f0`](https://github.com/LedgerHQ/ledger-live/commit/5fdd5f0acab5f990d46ad20d245315f38be0f08a) Thanks [@chabroA](https://github.com/chabroA)! - make Qtum work with old and new nano app interfaces
## 10.1.2-nightly.0

@@ -4,0 +10,0 @@

62

lib-es/Btc.js

@@ -10,2 +10,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

};
import semver from "semver";
import BtcNew from "./BtcNew";

@@ -39,9 +40,14 @@ import BtcOld from "./BtcOld";

], scrambleKey);
// new APDU (nano app API) for bitcoin and old APDU for altcoin
if (currency === "bitcoin" || currency === "bitcoin_testnet") {
this._impl = new BtcNew(new AppClient(this._transport));
}
else {
this._impl = new BtcOld(this._transport);
}
this._impl = (() => {
switch (currency) {
case "bitcoin":
case "bitcoin_testnet":
case "qtum":
// new APDU (nano app API) for currencies using app-bitcoin-new implementation
return new BtcNew(new AppClient(this._transport));
default:
// old APDU (legacy API) for currencies using legacy bitcoin app implementation
return new BtcOld(this._transport);
}
})();
}

@@ -206,20 +212,26 @@ /**

return this._impl;
const appAndVersion = yield getAppAndVersion(this._transport);
let isBtcLegacy = true; // default for all altcoins
if (appAndVersion.name === "Bitcoin" || appAndVersion.name === "Bitcoin Test") {
const [major, minor] = appAndVersion.version.split(".");
// we use the legacy protocol for versions below 2.1.0 of the Bitcoin app.
isBtcLegacy = parseInt(major) <= 1 || (parseInt(major) == 2 && parseInt(minor) == 0);
}
else if (appAndVersion.name === "Bitcoin Legacy" ||
appAndVersion.name === "Bitcoin Test Legacy") {
// the "Bitcoin Legacy" and "Bitcoin Testnet Legacy" app use the legacy protocol, regardless of the version
isBtcLegacy = true;
}
else if (appAndVersion.name === "Exchange") {
// We can't query the version of the Bitcoin app if we're coming from Exchange;
// therefore, we use a workaround to distinguish legacy and new versions.
// This can be removed once Ledger Live enforces minimum bitcoin version >= 2.1.0.
isBtcLegacy = yield checkIsBtcLegacy(this._transport);
}
const { name, version } = yield getAppAndVersion(this._transport);
const isBtcLegacy = yield (() => __awaiter(this, void 0, void 0, function* () {
switch (name) {
case "Bitcoin":
case "Bitcoin Test": {
// we use the legacy protocol for versions below 2.1.0 of the Bitcoin app.
return semver.lt(version, "2.1.0");
}
case "Bitcoin Legacy":
case "Bitcoin Test Legacy":
// the "Bitcoin Legacy" and "Bitcoin Testnet Legacy" app use the legacy protocol, regardless of the version
return true;
case "Exchange":
// We can't query the version of the Bitcoin app if we're coming from Exchange;
// therefore, we use a workaround to distinguish legacy and new versions.
// This can be removed once Ledger Live enforces minimum bitcoin version >= 2.1.0.
return yield checkIsBtcLegacy(this._transport);
case "Qtum":
// we use the legacy protocol for versions below 3.0.0 of the Qtum app.
return semver.lt(version, "3.0.0");
default:
return true;
}
}))();
if (isBtcLegacy) {

@@ -226,0 +238,0 @@ this._impl = new BtcOld(this._transport);

@@ -133,2 +133,3 @@ import type { CreateTransactionArg } from "./createTransaction";

}
export declare function isPathNormal(path: string): boolean;
//# sourceMappingURL=BtcNew.d.ts.map

@@ -369,7 +369,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

Standard paths are (currently):
M/44'/(1|0)'/X'
M/49'/(1|0)'/X'
M/84'/(1|0)'/X'
M/86'/(1|0)'/X'
M/48'/(1|0)'/X'/Y'
M/44'/(1|0|88)'/X'
M/49'/(1|0|88)'/X'
M/84'/(1|0|88)'/X'
M/86'/(1|0|88)'/X'
M/48'/(1|0|88)'/X'/Y'
followed by "", "(0|1)", or "(0|1)/b", where a and b are

@@ -385,14 +385,34 @@ non-hardened. For example, the following paths are standard

M/86'/1'/99'/2 // Change path item must be 0 or 1
Useful resource on derivation paths: https://learnmeabitcoin.com/technical/derivation-paths
*/
function isPathNormal(path) {
//path is not deepest hardened node of a standard path or deeper, use BtcOld
const h = 0x80000000; //HARDENED from bip32
//path is not deepest hardened node of a standard path or deeper, use BtcOld
const H = 0x80000000; //HARDENED from bip32
const VALID_COIN_TYPES = [
0,
1,
88, // Qtum
];
const VALID_SINGLE_SIG_PURPOSES = [
44,
49,
84,
86, // BIP86 - https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki
];
const VALID_MULTISIG_PURPOSES = [
48, // BIP48 - https://github.com/bitcoin/bips/blob/master/bip-0048.mediawiki
];
const hard = (n) => n >= H;
const soft = (n) => n === undefined || n < H;
const change = (n) => n === undefined || n === 0 || n === 1;
const validCoinPathPartsSet = new Set(VALID_COIN_TYPES.map(t => t + H));
const validSingleSigPurposePathPartsSet = new Set(VALID_SINGLE_SIG_PURPOSES.map(t => t + H));
const validMultiSigPurposePathPartsSet = new Set(VALID_MULTISIG_PURPOSES.map(t => t + H));
export function isPathNormal(path) {
const pathElems = pathStringToArray(path);
const hard = (n) => n >= h;
const soft = (n) => n === undefined || n < h;
const change = (n) => n === undefined || n === 0 || n === 1;
// Single sig
if (pathElems.length >= 3 &&
pathElems.length <= 5 &&
[44 + h, 49 + h, 84 + h, 86 + h].some(v => v == pathElems[0]) &&
[0 + h, 1 + h].some(v => v == pathElems[1]) &&
validSingleSigPurposePathPartsSet.has(pathElems[0]) &&
validCoinPathPartsSet.has(pathElems[1]) &&
hard(pathElems[2]) &&

@@ -403,6 +423,7 @@ change(pathElems[3]) &&

}
// Multi sig
if (pathElems.length >= 4 &&
pathElems.length <= 6 &&
48 + h == pathElems[0] &&
[0 + h, 1 + h].some(v => v == pathElems[1]) &&
validMultiSigPurposePathPartsSet.has(pathElems[0]) &&
validCoinPathPartsSet.has(pathElems[1]) &&
hard(pathElems[2]) &&

@@ -409,0 +430,0 @@ hard(pathElems[3]) &&

@@ -15,2 +15,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const semver_1 = __importDefault(require("semver"));
const BtcNew_1 = __importDefault(require("./BtcNew"));

@@ -44,9 +45,14 @@ const BtcOld_1 = __importDefault(require("./BtcOld"));

], scrambleKey);
// new APDU (nano app API) for bitcoin and old APDU for altcoin
if (currency === "bitcoin" || currency === "bitcoin_testnet") {
this._impl = new BtcNew_1.default(new appClient_1.AppClient(this._transport));
}
else {
this._impl = new BtcOld_1.default(this._transport);
}
this._impl = (() => {
switch (currency) {
case "bitcoin":
case "bitcoin_testnet":
case "qtum":
// new APDU (nano app API) for currencies using app-bitcoin-new implementation
return new BtcNew_1.default(new appClient_1.AppClient(this._transport));
default:
// old APDU (legacy API) for currencies using legacy bitcoin app implementation
return new BtcOld_1.default(this._transport);
}
})();
}

@@ -211,20 +217,26 @@ /**

return this._impl;
const appAndVersion = yield (0, getAppAndVersion_1.getAppAndVersion)(this._transport);
let isBtcLegacy = true; // default for all altcoins
if (appAndVersion.name === "Bitcoin" || appAndVersion.name === "Bitcoin Test") {
const [major, minor] = appAndVersion.version.split(".");
// we use the legacy protocol for versions below 2.1.0 of the Bitcoin app.
isBtcLegacy = parseInt(major) <= 1 || (parseInt(major) == 2 && parseInt(minor) == 0);
}
else if (appAndVersion.name === "Bitcoin Legacy" ||
appAndVersion.name === "Bitcoin Test Legacy") {
// the "Bitcoin Legacy" and "Bitcoin Testnet Legacy" app use the legacy protocol, regardless of the version
isBtcLegacy = true;
}
else if (appAndVersion.name === "Exchange") {
// We can't query the version of the Bitcoin app if we're coming from Exchange;
// therefore, we use a workaround to distinguish legacy and new versions.
// This can be removed once Ledger Live enforces minimum bitcoin version >= 2.1.0.
isBtcLegacy = yield (0, getAppAndVersion_1.checkIsBtcLegacy)(this._transport);
}
const { name, version } = yield (0, getAppAndVersion_1.getAppAndVersion)(this._transport);
const isBtcLegacy = yield (() => __awaiter(this, void 0, void 0, function* () {
switch (name) {
case "Bitcoin":
case "Bitcoin Test": {
// we use the legacy protocol for versions below 2.1.0 of the Bitcoin app.
return semver_1.default.lt(version, "2.1.0");
}
case "Bitcoin Legacy":
case "Bitcoin Test Legacy":
// the "Bitcoin Legacy" and "Bitcoin Testnet Legacy" app use the legacy protocol, regardless of the version
return true;
case "Exchange":
// We can't query the version of the Bitcoin app if we're coming from Exchange;
// therefore, we use a workaround to distinguish legacy and new versions.
// This can be removed once Ledger Live enforces minimum bitcoin version >= 2.1.0.
return yield (0, getAppAndVersion_1.checkIsBtcLegacy)(this._transport);
case "Qtum":
// we use the legacy protocol for versions below 3.0.0 of the Qtum app.
return semver_1.default.lt(version, "3.0.0");
default:
return true;
}
}))();
if (isBtcLegacy) {

@@ -231,0 +243,0 @@ this._impl = new BtcOld_1.default(this._transport);

@@ -133,2 +133,3 @@ import type { CreateTransactionArg } from "./createTransaction";

}
export declare function isPathNormal(path: string): boolean;
//# sourceMappingURL=BtcNew.d.ts.map

@@ -12,2 +12,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.isPathNormal = void 0;
const bitcoinjs_lib_1 = require("bitcoinjs-lib");

@@ -373,7 +374,7 @@ const tiny_secp256k1_1 = require("tiny-secp256k1");

Standard paths are (currently):
M/44'/(1|0)'/X'
M/49'/(1|0)'/X'
M/84'/(1|0)'/X'
M/86'/(1|0)'/X'
M/48'/(1|0)'/X'/Y'
M/44'/(1|0|88)'/X'
M/49'/(1|0|88)'/X'
M/84'/(1|0|88)'/X'
M/86'/(1|0|88)'/X'
M/48'/(1|0|88)'/X'/Y'
followed by "", "(0|1)", or "(0|1)/b", where a and b are

@@ -389,14 +390,34 @@ non-hardened. For example, the following paths are standard

M/86'/1'/99'/2 // Change path item must be 0 or 1
Useful resource on derivation paths: https://learnmeabitcoin.com/technical/derivation-paths
*/
//path is not deepest hardened node of a standard path or deeper, use BtcOld
const H = 0x80000000; //HARDENED from bip32
const VALID_COIN_TYPES = [
0,
1,
88, // Qtum
];
const VALID_SINGLE_SIG_PURPOSES = [
44,
49,
84,
86, // BIP86 - https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki
];
const VALID_MULTISIG_PURPOSES = [
48, // BIP48 - https://github.com/bitcoin/bips/blob/master/bip-0048.mediawiki
];
const hard = (n) => n >= H;
const soft = (n) => n === undefined || n < H;
const change = (n) => n === undefined || n === 0 || n === 1;
const validCoinPathPartsSet = new Set(VALID_COIN_TYPES.map(t => t + H));
const validSingleSigPurposePathPartsSet = new Set(VALID_SINGLE_SIG_PURPOSES.map(t => t + H));
const validMultiSigPurposePathPartsSet = new Set(VALID_MULTISIG_PURPOSES.map(t => t + H));
function isPathNormal(path) {
//path is not deepest hardened node of a standard path or deeper, use BtcOld
const h = 0x80000000; //HARDENED from bip32
const pathElems = (0, bip32_1.pathStringToArray)(path);
const hard = (n) => n >= h;
const soft = (n) => n === undefined || n < h;
const change = (n) => n === undefined || n === 0 || n === 1;
// Single sig
if (pathElems.length >= 3 &&
pathElems.length <= 5 &&
[44 + h, 49 + h, 84 + h, 86 + h].some(v => v == pathElems[0]) &&
[0 + h, 1 + h].some(v => v == pathElems[1]) &&
validSingleSigPurposePathPartsSet.has(pathElems[0]) &&
validCoinPathPartsSet.has(pathElems[1]) &&
hard(pathElems[2]) &&

@@ -407,6 +428,7 @@ change(pathElems[3]) &&

}
// Multi sig
if (pathElems.length >= 4 &&
pathElems.length <= 6 &&
48 + h == pathElems[0] &&
[0 + h, 1 + h].some(v => v == pathElems[1]) &&
validMultiSigPurposePathPartsSet.has(pathElems[0]) &&
validCoinPathPartsSet.has(pathElems[1]) &&
hard(pathElems[2]) &&

@@ -420,2 +442,3 @@ hard(pathElems[3]) &&

}
exports.isPathNormal = isPathNormal;
//# sourceMappingURL=BtcNew.js.map
{
"name": "@ledgerhq/hw-app-btc",
"version": "10.1.2-nightly.0",
"version": "10.2.0-nightly.1",
"description": "Ledger Hardware Wallet Bitcoin Application API",

@@ -5,0 +5,0 @@ "keywords": [

@@ -0,1 +1,2 @@

import semver from "semver";
import type Transport from "@ledgerhq/hw-transport";

@@ -52,8 +53,15 @@ import BtcNew from "./BtcNew";

);
// new APDU (nano app API) for bitcoin and old APDU for altcoin
if (currency === "bitcoin" || currency === "bitcoin_testnet") {
this._impl = new BtcNew(new AppClient(this._transport));
} else {
this._impl = new BtcOld(this._transport);
}
this._impl = (() => {
switch (currency) {
case "bitcoin":
case "bitcoin_testnet":
case "qtum":
// new APDU (nano app API) for currencies using app-bitcoin-new implementation
return new BtcNew(new AppClient(this._transport));
default:
// old APDU (legacy API) for currencies using legacy bitcoin app implementation
return new BtcOld(this._transport);
}
})();
}

@@ -267,21 +275,27 @@

const appAndVersion = await getAppAndVersion(this._transport);
let isBtcLegacy = true; // default for all altcoins
const { name, version } = await getAppAndVersion(this._transport);
if (appAndVersion.name === "Bitcoin" || appAndVersion.name === "Bitcoin Test") {
const [major, minor] = appAndVersion.version.split(".");
// we use the legacy protocol for versions below 2.1.0 of the Bitcoin app.
isBtcLegacy = parseInt(major) <= 1 || (parseInt(major) == 2 && parseInt(minor) == 0);
} else if (
appAndVersion.name === "Bitcoin Legacy" ||
appAndVersion.name === "Bitcoin Test Legacy"
) {
// the "Bitcoin Legacy" and "Bitcoin Testnet Legacy" app use the legacy protocol, regardless of the version
isBtcLegacy = true;
} else if (appAndVersion.name === "Exchange") {
// We can't query the version of the Bitcoin app if we're coming from Exchange;
// therefore, we use a workaround to distinguish legacy and new versions.
// This can be removed once Ledger Live enforces minimum bitcoin version >= 2.1.0.
isBtcLegacy = await checkIsBtcLegacy(this._transport);
}
const isBtcLegacy = await (async () => {
switch (name) {
case "Bitcoin":
case "Bitcoin Test": {
// we use the legacy protocol for versions below 2.1.0 of the Bitcoin app.
return semver.lt(version, "2.1.0");
}
case "Bitcoin Legacy":
case "Bitcoin Test Legacy":
// the "Bitcoin Legacy" and "Bitcoin Testnet Legacy" app use the legacy protocol, regardless of the version
return true;
case "Exchange":
// We can't query the version of the Bitcoin app if we're coming from Exchange;
// therefore, we use a workaround to distinguish legacy and new versions.
// This can be removed once Ledger Live enforces minimum bitcoin version >= 2.1.0.
return await checkIsBtcLegacy(this._transport);
case "Qtum":
// we use the legacy protocol for versions below 3.0.0 of the Qtum app.
return semver.lt(version, "3.0.0");
default:
return true;
}
})();

@@ -288,0 +302,0 @@ if (isBtcLegacy) {

@@ -448,7 +448,7 @@ import { crypto } from "bitcoinjs-lib";

Standard paths are (currently):
M/44'/(1|0)'/X'
M/49'/(1|0)'/X'
M/84'/(1|0)'/X'
M/86'/(1|0)'/X'
M/48'/(1|0)'/X'/Y'
M/44'/(1|0|88)'/X'
M/49'/(1|0|88)'/X'
M/84'/(1|0|88)'/X'
M/86'/(1|0|88)'/X'
M/48'/(1|0|88)'/X'/Y'
followed by "", "(0|1)", or "(0|1)/b", where a and b are

@@ -464,17 +464,43 @@ non-hardened. For example, the following paths are standard

M/86'/1'/99'/2 // Change path item must be 0 or 1
Useful resource on derivation paths: https://learnmeabitcoin.com/technical/derivation-paths
*/
function isPathNormal(path: string): boolean {
//path is not deepest hardened node of a standard path or deeper, use BtcOld
const h = 0x80000000; //HARDENED from bip32
//path is not deepest hardened node of a standard path or deeper, use BtcOld
const H = 0x80000000; //HARDENED from bip32
const VALID_COIN_TYPES = [
0, // Bitcoin
1, // Bitcoin (Testnet)
88, // Qtum
];
const VALID_SINGLE_SIG_PURPOSES = [
44, // BIP44 - https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
49, // BIP49 - https://github.com/bitcoin/bips/blob/master/bip-0049.mediawiki
84, // BIP84 - https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki
86, // BIP86 - https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki
];
const VALID_MULTISIG_PURPOSES = [
48, // BIP48 - https://github.com/bitcoin/bips/blob/master/bip-0048.mediawiki
];
const hard = (n: number) => n >= H;
const soft = (n: number | undefined) => n === undefined || n < H;
const change = (n: number | undefined) => n === undefined || n === 0 || n === 1;
const validCoinPathPartsSet = new Set(VALID_COIN_TYPES.map(t => t + H));
const validSingleSigPurposePathPartsSet = new Set(VALID_SINGLE_SIG_PURPOSES.map(t => t + H));
const validMultiSigPurposePathPartsSet = new Set(VALID_MULTISIG_PURPOSES.map(t => t + H));
export function isPathNormal(path: string): boolean {
const pathElems = pathStringToArray(path);
const hard = (n: number) => n >= h;
const soft = (n: number | undefined) => n === undefined || n < h;
const change = (n: number | undefined) => n === undefined || n === 0 || n === 1;
// Single sig
if (
pathElems.length >= 3 &&
pathElems.length <= 5 &&
[44 + h, 49 + h, 84 + h, 86 + h].some(v => v == pathElems[0]) &&
[0 + h, 1 + h].some(v => v == pathElems[1]) &&
validSingleSigPurposePathPartsSet.has(pathElems[0]) &&
validCoinPathPartsSet.has(pathElems[1]) &&
hard(pathElems[2]) &&

@@ -486,7 +512,9 @@ change(pathElems[3]) &&

}
// Multi sig
if (
pathElems.length >= 4 &&
pathElems.length <= 6 &&
48 + h == pathElems[0] &&
[0 + h, 1 + h].some(v => v == pathElems[1]) &&
validMultiSigPurposePathPartsSet.has(pathElems[0]) &&
validCoinPathPartsSet.has(pathElems[1]) &&
hard(pathElems[2]) &&

@@ -493,0 +521,0 @@ hard(pathElems[3]) &&

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc