@beclab/olaresid 0.1.6 β†’ 0.1.8

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.
@@ -21,7 +21,7 @@ async function example1_generateNew() {
21
21
 
22
22
  // Generate a 12-word mnemonic
23
23
  console.log('\nπŸ”‘ Generating 12-word mnemonic...');
24
- const mnemonic12 = await generateMnemonic(12);
24
+ const mnemonic12 = generateMnemonic(12);
25
25
  console.log(`Mnemonic: ${mnemonic12}`);
26
26
 
27
27
  console.log('\n⏳ Deriving keys using Trust Wallet Core...');
@@ -35,7 +35,7 @@ async function example1_generateNew() {
35
35
  // Generate a 24-word mnemonic
36
36
  console.log('\n' + '-'.repeat(60));
37
37
  console.log('\nπŸ”‘ Generating 24-word mnemonic...');
38
- const mnemonic24 = await generateMnemonic(24);
38
+ const mnemonic24 = generateMnemonic(24);
39
39
  console.log(`Mnemonic: ${mnemonic24}`);
40
40
 
41
41
  console.log('\n⏳ Deriving keys...');
@@ -95,7 +95,7 @@ async function example4_parallelDerivation() {
95
95
  console.log('Example 4: Parallel Key Derivation (Performance Test)');
96
96
  console.log('='.repeat(60));
97
97
 
98
- const mnemonic = await generateMnemonic(12);
98
+ const mnemonic = generateMnemonic(12);
99
99
  console.log(`\nπŸ“ Mnemonic: ${mnemonic}`);
100
100
 
101
101
  console.log('\n⏳ Deriving owner and DID in parallel...');
@@ -79,7 +79,7 @@ async function main() {
79
79
  console.log('\nπŸ“ Step 4: Generate Mnemonic for Subdomain');
80
80
  console.log('-'.repeat(60));
81
81
 
82
- const mnemonic = await generateMnemonic(12);
82
+ const mnemonic = generateMnemonic(12);
83
83
  console.log('βœ… Generated 12-word mnemonic:');
84
84
  console.log(` ${mnemonic}`);
85
85
  console.log(
@@ -98,7 +98,7 @@ async function main() {
98
98
  mnemonic = process.env.NEW_OWNER_MNEMONIC;
99
99
  console.log('πŸ“ Using provided mnemonic');
100
100
  } else {
101
- mnemonic = await generateMnemonic(12);
101
+ mnemonic = generateMnemonic(12);
102
102
  console.log('πŸ”‘ Generated 12-word mnemonic:');
103
103
  console.log(` ${mnemonic}`);
104
104
  console.log(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beclab/olaresid",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "DID Contract SDK with CLI tool",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -39,6 +39,7 @@
39
39
  "dependencies": {
40
40
  "@solana/web3.js": "^1.87.6",
41
41
  "@trustwallet/wallet-core": "^3.2.9",
42
+ "bip39": "^3.1.0",
42
43
  "ethers": "^6.9.1",
43
44
  "multiformats": "9.6.4",
44
45
  "tweetnacl": "^1.0.3",
@@ -4,12 +4,6 @@ import { parseContractError } from '../utils/error-parser';
4
4
  import { TagContext } from './tag-context';
5
5
  import { TagTypeBuilder } from '../utils/tag-type-builder';
6
6
  import { normalizeToDomain } from '../utils/olares-id';
7
- import {
8
- base64ToUint8Array,
9
- uint8ArrayToHex,
10
- hexToUint8Array,
11
- uint8ArrayToBase64
12
- } from '../utils/crypto-utils';
13
7
 
14
8
  export interface TransactionResult<T = any> {
15
9
  // Basic transaction information
@@ -54,11 +48,7 @@ export {
54
48
  getDIDFromMnemonic,
55
49
  generateDIDKeyData,
56
50
  deriveDIDFromMnemonic,
57
- getEd25519JwkFromMnemonic,
58
- base64ToUint8Array,
59
- uint8ArrayToHex,
60
- hexToUint8Array,
61
- uint8ArrayToBase64
51
+ getEd25519JwkFromMnemonic
62
52
  } from '../utils/crypto-utils';
63
53
  export type { RSAPublicKeyData, DIDKeyData } from '../utils/crypto-utils';
64
54
 
@@ -190,7 +180,7 @@ export class DomainContext {
190
180
  * ```typescript
191
181
  * // For parent domain "parent.com", register subdomain "child"
192
182
  * const parentDomain = olaresId.domain('parent.com');
193
- * const mnemonic = await generateMnemonic(12);
183
+ * const mnemonic = generateMnemonic(12);
194
184
  *
195
185
  * const result = await parentDomain.registerSubdomain('child', mnemonic);
196
186
  * // This will register "child.parent.com"
@@ -276,7 +266,7 @@ export class DomainContext {
276
266
  *
277
267
  * @example
278
268
  * ```typescript
279
- * const mnemonic = await generateMnemonic(12);
269
+ * const mnemonic = generateMnemonic(12);
280
270
  * const result = await domain.transfer(mnemonic);
281
271
  * if (result.success) {
282
272
  * console.log('Domain transferred!');
@@ -871,7 +861,7 @@ export class DomainContext {
871
861
  } catch {
872
862
  // Try base64
873
863
  try {
874
- const secretKey = base64ToUint8Array(solanaPrivateKey);
864
+ const secretKey = Buffer.from(solanaPrivateKey, 'base64');
875
865
  solanaWallet = Keypair.fromSecretKey(secretKey);
876
866
  } catch {
877
867
  // Try as JSON array
@@ -882,9 +872,9 @@ export class DomainContext {
882
872
  }
883
873
  }
884
874
 
885
- // Get Solana address as bytes32 (cross-platform)
875
+ // Get Solana address as bytes32
886
876
  const solanaAddressBytes =
887
- '0x' + uint8ArrayToHex(solanaWallet.publicKey.toBytes());
877
+ '0x' + solanaWallet.publicKey.toBuffer().toString('hex');
888
878
 
889
879
  // Get current timestamp
890
880
  const signAt = Math.floor(Date.now() / 1000) - 30 * 60; // 30 minutes ago
@@ -944,8 +934,8 @@ export class DomainContext {
944
934
  decodeUTF8(solanaMsg),
945
935
  solanaWallet.secretKey
946
936
  );
947
- // Convert signature to hex (cross-platform)
948
- const sigFromAuthAddrHex = '0x' + uint8ArrayToHex(sigFromAuthAddr);
937
+ const sigFromAuthAddrHex =
938
+ '0x' + Buffer.from(sigFromAuthAddr).toString('hex');
949
939
 
950
940
  // Call contract
951
941
  const tx = await rootTagger.updateSolanaWallet(
@@ -1008,7 +998,7 @@ export class DomainContext {
1008
998
  } catch {
1009
999
  // Try base64
1010
1000
  try {
1011
- const secretKey = base64ToUint8Array(solanaPrivateKey);
1001
+ const secretKey = Buffer.from(solanaPrivateKey, 'base64');
1012
1002
  solanaWallet = Keypair.fromSecretKey(secretKey);
1013
1003
  } catch {
1014
1004
  // Try as JSON array
@@ -1019,9 +1009,9 @@ export class DomainContext {
1019
1009
  }
1020
1010
  }
1021
1011
 
1022
- // Get Solana address as bytes32 (cross-platform)
1012
+ // Get Solana address as bytes32
1023
1013
  const solanaAddressBytes =
1024
- '0x' + uint8ArrayToHex(solanaWallet.publicKey.toBytes());
1014
+ '0x' + solanaWallet.publicKey.toBuffer().toString('hex');
1025
1015
 
1026
1016
  // Get current timestamp
1027
1017
  const signAt = Math.floor(Date.now() / 1000) - 30 * 60; // 30 minutes ago
@@ -1122,8 +1112,11 @@ export class DomainContext {
1122
1112
  // Extract addresses from the result and convert to base58
1123
1113
  // Result is array of { algorithm, addr } where addr is bytes32
1124
1114
  return result.map((item: any) => {
1125
- // Convert hex to Uint8Array (cross-platform)
1126
- const buffer = hexToUint8Array(item.addr);
1115
+ // Remove 0x prefix and convert hex to buffer
1116
+ const hexStr = item.addr.startsWith('0x')
1117
+ ? item.addr.slice(2)
1118
+ : item.addr;
1119
+ const buffer = Buffer.from(hexStr, 'hex');
1127
1120
  // Convert to Solana public key and then to base58
1128
1121
  return new PublicKey(buffer).toBase58();
1129
1122
  });
@@ -1438,16 +1431,13 @@ export function bytes4ToIpv4(bytes4Hex: string): string {
1438
1431
  */
1439
1432
  export function pemToDer(pem: string): string {
1440
1433
  // Remove PEM headers, footers, and whitespace
1441
- const base64Str = pem
1434
+ const base64 = pem
1442
1435
  .replace(/-----BEGIN.*?-----/g, '')
1443
1436
  .replace(/-----END.*?-----/g, '')
1444
1437
  .replace(/\s/g, '');
1445
1438
 
1446
- // Convert base64 to Uint8Array using cross-platform method
1447
- const derBuffer = base64ToUint8Array(base64Str);
1448
-
1449
- // Convert to hex string
1450
- const hexString = uint8ArrayToHex(derBuffer);
1439
+ const derBuffer = Buffer.from(base64, 'base64');
1440
+ const hexString = derBuffer.toString('hex');
1451
1441
 
1452
1442
  // Convert to hex string with 0x prefix
1453
1443
  return '0x' + hexString;
@@ -1462,14 +1452,13 @@ export function derToPem(derHex: string): string {
1462
1452
  // Remove '0x' prefix if present
1463
1453
  const hexString = derHex.startsWith('0x') ? derHex.slice(2) : derHex;
1464
1454
 
1465
- // Convert hex to base64 using cross-platform methods
1466
- const bytes = hexToUint8Array(hexString);
1467
- const base64Str = uint8ArrayToBase64(bytes);
1455
+ const derBuffer = Buffer.from(hexString, 'hex');
1456
+ const base64 = derBuffer.toString('base64');
1468
1457
 
1469
1458
  // Split base64 into 64-character lines for PEM format
1470
1459
  const lines: string[] = [];
1471
- for (let i = 0; i < base64Str.length; i += 64) {
1472
- lines.push(base64Str.slice(i, i + 64));
1460
+ for (let i = 0; i < base64.length; i += 64) {
1461
+ lines.push(base64.slice(i, i + 64));
1473
1462
  }
1474
1463
 
1475
1464
  // Construct PEM format with headers and footers
package/src/cli.ts CHANGED
@@ -72,7 +72,7 @@ function parseArgs(): {
72
72
  } {
73
73
  const args = process.argv.slice(2);
74
74
  const options: CliOptions = {
75
- network: 'sepolia',
75
+ network: 'mainnet',
76
76
  json: false,
77
77
  verbose: false,
78
78
  debug: false,
@@ -104,7 +104,7 @@ function parseArgs(): {
104
104
  console.log(CLI_VERSION);
105
105
  process.exit(0);
106
106
  } else if (arg === '--network' || arg === '-n') {
107
- options.network = args[++i] || 'sepolia';
107
+ options.network = args[++i] || 'mainnet';
108
108
  } else if (arg === '--rpc') {
109
109
  options.rpc = args[++i];
110
110
  } else if (arg === '--contract-did') {
@@ -181,11 +181,11 @@ COMMANDS:
181
181
  Subdomain Commands:
182
182
  subdomain register <parent> <label>
183
183
  Register a new subdomain (requires PRIVATE_KEY_OR_MNEMONIC)
184
- Use MNEMONIC env var for subdomain owner or auto-generates one
184
+ Use SUBDOMAIN_OWNER_MNEMONIC env var for subdomain owner or auto-generates one
185
185
 
186
186
  Transfer Commands:
187
187
  transfer <domain> Transfer domain ownership to a new owner (requires PRIVATE_KEY_OR_MNEMONIC)
188
- Use MNEMONIC env var for new owner or auto-generates one
188
+ Use TO_MNEMONIC env var for new owner or auto-generates one
189
189
 
190
190
  Wallet Management Commands:
191
191
  wallet evm add <domain> Add EVM wallet to domain (requires PRIVATE_KEY_OR_MNEMONIC & EVM_PRIVATE_KEY)
@@ -216,9 +216,15 @@ COMMANDS:
216
216
  tag get-tagger <domain> <tag-name>
217
217
  Get tagger address for a tag (read-only)
218
218
 
219
- Operator Commands:
220
- operator get Get current operator address
221
- operator set <address> Set operator address (requires PRIVATE_KEY_OR_MNEMONIC)
219
+ Admin Commands:
220
+ admin get-owner Get contract owner address
221
+ admin get-totalsupply Get total number of registered domains
222
+ admin get-operator Get current operator address
223
+ admin set-operator <address>
224
+ Set operator address (requires PRIVATE_KEY_OR_MNEMONIC)
225
+ admin transfer-ownership <address>
226
+ Transfer contract ownership to new address (requires PRIVATE_KEY_OR_MNEMONIC)
227
+ admin accept-ownership Accept pending ownership transfer (requires PRIVATE_KEY_OR_MNEMONIC)
222
228
 
223
229
  Crypto Utility Commands:
224
230
  crypto generate Generate a new mnemonic phrase (--words option)
@@ -243,7 +249,7 @@ COMMANDS:
243
249
  help Show this help message
244
250
 
245
251
  OPTIONS:
246
- -n, --network <network> Network to use (sepolia|mainnet) [default: sepolia]
252
+ -n, --network <network> Network to use (sepolia|mainnet) [default: mainnet]
247
253
  --rpc <url> Custom RPC endpoint URL
248
254
  --contract-did <address> Custom DID contract address
249
255
  --contract-resolver <address> Custom RootResolver contract address
@@ -262,8 +268,8 @@ OPTIONS:
262
268
 
263
269
  EXAMPLES:
264
270
  # Query domain info
265
- did-cli info example.olares.com --network mainnet
266
- did-cli owner example.olares.com
271
+ did-cli info example.olares.com
272
+ did-cli owner example.olares.com --network sepolia
267
273
  export PRIVATE_KEY_OR_MNEMONIC=0xYOUR_PRIVATE_KEY
268
274
  did-cli is-owner example.olares.com
269
275
 
@@ -292,7 +298,7 @@ EXAMPLES:
292
298
  did-cli subdomain register parent.com child --words 24
293
299
 
294
300
  # Subdomain management (use existing mnemonic for subdomain owner)
295
- export MNEMONIC="your twelve word mnemonic here"
301
+ export SUBDOMAIN_OWNER_MNEMONIC="your twelve word mnemonic here"
296
302
  did-cli subdomain register parent.com child
297
303
 
298
304
  # Subdomain management (JSON output)
@@ -304,7 +310,7 @@ EXAMPLES:
304
310
  did-cli transfer example.com --words 24
305
311
 
306
312
  # Transfer domain ownership (use existing mnemonic for new owner)
307
- export MNEMONIC="your twelve word mnemonic here"
313
+ export TO_MNEMONIC="your twelve word mnemonic here"
308
314
  did-cli transfer example.com
309
315
 
310
316
  # Crypto utilities
@@ -366,9 +372,13 @@ EXAMPLES:
366
372
  # Remove tag
367
373
  did-cli tag remove example.com email
368
374
 
369
- # Operator management
370
- did-cli operator get
371
- did-cli operator set 0x1234...
375
+ # Admin management
376
+ did-cli admin get-owner
377
+ did-cli admin get-totalsupply
378
+ did-cli admin get-operator
379
+ did-cli admin set-operator 0x1234...
380
+ did-cli admin transfer-ownership 0x5678...
381
+ did-cli admin accept-ownership
372
382
 
373
383
  # Utilities
374
384
  did-cli convert pem-to-der ./public-key.pem
@@ -378,8 +388,12 @@ EXAMPLES:
378
388
  ENVIRONMENT VARIABLES:
379
389
  PRIVATE_KEY_OR_MNEMONIC Private key (0x...) or mnemonic phrase for signing transactions
380
390
  (required for write operations)
381
- MNEMONIC Mnemonic phrase for generating owner identity
382
- (used in subdomain registration, domain transfer, and crypto utilities)
391
+ SUBDOMAIN_OWNER_MNEMONIC Mnemonic phrase for generating subdomain owner identity
392
+ (used in subdomain registration)
393
+ TO_MNEMONIC Mnemonic phrase for generating new owner identity
394
+ (used in domain transfer)
395
+ MNEMONIC Mnemonic phrase for crypto utility commands
396
+ (used in crypto address, did, privatekey, derive)
383
397
  EVM_PRIVATE_KEY EVM wallet private key for wallet management operations
384
398
  (required for wallet evm add/remove commands)
385
399
  SOLANA_PRIVATE_KEY Solana wallet private key for wallet management operations
@@ -845,9 +859,49 @@ async function removeIP(domain: string, options: CliOptions): Promise<void> {
845
859
  }
846
860
 
847
861
  // ============================================================================
848
- // Operator Commands
862
+ // Admin Commands
849
863
  // ============================================================================
850
864
 
865
+ async function getOwnerCli(options: CliOptions): Promise<void> {
866
+ try {
867
+ const didConsole = getConsole(options);
868
+ const owner = await didConsole.getOwner();
869
+
870
+ if (options.json) {
871
+ console.log(JSON.stringify({ owner }, null, 2));
872
+ } else {
873
+ console.log(`πŸ‘€ Contract Owner: ${owner}`);
874
+ }
875
+ } catch (error) {
876
+ console.error(
877
+ '❌ Error:',
878
+ error instanceof Error ? error.message : String(error)
879
+ );
880
+ process.exit(1);
881
+ }
882
+ }
883
+
884
+ async function getTotalSupplyCli(options: CliOptions): Promise<void> {
885
+ try {
886
+ const didConsole = getConsole(options);
887
+ const totalSupply = await didConsole.getTotalSupply();
888
+
889
+ if (options.json) {
890
+ console.log(
891
+ JSON.stringify({ totalSupply: totalSupply.toString() }, null, 2)
892
+ );
893
+ } else {
894
+ console.log(`πŸ“Š Total Domains: ${totalSupply.toString()}`);
895
+ }
896
+ } catch (error) {
897
+ console.error(
898
+ '❌ Error:',
899
+ error instanceof Error ? error.message : String(error)
900
+ );
901
+ process.exit(1);
902
+ }
903
+ }
904
+
851
905
  async function getOperator(options: CliOptions): Promise<void> {
852
906
  try {
853
907
  const didConsole = getConsole(options);
@@ -897,6 +951,66 @@ async function setOperator(
897
951
  }
898
952
  }
899
953
 
954
+ async function transferOwnershipCli(
955
+ newOwner: string,
956
+ options: CliOptions
957
+ ): Promise<void> {
958
+ try {
959
+ const privateKeyOrMnemonic = getPrivateKeyOrMnemonic();
960
+ const didConsole = getConsole(options);
961
+ await didConsole.setSigner(privateKeyOrMnemonic);
962
+
963
+ const result = await didConsole.transferOwnership(newOwner);
964
+
965
+ if (result.success) {
966
+ console.log(`βœ… Ownership transfer initiated to ${newOwner}`);
967
+ console.log(`πŸ“ Transaction: ${result.transactionHash}`);
968
+ if (result.gasUsed) {
969
+ console.log(`β›½ Gas used: ${result.gasUsed.toString()}`);
970
+ }
971
+ console.log(
972
+ '\n⚠️ Note: The new owner must call "admin accept-ownership" to complete the transfer'
973
+ );
974
+ } else {
975
+ console.error(`❌ Failed: ${result.error}`);
976
+ process.exit(1);
977
+ }
978
+ } catch (error) {
979
+ console.error(
980
+ '❌ Error:',
981
+ error instanceof Error ? error.message : String(error)
982
+ );
983
+ process.exit(1);
984
+ }
985
+ }
986
+
987
+ async function acceptOwnershipCli(options: CliOptions): Promise<void> {
988
+ try {
989
+ const privateKeyOrMnemonic = getPrivateKeyOrMnemonic();
990
+ const didConsole = getConsole(options);
991
+ await didConsole.setSigner(privateKeyOrMnemonic);
992
+
993
+ const result = await didConsole.acceptOwnership();
994
+
995
+ if (result.success) {
996
+ console.log('βœ… Ownership transfer accepted successfully');
997
+ console.log(`πŸ“ Transaction: ${result.transactionHash}`);
998
+ if (result.gasUsed) {
999
+ console.log(`β›½ Gas used: ${result.gasUsed.toString()}`);
1000
+ }
1001
+ } else {
1002
+ console.error(`❌ Failed: ${result.error}`);
1003
+ process.exit(1);
1004
+ }
1005
+ } catch (error) {
1006
+ console.error(
1007
+ '❌ Error:',
1008
+ error instanceof Error ? error.message : String(error)
1009
+ );
1010
+ process.exit(1);
1011
+ }
1012
+ }
1013
+
900
1014
  // ============================================================================
901
1015
  // Conversion Utilities
902
1016
  // ============================================================================
@@ -1001,11 +1115,13 @@ async function registerSubdomain(
1001
1115
 
1002
1116
  // Get or generate mnemonic for subdomain owner
1003
1117
  let mnemonic: string;
1004
- const subdomainMnemonic = process.env.MNEMONIC;
1118
+ const subdomainMnemonic = process.env.SUBDOMAIN_OWNER_MNEMONIC;
1005
1119
 
1006
1120
  if (subdomainMnemonic) {
1007
1121
  mnemonic = subdomainMnemonic;
1008
- console.log('πŸ“ Using mnemonic from MNEMONIC environment variable');
1122
+ console.log(
1123
+ 'πŸ“ Using mnemonic from SUBDOMAIN_OWNER_MNEMONIC environment variable'
1124
+ );
1009
1125
  } else {
1010
1126
  const wordCount = options.words || 12;
1011
1127
  if (![12, 15, 18, 21, 24].includes(wordCount)) {
@@ -1014,7 +1130,7 @@ async function registerSubdomain(
1014
1130
  );
1015
1131
  process.exit(1);
1016
1132
  }
1017
- mnemonic = await generateMnemonic(wordCount);
1133
+ mnemonic = generateMnemonic(wordCount);
1018
1134
 
1019
1135
  // Save mnemonic to file
1020
1136
  const mnemonicFile = './subdomain-mnemonic.txt';
@@ -1036,7 +1152,9 @@ async function registerSubdomain(
1036
1152
  );
1037
1153
  console.log(` β€’ Command: rm ${mnemonicFile}`);
1038
1154
  console.log('\nπŸ’‘ To use this mnemonic for future operations:');
1039
- console.log(` export MNEMONIC="$(cat ${mnemonicFile})"\n`);
1155
+ console.log(
1156
+ ` export SUBDOMAIN_OWNER_MNEMONIC="$(cat ${mnemonicFile})"\n`
1157
+ );
1040
1158
  }
1041
1159
 
1042
1160
  // Register subdomain
@@ -1126,12 +1244,12 @@ async function transferDomain(
1126
1244
 
1127
1245
  // Get or generate mnemonic for new owner
1128
1246
  let mnemonic: string;
1129
- const newOwnerMnemonic = process.env.MNEMONIC;
1247
+ const newOwnerMnemonic = process.env.TO_MNEMONIC;
1130
1248
 
1131
1249
  if (newOwnerMnemonic) {
1132
1250
  mnemonic = newOwnerMnemonic;
1133
1251
  console.log(
1134
- 'πŸ“ Using mnemonic from MNEMONIC environment variable for new owner'
1252
+ 'πŸ“ Using mnemonic from TO_MNEMONIC environment variable for new owner'
1135
1253
  );
1136
1254
  } else {
1137
1255
  const wordCount = options.words || 12;
@@ -1141,7 +1259,7 @@ async function transferDomain(
1141
1259
  );
1142
1260
  process.exit(1);
1143
1261
  }
1144
- mnemonic = await generateMnemonic(wordCount);
1262
+ mnemonic = generateMnemonic(wordCount);
1145
1263
 
1146
1264
  // Save mnemonic to file
1147
1265
  const mnemonicFile = './transfer-new-owner-mnemonic.txt';
@@ -1163,7 +1281,7 @@ async function transferDomain(
1163
1281
  );
1164
1282
  console.log(` β€’ Command: rm ${mnemonicFile}`);
1165
1283
  console.log('\nπŸ’‘ To use this mnemonic for future operations:');
1166
- console.log(` export MNEMONIC="$(cat ${mnemonicFile})"\n`);
1284
+ console.log(` export TO_MNEMONIC="$(cat ${mnemonicFile})"\n`);
1167
1285
  }
1168
1286
 
1169
1287
  // Transfer domain
@@ -1228,7 +1346,7 @@ async function cryptoGenerate(options: CliOptions): Promise<void> {
1228
1346
  process.exit(1);
1229
1347
  }
1230
1348
 
1231
- const mnemonic = await generateMnemonic(wordCount);
1349
+ const mnemonic = generateMnemonic(wordCount);
1232
1350
 
1233
1351
  // Save mnemonic to file
1234
1352
  const outputFile = options.output || './mnemonic.txt';
@@ -2339,7 +2457,7 @@ async function main(): Promise<void> {
2339
2457
  'Note: Set PRIVATE_KEY_OR_MNEMONIC environment variable first'
2340
2458
  );
2341
2459
  console.error(
2342
- 'Optional: Set MNEMONIC environment variable for new owner (auto-generates if not set)'
2460
+ 'Optional: Set TO_MNEMONIC environment variable for new owner (auto-generates if not set)'
2343
2461
  );
2344
2462
  process.exit(1);
2345
2463
  }
@@ -2474,7 +2592,7 @@ async function main(): Promise<void> {
2474
2592
  'Note: Set PRIVATE_KEY_OR_MNEMONIC environment variable first'
2475
2593
  );
2476
2594
  console.error(
2477
- 'Optional: Set MNEMONIC environment variable for subdomain owner (auto-generates if not set)'
2595
+ 'Optional: Set SUBDOMAIN_OWNER_MNEMONIC environment variable for subdomain owner (auto-generates if not set)'
2478
2596
  );
2479
2597
  process.exit(1);
2480
2598
  }
@@ -2488,24 +2606,32 @@ async function main(): Promise<void> {
2488
2606
  }
2489
2607
  break;
2490
2608
 
2491
- // Operator commands
2492
- case 'operator':
2609
+ // Admin commands
2610
+ case 'admin':
2493
2611
  if (!subCommand) {
2494
- console.error('❌ Error: Operator subcommand is required');
2495
- console.error('Usage: did-cli operator <get|set> [args]');
2612
+ console.error('❌ Error: Admin subcommand is required');
2613
+ console.error(
2614
+ 'Usage: did-cli admin <get-owner|get-totalsupply|get-operator|set-operator|transfer-ownership|accept-ownership> [args]'
2615
+ );
2496
2616
  process.exit(1);
2497
2617
  }
2498
2618
  switch (subCommand) {
2499
- case 'get':
2619
+ case 'get-owner':
2620
+ await getOwnerCli(options);
2621
+ break;
2622
+ case 'get-totalsupply':
2623
+ await getTotalSupplyCli(options);
2624
+ break;
2625
+ case 'get-operator':
2500
2626
  await getOperator(options);
2501
2627
  break;
2502
- case 'set':
2628
+ case 'set-operator':
2503
2629
  if (!domain) {
2504
2630
  console.error(
2505
2631
  '❌ Error: Operator address is required'
2506
2632
  );
2507
2633
  console.error(
2508
- 'Usage: did-cli operator set <address>'
2634
+ 'Usage: did-cli admin set-operator <address>'
2509
2635
  );
2510
2636
  console.error(
2511
2637
  'Note: Set PRIVATE_KEY_OR_MNEMONIC environment variable first'
@@ -2514,9 +2640,27 @@ async function main(): Promise<void> {
2514
2640
  }
2515
2641
  await setOperator(domain, options);
2516
2642
  break;
2643
+ case 'transfer-ownership':
2644
+ if (!domain) {
2645
+ console.error(
2646
+ '❌ Error: New owner address is required'
2647
+ );
2648
+ console.error(
2649
+ 'Usage: did-cli admin transfer-ownership <address>'
2650
+ );
2651
+ console.error(
2652
+ 'Note: Set PRIVATE_KEY_OR_MNEMONIC environment variable first'
2653
+ );
2654
+ process.exit(1);
2655
+ }
2656
+ await transferOwnershipCli(domain, options);
2657
+ break;
2658
+ case 'accept-ownership':
2659
+ await acceptOwnershipCli(options);
2660
+ break;
2517
2661
  default:
2518
2662
  console.error(
2519
- `❌ Unknown operator subcommand: ${subCommand}`
2663
+ `❌ Unknown admin subcommand: ${subCommand}`
2520
2664
  );
2521
2665
  process.exit(1);
2522
2666
  }
@@ -2953,7 +3097,6 @@ async function main(): Promise<void> {
2953
3097
  }
2954
3098
  }
2955
3099
 
2956
- // θΏθ‘ŒδΈ»ε‡½ζ•°
2957
3100
  main().catch((error) => {
2958
3101
  console.error(
2959
3102
  '❌ Unexpected error:',