您所有的去中心化操作都集中在一处(比特币链)
请运行以下命令来运行项目:
- npm 安装
- npm 运行构建
- dirmanager create // 创建钱包
- dirmanager list // 列出所有钱包
- dirmanager import // 使用助记词导入钱包
- dirmanager Balance // 获取钱包余额
- dirmanager transactions // 获取钱包的交易
- dirmanagergenerate // 为钱包生成一个未使用的地址
createWallet.ts
const { BIP32Factory } = require('bip32');
const ecc = require('tiny-secp256k1');
const bip32 = BIP32Factory(ecc);
const bip39 = require('bip39');
const bitcoin = require('bitcoinjs-lib');
const axios = require('axios');
require('dotenv').config();
const network = bitcoin.networks.bitcoin;
const fs = require('fs');
// console.log(bip39);
const bitPath = `m/44'/0'/0'/0/0`;
// generate wallet
const createBIP39Wallet = (name:string) => {
let mnemonic = bip39.generateMnemonic();
const seed = bip39.mnemonicToSeedSync(mnemonic);
let root = bip32.fromSeed(seed, network);
let account = root.derivePath(bitPath);
let node = account.derive(0).derive(0);
let btcAddress = bitcoin.payments.p2pkh({
pubkey: node.publicKey,
network: network,
}).address;
console.log(`
Wallet generated:
- Address : ${btcAddress},
- Key : ${node.toWIF()},
- Mnemonic : ${mnemonic}
`);
return {
name: name,
mnemonic: mnemonic,
address: btcAddress,
};
};
module.exports=createBIP39Wallet;
// mnemonicToSeedSync: [Function: mnemonicToSeedSync],
// mnemonicToSeed: [Function: mnemonicToSeed],
// mnemonicToEntropy: [Function: mnemonicToEntropy],
// entropyToMnemonic: [Function: entropyToMnemonic],
// generateMnemonic: [Function: generateMnemonic],
// validateMnemonic: [Function: validateMnemonic],
// setDefaultWordlist: [Function: setDefaultWordlist],
// getDefaultWordlist: [Function: getDefaultWordlist],
fetchBalance.ts
const axios = require('axios');
require('dotenv').config();
// fetch balance
async function getBitcoinBalance(address:string){
const apiUrl = `https://api.blockcypher.com/v1/btc/main/addrs/${address}/balance?token=${process.env.BITCOIN_NODE_TOKEN}`;
try {
const response = await axios.get(apiUrl);
const balance = response.data.balance;
console.log(`Bitcoin Address: ${address}`);
console.log(`Balance: ${balance} Satoshi (${balance / 1e8} BTC)`);
} catch (error) {
console.error(error);
}
};
module.exports=getBitcoinBalance;
getUnusedBitcoinAddress.ts
const axios = require('axios');
require('dotenv').config();
const args = process.argv.slice(2);
const apiUrl = `https://api.blockcypher.com/v1/btc/main/addrs?token=${process.env.BITCOIN_NODE_TOKEN}&bech32=true`;
// Function to generate a new Bitcoin address
async function generateBitcoinAddress() {
try {
const response = await axios.post(apiUrl);
console.log(response.data);
const newAddress = response.data.address;
console.log(`Generated Bitcoin Address: ${newAddress}`);
return newAddress;
} catch (error) {
console.error('Error generating Bitcoin address:', error);
throw error;
}
}
// Function to check if a specific address has transactions
async function hasTransactionsForAddress(address:string) {
const transactions = await getBitcoinTransactions(address);
return transactions.length > 0;
}
// Function to get Bitcoin transactions for a specific address
async function getBitcoinTransactions(address:string) {
const transactionsUrl = `https://api.blockcypher.com/v1/btc/main/addrs/${address}/full?token=${process.env.BITCOIN_NODE_TOKEN}`;
try {
const response = await axios.get(transactionsUrl);
return response.data.txs || [];
} catch (error) {
console.error('Error fetching transactions:', error);
throw error;
}
}
// Function to generate an unused Bitcoin address for a specific wallet address
async function generateUnusedBitcoinAddressForWallet(walletAddress:string) {
let address;
let attempts = 0;
// Try generating a new address until an unused one is found
do {
address = await generateBitcoinAddress();
attempts++;
} while ((await hasTransactionsForAddress(walletAddress)) && attempts < 15); // Limit the number of attempts
if (attempts === 15) {
throw new Error(
'Unable to find an unused address for the wallet. Please try again later.'
);
}
return address;
}
// Example usage with a specific wallet address:
// generateUnusedBitcoinAddressForWallet(args[0])
// .then((unusedAddress) => {
// console.log(
// `Unused Bitcoin Address for the specific wallet: ${unusedAddress}`
// );
// })
// .catch((error) => {
// console.error('An error occurred:', error.message);
// });
module.exports = generateUnusedBitcoinAddressForWallet;
getWalletTransaction.ts
const axios = require('axios');
require('dotenv').config();
// const args = process.argv.slice(2);
function formatDateTime(dateString:any) {
const dateObject = new Date(dateString);
// Format the date and time components
const year = dateObject.getFullYear();
const month = ('0' + (dateObject.getMonth() + 1)).slice(-2);
const day = ('0' + dateObject.getDate()).slice(-2);
const hours = ('0' + dateObject.getHours()).slice(-2);
const minutes = ('0' + dateObject.getMinutes()).slice(-2);
const seconds = ('0' + dateObject.getSeconds()).slice(-2);
// Create a human-readable date and time string
const formattedDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
return formattedDateTime;
}
async function getWalletTransactions(address:string) {
const apiUrl = `https://api.blockcypher.com/v1/btc/main/addrs/${address}/full?token=${process.env.BITCOIN_NODE_TOKEN}`;
try {
const response = await axios.get(apiUrl);
if (response.data.txs.length === 0) {
throw new Error(`No transactions found for address ${address}`);
}
// Map the transactions
const transactions = response.data.txs.map((tx:any) => {
return {
transactionId: tx.hash,
transactionDate: formatDateTime(tx.received),
transactionAmount:
tx.inputs.reduce(
(sum: any, input: any) => sum + input.output_value,
0
) /
1e8 +
' BTC',
confirmations: tx.confirmations,
};
});
// Log or return the transactions
console.log(transactions);
return transactions;
} catch (error) {
console.error('Error fetching transactions:', error);
throw error;
}
}
// Example usage:
module.exports = getWalletTransactions;
importWallet.ts
const fs = require('fs');
const { BIP32Factory } = require('bip32');
const ecc = require('tiny-secp256k1');
const bip32 = BIP32Factory(ecc);
const bip39 = require('bip39');
const bitcoin = require('bitcoinjs-lib');
const axios = require('axios');
const network = bitcoin.networks.bitcoin;
// console.log(bip39);
const bitPath = `m/44'/0'/0'/0/0`;
// Function to import a wallet from BIP39 mnemonic
function importBIP39Wallet(name:string, mnemonic:string) {
try {
if (!bip39.validateMnemonic(mnemonic)) {
throw new Error('Invalid BIP39 mnemonic provided.');
}
// Derive the HD wallet from the mnemonic
const seed = bip39.mnemonicToSeedSync(mnemonic);
let root = bip32.fromSeed(seed, network);
let account = root.derivePath(bitPath);
let node = account.derive(0).derive(0);
let btcAddress = bitcoin.payments.p2pkh({
pubkey: node.publicKey,
network: network,
}).address;
console.log(`
Wallet imported:
- Name: ${name},
- Address : ${btcAddress},
- Key : ${node.toWIF()},
- Mnemonic : ${mnemonic}
`);
const wallet = { name: name, mnemonic: mnemonic, address: btcAddress };
return wallet;
} catch (error) {
console.error('Error importing wallet:', error);
process.exit(1);
}
}
// Example usage:
// Replace with your actual arguments
module.exports=importBIP39Wallet;
// Function to save the wallet locally
// 1LonwhNoUF6tH3WZGxvr2qeR2WT1o2rA3f
// 1LonwhNoUF6tH3WZGxvr2qeR2WT1o2rA3f
// heart father clog payment rapid clown soda short possible response leopard worth
// Function to load existing wallets
// Get the name and mnemonic for the new wallet from the user
//1NajF482nJ5Hy48DvvbqTk4Kf8tr7k55m5
//1NajF482nJ5Hy48DvvbqTk4Kf8tr7k55m5
listAllWallets.ts
const axios = require('axios');
require('dotenv').config();
const fs = require('fs');
function displayWallets(wallets:any) {
if (wallets.length === 0) {
console.log('No wallets found.');
} else {
console.log('Wallet List:');
wallets.forEach((wallet:any, index:any) => {
console.log(`${index + 1}. ${wallet.name} (${wallet.address})`);
});
}
}
module.exports = displayWallets;
index.ts
#! /usr/bin/env node
const axios = require('axios');
const { Command } = require('commander'); // add this line
const figlet = require('figlet');
const fs = require('fs');
const path = require('path');
require('dotenv').config();
const createBIP39Wallet = require('./api/createWallet');
const displayWallets = require('./api/listAllWallets');
const importBIP39Wallet = require('./api/importWallet');
const getBitcoinBalance = require('./api/fetchBalance');
const getWalletTransactions = require('./api/getWalletTransaction');
const generateUnusedBitcoinAddressForWallet = require('./api/getUnusedBitcoinAddress');
const program = new Command();
console.log(figlet.textSync('Directory Manager'));
program
.version('1.0.0')
.description('An example CLI for managing a directory')
.option('-l, --ls [value]', 'List directory contents')
.option('-m, --mkdir <value>', 'Create a directory')
.option('-t, --touch <value>', 'Create a file')
.parse(process.argv);
program
.command('create <walletName>')
.description('Generate a BIP39 wallet ')
.action((walletName: string) => {
// Your custom command logic here
console.log('Executing create wallet command...');
const newWallet = createBIP39Wallet(walletName);
saveNewWallet(newWallet);
});
program
.command('import <walletName> <mnemonic>')
.description('Generate a BIP39 wallet from BIP39 Mnemonic')
.action((name: string, mnemonic: string) => {
// Your custom command logic here
console.log('Executing import wallet command...');
console.log(name, mnemonic);
const importedWallet = importBIP39Wallet(name, mnemonic);
saveWallet(importedWallet);
});
program
.command('list')
.description('List all wallets')
.action(() => {
// Your custom command logic here
console.log('Executing Wallet list command...');
const wallets = loadWallets();
// Display the list of wallets
displayWallets(wallets);
});
// Get bitcoin balance of a wallet
program
.command('balance <walletAddress>')
.description('Get the bitcoin balance of a wallet')
.action((walletAddress: string) => {
// Your custom command logic here
console.log('Executing wallet balance command...');
getBitcoinBalance(walletAddress);
});
// Get bitcoin transactions of a wallet
program
.command('transactions <walletAddress>')
.description('Get the bitcoin transactions of a wallet')
.action((walletAddress: string) => {
// Your custom command logic here
console.log('Executing transaction command...');
getWalletTransactions(walletAddress)
.then((transactions:any) => {
// Handle the transactions as needed
console.log('Processed transactions:', transactions);
})
.catch((error:any) => {
// Handle errors
console.error('An error occurred:', error);
});
});
// Generate an unused bitcoin address for a wallet
program
.command('generate <walletAddress>')
.description('Generate an unused bitcoin address for a wallet')
.action((walletAddress: string) => {
// Your custom command logic here
console.log('Executing generate command...');
generateUnusedBitcoinAddressForWallet(walletAddress)
.then((unusedAddress:string) => {
console.log(
`Unused Bitcoin Address for the wallet: ${unusedAddress}`
);
})
.catch((error:any) => {
console.error('An error occurred:', error);
});
});
program.parse(process.argv);
const options = program.opts();
async function listDirContents(filepath: string) {
try {
const files = await fs.promises.readdir(filepath);
const detailedFilesPromises = files.map(async (file: string) => {
let fileDetails = await fs.promises.lstat(path.resolve(filepath, file));
const { size, birthtime } = fileDetails;
return { filename: file, 'size(KB)': size, created_at: birthtime };
});
const detailedFiles = await Promise.all(detailedFilesPromises);
console.table(detailedFiles);
} catch (error) {
console.error('Error occurred while reading the directory!', error);
}
}
function createDir(filepath: string) {
if (!fs.existsSync(filepath)) {
fs.mkdirSync(filepath);
console.log('The directory has been created successfully');
}
}
function createFile(filepath: string) {
fs.openSync(filepath, 'w');
console.log('An empty file has been created');
}
if (options.ls) {
const filepath = typeof options.ls === 'string' ? options.ls : __dirname;
listDirContents(filepath);
}
if (options.mkdir) {
createDir(path.resolve(__dirname, options.mkdir));
}
if (options.touch) {
createFile(path.resolve(__dirname, options.touch));
}
if (!process.argv.slice(2).length) {
program.outputHelp();
}
function loadWallets() {
try {
const data = fs.readFileSync('wallets.json');
return JSON.parse(data);
} catch (error) {
return [];
}
}
function saveWallet(wallet: any) {
const wallets = loadWallets();
// Check if the wallet is already present
const isWalletAlreadyPresent = wallets.some(
(w: any) => w.address === wallet.address
);
console.log(isWalletAlreadyPresent);
if (!isWalletAlreadyPresent) {
wallets.push(wallet);
fs.writeFileSync('wallets.json', JSON.stringify(wallets, null, 2));
console.log('Wallet saved successfully.');
} else {
console.log('Wallet already exists in storage, Not saving again.');
}
}
function saveNewWallet(wallet: any) {
const wallets = loadWallets();
wallets.push(wallet);
fs.writeFileSync('wallets.json', JSON.stringify(wallets, null, 2));
}
package-lock.json
{
"name": "directory_manager",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "directory_manager",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"axios": "^1.6.2",
"bip32": "^4.0.0",
"bip39": "^3.1.0",
"bip44": "^0.0.1",
"bitcoind-rpc": "^0.9.1",
"bitcoinjs-lib": "^6.1.5",
"commander": "^11.1.0",
"dotenv": "^16.3.1",
"ecpair": "^2.1.0",
"figlet": "^1.7.0",
"tiny-secp256k1": "^2.2.3"
},
"bin": {
"dirmanager": "dist/index.js"
},
"devDependencies": {
"@types/node": "^20.10.3",
"typescript": "^5.3.2"
}
},
"node_modules/@noble/hashes": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz",
"integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==",
"engines": {
"node": ">= 16"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@scure/base": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.3.tgz",
"integrity": "sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==",
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@types/node": {
"version": "20.10.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.3.tgz",
"integrity": "sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==",
"dev": true,
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz",
"integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/base-x": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz",
"integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw=="
},
"node_modules/bech32": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz",
"integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg=="
},
"node_modules/bip174": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/bip174/-/bip174-2.1.1.tgz",
"integrity": "sha512-mdFV5+/v0XyNYXjBS6CQPLo9ekCx4gtKZFnJm5PMto7Fs9hTTDpkkzOB7/FtluRI6JbUUAu+snTYfJRgHLZbZQ==",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bip32": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/bip32/-/bip32-4.0.0.tgz",
"integrity": "sha512-aOGy88DDlVUhspIXJN+dVEtclhIsfAUppD43V0j40cPTld3pv/0X/MlrZSZ6jowIaQQzFwP8M6rFU2z2mVYjDQ==",
"dependencies": {
"@noble/hashes": "^1.2.0",
"@scure/base": "^1.1.1",
"typeforce": "^1.11.5",
"wif": "^2.0.6"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/bip39": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz",
"integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==",
"dependencies": {
"@noble/hashes": "^1.2.0"
}
},
"node_modules/bip44": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/bip44/-/bip44-0.0.1.tgz",
"integrity": "sha512-pDrapZGhwn+ro3aGw24ShQjhmvoNWS2WdsQub6WqVA1kG5HJhcJk3bsMHemDC2BN2u+NUsQ4cIoeS7qZJ/LsRw=="
},
"node_modules/bitcoind-rpc": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/bitcoind-rpc/-/bitcoind-rpc-0.9.1.tgz",
"integrity": "sha512-fWjepYe3I6W8pw8WiDUrHAMKZXyRqtm6HfcUaDeLAQLr1KoKcVzqR4xzdJFJgUMBShNmN4GRMg0rLFr6ZKGZ6A=="
},
"node_modules/bitcoinjs-lib": {
"version": "6.1.5",
"resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-6.1.5.tgz",
"integrity": "sha512-yuf6xs9QX/E8LWE2aMJPNd0IxGofwfuVOiYdNUESkc+2bHHVKjhJd8qewqapeoolh9fihzHGoDCB5Vkr57RZCQ==",
"dependencies": {
"@noble/hashes": "^1.2.0",
"bech32": "^2.0.0",
"bip174": "^2.1.1",
"bs58check": "^3.0.1",
"typeforce": "^1.11.3",
"varuint-bitcoin": "^1.1.2"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bs58": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz",
"integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==",
"dependencies": {
"base-x": "^4.0.0"
}
},
"node_modules/bs58check": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/bs58check/-/bs58check-3.0.1.tgz",
"integrity": "sha512-hjuuJvoWEybo7Hn/0xOrczQKKEKD63WguEjlhLExYs2wUBcebDC1jDNK17eEAD2lYfw82d5ASC1d7K3SWszjaQ==",
"dependencies": {
"@noble/hashes": "^1.2.0",
"bs58": "^5.0.0"
}
},
"node_modules/cipher-base": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
"integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
"dependencies": {
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
"engines": {
"node": ">=16"
}
},
"node_modules/create-hash": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"dependencies": {
"cipher-base": "^1.0.1",
"inherits": "^2.0.1",
"md5.js": "^1.3.4",
"ripemd160": "^2.0.1",
"sha.js": "^2.4.0"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/dotenv": {
"version": "16.3.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
"integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/motdotla/dotenv?sponsor=1"
}
},
"node_modules/ecpair": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/ecpair/-/ecpair-2.1.0.tgz",
"integrity": "sha512-cL/mh3MtJutFOvFc27GPZE2pWL3a3k4YvzUWEOvilnfZVlH3Jwgx/7d6tlD7/75tNk8TG2m+7Kgtz0SI1tWcqw==",
"dependencies": {
"randombytes": "^2.1.0",
"typeforce": "^1.18.0",
"wif": "^2.0.6"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/figlet": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/figlet/-/figlet-1.7.0.tgz",
"integrity": "sha512-gO8l3wvqo0V7wEFLXPbkX83b7MVjRrk1oRLfYlZXol8nEpb/ON9pcKLI4qpBv5YtOTfrINtqb7b40iYY2FTWFg==",
"bin": {
"figlet": "bin/index.js"
},
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/follow-redirects": {
"version": "1.15.3",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
"integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/hash-base": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
"integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
"dependencies": {
"inherits": "^2.0.4",
"readable-stream": "^3.6.0",
"safe-buffer": "^5.2.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
"integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
"dependencies": {
"hash-base": "^3.0.0",
"inherits": "^2.0.1",
"safe-buffer": "^5.1.2"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dependencies": {
"safe-buffer": "^5.1.0"
}
},
"node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/ripemd160": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
"integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
"dependencies": {
"hash-base": "^3.0.0",
"inherits": "^2.0.1"
}
},
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/sha.js": {
"version": "2.4.11",
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"dependencies": {
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
},
"bin": {
"sha.js": "bin.js"
}
},
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dependencies": {
"safe-buffer": "~5.2.0"
}
},
"node_modules/tiny-secp256k1": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-2.2.3.tgz",
"integrity": "sha512-SGcL07SxcPN2nGKHTCvRMkQLYPSoeFcvArUSCYtjVARiFAWU44cCIqYS0mYAU6nY7XfvwURuTIGo2Omt3ZQr0Q==",
"dependencies": {
"uint8array-tools": "0.0.7"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/typeforce": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz",
"integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g=="
},
"node_modules/typescript": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz",
"integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/uint8array-tools": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/uint8array-tools/-/uint8array-tools-0.0.7.tgz",
"integrity": "sha512-vrrNZJiusLWoFWBqz5Y5KMCgP9W9hnjZHzZiZRT8oNAkq3d5Z5Oe76jAvVVSRh4U8GGR90N2X1dWtrhvx6L8UQ==",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"dev": true
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/varuint-bitcoin": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz",
"integrity": "sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw==",
"dependencies": {
"safe-buffer": "^5.1.1"
}
},
"node_modules/wif": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz",
"integrity": "sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ==",
"dependencies": {
"bs58check": "<3.0.0"
}
},
"node_modules/wif/node_modules/base-x": {
"version": "3.0.9",
"resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz",
"integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==",
"dependencies": {
"safe-buffer": "^5.0.1"
}
},
"node_modules/wif/node_modules/bs58": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
"integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==",
"dependencies": {
"base-x": "^3.0.2"
}
},
"node_modules/wif/node_modules/bs58check": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
"integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
"dependencies": {
"bs58": "^4.0.0",
"create-hash": "^1.1.0",
"safe-buffer": "^5.1.2"
}
}
}
}
package.json
{
"name": "directory_manager",
"version": "1.0.0",
"description": "",
"main": "dist/index.js",
"bin": {
"dirmanager": "./dist/index.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "npx tsc"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^1.6.2",
"bip32": "^4.0.0",
"bip39": "^3.1.0",
"bip44": "^0.0.1",
"bitcoind-rpc": "^0.9.1",
"bitcoinjs-lib": "^6.1.5",
"commander": "^11.1.0",
"dotenv": "^16.3.1",
"ecpair": "^2.1.0",
"figlet": "^1.7.0",
"tiny-secp256k1": "^2.2.3"
},
"devDependencies": {
"@types/node": "^20.10.3",
"typescript": "^5.3.2"
}
}
tsconfig.json
{
"compilerOptions": {
"rootDir": "src",
"outDir": "dist",
"strict": true,
"target": "es6",
"module": "commonjs",
"sourceMap": true,
"esModuleInterop": true,
"moduleResolution": "node",
"moduleDetection": "force"
},
}
原文来自:TokenPocket社区