@tech-bureau/mijin-catapult-tools 0.1.4 → 0.1.5

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.
package/README.md CHANGED
@@ -12,7 +12,13 @@ This tool is for easy operation of mijin Catapult(v.2)
12
12
  * Transaction
13
13
  * Mosaic
14
14
  * Create
15
- * info
15
+ * Info
16
+ * Namespace
17
+ * Create Root
18
+ * Create Sub
19
+ * Link Mosaic
20
+ * Link Address
21
+ * Info
16
22
  * Voting
17
23
  * Create
18
24
  * Info
@@ -573,6 +579,75 @@ $ mijin-catapult-tools transaction mosaic create -r config.json -o work -s 1000
573
579
  2023-01-16T06:28:34.464Z [info] : http://localhost:3000/transactions/confirmed/733BA25FECEECC334CAD0E4B86F80676661EA34DC1781E205C0034536A5A330A
574
580
  ```
575
581
 
582
+ ## Namespace
583
+
584
+ ```bash
585
+ $ mijin-catapult-tools transaction namespace -h
586
+ Usage: mijin-catapult-tools transaction namespace [options] [command]
587
+
588
+ Namespace Transaction Announce or Info
589
+
590
+ Options:
591
+ -h, --help display help for command
592
+
593
+ Commands:
594
+ create-root [options] Create Root Namespace and Announce Mosaic Transaction
595
+ create-sub [options] Create Sub Namespace and Announce Mosaic Transaction
596
+ link-mosaic [options] Link Mosaic and Announce Transaction
597
+ link-address [options] Link Address and Announce Transaction
598
+ info [options] Get Namespace Info
599
+ help [command] display help for command
600
+ ```
601
+
602
+ ### Namespace Example Commands
603
+
604
+ ``` bash
605
+ $ mijin-catapult-tools transaction namespace create-root -r config.json -o work -n test -d 1000
606
+ $ mijin-catapult-tools transaction namespace create-sub -r config.json -o work -n sub -pn test
607
+ $ mijin-catapult-tools transaction namespace create-sub -r config.json -o work -n sub2 -pn test
608
+ $ mijin-catapult-tools transaction namespace link-mosaic -r config.json -o work -n test.sub -m 287CD558128F6C53
609
+ $ mijin-catapult-tools transaction namespace link-address -r config.json -o work -n test.sub2 -a MDLEKG5MKKAPFBM3XWZKYQEDYRJO67MUJXFDP6I
610
+ $ mijin-catapult-tools transaction namespace info -r config.json -n test
611
+ ```
612
+
613
+ ### Create Root Namespace (Owner work Account)
614
+
615
+ Namespace Name: test
616
+ Duration: 1000
617
+
618
+ ```bash
619
+ $ mijin-catapult-tools transaction namespace create-root -r config.json -o work -n test -d 1000
620
+ 2023-03-10T06:11:01.298Z [info] : mijin URL: http://localhost:3000
621
+ 2023-03-10T06:11:01.299Z [info] : Network: 96
622
+ 2023-03-10T06:11:01.300Z [info] : Create Root Namespace...
623
+ 2023-03-10T06:11:01.345Z [info] : Root Namespace Owner Account: MDLEKG5MKKAPFBM3XWZKYQEDYRJO67MUJXFDP6I
624
+ 2023-03-10T06:11:01.346Z [info] : Namespace Name: test
625
+ 2023-03-10T06:11:01.348Z [info] : Namespace Transaction: {"transaction":{"type":16718,"network":96,"version":1,"maxFee":"0","deadline":"118141861343","signature":"","registrationType":0,"name":"test","id":"D401054C1965C26E","duration":"1000"}}
626
+ 2023-03-10T06:11:01.378Z [info] : Transaction Fee: 0
627
+ 2023-03-10T06:11:01.378Z [info] : Namespace Rental Fee Per Block: 1
628
+ 2023-03-10T06:11:01.378Z [info] : Start Announce Transaction...
629
+ 2023-03-10T06:11:06.415Z [info] : End Transaction
630
+ 2023-03-10T06:11:06.415Z [info] : http://localhost:3000/transactionStatus/57275DF8349C3FB582BA5B1B854FA8C270C467B8A48EB9B9E24EC6F3F7A1786B
631
+ 2023-03-10T06:11:06.415Z [info] : http://localhost:3000/transactions/confirmed/57275DF8349C3FB582BA5B1B854FA8C270C467B8A48EB9B9E24EC6F3F7A1786B
632
+ ```
633
+
634
+ ### Namespace Info
635
+
636
+ Namespace Name: test
637
+
638
+ ```bash
639
+ $ mijin-catapult-tools transaction namespace info -r config.json -n test
640
+ 2023-03-10T06:13:34.668Z [info] : mijin URL: http://localhost:3000
641
+ 2023-03-10T06:13:34.669Z [info] : Network: 96
642
+ 2023-03-10T06:13:34.670Z [info] : Namespace Id: test
643
+ 2023-03-10T06:13:34.749Z [info] : Namespace Info: {
644
+ "active": true,
645
+ "ownerAddress": "MDLEKG5MKKAPFBM3XWZKYQEDYRJO67MUJXFDP6I",
646
+ "namespaceId": "D401054C1965C26E",
647
+ "parentId": "0000000000000000"
648
+ }
649
+ ```
650
+
576
651
  ## Create Votingkey Dat file(for main Account)
577
652
 
578
653
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tech-bureau/mijin-catapult-tools",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "This tool is for easy operation of mijin Catapult(v.2)",
5
5
  "private": false,
6
6
  "main": "dist/main.js",
@@ -52,4 +52,4 @@
52
52
  "webpack": "^5.24.2",
53
53
  "webpack-cli": "^4.5.0"
54
54
  }
55
- }
55
+ }
@@ -0,0 +1,97 @@
1
+ import NamespaceServices from '../../service/NamespaceServices'
2
+ import { NetworkType } from '@tech-bureau/symbol-sdk'
3
+
4
+ const config = {
5
+ url: 'http://localhost:3000',
6
+ workAccount: {
7
+ publicKey: '65AB2F5671F285325E0A196651566D3770A1A809C4C169DDFED157E86F63ABA1',
8
+ privateKey: '1E33ACC3CD9F7BB01D1EDD0F560F2D9635D7E6F98D7BFB3EA7EF7EDA5303FB80',
9
+ address: 'MD2NEFQ75FKV5HDOTLTZNEE5SYRRMIAYFYJKA3Q',
10
+ },
11
+ balanceAccount: {
12
+ publicKey: '',
13
+ privateKey: '',
14
+ address: '',
15
+ },
16
+ mainAccount: {
17
+ publicKey: 'CF4250FA98A00C2B201D3BCB4CF5B7965C41DFBD6D331CB56F16BCC03DB79B4C',
18
+ privateKey: 'BFC70F2FC37D1CD31F60CE3DC11DD9CF3E0DAEA2B5D960F3456FB63AA0AC83C2',
19
+ address: 'MDAHM3BQQTLIA4WHWN572U35ZJG2ULVJWYCSG5I',
20
+ },
21
+ keylink: {
22
+ vrf: {
23
+ publicKey: '4DC4AFDC04F0271CFFB2B65B0A5E505184EC5AD81892B7541397D2F85F1533D3',
24
+ privateKey: '495656E00893DD1FB8AEF833FF1F60ED2D1D7EF050213EE4DADCC7CC01493ADF',
25
+ address: 'MBR6DL2MMFAG2ASPU5N4HSZPK6I6IEDKB747BRQ',
26
+ },
27
+ voting: {
28
+ publicKey: '937E1684027FB86BAFF47146C98F166767BD3BE3C00E1BF47657C72EBE2C3500',
29
+ privateKey: '1393923A4CE0547D713C9D6C5C327F23ADFB6CCEE344E173528C9119F9654F65',
30
+ address: 'MAL6PBEOZ4KQD4RKTUHCFA2CO2FYYGGMY77KFEA',
31
+ },
32
+ },
33
+ test1Account: {
34
+ publicKey: '49CEF8886711941127EFA8492829748D523F5C6CD4B17EA45759AFEC37BA4C22',
35
+ privateKey: 'D60BA72D4AA73D0845F1742F95C6CEC2F5576DE0C9AA3C4AC764C362AC93ED2C',
36
+ address: 'MDBZDEIYKPLEYGJ7S55TLTXH3R5JZDKP2TPLOUQ',
37
+ },
38
+ test2Account: {
39
+ publicKey: 'A0E0D1D095E22E49A8E679AA470A1A0B10714C27E6471F6C99D982A7FF8A025B',
40
+ privateKey: 'F141362C6F636FCE21BE72C2E42779202F54A91AF14A9BF6140FAA3FCC641944',
41
+ address: 'MAURGUI3OOJ6NF7OUYYEWS6QTAIFLJFK4EQGWZA',
42
+ },
43
+ }
44
+
45
+ const rootNamespaceName = 'mijin'
46
+ const subNamespaceName = 'cat'
47
+ const namespaceRawId = 'CF70B22792D08638'
48
+ const mosaicRawId = '13CD4D0575AD0250'
49
+ const epoch = 100
50
+ const duration = 1000
51
+ const networkType = NetworkType.MIJIN
52
+ const minFeeMultiplier = 100
53
+
54
+ describe('start namespace test', () => {
55
+ it('Create Root Namespace function', () => {
56
+ const createRootNamespace = NamespaceServices.createRootNamespace(
57
+ epoch,
58
+ rootNamespaceName,
59
+ duration,
60
+ networkType,
61
+ minFeeMultiplier
62
+ )
63
+ expect(createRootNamespace).toBeDefined()
64
+ })
65
+
66
+ it('Create Sub Namespace function', () => {
67
+ const createSubNamespace = NamespaceServices.createSubNamespace(
68
+ epoch,
69
+ rootNamespaceName,
70
+ subNamespaceName,
71
+ networkType,
72
+ minFeeMultiplier
73
+ )
74
+ expect(createSubNamespace).toBeDefined()
75
+ })
76
+ it('Create mosaic link function', () => {
77
+ const mosaicLink = NamespaceServices.linkMosaic(epoch, namespaceRawId, mosaicRawId, networkType, minFeeMultiplier)
78
+ expect(mosaicLink).toBeDefined()
79
+ })
80
+ it('Create account link function', () => {
81
+ const mosaicLink = NamespaceServices.linkAddress(
82
+ epoch,
83
+ namespaceRawId,
84
+ config.workAccount.address,
85
+ networkType,
86
+ minFeeMultiplier
87
+ )
88
+ expect(mosaicLink).toBeDefined()
89
+ })
90
+ it('Get Namespace Id function', () => {
91
+ const namespace = NamespaceServices.getNamespaceId(rootNamespaceName)
92
+ expect(namespace?.fullName).toBe(rootNamespaceName)
93
+
94
+ const namespace2 = NamespaceServices.getNamespaceId(namespaceRawId)
95
+ expect(namespace2?.toHex()).toBe(namespaceRawId)
96
+ })
97
+ })
package/src/cli.ts CHANGED
@@ -8,7 +8,7 @@ import transaction from './commands/transaction/transaction'
8
8
  program
9
9
  .name('mijin-catapult-tools')
10
10
  .description('This tool allows you to easily operate mijin Catapult')
11
- .version('0.1.4')
11
+ .version('0.1.5')
12
12
 
13
13
  program.addCommand(account())
14
14
  program.addCommand(voting())
@@ -0,0 +1,16 @@
1
+ import { Command } from 'commander'
2
+ import linkAddress from '../../infrastructure/namespace/linkAddress'
3
+ const program = new Command()
4
+
5
+ program
6
+ .name('link-address')
7
+ .description('Link Address and Announce Transaction')
8
+ .option('-o, --owner <work|balance|main|test1|test2|other>', 'Specify the input of from Account', 'other')
9
+ .option('-u, --url <mijinCatapultURL>', 'Specify the input of mijin URL')
10
+ .option('-n, --name <name>', 'Specify the input of Namespace Name')
11
+ .option('-a, --address <address>', 'Specify the input of Address')
12
+ .option('-r, --readfile <config.json>', 'Specify the input of Read Config File')
13
+ .option('-p, --privatekey <privateKey>', 'Specify the input of Mosaic Owner Account Private Key')
14
+ .action(linkAddress)
15
+
16
+ export default program
@@ -0,0 +1,16 @@
1
+ import { Command } from 'commander'
2
+ import linkMosaic from '../../infrastructure/namespace/linkMosaic'
3
+ const program = new Command()
4
+
5
+ program
6
+ .name('link-mosaic')
7
+ .description('Link Mosaic and Announce Transaction')
8
+ .option('-o, --owner <work|balance|main|test1|test2|other>', 'Specify the input of from Account', 'other')
9
+ .option('-u, --url <mijinCatapultURL>', 'Specify the input of mijin URL')
10
+ .option('-n, --name <name>', 'Specify the input of Namespace Name')
11
+ .option('-m, --mosaic-id <mosaic-id>', 'Specify the input of Mosaic Id')
12
+ .option('-r, --readfile <config.json>', 'Specify the input of Read Config File')
13
+ .option('-p, --privatekey <privateKey>', 'Specify the input of Mosaic Owner Account Private Key')
14
+ .action(linkMosaic)
15
+
16
+ export default program
@@ -0,0 +1,22 @@
1
+ import { Command } from 'commander'
2
+ import rootNamespaceCreate from './rootNamespaceCreate'
3
+ import subNamespaceCreate from './subNamespaceCreate'
4
+ import linkMosaic from './linkMosaic'
5
+ import linkAddress from './linkAddress'
6
+ import namespaceInfo from './namespaceInfo'
7
+
8
+ const mosaic = () => {
9
+ const program = new Command('namespace')
10
+
11
+ program.description('Namespace Transaction Announce or Info')
12
+
13
+ program.addCommand(rootNamespaceCreate)
14
+ program.addCommand(subNamespaceCreate)
15
+ program.addCommand(linkMosaic)
16
+ program.addCommand(linkAddress)
17
+ program.addCommand(namespaceInfo)
18
+
19
+ return program
20
+ }
21
+
22
+ export default mosaic
@@ -0,0 +1,13 @@
1
+ import { Command } from 'commander'
2
+ import namespaceInfo from '../../infrastructure/namespace/namespaceInfo'
3
+ const program = new Command()
4
+
5
+ program
6
+ .name('info')
7
+ .description('Get Namespace Info')
8
+ .option('-u, --url <mijinCatapultURL>', 'Specify the input of mijin URL')
9
+ .option('-r, --readfile <config.json>', 'Specify the input of Read Config File')
10
+ .option('-n, --namespaceId <namespaceId>', 'Specify the input of Namespace Id or Name')
11
+ .action(namespaceInfo)
12
+
13
+ export default program
@@ -0,0 +1,16 @@
1
+ import { Command } from 'commander'
2
+ import rootNamespaceCreate from '../../infrastructure/namespace/rootNamespaceCreate'
3
+ const program = new Command()
4
+
5
+ program
6
+ .name('create-root')
7
+ .description('Create Root Namespace and Announce Mosaic Transaction')
8
+ .option('-o, --owner <work|balance|main|test1|test2|other>', 'Specify the input of from Account', 'other')
9
+ .option('-u, --url <mijinCatapultURL>', 'Specify the input of mijin URL')
10
+ .option('-d, --duration <duration>', 'Specify the input of Namespace Duration')
11
+ .option('-n, --name <name>', 'Specify the input of Namespace Name')
12
+ .option('-r, --readfile <config.json>', 'Specify the input of Read Config File')
13
+ .option('-p, --privatekey <privateKey>', 'Specify the input of Mosaic Owner Account Private Key')
14
+ .action(rootNamespaceCreate)
15
+
16
+ export default program
@@ -0,0 +1,16 @@
1
+ import { Command } from 'commander'
2
+ import subNamespaceCreate from '../../infrastructure/namespace/subNamespaceCreate'
3
+ const program = new Command()
4
+
5
+ program
6
+ .name('create-sub')
7
+ .description('Create Sub Namespace and Announce Mosaic Transaction')
8
+ .option('-o, --owner <work|balance|main|test1|test2|other>', 'Specify the input of from Account', 'other')
9
+ .option('-u, --url <mijinCatapultURL>', 'Specify the input of mijin URL')
10
+ .option('-n, --name <name>', 'Specify the input of Namespace Name')
11
+ .option('-pn, --parent-name <parent-name>', 'Specify the input of Namespace Parent Name')
12
+ .option('-r, --readfile <config.json>', 'Specify the input of Read Config File')
13
+ .option('-p, --privatekey <privateKey>', 'Specify the input of Mosaic Owner Account Private Key')
14
+ .action(subNamespaceCreate)
15
+
16
+ export default program
@@ -2,8 +2,9 @@ import { Command } from 'commander'
2
2
  import transfer from './transfer'
3
3
  import status from './transactionStatus'
4
4
  import mosaic from '../mosaic/mosaic'
5
+ import namespace from '../namespace/namespace'
5
6
 
6
- const votingkey = () => {
7
+ const transaction = () => {
7
8
  const program = new Command('transaction')
8
9
 
9
10
  program.description('Transaction Announce or Info')
@@ -11,8 +12,9 @@ const votingkey = () => {
11
12
  program.addCommand(transfer)
12
13
  program.addCommand(status)
13
14
  program.addCommand(mosaic())
15
+ program.addCommand(namespace())
14
16
 
15
17
  return program
16
18
  }
17
19
 
18
- export default votingkey
20
+ export default transaction
@@ -0,0 +1,126 @@
1
+ import AccountServices from '../../service/AccountServices'
2
+ import RepositoryFactory from '../../service/RepositoryFactory'
3
+ import { INamespaceCreateOption } from '../../types'
4
+ import LoggerFactory from '../../service/Logger'
5
+ import { readConfig, checkFile } from '../../utils'
6
+ import TransactionServices from '../../service/TransactionServices'
7
+ import NamespaceServices from '../../service/NamespaceServices'
8
+
9
+ const logger = LoggerFactory.getLogger()
10
+
11
+ export default async (option: INamespaceCreateOption) => {
12
+ const { owner, url, readfile, name, address, privatekey } = option
13
+
14
+ let configFile
15
+
16
+ if (readfile && (await checkFile(readfile))) {
17
+ configFile = await readConfig(readfile)
18
+ }
19
+
20
+ const mijinUrl = url ? url : configFile ? configFile.url : undefined
21
+
22
+ if (!mijinUrl) {
23
+ logger.error(`Must Set mijin URL(-u http://xxxxxx.com:3000) or Set Read Config(-r config.json)`)
24
+ return
25
+ }
26
+
27
+ let repo
28
+
29
+ try {
30
+ repo = new RepositoryFactory(mijinUrl)
31
+ await repo.init()
32
+ } catch (error) {
33
+ logger.error(`Please specify a valid URL: ${mijinUrl}`)
34
+ return
35
+ }
36
+
37
+ const networkType = repo.getNetwork()
38
+ const epoch = repo.getEpoch()
39
+
40
+ logger.info(`mijin URL: ${mijinUrl}`)
41
+ logger.info(`Network: ${networkType.toString()}`)
42
+
43
+ logger.info('Link Address...')
44
+
45
+ let createAccount
46
+
47
+ switch (owner) {
48
+ case 'work':
49
+ createAccount = configFile
50
+ ? AccountServices.createAccount(configFile.workAccount.privateKey, networkType)
51
+ : undefined
52
+ break
53
+ case 'balance':
54
+ createAccount = configFile
55
+ ? AccountServices.createAccount(configFile.balanceAccount.privateKey, networkType)
56
+ : undefined
57
+ break
58
+ case 'main':
59
+ createAccount = configFile
60
+ ? AccountServices.createAccount(configFile.mainAccount.privateKey, networkType)
61
+ : undefined
62
+ break
63
+ case 'test1':
64
+ createAccount = configFile
65
+ ? AccountServices.createAccount(configFile.test1Account.privateKey, networkType)
66
+ : undefined
67
+ break
68
+ case 'test2':
69
+ createAccount = configFile
70
+ ? AccountServices.createAccount(configFile.test2Account.privateKey, networkType)
71
+ : undefined
72
+ break
73
+ default:
74
+ createAccount =
75
+ privatekey && privatekey.length === 64 ? AccountServices.createAccount(privatekey, networkType) : undefined
76
+ break
77
+ }
78
+
79
+ if (!createAccount) {
80
+ logger.error('Create Account Not Found Set (-r config -o owner) or -p')
81
+ return
82
+ }
83
+
84
+ if (!name) {
85
+ logger.error('Namespace name Not Found Set -n option')
86
+ return
87
+ }
88
+
89
+ if (!address) {
90
+ logger.error('Namespace link address Not Found Set -a option')
91
+ return
92
+ }
93
+
94
+ const minFeeMultiplier = repo.getTransactionFees().minFeeMultiplier
95
+ const mosaicLinkTransaction = NamespaceServices.linkAddress(epoch, name, address, networkType, minFeeMultiplier)
96
+ if (!mosaicLinkTransaction) {
97
+ logger.error('invalid name or address option')
98
+ return
99
+ }
100
+
101
+ logger.info(`Account: ${createAccount.address.plain()}`)
102
+ logger.info(`Namespace Name: ${name}`)
103
+ logger.info(`Namespace Link Address: ${address}`)
104
+ logger.info(`Namespace Transaction: ${JSON.stringify(mosaicLinkTransaction)}`)
105
+ const signedTransaction = createAccount.sign(mosaicLinkTransaction, repo.getGnerationHash())
106
+
107
+ logger.info(`Transaction Fee: ${repo.getTransactionFees().minFeeMultiplier}`)
108
+ logger.info('Start Announce Transaction...')
109
+
110
+ const announce = await TransactionServices.announce(
111
+ signedTransaction,
112
+ repo.createLitener(),
113
+ repo.createTransactionRepository(),
114
+ repo.createReceiptRepository()
115
+ ).catch((err) => {
116
+ return err
117
+ })
118
+ if (announce instanceof Error) {
119
+ logger.error(`Namespace Announce ${announce}`)
120
+ return
121
+ }
122
+
123
+ logger.info('End Transaction')
124
+ logger.info(`${mijinUrl}/transactionStatus/${signedTransaction.hash}`)
125
+ logger.info(`${mijinUrl}/transactions/confirmed/${signedTransaction.hash}`)
126
+ }
@@ -0,0 +1,126 @@
1
+ import AccountServices from '../../service/AccountServices'
2
+ import RepositoryFactory from '../../service/RepositoryFactory'
3
+ import { INamespaceCreateOption } from '../../types'
4
+ import LoggerFactory from '../../service/Logger'
5
+ import { readConfig, checkFile } from '../../utils'
6
+ import TransactionServices from '../../service/TransactionServices'
7
+ import NamespaceServices from '../../service/NamespaceServices'
8
+
9
+ const logger = LoggerFactory.getLogger()
10
+
11
+ export default async (option: INamespaceCreateOption) => {
12
+ const { owner, url, readfile, name, mosaicId, privatekey } = option
13
+
14
+ let configFile
15
+
16
+ if (readfile && (await checkFile(readfile))) {
17
+ configFile = await readConfig(readfile)
18
+ }
19
+
20
+ const mijinUrl = url ? url : configFile ? configFile.url : undefined
21
+
22
+ if (!mijinUrl) {
23
+ logger.error(`Must Set mijin URL(-u http://xxxxxx.com:3000) or Set Read Config(-r config.json)`)
24
+ return
25
+ }
26
+
27
+ let repo
28
+
29
+ try {
30
+ repo = new RepositoryFactory(mijinUrl)
31
+ await repo.init()
32
+ } catch (error) {
33
+ logger.error(`Please specify a valid URL: ${mijinUrl}`)
34
+ return
35
+ }
36
+
37
+ const networkType = repo.getNetwork()
38
+ const epoch = repo.getEpoch()
39
+
40
+ logger.info(`mijin URL: ${mijinUrl}`)
41
+ logger.info(`Network: ${networkType.toString()}`)
42
+
43
+ logger.info('Link Mosaic...')
44
+
45
+ let createAccount
46
+
47
+ switch (owner) {
48
+ case 'work':
49
+ createAccount = configFile
50
+ ? AccountServices.createAccount(configFile.workAccount.privateKey, networkType)
51
+ : undefined
52
+ break
53
+ case 'balance':
54
+ createAccount = configFile
55
+ ? AccountServices.createAccount(configFile.balanceAccount.privateKey, networkType)
56
+ : undefined
57
+ break
58
+ case 'main':
59
+ createAccount = configFile
60
+ ? AccountServices.createAccount(configFile.mainAccount.privateKey, networkType)
61
+ : undefined
62
+ break
63
+ case 'test1':
64
+ createAccount = configFile
65
+ ? AccountServices.createAccount(configFile.test1Account.privateKey, networkType)
66
+ : undefined
67
+ break
68
+ case 'test2':
69
+ createAccount = configFile
70
+ ? AccountServices.createAccount(configFile.test2Account.privateKey, networkType)
71
+ : undefined
72
+ break
73
+ default:
74
+ createAccount =
75
+ privatekey && privatekey.length === 64 ? AccountServices.createAccount(privatekey, networkType) : undefined
76
+ break
77
+ }
78
+
79
+ if (!createAccount) {
80
+ logger.error('Create Account Not Found Set (-r config -o owner) or -p')
81
+ return
82
+ }
83
+
84
+ if (!name) {
85
+ logger.error('Namespace name Not Found Set -n option')
86
+ return
87
+ }
88
+
89
+ if (!mosaicId) {
90
+ logger.error('Namespace Link Mosaic Id Not Found Set -m option')
91
+ return
92
+ }
93
+
94
+ const minFeeMultiplier = repo.getTransactionFees().minFeeMultiplier
95
+ const mosaicLinkTransaction = NamespaceServices.linkMosaic(epoch, name, mosaicId, networkType, minFeeMultiplier)
96
+ if (!mosaicLinkTransaction) {
97
+ logger.error('invalid name or mosaic option')
98
+ return
99
+ }
100
+
101
+ logger.info(`Account: ${createAccount.address.plain()}`)
102
+ logger.info(`Namespace Name: ${name}`)
103
+ logger.info(`Namespace Link Mosaic Id: ${mosaicId}`)
104
+ logger.info(`Namespace Transaction: ${JSON.stringify(mosaicLinkTransaction)}`)
105
+ const signedTransaction = createAccount.sign(mosaicLinkTransaction, repo.getGnerationHash())
106
+
107
+ logger.info(`Transaction Fee: ${repo.getTransactionFees().minFeeMultiplier}`)
108
+ logger.info('Start Announce Transaction...')
109
+
110
+ const announce = await TransactionServices.announce(
111
+ signedTransaction,
112
+ repo.createLitener(),
113
+ repo.createTransactionRepository(),
114
+ repo.createReceiptRepository()
115
+ ).catch((err) => {
116
+ return err
117
+ })
118
+ if (announce instanceof Error) {
119
+ logger.error(`Namespace Link Announce ${announce}`)
120
+ return
121
+ }
122
+
123
+ logger.info('End Transaction')
124
+ logger.info(`${mijinUrl}/transactionStatus/${signedTransaction.hash}`)
125
+ logger.info(`${mijinUrl}/transactions/confirmed/${signedTransaction.hash}`)
126
+ }
@@ -0,0 +1,44 @@
1
+ import RepositoryFactory from '../../service/RepositoryFactory'
2
+ import { INamespaceInfoOption } from '../../types'
3
+ import LoggerFactory from '../../service/Logger'
4
+ import { readConfig, checkFile } from '../../utils'
5
+ import NamespaceServices from '../../service/NamespaceServices'
6
+
7
+ const logger = LoggerFactory.getLogger()
8
+
9
+ export default async (option: INamespaceInfoOption) => {
10
+ const { url, readfile, namespaceId } = option
11
+
12
+ let configFile
13
+
14
+ if (readfile && (await checkFile(readfile))) {
15
+ configFile = await readConfig(readfile)
16
+ }
17
+
18
+ if (!url && !configFile) {
19
+ logger.error(`Must Set mijin URL(-u http://xxxxxx.com:3000) or Set Read Config(-r config.json)`)
20
+ return
21
+ }
22
+
23
+ const mijinUrl = url ? url : configFile ? configFile.url : ''
24
+
25
+ const repo = new RepositoryFactory(mijinUrl)
26
+ await repo.init()
27
+
28
+ const networkType = repo.getNetwork()
29
+
30
+ logger.info(`mijin URL: ${mijinUrl}`)
31
+ logger.info(`Network: ${networkType.toString()}`)
32
+
33
+ if (!namespaceId) {
34
+ logger.error(`Must set Namespace Id`)
35
+ return
36
+ }
37
+ logger.info(`Namespace Id: ${namespaceId}`)
38
+ const namespaceInfo = await NamespaceServices.getNamespace(namespaceId, repo.createNamespaceRepository())
39
+ if (!namespaceInfo) {
40
+ logger.info(`Namespace Not Found`)
41
+ return
42
+ }
43
+ logger.info(`Namespace Info: ${JSON.stringify(NamespaceServices.namespaceInfo(namespaceInfo), null, ' ')}`)
44
+ }
@@ -0,0 +1,134 @@
1
+ import AccountServices from '../../service/AccountServices'
2
+ import RepositoryFactory from '../../service/RepositoryFactory'
3
+ import { INamespaceCreateOption } from '../../types'
4
+ import LoggerFactory from '../../service/Logger'
5
+ import { readConfig, checkFile } from '../../utils'
6
+ import TransactionServices from '../../service/TransactionServices'
7
+ import NamespaceServices from '../../service/NamespaceServices'
8
+
9
+ const logger = LoggerFactory.getLogger()
10
+
11
+ export default async (option: INamespaceCreateOption) => {
12
+ const { owner, url, readfile, name, duration, privatekey } = option
13
+
14
+ let configFile
15
+
16
+ if (readfile && (await checkFile(readfile))) {
17
+ configFile = await readConfig(readfile)
18
+ }
19
+
20
+ const mijinUrl = url ? url : configFile ? configFile.url : undefined
21
+
22
+ if (!mijinUrl) {
23
+ logger.error(`Must Set mijin URL(-u http://xxxxxx.com:3000) or Set Read Config(-r config.json)`)
24
+ return
25
+ }
26
+
27
+ let repo
28
+
29
+ try {
30
+ repo = new RepositoryFactory(mijinUrl)
31
+ await repo.init()
32
+ } catch (error) {
33
+ logger.error(`Please specify a valid URL: ${mijinUrl}`)
34
+ return
35
+ }
36
+
37
+ const networkType = repo.getNetwork()
38
+ const epoch = repo.getEpoch()
39
+
40
+ logger.info(`mijin URL: ${mijinUrl}`)
41
+ logger.info(`Network: ${networkType.toString()}`)
42
+
43
+ logger.info('Create Root Namespace...')
44
+
45
+ let createAccount
46
+
47
+ switch (owner) {
48
+ case 'work':
49
+ createAccount = configFile
50
+ ? AccountServices.createAccount(configFile.workAccount.privateKey, networkType)
51
+ : undefined
52
+ break
53
+ case 'balance':
54
+ createAccount = configFile
55
+ ? AccountServices.createAccount(configFile.balanceAccount.privateKey, networkType)
56
+ : undefined
57
+ break
58
+ case 'main':
59
+ createAccount = configFile
60
+ ? AccountServices.createAccount(configFile.mainAccount.privateKey, networkType)
61
+ : undefined
62
+ break
63
+ case 'test1':
64
+ createAccount = configFile
65
+ ? AccountServices.createAccount(configFile.test1Account.privateKey, networkType)
66
+ : undefined
67
+ break
68
+ case 'test2':
69
+ createAccount = configFile
70
+ ? AccountServices.createAccount(configFile.test2Account.privateKey, networkType)
71
+ : undefined
72
+ break
73
+ default:
74
+ createAccount =
75
+ privatekey && privatekey.length === 64 ? AccountServices.createAccount(privatekey, networkType) : undefined
76
+ break
77
+ }
78
+
79
+ if (!createAccount) {
80
+ logger.error('Create Account Not Found Set (-r config -o owner) or -p')
81
+ return
82
+ }
83
+
84
+ if (!duration) {
85
+ logger.error('duration Not Found Set -d option')
86
+ return
87
+ }
88
+
89
+ if (!name) {
90
+ logger.error('name Not Found Set -n option')
91
+ return
92
+ }
93
+
94
+ const minFeeMultiplier = repo.getTransactionFees().minFeeMultiplier
95
+ const createRootNamespaceTransaction = NamespaceServices.createRootNamespace(
96
+ epoch,
97
+ name,
98
+ duration,
99
+ networkType,
100
+ minFeeMultiplier
101
+ )
102
+ if (!createRootNamespaceTransaction) {
103
+ logger.error('invalid name option')
104
+ return
105
+ }
106
+
107
+ logger.info(`Root Namespace Owner Account: ${createAccount.address.plain()}`)
108
+ logger.info(`Namespace Name: ${name}`)
109
+ logger.info(`Namespace Transaction: ${JSON.stringify(createRootNamespaceTransaction)}`)
110
+ const signedTransaction = createAccount.sign(createRootNamespaceTransaction, repo.getGnerationHash())
111
+
112
+ logger.info(`Transaction Fee: ${repo.getTransactionFees().minFeeMultiplier}`)
113
+ logger.info(
114
+ `Namespace Rental Fee Per Block: ${repo.getNetworkProperties().plugins.namespace?.rootNamespaceRentalFeePerBlock}`
115
+ )
116
+ logger.info('Start Announce Transaction...')
117
+
118
+ const announce = await TransactionServices.announce(
119
+ signedTransaction,
120
+ repo.createLitener(),
121
+ repo.createTransactionRepository(),
122
+ repo.createReceiptRepository()
123
+ ).catch((err) => {
124
+ return err
125
+ })
126
+ if (announce instanceof Error) {
127
+ logger.error(`Namespace Announce ${announce}`)
128
+ return
129
+ }
130
+
131
+ logger.info('End Transaction')
132
+ logger.info(`${mijinUrl}/transactionStatus/${signedTransaction.hash}`)
133
+ logger.info(`${mijinUrl}/transactions/confirmed/${signedTransaction.hash}`)
134
+ }
@@ -0,0 +1,135 @@
1
+ import AccountServices from '../../service/AccountServices'
2
+ import RepositoryFactory from '../../service/RepositoryFactory'
3
+ import { INamespaceCreateOption } from '../../types'
4
+ import LoggerFactory from '../../service/Logger'
5
+ import { readConfig, checkFile } from '../../utils'
6
+ import TransactionServices from '../../service/TransactionServices'
7
+ import NamespaceServices from '../../service/NamespaceServices'
8
+
9
+ const logger = LoggerFactory.getLogger()
10
+
11
+ export default async (option: INamespaceCreateOption) => {
12
+ const { owner, url, readfile, name, parentName, privatekey } = option
13
+
14
+ let configFile
15
+
16
+ if (readfile && (await checkFile(readfile))) {
17
+ configFile = await readConfig(readfile)
18
+ }
19
+
20
+ const mijinUrl = url ? url : configFile ? configFile.url : undefined
21
+
22
+ if (!mijinUrl) {
23
+ logger.error(`Must Set mijin URL(-u http://xxxxxx.com:3000) or Set Read Config(-r config.json)`)
24
+ return
25
+ }
26
+
27
+ let repo
28
+
29
+ try {
30
+ repo = new RepositoryFactory(mijinUrl)
31
+ await repo.init()
32
+ } catch (error) {
33
+ logger.error(`Please specify a valid URL: ${mijinUrl}`)
34
+ return
35
+ }
36
+
37
+ const networkType = repo.getNetwork()
38
+ const epoch = repo.getEpoch()
39
+
40
+ logger.info(`mijin URL: ${mijinUrl}`)
41
+ logger.info(`Network: ${networkType.toString()}`)
42
+
43
+ logger.info('Create Sub Namespace...')
44
+
45
+ let createAccount
46
+
47
+ switch (owner) {
48
+ case 'work':
49
+ createAccount = configFile
50
+ ? AccountServices.createAccount(configFile.workAccount.privateKey, networkType)
51
+ : undefined
52
+ break
53
+ case 'balance':
54
+ createAccount = configFile
55
+ ? AccountServices.createAccount(configFile.balanceAccount.privateKey, networkType)
56
+ : undefined
57
+ break
58
+ case 'main':
59
+ createAccount = configFile
60
+ ? AccountServices.createAccount(configFile.mainAccount.privateKey, networkType)
61
+ : undefined
62
+ break
63
+ case 'test1':
64
+ createAccount = configFile
65
+ ? AccountServices.createAccount(configFile.test1Account.privateKey, networkType)
66
+ : undefined
67
+ break
68
+ case 'test2':
69
+ createAccount = configFile
70
+ ? AccountServices.createAccount(configFile.test2Account.privateKey, networkType)
71
+ : undefined
72
+ break
73
+ default:
74
+ createAccount =
75
+ privatekey && privatekey.length === 64 ? AccountServices.createAccount(privatekey, networkType) : undefined
76
+ break
77
+ }
78
+
79
+ if (!createAccount) {
80
+ logger.error('Create Account Not Found Set (-r config -o owner) or -p')
81
+ return
82
+ }
83
+
84
+ if (!name) {
85
+ logger.error('Namespace name Not Found Set -n option')
86
+ return
87
+ }
88
+
89
+ if (!parentName) {
90
+ logger.error('Namespace parentName Not Found Set -pn option')
91
+ return
92
+ }
93
+
94
+ const minFeeMultiplier = repo.getTransactionFees().minFeeMultiplier
95
+ const createsubNamespaceTransaction = NamespaceServices.createSubNamespace(
96
+ epoch,
97
+ name,
98
+ parentName,
99
+ networkType,
100
+ minFeeMultiplier
101
+ )
102
+ if (!createsubNamespaceTransaction) {
103
+ logger.error('invalid name option')
104
+ return
105
+ }
106
+
107
+ logger.info(`Sub Namespace Owner Account: ${createAccount.address.plain()}`)
108
+ logger.info(`Namespace Name: ${name}`)
109
+ logger.info(`Namespace Parent Name: ${parentName}`)
110
+ logger.info(`Namespace Transaction: ${JSON.stringify(createsubNamespaceTransaction)}`)
111
+ const signedTransaction = createAccount.sign(createsubNamespaceTransaction, repo.getGnerationHash())
112
+
113
+ logger.info(`Transaction Fee: ${repo.getTransactionFees().minFeeMultiplier}`)
114
+ logger.info(
115
+ `Namespace Rental Fee Per Block: ${repo.getNetworkProperties().plugins.namespace?.rootNamespaceRentalFeePerBlock}`
116
+ )
117
+ logger.info('Start Announce Transaction...')
118
+
119
+ const announce = await TransactionServices.announce(
120
+ signedTransaction,
121
+ repo.createLitener(),
122
+ repo.createTransactionRepository(),
123
+ repo.createReceiptRepository()
124
+ ).catch((err) => {
125
+ return err
126
+ })
127
+ if (announce instanceof Error) {
128
+ logger.error(`Namespace Announce ${announce}`)
129
+ return
130
+ }
131
+
132
+ logger.info('End Transaction')
133
+ logger.info(`${mijinUrl}/transactionStatus/${signedTransaction.hash}`)
134
+ logger.info(`${mijinUrl}/transactions/confirmed/${signedTransaction.hash}`)
135
+ }
@@ -0,0 +1,145 @@
1
+ import {
2
+ UInt64,
3
+ NamespaceRegistrationTransaction,
4
+ Deadline,
5
+ NetworkType,
6
+ NamespaceId,
7
+ NamespaceRepository,
8
+ NamespaceInfo,
9
+ AliasAction,
10
+ AliasTransaction,
11
+ MosaicId,
12
+ Address,
13
+ } from '@tech-bureau/symbol-sdk'
14
+ import { firstValueFrom } from 'rxjs'
15
+
16
+ export default class NamespaceServices {
17
+ constructor() {}
18
+
19
+ static createRootNamespace(
20
+ epoch: number,
21
+ name: string,
22
+ duration: number,
23
+ networkType: NetworkType,
24
+ feeMultiplier: number
25
+ ) {
26
+ // check name
27
+ const namespace = this.getNamespaceId(name)
28
+ if (!namespace) {
29
+ return null
30
+ }
31
+ return NamespaceRegistrationTransaction.createRootNamespace(
32
+ Deadline.create(epoch),
33
+ name,
34
+ UInt64.fromUint(duration),
35
+ networkType
36
+ ).setMaxFee(feeMultiplier)
37
+ }
38
+
39
+ static createSubNamespace(
40
+ epoch: number,
41
+ name: string,
42
+ parentName: string,
43
+ networkType: NetworkType,
44
+ feeMultiplier: number
45
+ ) {
46
+ // check name and parent name
47
+ const namespace = this.getNamespaceId(name)
48
+ if (!namespace) {
49
+ return null
50
+ }
51
+ const parentNamespace = this.getNamespaceId(parentName)
52
+ if (!parentNamespace) {
53
+ return null
54
+ }
55
+ return NamespaceRegistrationTransaction.createSubNamespace(
56
+ Deadline.create(epoch),
57
+ name,
58
+ parentName,
59
+ networkType
60
+ ).setMaxFee(feeMultiplier)
61
+ }
62
+
63
+ static linkMosaic(
64
+ epoch: number,
65
+ namespaceId: string,
66
+ mosaicId: string,
67
+ networkType: NetworkType,
68
+ feeMultiplier: number
69
+ ) {
70
+ const namespace = this.getNamespaceId(namespaceId)
71
+ if (!namespace) {
72
+ return null
73
+ }
74
+ let mosaic: MosaicId | null = null
75
+ try {
76
+ mosaic = new MosaicId(mosaicId)
77
+ } catch {}
78
+ if (!mosaic) {
79
+ return null
80
+ }
81
+ const mosaicAliasTransaction = AliasTransaction.createForMosaic(
82
+ Deadline.create(epoch),
83
+ AliasAction.Link,
84
+ namespace,
85
+ mosaic,
86
+ networkType
87
+ ).setMaxFee(feeMultiplier) as AliasTransaction
88
+ return mosaicAliasTransaction
89
+ }
90
+
91
+ static linkAddress(
92
+ epoch: number,
93
+ namespaceId: string,
94
+ address: string,
95
+ networkType: NetworkType,
96
+ feeMultiplier: number
97
+ ) {
98
+ const namespace = this.getNamespaceId(namespaceId)
99
+ if (!namespace) {
100
+ return null
101
+ }
102
+ if (!Address.isValidRawAddress(address)) {
103
+ return null
104
+ }
105
+ const addressObj = Address.createFromRawAddress(address)
106
+ const addressAliasTransaction = AliasTransaction.createForAddress(
107
+ Deadline.create(epoch),
108
+ AliasAction.Link,
109
+ namespace,
110
+ addressObj,
111
+ networkType
112
+ ).setMaxFee(feeMultiplier)
113
+ return addressAliasTransaction
114
+ }
115
+
116
+ static getNamespaceId(id: string) {
117
+ let namespaceId: NamespaceId | null = null
118
+ try {
119
+ namespaceId = new NamespaceId(id)
120
+ } catch {}
121
+ try {
122
+ namespaceId = NamespaceId.createFromEncoded(id)
123
+ } catch {}
124
+ return namespaceId
125
+ }
126
+
127
+ static async getNamespace(namespaceId: string, namespaceRepository: NamespaceRepository) {
128
+ const convertedNamespaceId = this.getNamespaceId(namespaceId)
129
+ if (!convertedNamespaceId) {
130
+ return null
131
+ }
132
+ const namespaceInfo = await firstValueFrom(namespaceRepository.getNamespace(convertedNamespaceId)).catch(() => null)
133
+ return namespaceInfo
134
+ }
135
+ static namespaceInfo(namespaceInfo: NamespaceInfo) {
136
+ return {
137
+ active: namespaceInfo.active,
138
+ ownerAddress: namespaceInfo.ownerAddress.plain(),
139
+ namespaceId: namespaceInfo.id.toHex(),
140
+ parentId: namespaceInfo.parentId.toHex(),
141
+ aliasMosaicId: namespaceInfo.alias.mosaicId?.toHex(),
142
+ aliasAddress: namespaceInfo.alias.address?.plain(),
143
+ }
144
+ }
145
+ }
@@ -0,0 +1,17 @@
1
+ export interface INamespaceCreateOption {
2
+ owner: string
3
+ url?: string
4
+ name: string
5
+ duration?: number
6
+ parentName?: string
7
+ mosaicId?: string
8
+ address?: string
9
+ readfile?: string
10
+ privatekey?: string
11
+ }
12
+
13
+ export interface INamespaceInfoOption {
14
+ url?: string
15
+ readfile?: string
16
+ namespaceId?: string
17
+ }
@@ -7,3 +7,4 @@ export * from './ILinkOption'
7
7
  export * from './ConfigFile'
8
8
  export * from './IVotingOption'
9
9
  export * from './IMosaicOption'
10
+ export * from './INamespaceOption'