General cleaning up, also changing some operations to not return errors, but throw OperationErrors.

This commit is contained in:
David C Goldenberg 2025-06-20 15:44:44 -04:00
parent d47c7a633a
commit 5265da5714
10 changed files with 20 additions and 27 deletions

View File

@ -5,7 +5,7 @@
*/ */
import Operation from "../Operation.mjs"; import Operation from "../Operation.mjs";
// import OperationError from "../errors/OperationError.mjs"; import OperationError from "../errors/OperationError.mjs";
import { b58DoubleSHAChecksum} from "../lib/Bitcoin.mjs"; import { b58DoubleSHAChecksum} from "../lib/Bitcoin.mjs";
import { BIP32Factory} from "bip32"; import { BIP32Factory} from "bip32";
import ecc from "@bitcoinerlab/secp256k1"; import ecc from "@bitcoinerlab/secp256k1";
@ -76,11 +76,11 @@ class BIP32Derive extends Operation {
} }
input = input.trim(); input = input.trim();
if (!verifyDerivationPath(args[0])) { if (!verifyDerivationPath(args[0])) {
return "Invalid derivation path: " + args[0] + "\n"; throw new OperationError("Invalid derivation path: " + args[0] + "\n");
} }
const xkeyRe = /^(X|x|Y|y|Z|z|L|l|T|t)[pub|prv|tbv|tub][A-HJ-NP-Za-km-z1-9]{2,}$/g; const xkeyRe = /^(X|x|Y|y|Z|z|L|l|T|t)[pub|prv|tbv|tub][A-HJ-NP-Za-km-z1-9]{2,}$/g;
if (!b58DoubleSHAChecksum(input) || !xkeyRe.test(input)) { if (!b58DoubleSHAChecksum(input) || !xkeyRe.test(input)) {
return "Possibly invalid Extended Key: " + input + "\n"; throw new OperationError("Possibly invalid Extended Key: " + input + "\n");
} }
const bip32 = BIP32Factory(ecc); const bip32 = BIP32Factory(ecc);
const node = bip32.fromBase58(input); const node = bip32.fromBase58(input);

View File

@ -32,7 +32,6 @@ class ChangeExtendedKeyVersion extends Operation {
"name": "Version Type", "name": "Version Type",
"type": "option", "type": "option",
"value": getVersions() "value": getVersions()
// "value": ["xpub", "xprv", "ypub", "yprv", "zpub", "zprv", "Zpub", "Zprv", "Ypub", "Yprv", "Ltub", "Ltpv", "Mtub", "Mtpv", "ttub", "ttpv", "tpub", "tprv", "upub", "uprv", "vpub", "vprv", "Upub", "Uprv", "Vpub", "Vprv"]
} }
]; ];
this.checks = [ this.checks = [

View File

@ -6,6 +6,7 @@
* @license Apache-2.0 * @license Apache-2.0
*/ */
import Operation from "../Operation.mjs"; import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import { deserializeExtendedKeyFunc } from "../lib/Bitcoin.mjs"; import { deserializeExtendedKeyFunc } from "../lib/Bitcoin.mjs";
@ -66,7 +67,7 @@ class DeserializeExtendedKey extends Operation {
*/ */
present(output) { present(output) {
if ("error" in output) { if ("error" in output) {
return output.error; throw new OperationError(output.error);
} else { } else {
if (Object.prototype.hasOwnProperty.call(output, "masterkey") && Object.prototype.hasOwnProperty.call(output, "checksum")) { if (Object.prototype.hasOwnProperty.call(output, "masterkey") && Object.prototype.hasOwnProperty.call(output, "checksum")) {
let finalOutput = "Key Analyzed: " + output.key + "\n"; let finalOutput = "Key Analyzed: " + output.key + "\n";

View File

@ -5,6 +5,7 @@
*/ */
import Operation from "../Operation.mjs"; import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import {base58Decode, base58Encode, doubleSHA, b58DoubleSHAChecksum} from "../lib/Bitcoin.mjs"; import {base58Decode, base58Encode, doubleSHA, b58DoubleSHAChecksum} from "../lib/Bitcoin.mjs";
import Utils from "../Utils.mjs"; import Utils from "../Utils.mjs";
import {toHex} from "crypto-api/src/encoder/hex.mjs"; import {toHex} from "crypto-api/src/encoder/hex.mjs";
@ -94,7 +95,7 @@ class ETHTRXConversion extends Operation {
switch (direction) { switch (direction) {
case "ETH->TRX":{ case "ETH->TRX":{
if (!validateETHAddress(input)) { if (!validateETHAddress(input)) {
return "Invalid ETH address. ETH addresses should have 20 bytes (40 characters) prefaced by 0x."; throw new OperationError("Invalid ETH address. ETH addresses should have 20 bytes (40 characters) prefaced by 0x.");
} }
const unencodedAddress = input.slice(2,); const unencodedAddress = input.slice(2,);
const checksumHash = toHex(doubleSHA(fromArrayBuffer(Utils.convertToByteArray("41" + unencodedAddress, "hex")))); const checksumHash = toHex(doubleSHA(fromArrayBuffer(Utils.convertToByteArray("41" + unencodedAddress, "hex"))));
@ -104,7 +105,7 @@ class ETHTRXConversion extends Operation {
} }
case "TRX->ETH":{ case "TRX->ETH":{
if (!validateTRXAddress(input)) { if (!validateTRXAddress(input)) {
return "Invalid TRX Address. Checksum failed."; throw new OperationError("Invalid TRX Address. Checksum failed.");
} }
return ethCheckSum("0x" + toHex(fromArrayBuffer(base58Decode(input).slice(1, -4)))); return ethCheckSum("0x" + toHex(fromArrayBuffer(base58Decode(input).slice(1, -4))));
} }

View File

@ -37,20 +37,7 @@ class KeyToExtendedKey extends Operation {
"name": "Version Type", "name": "Version Type",
"type": "option", "type": "option",
"value": getVersions() "value": getVersions()
// "value": ["xpub", "xprv", "ypub", "yprv", "zpub", "zprv", "Zpub", "Zprv", "Ypub", "Yprv", "Ltub", "Ltpv", "Mtub", "Mtpv", "ttub", "ttpv", "tpub", "tprv", "upub", "uprv", "vpub", "vprv", "Upub", "Uprv", "Vpub", "Vprv"]
} }
/* Example arguments. See the project wiki for full details.
{
name: "First arg",
type: "string",
value: "Don't Panic"
},
{
name: "Second arg",
type: "number",
value: 42
}
*/
]; ];
} }

View File

@ -7,8 +7,10 @@
*/ */
import Operation from "../Operation.mjs"; import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import ec from "elliptic"; import ec from "elliptic";
import { validatePrivateKey, makeSureIsHex} from "../lib/Bitcoin.mjs"; import { validatePrivateKey, makeSureIsHex} from "../lib/Bitcoin.mjs";
// import { toHex } from "crypto-api/src/encoder/hex.mjs"; // import { toHex } from "crypto-api/src/encoder/hex.mjs";
// const curves = ["secp256k1", "ed25519", "curve25519", "p521", "p384", "p256", "p224", "p192"]; // const curves = ["secp256k1", "ed25519", "curve25519", "p521", "p384", "p256", "p224", "p192"];
@ -62,7 +64,7 @@ class PrivateECKeyToPublic extends Operation {
const privKeyCheck = validatePrivateKey(input); const privKeyCheck = validatePrivateKey(input);
if (privKeyCheck.trim().length !== 0) { if (privKeyCheck.trim().length !== 0) {
return "Error with the input as private key. Error is:\n\t" + privKeyCheck; throw new OperationError("Error with the input as private key. Error is:\n\t" + privKeyCheck);
} }
const processedInput = makeSureIsHex(input); const processedInput = makeSureIsHex(input);
const ecContext = ec.ec("secp256k1"); const ecContext = ec.ec("secp256k1");

View File

@ -7,9 +7,11 @@
*/ */
import Operation from "../Operation.mjs"; import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import { base58Encode, getWIFVersionByte, doubleSHA, validatePrivateKey, makeSureIsHex} from "../lib/Bitcoin.mjs"; import { base58Encode, getWIFVersionByte, doubleSHA, validatePrivateKey, makeSureIsHex} from "../lib/Bitcoin.mjs";
import { fromArrayBuffer } from "crypto-api/src/encoder/array-buffer.mjs"; import { fromArrayBuffer } from "crypto-api/src/encoder/array-buffer.mjs";
import {toHex} from "crypto-api/src/encoder/hex.mjs"; import {toHex} from "crypto-api/src/encoder/hex.mjs";
// import {toHex as toHexOther} from "../lib/Hex.mjs"; // import {toHex as toHexOther} from "../lib/Hex.mjs";
import Utils from "../Utils.mjs"; import Utils from "../Utils.mjs";
@ -67,7 +69,7 @@ class PrivateKeyToWIF extends Operation {
input = input.trim(); input = input.trim();
const privateKeyCheck = validatePrivateKey(input); const privateKeyCheck = validatePrivateKey(input);
if (privateKeyCheck.trim().length !== 0) { if (privateKeyCheck.trim().length !== 0) {
return "Error parsing private key. Error is:\n\t" + privateKeyCheck; throw new OperationError("Error parsing private key. Error is:\n\t" + privateKeyCheck);
} }
const processedKey = makeSureIsHex(input); const processedKey = makeSureIsHex(input);
const versionByte = getWIFVersionByte(args[0]); const versionByte = getWIFVersionByte(args[0]);

View File

@ -7,6 +7,7 @@
*/ */
import Operation from "../Operation.mjs"; import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import { fromArrayBuffer } from "crypto-api/src/encoder/array-buffer.mjs"; import { fromArrayBuffer } from "crypto-api/src/encoder/array-buffer.mjs";
import {toHex} from "crypto-api/src/encoder/hex.mjs"; import {toHex} from "crypto-api/src/encoder/hex.mjs";
import { base58Encode, getP2PKHVersionByte, getP2SHVersionByte, hash160Func, doubleSHA, getHumanReadablePart, makeSureIsBytes, validatePublicKey, tweakHash, liftX, makeSureIsHex} from "../lib/Bitcoin.mjs"; import { base58Encode, getP2PKHVersionByte, getP2SHVersionByte, hash160Func, doubleSHA, getHumanReadablePart, makeSureIsBytes, validatePublicKey, tweakHash, liftX, makeSureIsHex} from "../lib/Bitcoin.mjs";
@ -90,14 +91,14 @@ class PublicKeyToP2PKHAddress extends Operation {
return ""; return "";
} }
if (validatePublicKey(input) !== "") { if (validatePublicKey(input) !== "") {
return validatePublicKey(input); throw new OperationError(validatePublicKey(input));
} }
// P2TR are their own separate case. We handle those first. // P2TR are their own separate case. We handle those first.
if (args[1] === "Taproot (P2TR bc1p Addresses)") { if (args[1] === "Taproot (P2TR bc1p Addresses)") {
const hrp = getHumanReadablePart(args[0]); const hrp = getHumanReadablePart(args[0]);
const resultKey = tweakKey(input); const resultKey = tweakKey(input);
if (resultKey === -1) { if (resultKey === -1) {
return "Error: Bad Public Key to turn into P2TR Address."; throw new OperationError("Error: Bad Public Key to turn into P2TR Address.");
} }
return encodeProgramToSegwit(hrp, 1, Utils.convertToByteArray(resultKey.slice(2,), "hex")); return encodeProgramToSegwit(hrp, 1, Utils.convertToByteArray(resultKey.slice(2,), "hex"));
} else { } else {
@ -111,7 +112,7 @@ class PublicKeyToP2PKHAddress extends Operation {
if (hrp !== "") { if (hrp !== "") {
return encodeProgramToSegwit(hrp, 0, Utils.convertToByteArray(redeemScript, "hex")); return encodeProgramToSegwit(hrp, 0, Utils.convertToByteArray(redeemScript, "hex"));
} else { } else {
return args[0] + " does not support Segwit Addresses."; throw new OperationError(args[0] + " does not support Segwit Addresses.");
} }
} }
// It its not segwit, we create the redeemScript either for P2PKH or P2SH-P2WPKH addresses. // It its not segwit, we create the redeemScript either for P2PKH or P2SH-P2WPKH addresses.

View File

@ -5,6 +5,7 @@
*/ */
import Operation from "../Operation.mjs"; import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import {makeSureIsBytes, validatePublicKey, base58Encode, doubleSHA} from "../lib/Bitcoin.mjs"; import {makeSureIsBytes, validatePublicKey, base58Encode, doubleSHA} from "../lib/Bitcoin.mjs";
import { fromArrayBuffer } from "crypto-api/src/encoder/array-buffer.mjs"; import { fromArrayBuffer } from "crypto-api/src/encoder/array-buffer.mjs";
import {toHex} from "crypto-api/src/encoder/hex.mjs"; import {toHex} from "crypto-api/src/encoder/hex.mjs";
@ -71,7 +72,7 @@ class PublicKeyToTRXStyleAddress extends Operation {
return ""; return "";
} }
if (validatePublicKey(input) !== "") { if (validatePublicKey(input) !== "") {
return validatePublicKey(input); throw new OperationError(validatePublicKey(input));
} }
return pubKeyToTRXAddress(input); return pubKeyToTRXAddress(input);
} }

View File

@ -34,7 +34,6 @@ class SeedToMPK extends Operation {
"name": "Version Type", "name": "Version Type",
"type": "option", "type": "option",
"value": getVersions() "value": getVersions()
// "value": ["xprv", "yprv", "zprv", "Zprv", "Yprv", "Ltpv", "Mtpv", "ttpv", "tprv", "uprv", "vprv", "Uprv", "Vprv"]
} }
]; ];
} }