@btc-vision/cli 1.0.0

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.
Files changed (110) hide show
  1. package/.gitattributes +2 -0
  2. package/.github/dependabot.yml +9 -0
  3. package/.github/workflows/ci.yml +48 -0
  4. package/.prettierrc.json +12 -0
  5. package/CONTRIBUTING.md +56 -0
  6. package/LICENSE +190 -0
  7. package/NOTICE +17 -0
  8. package/README.md +509 -0
  9. package/SECURITY.md +35 -0
  10. package/build/commands/AcceptCommand.d.ts +7 -0
  11. package/build/commands/AcceptCommand.js +110 -0
  12. package/build/commands/BaseCommand.d.ts +12 -0
  13. package/build/commands/BaseCommand.js +27 -0
  14. package/build/commands/CompileCommand.d.ts +7 -0
  15. package/build/commands/CompileCommand.js +138 -0
  16. package/build/commands/ConfigCommand.d.ts +17 -0
  17. package/build/commands/ConfigCommand.js +124 -0
  18. package/build/commands/DeprecateCommand.d.ts +7 -0
  19. package/build/commands/DeprecateCommand.js +112 -0
  20. package/build/commands/InfoCommand.d.ts +10 -0
  21. package/build/commands/InfoCommand.js +223 -0
  22. package/build/commands/InitCommand.d.ts +16 -0
  23. package/build/commands/InitCommand.js +336 -0
  24. package/build/commands/InstallCommand.d.ts +7 -0
  25. package/build/commands/InstallCommand.js +130 -0
  26. package/build/commands/KeygenCommand.d.ts +13 -0
  27. package/build/commands/KeygenCommand.js +133 -0
  28. package/build/commands/ListCommand.d.ts +7 -0
  29. package/build/commands/ListCommand.js +117 -0
  30. package/build/commands/LoginCommand.d.ts +9 -0
  31. package/build/commands/LoginCommand.js +139 -0
  32. package/build/commands/LogoutCommand.d.ts +7 -0
  33. package/build/commands/LogoutCommand.js +57 -0
  34. package/build/commands/PublishCommand.d.ts +7 -0
  35. package/build/commands/PublishCommand.js +163 -0
  36. package/build/commands/SearchCommand.d.ts +7 -0
  37. package/build/commands/SearchCommand.js +97 -0
  38. package/build/commands/SignCommand.d.ts +7 -0
  39. package/build/commands/SignCommand.js +80 -0
  40. package/build/commands/TransferCommand.d.ts +8 -0
  41. package/build/commands/TransferCommand.js +179 -0
  42. package/build/commands/UndeprecateCommand.d.ts +7 -0
  43. package/build/commands/UndeprecateCommand.js +95 -0
  44. package/build/commands/UpdateCommand.d.ts +7 -0
  45. package/build/commands/UpdateCommand.js +130 -0
  46. package/build/commands/VerifyCommand.d.ts +7 -0
  47. package/build/commands/VerifyCommand.js +167 -0
  48. package/build/commands/WhoamiCommand.d.ts +7 -0
  49. package/build/commands/WhoamiCommand.js +84 -0
  50. package/build/index.d.ts +2 -0
  51. package/build/index.js +64 -0
  52. package/build/lib/PackageRegistry.abi.d.ts +2 -0
  53. package/build/lib/PackageRegistry.abi.js +356 -0
  54. package/build/lib/binary.d.ts +16 -0
  55. package/build/lib/binary.js +165 -0
  56. package/build/lib/config.d.ts +11 -0
  57. package/build/lib/config.js +160 -0
  58. package/build/lib/credentials.d.ts +10 -0
  59. package/build/lib/credentials.js +89 -0
  60. package/build/lib/ipfs.d.ts +16 -0
  61. package/build/lib/ipfs.js +209 -0
  62. package/build/lib/manifest.d.ts +14 -0
  63. package/build/lib/manifest.js +88 -0
  64. package/build/lib/provider.d.ts +9 -0
  65. package/build/lib/provider.js +48 -0
  66. package/build/lib/registry.d.ts +58 -0
  67. package/build/lib/registry.js +197 -0
  68. package/build/lib/wallet.d.ts +32 -0
  69. package/build/lib/wallet.js +114 -0
  70. package/build/types/PackageRegistry.d.ts +177 -0
  71. package/build/types/PackageRegistry.js +1 -0
  72. package/build/types/index.d.ts +30 -0
  73. package/build/types/index.js +52 -0
  74. package/eslint.config.js +41 -0
  75. package/gulpfile.js +41 -0
  76. package/package.json +83 -0
  77. package/src/commands/AcceptCommand.ts +151 -0
  78. package/src/commands/BaseCommand.ts +59 -0
  79. package/src/commands/CompileCommand.ts +196 -0
  80. package/src/commands/ConfigCommand.ts +144 -0
  81. package/src/commands/DeprecateCommand.ts +156 -0
  82. package/src/commands/InfoCommand.ts +293 -0
  83. package/src/commands/InitCommand.ts +465 -0
  84. package/src/commands/InstallCommand.ts +179 -0
  85. package/src/commands/KeygenCommand.ts +157 -0
  86. package/src/commands/ListCommand.ts +169 -0
  87. package/src/commands/LoginCommand.ts +197 -0
  88. package/src/commands/LogoutCommand.ts +76 -0
  89. package/src/commands/PublishCommand.ts +230 -0
  90. package/src/commands/SearchCommand.ts +141 -0
  91. package/src/commands/SignCommand.ts +122 -0
  92. package/src/commands/TransferCommand.ts +235 -0
  93. package/src/commands/UndeprecateCommand.ts +134 -0
  94. package/src/commands/UpdateCommand.ts +200 -0
  95. package/src/commands/VerifyCommand.ts +228 -0
  96. package/src/commands/WhoamiCommand.ts +113 -0
  97. package/src/index.ts +86 -0
  98. package/src/lib/PackageRegistry.abi.json +765 -0
  99. package/src/lib/PackageRegistry.abi.ts +365 -0
  100. package/src/lib/binary.ts +336 -0
  101. package/src/lib/config.ts +265 -0
  102. package/src/lib/credentials.ts +176 -0
  103. package/src/lib/ipfs.ts +369 -0
  104. package/src/lib/manifest.ts +172 -0
  105. package/src/lib/provider.ts +121 -0
  106. package/src/lib/registry.ts +464 -0
  107. package/src/lib/wallet.ts +271 -0
  108. package/src/types/PackageRegistry.ts +344 -0
  109. package/src/types/index.ts +145 -0
  110. package/tsconfig.json +25 -0
@@ -0,0 +1,177 @@
1
+ import { Address } from '@btc-vision/transaction';
2
+ import { CallResult, OPNetEvent, IOP_NETContract } from 'opnet';
3
+ export type TreasuryAddressChangedEvent = {
4
+ readonly previousAddressHash: bigint;
5
+ readonly newAddressHash: bigint;
6
+ readonly timestamp: bigint;
7
+ };
8
+ export type ScopePriceChangedEvent = {
9
+ readonly oldPrice: bigint;
10
+ readonly newPrice: bigint;
11
+ readonly timestamp: bigint;
12
+ };
13
+ export type PackagePriceChangedEvent = {
14
+ readonly oldPrice: bigint;
15
+ readonly newPrice: bigint;
16
+ readonly timestamp: bigint;
17
+ };
18
+ export type ScopeRegisteredEvent = {
19
+ readonly scopeHash: bigint;
20
+ readonly owner: Address;
21
+ readonly timestamp: bigint;
22
+ };
23
+ export type ScopeTransferInitiatedEvent = {
24
+ readonly scopeHash: bigint;
25
+ readonly currentOwner: Address;
26
+ readonly newOwner: Address;
27
+ readonly timestamp: bigint;
28
+ };
29
+ export type ScopeTransferCompletedEvent = {
30
+ readonly scopeHash: bigint;
31
+ readonly previousOwner: Address;
32
+ readonly newOwner: Address;
33
+ readonly timestamp: bigint;
34
+ };
35
+ export type ScopeTransferCancelledEvent = {
36
+ readonly scopeHash: bigint;
37
+ readonly owner: Address;
38
+ readonly timestamp: bigint;
39
+ };
40
+ export type PackageRegisteredEvent = {
41
+ readonly packageHash: bigint;
42
+ readonly owner: Address;
43
+ readonly timestamp: bigint;
44
+ };
45
+ export type VersionPublishedEvent = {
46
+ readonly packageHash: bigint;
47
+ readonly versionHash: bigint;
48
+ readonly publisher: Address;
49
+ readonly checksum: bigint;
50
+ readonly timestamp: bigint;
51
+ readonly mldsaLevel: number;
52
+ readonly pluginType: number;
53
+ };
54
+ export type VersionDeprecatedEvent = {
55
+ readonly packageHash: bigint;
56
+ readonly versionHash: bigint;
57
+ readonly timestamp: bigint;
58
+ };
59
+ export type VersionUndeprecatedEvent = {
60
+ readonly packageHash: bigint;
61
+ readonly versionHash: bigint;
62
+ readonly timestamp: bigint;
63
+ };
64
+ export type PackageTransferInitiatedEvent = {
65
+ readonly packageHash: bigint;
66
+ readonly currentOwner: Address;
67
+ readonly newOwner: Address;
68
+ readonly timestamp: bigint;
69
+ };
70
+ export type PackageTransferCompletedEvent = {
71
+ readonly packageHash: bigint;
72
+ readonly previousOwner: Address;
73
+ readonly newOwner: Address;
74
+ readonly timestamp: bigint;
75
+ };
76
+ export type PackageTransferCancelledEvent = {
77
+ readonly packageHash: bigint;
78
+ readonly owner: Address;
79
+ readonly timestamp: bigint;
80
+ };
81
+ export type SetTreasuryAddress = CallResult<{}, OPNetEvent<TreasuryAddressChangedEvent>[]>;
82
+ export type SetScopePrice = CallResult<{}, OPNetEvent<ScopePriceChangedEvent>[]>;
83
+ export type SetPackagePrice = CallResult<{}, OPNetEvent<PackagePriceChangedEvent>[]>;
84
+ export type RegisterScope = CallResult<{}, OPNetEvent<ScopeRegisteredEvent>[]>;
85
+ export type InitiateScopeTransfer = CallResult<{}, OPNetEvent<ScopeTransferInitiatedEvent>[]>;
86
+ export type AcceptScopeTransfer = CallResult<{}, OPNetEvent<ScopeTransferCompletedEvent>[]>;
87
+ export type CancelScopeTransfer = CallResult<{}, OPNetEvent<ScopeTransferCancelledEvent>[]>;
88
+ export type RegisterPackage = CallResult<{}, OPNetEvent<PackageRegisteredEvent>[]>;
89
+ export type PublishVersion = CallResult<{}, OPNetEvent<VersionPublishedEvent>[]>;
90
+ export type DeprecateVersion = CallResult<{}, OPNetEvent<VersionDeprecatedEvent>[]>;
91
+ export type UndeprecateVersion = CallResult<{}, OPNetEvent<VersionUndeprecatedEvent>[]>;
92
+ export type InitiateTransfer = CallResult<{}, OPNetEvent<PackageTransferInitiatedEvent>[]>;
93
+ export type AcceptTransfer = CallResult<{}, OPNetEvent<PackageTransferCompletedEvent>[]>;
94
+ export type CancelTransfer = CallResult<{}, OPNetEvent<PackageTransferCancelledEvent>[]>;
95
+ export type GetScope = CallResult<{
96
+ exists: boolean;
97
+ owner: Address;
98
+ createdAt: bigint;
99
+ }, OPNetEvent<never>[]>;
100
+ export type GetScopeOwner = CallResult<{
101
+ owner: Address;
102
+ }, OPNetEvent<never>[]>;
103
+ export type GetPackage = CallResult<{
104
+ exists: boolean;
105
+ owner: Address;
106
+ createdAt: bigint;
107
+ versionCount: bigint;
108
+ latestVersion: string;
109
+ }, OPNetEvent<never>[]>;
110
+ export type GetOwner = CallResult<{
111
+ owner: Address;
112
+ }, OPNetEvent<never>[]>;
113
+ export type GetVersion = CallResult<{
114
+ exists: boolean;
115
+ ipfsCid: string;
116
+ checksum: Uint8Array;
117
+ sigHash: Uint8Array;
118
+ mldsaLevel: number;
119
+ opnetVersionRange: string;
120
+ pluginType: number;
121
+ permissionsHash: Uint8Array;
122
+ depsHash: Uint8Array;
123
+ publisher: Address;
124
+ publishedAt: bigint;
125
+ deprecated: boolean;
126
+ }, OPNetEvent<never>[]>;
127
+ export type IsDeprecated = CallResult<{
128
+ deprecated: boolean;
129
+ }, OPNetEvent<never>[]>;
130
+ export type IsImmutable = CallResult<{
131
+ immutable: boolean;
132
+ }, OPNetEvent<never>[]>;
133
+ export type GetPendingTransfer = CallResult<{
134
+ pendingOwner: Address;
135
+ initiatedAt: bigint;
136
+ }, OPNetEvent<never>[]>;
137
+ export type GetPendingScopeTransfer = CallResult<{
138
+ pendingOwner: Address;
139
+ initiatedAt: bigint;
140
+ }, OPNetEvent<never>[]>;
141
+ export type GetTreasuryAddress = CallResult<{
142
+ treasuryAddress: string;
143
+ }, OPNetEvent<never>[]>;
144
+ export type GetScopePrice = CallResult<{
145
+ priceSats: bigint;
146
+ }, OPNetEvent<never>[]>;
147
+ export type GetPackagePrice = CallResult<{
148
+ priceSats: bigint;
149
+ }, OPNetEvent<never>[]>;
150
+ export interface IPackageRegistry extends IOP_NETContract {
151
+ setTreasuryAddress(treasuryAddress: string): Promise<SetTreasuryAddress>;
152
+ setScopePrice(priceSats: bigint): Promise<SetScopePrice>;
153
+ setPackagePrice(priceSats: bigint): Promise<SetPackagePrice>;
154
+ registerScope(scopeName: string): Promise<RegisterScope>;
155
+ initiateScopeTransfer(scopeName: string, newOwner: Address): Promise<InitiateScopeTransfer>;
156
+ acceptScopeTransfer(scopeName: string): Promise<AcceptScopeTransfer>;
157
+ cancelScopeTransfer(scopeName: string): Promise<CancelScopeTransfer>;
158
+ registerPackage(packageName: string): Promise<RegisterPackage>;
159
+ publishVersion(packageName: string, version: string, ipfsCid: string, checksum: Uint8Array, signature: Uint8Array, mldsaLevel: number, opnetVersionRange: string, pluginType: number, permissionsHash: Uint8Array, dependencies: Uint8Array): Promise<PublishVersion>;
160
+ deprecateVersion(packageName: string, version: string, reason: string): Promise<DeprecateVersion>;
161
+ undeprecateVersion(packageName: string, version: string): Promise<UndeprecateVersion>;
162
+ initiateTransfer(packageName: string, newOwner: Address): Promise<InitiateTransfer>;
163
+ acceptTransfer(packageName: string): Promise<AcceptTransfer>;
164
+ cancelTransfer(packageName: string): Promise<CancelTransfer>;
165
+ getScope(scopeName: string): Promise<GetScope>;
166
+ getScopeOwner(scopeName: string): Promise<GetScopeOwner>;
167
+ getPackage(packageName: string): Promise<GetPackage>;
168
+ getOwner(packageName: string): Promise<GetOwner>;
169
+ getVersion(packageName: string, version: string): Promise<GetVersion>;
170
+ isDeprecated(packageName: string, version: string): Promise<IsDeprecated>;
171
+ isImmutable(packageName: string, version: string): Promise<IsImmutable>;
172
+ getPendingTransfer(packageName: string): Promise<GetPendingTransfer>;
173
+ getPendingScopeTransfer(scopeName: string): Promise<GetPendingScopeTransfer>;
174
+ getTreasuryAddress(): Promise<GetTreasuryAddress>;
175
+ getScopePrice(): Promise<GetScopePrice>;
176
+ getPackagePrice(): Promise<GetPackagePrice>;
177
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,30 @@
1
+ import { MLDSALevel } from '@btc-vision/plugin-sdk';
2
+ export type NetworkName = 'mainnet' | 'testnet' | 'regtest';
3
+ export type CLIMldsaLevel = 44 | 65 | 87;
4
+ export interface CLIConfig {
5
+ defaultNetwork: NetworkName;
6
+ rpcUrls: Record<NetworkName, string>;
7
+ ipfsGateway: string;
8
+ ipfsGateways: string[];
9
+ ipfsPinningEndpoint: string;
10
+ ipfsPinningApiKey: string;
11
+ ipfsPinningAuthHeader: string;
12
+ registryAddresses: Record<NetworkName, string>;
13
+ defaultMldsaLevel: CLIMldsaLevel;
14
+ indexerUrl: string;
15
+ }
16
+ export interface CLICredentials {
17
+ mnemonic?: string;
18
+ wif?: string;
19
+ mldsaPrivateKey?: string;
20
+ mldsaLevel: CLIMldsaLevel;
21
+ network: NetworkName;
22
+ }
23
+ export type RegistryPluginType = 'standalone' | 'library';
24
+ export declare function cliLevelToMLDSALevel(level: CLIMldsaLevel): MLDSALevel;
25
+ export declare function mldsaLevelToCLI(level: MLDSALevel): CLIMldsaLevel;
26
+ export declare function registryLevelToCLI(level: number): CLIMldsaLevel;
27
+ export declare function cliLevelToRegistry(level: CLIMldsaLevel): number;
28
+ export declare function getPublicKeySize(level: CLIMldsaLevel): number;
29
+ export declare function getSignatureSize(level: CLIMldsaLevel): number;
30
+ export declare function isValidCLIMldsaLevel(level: number): level is CLIMldsaLevel;
@@ -0,0 +1,52 @@
1
+ import { MLDSALevel, MLDSA_PUBLIC_KEY_SIZES, MLDSA_SIGNATURE_SIZES } from '@btc-vision/plugin-sdk';
2
+ export function cliLevelToMLDSALevel(level) {
3
+ switch (level) {
4
+ case 44:
5
+ return MLDSALevel.MLDSA44;
6
+ case 65:
7
+ return MLDSALevel.MLDSA65;
8
+ case 87:
9
+ return MLDSALevel.MLDSA87;
10
+ }
11
+ }
12
+ export function mldsaLevelToCLI(level) {
13
+ switch (level) {
14
+ case MLDSALevel.MLDSA44:
15
+ return 44;
16
+ case MLDSALevel.MLDSA65:
17
+ return 65;
18
+ case MLDSALevel.MLDSA87:
19
+ return 87;
20
+ }
21
+ }
22
+ export function registryLevelToCLI(level) {
23
+ switch (level) {
24
+ case 1:
25
+ return 44;
26
+ case 2:
27
+ return 65;
28
+ case 3:
29
+ return 87;
30
+ default:
31
+ throw new Error(`Invalid registry MLDSA level: ${level}`);
32
+ }
33
+ }
34
+ export function cliLevelToRegistry(level) {
35
+ switch (level) {
36
+ case 44:
37
+ return 1;
38
+ case 65:
39
+ return 2;
40
+ case 87:
41
+ return 3;
42
+ }
43
+ }
44
+ export function getPublicKeySize(level) {
45
+ return MLDSA_PUBLIC_KEY_SIZES[cliLevelToMLDSALevel(level)];
46
+ }
47
+ export function getSignatureSize(level) {
48
+ return MLDSA_SIGNATURE_SIZES[cliLevelToMLDSALevel(level)];
49
+ }
50
+ export function isValidCLIMldsaLevel(level) {
51
+ return level === 44 || level === 65 || level === 87;
52
+ }
@@ -0,0 +1,41 @@
1
+ // @ts-check
2
+
3
+ import eslint from '@eslint/js';
4
+ import tseslint from 'typescript-eslint';
5
+
6
+ export default tseslint.config(
7
+ eslint.configs.recommended,
8
+ ...tseslint.configs.strictTypeChecked,
9
+ {
10
+ languageOptions: {
11
+ parserOptions: {
12
+ projectService: true,
13
+ tsconfigDirName: import.meta.dirname,
14
+ },
15
+ },
16
+ rules: {
17
+ 'no-undef': 'off',
18
+ '@typescript-eslint/no-unused-vars': 'off',
19
+ 'no-empty': 'off',
20
+ '@typescript-eslint/restrict-template-expressions': 'off',
21
+ '@typescript-eslint/only-throw-error': 'off',
22
+ '@typescript-eslint/no-unnecessary-condition': 'off',
23
+ '@typescript-eslint/unbound-method': 'warn',
24
+ '@typescript-eslint/no-confusing-void-expression': 'off',
25
+ '@typescript-eslint/no-extraneous-class': 'off',
26
+ 'no-async-promise-executor': 'off',
27
+ '@typescript-eslint/no-misused-promises': 'off',
28
+ '@typescript-eslint/no-unnecessary-type-parameters': 'off',
29
+ '@typescript-eslint/no-duplicate-enum-values': 'off',
30
+ 'prefer-spread': 'off',
31
+ '@typescript-eslint/no-empty-object-type': 'off',
32
+ '@typescript-eslint/no-base-to-string': 'off',
33
+ '@typescript-eslint/no-dynamic-delete': 'off',
34
+ '@typescript-eslint/no-redundant-type-constituents': 'off',
35
+ },
36
+ },
37
+ {
38
+ files: ['**/*.js'],
39
+ ...tseslint.configs.disableTypeChecked,
40
+ },
41
+ );
package/gulpfile.js ADDED
@@ -0,0 +1,41 @@
1
+ import gulp from 'gulp';
2
+ import gulpcache from 'gulp-cached';
3
+ import gulpClean from 'gulp-clean';
4
+ import gulpESLintNew from 'gulp-eslint-new';
5
+ import logger from 'gulp-logger-new';
6
+ import ts from 'gulp-typescript';
7
+
8
+ process.on('uncaughtException', function (err) {
9
+ console.log('Caught exception: ', err);
10
+ });
11
+
12
+ const tsProject = ts.createProject('tsconfig.json');
13
+
14
+ function buildESM() {
15
+ return tsProject
16
+ .src()
17
+ .pipe(gulpcache('ts-esm'))
18
+ .pipe(
19
+ logger({
20
+ before: 'Starting...',
21
+ after: 'Project compiled!',
22
+ extname: '.js',
23
+ showChange: true,
24
+ }),
25
+ )
26
+ .pipe(gulpESLintNew())
27
+ .pipe(gulpESLintNew.format())
28
+ .pipe(tsProject())
29
+ .pipe(gulp.dest('build'));
30
+ }
31
+
32
+ export async function clean() {
33
+ return gulp.src('./build', { read: false, allowEmpty: true }).pipe(gulpClean());
34
+ }
35
+
36
+ export const build = buildESM;
37
+ export default build;
38
+
39
+ export function watch() {
40
+ gulp.watch(['src/**/*.ts'], gulp.series(buildESM));
41
+ }
package/package.json ADDED
@@ -0,0 +1,83 @@
1
+ {
2
+ "name": "@btc-vision/cli",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "CLI for the OPNet plugin ecosystem - scaffolding, compilation, signing, and registry interaction",
6
+ "author": "OP_NET",
7
+ "license": "Apache-2.0",
8
+ "homepage": "https://opnet.org",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git://github.com/btc-vision/opnet-cli.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/btc-vision/opnet-cli/issues"
15
+ },
16
+ "engines": {
17
+ "node": ">=20.0.0"
18
+ },
19
+ "bin": {
20
+ "opnet": "./build/index.js"
21
+ },
22
+ "exports": {
23
+ ".": {
24
+ "import": "./build/index.js",
25
+ "require": "./build/index.js",
26
+ "types": "./build/index.d.ts"
27
+ }
28
+ },
29
+ "main": "build/index.js",
30
+ "types": "build/index.d.ts",
31
+ "typings": "build/index.d.ts",
32
+ "module": "build/index.js",
33
+ "publishConfig": {
34
+ "access": "public",
35
+ "tag": "latest"
36
+ },
37
+ "scripts": {
38
+ "build": "gulp build",
39
+ "watch": "gulp watch",
40
+ "clean": "gulp clean",
41
+ "lint": "eslint src/",
42
+ "format": "prettier --write src/",
43
+ "start": "node build/index.js",
44
+ "test": "echo \"Tests not yet implemented\""
45
+ },
46
+ "dependencies": {
47
+ "@btc-vision/bip32": "^6.0.3",
48
+ "@btc-vision/bitcoin": "^6.4.11",
49
+ "@btc-vision/logger": "^1.0.0",
50
+ "@btc-vision/plugin-sdk": "^1.0.0",
51
+ "@btc-vision/transaction": "^1.7.19",
52
+ "@inquirer/prompts": "^7.5.3",
53
+ "bytenode": "^1.5.7",
54
+ "commander": "^14.0.0",
55
+ "esbuild": "^0.25.5",
56
+ "opnet": "^1.7.17",
57
+ "ora": "^8.2.0"
58
+ },
59
+ "devDependencies": {
60
+ "@eslint/js": "^9.39.1",
61
+ "@types/node": "^24.3.0",
62
+ "eslint": "^9.39.1",
63
+ "gulp": "^5.0.1",
64
+ "gulp-cached": "^1.1.1",
65
+ "gulp-clean": "^0.4.0",
66
+ "gulp-eslint-new": "^2.4.0",
67
+ "gulp-logger-new": "^1.0.1",
68
+ "gulp-typescript": "^6.0.0-alpha.1",
69
+ "prettier": "^3.6.2",
70
+ "typescript": "^5.9.2",
71
+ "typescript-eslint": "^8.39.1"
72
+ },
73
+ "keywords": [
74
+ "opnet",
75
+ "cli",
76
+ "plugin",
77
+ "bitcoin",
78
+ "typescript",
79
+ "blockchain",
80
+ "mldsa",
81
+ "quantum"
82
+ ]
83
+ }
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Accept command - Accept ownership transfer
3
+ *
4
+ * @module commands/AcceptCommand
5
+ */
6
+
7
+ import { confirm } from '@inquirer/prompts';
8
+ import { BaseCommand } from './BaseCommand.js';
9
+ import { getPendingScopeTransfer, getPendingTransfer } from '../lib/registry.js';
10
+ import { canSign, loadCredentials } from '../lib/credentials.js';
11
+ import { CLIWallet } from '../lib/wallet.js';
12
+ import { NetworkName } from '../types/index.js';
13
+
14
+ interface AcceptOptions {
15
+ network: string;
16
+ yes?: boolean;
17
+ }
18
+
19
+ export class AcceptCommand extends BaseCommand {
20
+ constructor() {
21
+ super('accept', 'Accept pending ownership transfer');
22
+ }
23
+
24
+ protected configure(): void {
25
+ this.command
26
+ .argument('<name>', 'Package name or @scope')
27
+ .option('-n, --network <network>', 'Network', 'mainnet')
28
+ .option('-y, --yes', 'Skip confirmation')
29
+ .action((name: string, options?: AcceptOptions) =>
30
+ this.execute(name, options || { network: 'mainnet' }),
31
+ );
32
+ }
33
+
34
+ private async execute(name: string, options?: AcceptOptions): Promise<void> {
35
+ try {
36
+ // Load credentials
37
+ this.logger.info('Loading wallet...');
38
+ const credentials = loadCredentials();
39
+ if (!credentials || !canSign(credentials)) {
40
+ this.logger.fail('No credentials configured');
41
+ this.logger.warn('Run `opnet login` to configure your wallet.');
42
+ process.exit(1);
43
+ }
44
+ CLIWallet.fromCredentials(credentials);
45
+ this.logger.success('Wallet loaded');
46
+
47
+ const network = (options?.network || 'mainnet') as NetworkName;
48
+ const isScope = name.startsWith('@') && !name.includes('/');
49
+
50
+ // Check for pending transfer
51
+ this.logger.info('Checking pending transfer...');
52
+
53
+ if (isScope) {
54
+ const scopeName = name.substring(1);
55
+ const pending = await getPendingScopeTransfer(scopeName, network);
56
+
57
+ if (!pending) {
58
+ this.logger.warn('No pending transfer');
59
+ this.logger.log(`No pending transfer for ${name}.`);
60
+ return;
61
+ }
62
+
63
+ this.logger.success('Found pending transfer');
64
+
65
+ // Display summary
66
+ this.logger.log('');
67
+ this.logger.info('Accept Transfer');
68
+ this.logger.log('─'.repeat(50));
69
+ this.logger.log(`Type: Scope`);
70
+ this.logger.log(`Name: ${name}`);
71
+ this.logger.log(`Network: ${options?.network}`);
72
+ this.logger.log('');
73
+
74
+ // Confirmation
75
+ if (!options?.yes) {
76
+ const confirmed = await confirm({
77
+ message: `Accept ownership of ${name}?`,
78
+ default: true,
79
+ });
80
+
81
+ if (!confirmed) {
82
+ this.logger.warn('Transfer acceptance cancelled.');
83
+ return;
84
+ }
85
+ }
86
+
87
+ // Execute acceptance
88
+ this.logger.info('Accepting transfer...');
89
+ this.logger.warn('Acceptance transaction required.');
90
+ this.logger.log('Transaction would call: acceptScopeTransfer(');
91
+ this.logger.log(` scopeName: "${scopeName}"`);
92
+ this.logger.log(')');
93
+ } else {
94
+ const pending = await getPendingTransfer(name, network);
95
+
96
+ if (!pending) {
97
+ this.logger.warn('No pending transfer');
98
+ this.logger.log(`No pending transfer for ${name}.`);
99
+ return;
100
+ }
101
+
102
+ this.logger.success('Found pending transfer');
103
+
104
+ // Display summary
105
+ this.logger.log('');
106
+ this.logger.info('Accept Transfer');
107
+ this.logger.log('─'.repeat(50));
108
+ this.logger.log(`Type: Package`);
109
+ this.logger.log(`Name: ${name}`);
110
+ this.logger.log(`Network: ${options?.network}`);
111
+ this.logger.log('');
112
+
113
+ // Confirmation
114
+ if (!options?.yes) {
115
+ const confirmed = await confirm({
116
+ message: `Accept ownership of ${name}?`,
117
+ default: true,
118
+ });
119
+
120
+ if (!confirmed) {
121
+ this.logger.warn('Transfer acceptance cancelled.');
122
+ return;
123
+ }
124
+ }
125
+
126
+ // Execute acceptance
127
+ this.logger.info('Accepting transfer...');
128
+ this.logger.warn('Acceptance transaction required.');
129
+ this.logger.log('Transaction would call: acceptTransfer(');
130
+ this.logger.log(` packageName: "${name}"`);
131
+ this.logger.log(')');
132
+ }
133
+
134
+ this.logger.info('Acceptance (transaction pending)');
135
+
136
+ this.logger.log('');
137
+ this.logger.success('Transfer acceptance submitted!');
138
+ this.logger.warn('Note: Registry transaction support is coming soon.');
139
+ this.logger.log('');
140
+ } catch (error) {
141
+ this.logger.fail('Acceptance failed');
142
+ if (this.isUserCancelled(error)) {
143
+ this.logger.warn('Acceptance cancelled.');
144
+ process.exit(0);
145
+ }
146
+ this.exitWithError(this.formatError(error));
147
+ }
148
+ }
149
+ }
150
+
151
+ export const acceptCommand = new AcceptCommand().getCommand();
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Base command class for OPNet CLI
3
+ *
4
+ * @module commands/BaseCommand
5
+ */
6
+
7
+ import { Command } from 'commander';
8
+ import { Logger } from '@btc-vision/logger';
9
+
10
+ /**
11
+ * Abstract base class for all CLI commands
12
+ */
13
+ export abstract class BaseCommand {
14
+ protected readonly logger: Logger;
15
+ protected readonly command: Command;
16
+
17
+ constructor(name: string, description: string) {
18
+ this.logger = new Logger();
19
+ this.command = new Command(name).description(description);
20
+ this.configure();
21
+ }
22
+
23
+ /**
24
+ * Get the configured command instance
25
+ */
26
+ public getCommand(): Command {
27
+ return this.command;
28
+ }
29
+
30
+ /**
31
+ * Configure the command with options and action
32
+ */
33
+ protected abstract configure(): void;
34
+
35
+ /**
36
+ * Format an error message for display
37
+ */
38
+ protected formatError(error: unknown): string {
39
+ if (error instanceof Error) {
40
+ return error.message;
41
+ }
42
+ return String(error);
43
+ }
44
+
45
+ /**
46
+ * Exit with error
47
+ */
48
+ protected exitWithError(message: string, code: number = 1): never {
49
+ this.logger.error(message);
50
+ process.exit(code);
51
+ }
52
+
53
+ /**
54
+ * Check if user cancelled (for inquirer)
55
+ */
56
+ protected isUserCancelled(error: unknown): boolean {
57
+ return error instanceof Error && error.message.includes('User force closed');
58
+ }
59
+ }