@trezor/connect
Version:
High-level javascript interface for Trezor hardware wallet.
188 lines • 6.54 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getLabel = exports.fixPath = exports.getIndexFromPath = exports.getPathFromIndex = exports.getSerializedPath = exports.validatePath = exports.getOutputScriptType = exports.getScriptType = exports.getAccountType = exports.isTaprootPath = exports.isBech32Path = exports.isSegwitPath = exports.getHDPath = exports.getSlip44ByPath = exports.fromHardened = exports.toHardened = exports.HD_HARDENED = void 0;
const constants_1 = require("../constants");
exports.HD_HARDENED = 0x80000000;
const toHardened = (n) => (n | exports.HD_HARDENED) >>> 0;
exports.toHardened = toHardened;
const fromHardened = (n) => (n & ~exports.HD_HARDENED) >>> 0;
exports.fromHardened = fromHardened;
const getSlip44ByPath = (path) => (0, exports.fromHardened)(path[1]);
exports.getSlip44ByPath = getSlip44ByPath;
const PATH_NOT_VALID = constants_1.ERRORS.TypedError('Method_InvalidParameter', 'Not a valid path');
const PATH_NEGATIVE_VALUES = constants_1.ERRORS.TypedError('Method_InvalidParameter', 'Path cannot contain negative values');
const getHDPath = (path) => {
const parts = path.toLowerCase().split('/');
if (parts[0] !== 'm')
throw PATH_NOT_VALID;
return parts
.filter(p => p !== 'm' && p !== '')
.map(p => {
let hardened = false;
if (p.endsWith("'")) {
hardened = true;
p = p.substring(0, p.length - 1);
}
let n = parseInt(p, 10);
if (Number.isNaN(n)) {
throw PATH_NOT_VALID;
}
else if (n < 0) {
throw PATH_NEGATIVE_VALUES;
}
if (hardened) {
n = (0, exports.toHardened)(n);
}
return n;
});
};
exports.getHDPath = getHDPath;
const isSegwitPath = (path) => Array.isArray(path) && path[0] === (0, exports.toHardened)(49);
exports.isSegwitPath = isSegwitPath;
const isBech32Path = (path) => Array.isArray(path) && path[0] === (0, exports.toHardened)(84);
exports.isBech32Path = isBech32Path;
const isTaprootPath = (path) => Array.isArray(path) && (path[0] === (0, exports.toHardened)(86) || path[0] === (0, exports.toHardened)(10025));
exports.isTaprootPath = isTaprootPath;
const getAccountType = (path) => {
if ((0, exports.isTaprootPath)(path))
return 'p2tr';
if ((0, exports.isBech32Path)(path))
return 'p2wpkh';
if ((0, exports.isSegwitPath)(path))
return 'p2sh';
return 'p2pkh';
};
exports.getAccountType = getAccountType;
const getScriptType = (path) => {
if (!Array.isArray(path) || path.length < 1)
return undefined;
const p1 = (0, exports.fromHardened)(path[0]);
switch (p1) {
case 44:
return 'SPENDADDRESS';
case 48: {
if (path.length < 4)
return undefined;
const p3 = (0, exports.fromHardened)(path[3]);
switch (p3) {
case 0:
return 'SPENDMULTISIG';
case 1:
return 'SPENDP2SHWITNESS';
case 2:
return 'SPENDWITNESS';
default:
return undefined;
}
}
case 49:
return 'SPENDP2SHWITNESS';
case 84:
return 'SPENDWITNESS';
case 86:
case 10025:
return 'SPENDTAPROOT';
default:
return undefined;
}
};
exports.getScriptType = getScriptType;
const getOutputScriptType = (path) => {
if (!Array.isArray(path) || path.length < 1)
return undefined;
const p = (0, exports.fromHardened)(path[0]);
switch (p) {
case 44:
return 'PAYTOADDRESS';
case 48: {
if (path.length < 4)
return undefined;
const p3 = (0, exports.fromHardened)(path[3]);
switch (p3) {
case 0:
return 'PAYTOMULTISIG';
case 1:
return 'PAYTOP2SHWITNESS';
case 2:
return 'PAYTOWITNESS';
default:
return undefined;
}
}
case 49:
return 'PAYTOP2SHWITNESS';
case 84:
return 'PAYTOWITNESS';
case 86:
case 10025:
return 'PAYTOTAPROOT';
default:
return undefined;
}
};
exports.getOutputScriptType = getOutputScriptType;
const validatePath = (path, length = 0, base = false) => {
let valid;
if (typeof path === 'string') {
valid = (0, exports.getHDPath)(path);
}
else if (Array.isArray(path)) {
valid = path.map((p) => {
const n = parseInt(p, 10);
if (Number.isNaN(n)) {
throw PATH_NOT_VALID;
}
else if (n < 0) {
throw PATH_NEGATIVE_VALUES;
}
return n;
});
}
if (!valid)
throw PATH_NOT_VALID;
if (length > 0 && valid.length < length)
throw PATH_NOT_VALID;
return base ? valid.splice(0, 3) : valid;
};
exports.validatePath = validatePath;
const getSerializedPath = (path) => `m/${path
.map(i => {
const s = (i & ~exports.HD_HARDENED).toString();
if (i & exports.HD_HARDENED) {
return `${s}'`;
}
return s;
})
.join('/')}`;
exports.getSerializedPath = getSerializedPath;
const getPathFromIndex = (bip44purpose, bip44cointype, index) => [
(0, exports.toHardened)(bip44purpose),
(0, exports.toHardened)(bip44cointype),
(0, exports.toHardened)(index),
];
exports.getPathFromIndex = getPathFromIndex;
const getIndexFromPath = (path) => {
if (path.length < 3) {
throw constants_1.ERRORS.TypedError('Method_InvalidParameter', `getIndexFromPath: invalid path length ${path.toString()}`);
}
return (0, exports.fromHardened)(path[2]);
};
exports.getIndexFromPath = getIndexFromPath;
const fixPath = (utxo) => {
if (utxo.address_n && Array.isArray(utxo.address_n)) {
utxo.address_n = utxo.address_n.map(i => i >>> 0);
}
if (utxo.address_n && typeof utxo.address_n === 'string') {
utxo.address_n = (0, exports.getHDPath)(utxo.address_n);
}
return utxo;
};
exports.fixPath = fixPath;
const getLabel = (label, coinInfo) => {
if (coinInfo) {
return label.replace('#NETWORK', coinInfo.label);
}
return label.replace('#NETWORK', '');
};
exports.getLabel = getLabel;
//# sourceMappingURL=pathUtils.js.map