@btc-vision/cli 1.0.8 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { confirm, input } from '@inquirer/prompts';
2
2
  import { BaseCommand } from './BaseCommand.js';
3
- import { getPackage, getRegistryContract, getVersion, isVersionImmutable, } from '../lib/registry.js';
3
+ import { getPackage, getRegistryContract, getVersion, isVersionImmutable } from '../lib/registry.js';
4
4
  import { canSign, loadCredentials } from '../lib/credentials.js';
5
5
  import { CLIWallet } from '../lib/wallet.js';
6
6
  import { buildTransactionParams, checkBalance, formatSats, getWalletAddress, } from '../lib/transaction.js';
@@ -3,7 +3,7 @@ import { confirm } from '@inquirer/prompts';
3
3
  import { Logger } from '@btc-vision/logger';
4
4
  import { CLIWallet } from '../lib/wallet.js';
5
5
  import { canSign, loadCredentials } from '../lib/credentials.js';
6
- import { getContenthash, getContenthashTypeName, getDomain, getDomainPrice, getResolverContract, getTreasuryAddress, parseDomainName, validateDomainName, } from '../lib/resolver.js';
6
+ import { getResolverContract, getDomain, getContenthash, getContenthashTypeName, validateDomainName, getTreasuryAddress, getDomainPrice, parseDomainName, } from '../lib/resolver.js';
7
7
  import { buildTransactionParams, checkBalance, DEFAULT_FEE_RATE, DEFAULT_MAX_SAT_TO_SPEND, formatSats, getWalletAddress, waitForTransactionConfirmation, } from '../lib/transaction.js';
8
8
  import { TransactionOutputFlags } from 'opnet';
9
9
  const logger = new Logger();
@@ -67,7 +67,6 @@ async function registerDomain(domain, options) {
67
67
  logger.log(`Treasury: ${treasuryAddr}`);
68
68
  logger.log(`Network: ${network}`);
69
69
  logger.log(`Your wallet: ${wallet.p2trAddress}`);
70
- logger.log(`MLDSA Public Key Hash: ${wallet.address.toHex()}`);
71
70
  logger.log('');
72
71
  if (options.dryRun) {
73
72
  logger.warn('Dry run - no changes made.');
@@ -223,7 +222,8 @@ async function domainInfo(domain, options) {
223
222
  process.exit(1);
224
223
  }
225
224
  }
226
- const domainCommand = new Command('domain').description('Manage .btc domains');
225
+ const domainCommand = new Command('domain')
226
+ .description('Manage .btc domains');
227
227
  domainCommand
228
228
  .command('register')
229
229
  .description('Register a new .btc domain')
@@ -3,5 +3,7 @@ export declare class InstallCommand extends BaseCommand {
3
3
  constructor();
4
4
  protected configure(): void;
5
5
  private execute;
6
+ private removeOldVersions;
7
+ private escapeRegex;
6
8
  }
7
9
  export declare const installCommand: import("commander").Command;
@@ -106,8 +106,10 @@ export class InstallCommand extends BaseCommand {
106
106
  }
107
107
  const outputDir = options?.output || path.join(process.cwd(), 'plugins');
108
108
  fs.mkdirSync(outputDir, { recursive: true });
109
- const fileName = `${packageName.replace(/^@/, '').replace(/\//g, '-')}-${version}.opnet`;
109
+ const packageBaseName = packageName.replace(/^@/, '').replace(/\//g, '-');
110
+ const fileName = `${packageBaseName}-${version}.opnet`;
110
111
  const outputPath = path.join(outputDir, fileName);
112
+ this.removeOldVersions(outputDir, packageBaseName, version);
111
113
  this.logger.info('Saving plugin...');
112
114
  fs.writeFileSync(outputPath, result.data);
113
115
  this.logger.success('Plugin installed');
@@ -126,5 +128,31 @@ export class InstallCommand extends BaseCommand {
126
128
  this.exitWithError(this.formatError(error));
127
129
  }
128
130
  }
131
+ removeOldVersions(outputDir, packageBaseName, newVersion) {
132
+ try {
133
+ const entries = fs.readdirSync(outputDir, { withFileTypes: true });
134
+ for (const entry of entries) {
135
+ if (!entry.isFile() || !entry.name.endsWith('.opnet')) {
136
+ continue;
137
+ }
138
+ const pattern = new RegExp(`^${this.escapeRegex(packageBaseName)}-(.+)\\.opnet$`);
139
+ const match = entry.name.match(pattern);
140
+ if (match) {
141
+ const oldVersion = match[1];
142
+ if (oldVersion !== newVersion) {
143
+ const oldFilePath = path.join(outputDir, entry.name);
144
+ this.logger.info(`Removing old version: ${entry.name}`);
145
+ fs.unlinkSync(oldFilePath);
146
+ }
147
+ }
148
+ }
149
+ }
150
+ catch (error) {
151
+ this.logger.warn(`Could not clean up old versions: ${this.formatError(error)}`);
152
+ }
153
+ }
154
+ escapeRegex(str) {
155
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
156
+ }
129
157
  }
130
158
  export const installCommand = new InstallCommand().getCommand();
@@ -76,9 +76,9 @@ export class LoginCommand extends BaseCommand {
76
76
  network: options.network,
77
77
  };
78
78
  }
79
- return this.interactiveLogin(options.network, mldsaLevel);
79
+ return this.interactiveLogin(options.network);
80
80
  }
81
- async interactiveLogin(defaultNetwork, defaultLevel) {
81
+ async interactiveLogin(defaultNetwork) {
82
82
  this.logger.info('OPNet Wallet Configuration\n');
83
83
  const loginMethod = await select({
84
84
  message: 'How would you like to authenticate?',
@@ -104,27 +104,8 @@ export class LoginCommand extends BaseCommand {
104
104
  ],
105
105
  default: defaultNetwork,
106
106
  }));
107
- const selectedLevel = (await select({
108
- message: 'Select MLDSA security level:',
109
- choices: [
110
- {
111
- name: 'MLDSA-44 (Level 2, fastest)',
112
- value: 44,
113
- description: '1312 byte public key',
114
- },
115
- {
116
- name: 'MLDSA-65 (Level 3, balanced)',
117
- value: 65,
118
- description: '1952 byte public key',
119
- },
120
- {
121
- name: 'MLDSA-87 (Level 5, most secure)',
122
- value: 87,
123
- description: '2592 byte public key',
124
- },
125
- ],
126
- default: defaultLevel,
127
- }));
107
+ const selectedLevel = 44;
108
+ this.logger.info('Using MLDSA-44 (only supported level on OPNet)');
128
109
  if (loginMethod === 'mnemonic') {
129
110
  const mnemonic = await password({
130
111
  message: 'Enter your mnemonic phrase (12 or 24 words):',
@@ -1,6 +1,6 @@
1
1
  import { confirm } from '@inquirer/prompts';
2
2
  import { BaseCommand } from './BaseCommand.js';
3
- import { getPackage, getRegistryContract, getVersion, isVersionImmutable, } from '../lib/registry.js';
3
+ import { getPackage, getRegistryContract, getVersion, isVersionImmutable } from '../lib/registry.js';
4
4
  import { canSign, loadCredentials } from '../lib/credentials.js';
5
5
  import { CLIWallet } from '../lib/wallet.js';
6
6
  import { buildTransactionParams, checkBalance, formatSats, getWalletAddress, } from '../lib/transaction.js';
@@ -6,7 +6,7 @@ import { CLIWallet } from '../lib/wallet.js';
6
6
  import { canSign, loadCredentials } from '../lib/credentials.js';
7
7
  import { uploadDirectory, uploadFile } from '../lib/ipfs.js';
8
8
  import { formatFileSize } from '../lib/binary.js';
9
- import { getContenthash, getContenthashTypeName, getDomain, getResolverContract, getSubdomain, isSubdomain, parseDomainName, } from '../lib/resolver.js';
9
+ import { getResolverContract, getDomain, getSubdomain, getContenthash, getContenthashTypeName, isSubdomain, parseDomainName, } from '../lib/resolver.js';
10
10
  import { buildTransactionParams, checkBalance, DEFAULT_FEE_RATE, DEFAULT_MAX_SAT_TO_SPEND, formatSats, getWalletAddress, waitForTransactionConfirmation, } from '../lib/transaction.js';
11
11
  export class WebsiteDeployCommand extends BaseCommand {
12
12
  constructor() {
@@ -17,7 +17,7 @@ export class WebsiteDeployCommand extends BaseCommand {
17
17
  .argument('<domain>', 'Domain name (e.g., mysite or mysite.btc)')
18
18
  .argument('<path>', 'Path to website directory or HTML file')
19
19
  .option('-n, --network <network>', 'Network to use', 'mainnet')
20
- .option('--dry-run', "Upload to IPFS but don't update on-chain")
20
+ .option('--dry-run', 'Upload to IPFS but don\'t update on-chain')
21
21
  .option('-y, --yes', 'Skip confirmation prompts')
22
22
  .action((domain, websitePath, options) => this.execute(domain, websitePath, options || { network: 'mainnet' }));
23
23
  }
@@ -84,7 +84,7 @@ export class WebsiteDeployCommand extends BaseCommand {
84
84
  if (wallet.address.toHex() !== ownerAddress) {
85
85
  this.logger.fail('You are not the owner of this domain');
86
86
  this.logger.log(`Domain owner: ${ownerAddress}`);
87
- this.logger.log(`Your address: ${wallet.p2trAddress}`);
87
+ this.logger.log(`Your address: ${wallet.address.toHex()}`);
88
88
  process.exit(1);
89
89
  }
90
90
  this.logger.success('Ownership verified');
@@ -2,7 +2,7 @@ import { confirm } from '@inquirer/prompts';
2
2
  import { BaseCommand } from './BaseCommand.js';
3
3
  import { CLIWallet } from '../lib/wallet.js';
4
4
  import { canSign, loadCredentials } from '../lib/credentials.js';
5
- import { detectContenthashType, getContenthash, getContenthashTypeName, getDomain, getResolverContract, getSubdomain, isSubdomain, parseDomainName, validateCIDv0, validateCIDv1, validateIPNS, } from '../lib/resolver.js';
5
+ import { getResolverContract, getDomain, getSubdomain, getContenthash, detectContenthashType, validateCIDv0, validateCIDv1, validateIPNS, getContenthashTypeName, isSubdomain, parseDomainName, } from '../lib/resolver.js';
6
6
  import { buildTransactionParams, checkBalance, DEFAULT_FEE_RATE, DEFAULT_MAX_SAT_TO_SPEND, formatSats, getWalletAddress, waitForTransactionConfirmation, } from '../lib/transaction.js';
7
7
  import { CONTENTHASH_TYPE_CIDv0, CONTENTHASH_TYPE_CIDv1, CONTENTHASH_TYPE_IPNS, CONTENTHASH_TYPE_SHA256, } from '../types/BtcResolver.js';
8
8
  export class WebsitePublishCommand extends BaseCommand {
@@ -110,8 +110,7 @@ export class WebsitePublishCommand extends BaseCommand {
110
110
  if (wallet.address.toHex() !== ownerAddress) {
111
111
  this.logger.fail('You are not the owner of this domain');
112
112
  this.logger.log(`Domain owner: ${ownerAddress}`);
113
- this.logger.log(`Your address: ${wallet.p2trAddress}`);
114
- this.logger.log(`MLDSA Public Key Hash: ${wallet.address.toHex()}`);
113
+ this.logger.log(`Your address: ${wallet.address.toHex()}`);
115
114
  process.exit(1);
116
115
  }
117
116
  this.logger.success('Ownership verified');
package/build/lib/ipfs.js CHANGED
@@ -23,13 +23,17 @@ async function httpRequest(url, options, redirectCount = 0) {
23
23
  };
24
24
  const req = lib.request(reqOptions, (res) => {
25
25
  const statusCode = res.statusCode ?? 0;
26
- if (followRedirect && statusCode >= 300 && statusCode < 400 && res.headers.location) {
27
- const redirectUrl = new URL(res.headers.location, url).href;
28
- res.resume();
29
- httpRequest(redirectUrl, options, redirectCount + 1)
30
- .then(resolve)
31
- .catch(reject);
32
- return;
26
+ if (followRedirect && statusCode >= 300 && statusCode < 400) {
27
+ const locationHeader = res.headers.location || res.headers['Location'];
28
+ const location = Array.isArray(locationHeader) ? locationHeader[0] : locationHeader;
29
+ if (location) {
30
+ const redirectUrl = new URL(location, url).href;
31
+ res.resume();
32
+ httpRequest(redirectUrl, options, redirectCount + 1)
33
+ .then(resolve)
34
+ .catch(reject);
35
+ return;
36
+ }
33
37
  }
34
38
  const chunks = [];
35
39
  res.on('data', (chunk) => {
@@ -37,6 +41,17 @@ async function httpRequest(url, options, redirectCount = 0) {
37
41
  });
38
42
  res.on('end', () => {
39
43
  const body = Buffer.concat(chunks);
44
+ if (followRedirect && statusCode >= 300 && statusCode < 400) {
45
+ const bodyStr = body.toString();
46
+ const hrefMatch = bodyStr.match(/href="([^"]+)"/);
47
+ if (hrefMatch && hrefMatch[1]) {
48
+ const redirectUrl = new URL(hrefMatch[1], url).href;
49
+ httpRequest(redirectUrl, options, redirectCount + 1)
50
+ .then(resolve)
51
+ .catch(reject);
52
+ return;
53
+ }
54
+ }
40
55
  if (statusCode >= 200 && statusCode < 300) {
41
56
  resolve(body);
42
57
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@btc-vision/cli",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "type": "module",
5
5
  "description": "CLI for the OPNet plugin ecosystem - scaffolding, compilation, signing, and registry interaction",
6
6
  "author": "OP_NET",