atomicals-js
Version:
Atomicals JavaScript SDK and CLI
186 lines (185 loc) • 8.87 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateWalletStorage = void 0;
const bitcoin = require('bitcoinjs-lib');
const ecpair_1 = __importDefault(require("ecpair"));
const ecc = __importStar(require("tiny-secp256k1"));
bitcoin.initEccLib(ecc);
const ECPair = (0, ecpair_1.default)(ecc);
const bip39 = __importStar(require("bip39"));
const bip32_1 = __importDefault(require("bip32"));
const file_utils_1 = require("./file-utils");
const create_key_pair_1 = require("./create-key-pair");
const wallet_path_resolver_1 = require("./wallet-path-resolver");
const command_helpers_1 = require("../commands/command-helpers");
const bip32 = (0, bip32_1.default)(ecc);
const walletPath = (0, wallet_path_resolver_1.walletPathResolver)();
const validateWalletStorage = () => __awaiter(void 0, void 0, void 0, function* () {
try {
console.log('walletPath', walletPath);
const wallet = yield (0, file_utils_1.jsonFileReader)(walletPath);
if (!wallet.phrase) {
console.log(`phrase field not found in ${walletPath}`);
throw new Error(`phrase field not found in ${walletPath}`);
}
// Validate is a valid mnemonic
if (!bip39.validateMnemonic(wallet.phrase)) {
console.log('phrase is not a valid mnemonic phrase!');
throw new Error("phrase is not a valid mnemonic phrase!");
}
if (!wallet.primary) {
console.log(`Wallet needs a primary address`);
throw new Error(`Wallet needs a primary address`);
}
if (!wallet.funding) {
console.log(`Wallet needs a funding address`);
throw new Error(`Wallet needs a funding address`);
}
// Validate WIF
if (!wallet.primary.WIF) {
console.log(`Primary WIF not set`);
throw new Error(`Primary WIF not set`);
}
if (!wallet.funding.WIF) {
console.log(`Funding WIF not set`);
throw new Error(`Funding WIF not set`);
}
// Validate Addresses
if (!wallet.primary.address) {
console.log(`Primary address not set`);
throw new Error(`Primary address not set`);
}
if (!wallet.funding.address) {
console.log(`Funding address not set`);
throw new Error(`Funding address not set`);
}
const seed = yield bip39.mnemonicToSeed(wallet.phrase, wallet.passphrase);
const rootKey = bip32.fromSeed(seed);
const derivePathPrimary = wallet.primary.path;
const childNodePrimary = rootKey.derivePath(derivePathPrimary);
const childNodeXOnlyPubkeyPrimary = (0, create_key_pair_1.toXOnly)(childNodePrimary.publicKey);
const p2trPrimary = bitcoin.payments.p2tr({
internalPubkey: childNodeXOnlyPubkeyPrimary,
network: command_helpers_1.NETWORK
});
if (!p2trPrimary.address || !p2trPrimary.output) {
throw "error creating p2tr primary";
}
const derivePathFunding = wallet.funding.path;
const childNodeFunding = rootKey.derivePath(derivePathFunding);
const childNodeXOnlyPubkeyFunding = (0, create_key_pair_1.toXOnly)(childNodeFunding.publicKey);
const p2trFunding = bitcoin.payments.p2tr({
internalPubkey: childNodeXOnlyPubkeyFunding,
network: command_helpers_1.NETWORK
});
if (!p2trFunding.address || !p2trFunding.output) {
throw "error creating p2tr funding";
}
//const childNodeFunding = rootKey.derivePath(derivePathFunding);
// const { address } = bitcoin.payments.p2pkh({ pubkey: childNode.publicKey });
// const wif = childNodePrimary.toWIF();
const keypairPrimary = ECPair.fromWIF(wallet.primary.WIF);
if (childNodePrimary.toWIF() !== wallet.primary.WIF) {
throw 'primary wif does not match';
}
const p2trPrimaryCheck = bitcoin.payments.p2tr({
internalPubkey: (0, create_key_pair_1.toXOnly)(keypairPrimary.publicKey),
network: command_helpers_1.NETWORK
});
if (p2trPrimaryCheck.address !== p2trPrimary.address && p2trPrimary.address !== wallet.primary.address) {
const m = `primary address is not correct and does not match associated phrase at ${derivePathPrimary}. Found: ` + p2trPrimaryCheck.address;
console.log(m);
throw new Error(m);
}
const keypairFunding = ECPair.fromWIF(wallet.funding.WIF);
if (childNodeFunding.toWIF() !== wallet.funding.WIF) {
throw 'funding wif does not match';
}
const p2trFundingCheck = bitcoin.payments.p2tr({
internalPubkey: (0, create_key_pair_1.toXOnly)(keypairFunding.publicKey),
network: command_helpers_1.NETWORK
});
if (p2trFundingCheck.address !== p2trFundingCheck.address && p2trFundingCheck.address !== wallet.funding.address) {
const m = `funding address is not correct and does not match associated phrase at ${derivePathFunding}. Found: ` + p2trFundingCheck.address;
console.log(m);
throw new Error(m);
}
// Now we loop over every imported wallet and validate that they are correct
const imported = {};
for (const prop in wallet.imported) {
if (!wallet.imported.hasOwnProperty(prop)) {
continue;
}
// Get the wif and the address and ensure they match
const importedKeypair = ECPair.fromWIF(wallet.imported[prop].WIF);
// Sanity check
if (importedKeypair.toWIF() !== wallet.imported[prop].WIF) {
throw 'Imported WIF does not match';
}
const p2trImported = bitcoin.payments.p2tr({
internalPubkey: (0, create_key_pair_1.toXOnly)(importedKeypair.publicKey),
network: command_helpers_1.NETWORK
});
if (p2trImported.address !== wallet.imported[prop].address) {
throw `Imported address does not match for alias ${prop}. Expected: ` + wallet.imported[prop].address + ', Found: ' + p2trImported.address;
}
imported[prop] = {
address: p2trImported.address,
WIF: wallet.imported[prop].WIF
};
}
return {
primary: {
childNode: childNodePrimary,
address: p2trPrimary.address,
WIF: childNodePrimary.toWIF()
},
funding: {
childNode: childNodeFunding,
address: p2trFunding.address,
WIF: childNodeFunding.toWIF()
},
imported
};
}
catch (err) {
console.log(`Error reading ${walletPath}. Create a new wallet with "npm cli wallet-init"`);
throw err;
}
});
exports.validateWalletStorage = validateWalletStorage;