@ledgerhq/hw-app-btc
Advanced tools
Comparing version 10.1.2-nightly.0 to 10.2.0-nightly.1
# @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 @@ |
@@ -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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
1053509
337
15196
0