@stacks/cli
Version:
Stacks command line tool
171 lines • 7.51 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;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractAppKey = exports.getApplicationKeyInfo = exports.findIdentityIndex = exports.getStacksWalletKeyInfo = exports.getPaymentKeyInfo = exports.getOwnerKeyInfo = exports.DERIVATION_PATH = exports.STX_WALLET_COMPATIBLE_SEED_STRENGTH = void 0;
const c32check = require('c32check');
const bip32_1 = require("@scure/bip32");
const scureBip39 = __importStar(require("@scure/bip39"));
const encryption_1 = require("@stacks/encryption");
const wallet_sdk_1 = require("@stacks/wallet-sdk");
const bip32 = __importStar(require("bip32"));
const bip39 = __importStar(require("bip39"));
const blockstack = __importStar(require("blockstack"));
const wif = __importStar(require("wif"));
const common_1 = require("./common");
const transactions_1 = require("@stacks/transactions");
const BITCOIN_PUBKEYHASH = 0;
const BITCOIN_PUBKEYHASH_TESTNET = 111;
const BITCOIN_WIF = 128;
const BITCOIN_WIF_TESTNET = 239;
exports.STX_WALLET_COMPATIBLE_SEED_STRENGTH = 256;
exports.DERIVATION_PATH = "m/44'/5757'/0'/0/0";
async function walletFromMnemonic(mnemonic) {
const seed = await bip39.mnemonicToSeed(mnemonic);
return new blockstack.BlockstackWallet(bip32.fromSeed(seed));
}
async function getOwnerKeyInfo(network, mnemonic, index, version = 'v0.10-current') {
const wallet = await (0, wallet_sdk_1.generateWallet)({ secretKey: mnemonic, password: '' });
const account = (0, wallet_sdk_1.deriveAccount)({
rootNode: (0, wallet_sdk_1.getRootNode)(wallet),
salt: wallet.salt,
stxDerivationType: wallet_sdk_1.DerivationType.Wallet,
index,
});
const publicKey = (0, encryption_1.getPublicKeyFromPrivate)(account.dataPrivateKey);
const addr = network.coerceAddress((0, encryption_1.publicKeyToBtcAddress)(publicKey));
return {
privateKey: account.dataPrivateKey + '01',
idAddress: `ID-${addr}`,
version,
index,
};
}
exports.getOwnerKeyInfo = getOwnerKeyInfo;
async function getPaymentKeyInfo(network, mnemonic) {
const wallet = await walletFromMnemonic(mnemonic);
const privkey = wallet.getBitcoinPrivateKey(0);
const addr = (0, common_1.getPrivateKeyAddress)(network, privkey);
const result = {
privateKey: privkey,
address: {
BTC: addr,
STACKS: c32check.b58ToC32(addr),
},
index: 0,
};
return result;
}
exports.getPaymentKeyInfo = getPaymentKeyInfo;
async function getStacksWalletKeyInfo(network, mnemonic, derivationPath = exports.DERIVATION_PATH) {
const seed = await scureBip39.mnemonicToSeed(mnemonic);
const master = bip32_1.HDKey.fromMasterSeed(seed);
const child = master.derive(derivationPath);
const pubkey = Buffer.from(child.publicKey);
const privkeyBuffer = Buffer.from(child.privateKey);
const privkey = (0, transactions_1.compressPrivateKey)(privkeyBuffer);
const wifVersion = network.isTestnet() ? BITCOIN_WIF_TESTNET : BITCOIN_WIF;
const walletImportFormat = wif.encode(wifVersion, privkeyBuffer, true);
const addr = (0, common_1.getPrivateKeyAddress)(network, privkey);
const btcAddress = (0, encryption_1.publicKeyToBtcAddress)(pubkey, network.isTestnet() ? BITCOIN_PUBKEYHASH_TESTNET : BITCOIN_PUBKEYHASH);
return {
privateKey: privkey,
publicKey: pubkey.toString('hex'),
address: c32check.b58ToC32(addr),
btcAddress,
wif: walletImportFormat,
index: 0,
};
}
exports.getStacksWalletKeyInfo = getStacksWalletKeyInfo;
async function findIdentityIndex(network, mnemonic, idAddress, maxIndex) {
if (!maxIndex) {
maxIndex = (0, common_1.getMaxIDSearchIndex)();
}
if (idAddress.substring(0, 3) !== 'ID-') {
throw new Error('Not an identity address');
}
const wallet = await (0, wallet_sdk_1.generateWallet)({ secretKey: mnemonic, password: '' });
const needle = network.coerceAddress(idAddress.slice(3));
for (let i = 0; i < maxIndex; i++) {
const account = (0, wallet_sdk_1.deriveAccount)({
rootNode: (0, wallet_sdk_1.getRootNode)(wallet),
salt: wallet.salt,
stxDerivationType: wallet_sdk_1.DerivationType.Wallet,
index: i,
});
const publicKey = (0, encryption_1.getPublicKeyFromPrivate)(account.dataPrivateKey);
const address = network.coerceAddress((0, encryption_1.publicKeyToBtcAddress)(publicKey));
if (address === needle)
return i;
}
return -1;
}
exports.findIdentityIndex = findIdentityIndex;
async function getApplicationKeyInfo(network, mnemonic, idAddress, appDomain, idIndex) {
if (!idIndex) {
idIndex = -1;
}
if (idIndex < 0) {
idIndex = await findIdentityIndex(network, mnemonic, idAddress);
if (idIndex < 0) {
throw new Error('Identity address does not belong to this keychain');
}
}
const wallet = await walletFromMnemonic(mnemonic);
const identityOwnerAddressNode = wallet.getIdentityAddressNode(idIndex);
const appsNode = blockstack.BlockstackWallet.getAppsNode(identityOwnerAddressNode);
const legacyAppPrivateKey = blockstack.BlockstackWallet.getLegacyAppPrivateKey(appsNode.toBase58(), wallet.getIdentitySalt(), appDomain);
const res = {
keyInfo: {
privateKey: 'TODO',
address: 'TODO',
},
legacyKeyInfo: {
privateKey: legacyAppPrivateKey,
address: (0, common_1.getPrivateKeyAddress)(network, `${legacyAppPrivateKey}01`),
},
ownerKeyIndex: idIndex,
};
return res;
}
exports.getApplicationKeyInfo = getApplicationKeyInfo;
function extractAppKey(network, appKeyInfo, appAddress) {
if (appAddress) {
if (network.coerceMainnetAddress(appKeyInfo.keyInfo.address) ===
network.coerceMainnetAddress(appAddress)) {
return appKeyInfo.keyInfo.privateKey;
}
if (network.coerceMainnetAddress(appKeyInfo.legacyKeyInfo.address) ===
network.coerceMainnetAddress(appAddress)) {
return appKeyInfo.legacyKeyInfo.privateKey;
}
}
const appPrivateKey = appKeyInfo.keyInfo.privateKey === 'TODO' || !appKeyInfo.keyInfo.privateKey
? appKeyInfo.legacyKeyInfo.privateKey
: appKeyInfo.keyInfo.privateKey;
return appPrivateKey;
}
exports.extractAppKey = extractAppKey;
//# sourceMappingURL=keys.js.map