@semaphore-protocol/cli 0.1.0 → 0.3.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.
- package/README.md +23 -9
- package/dist/index.js +116 -47
- package/package.json +5 -2
- package/src/index.ts +116 -49
- package/src/spinner.ts +25 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<h1 align="center">
|
|
3
3
|
Semaphore CLI
|
|
4
4
|
</h1>
|
|
5
|
-
<p align="center">A command line tool to set up
|
|
5
|
+
<p align="center">A command line tool to set up your Semaphore project and get group data.</p>
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
8
|
<p align="center">
|
|
@@ -46,23 +46,37 @@
|
|
|
46
46
|
</h4>
|
|
47
47
|
</div>
|
|
48
48
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
49
|
+
| Setting up a project, although not particularly complex, can be a lengthy process for some people. A command line to initialize a Semaphore project can reduce the set-up time from a few minutes to a few seconds. In addition, the Semaphore CLI can also be used to obtain on-chain group data. |
|
|
50
|
+
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
51
51
|
|
|
52
52
|
## 🛠 Install
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
Install the `@semaphore-protocol/cli` package with npm:
|
|
54
|
+
Install the `@semaphore-protocol/cli` package globally:
|
|
57
55
|
|
|
58
56
|
```bash
|
|
59
|
-
npm i @semaphore-protocol/cli
|
|
57
|
+
npm i -g @semaphore-protocol/cli
|
|
60
58
|
```
|
|
61
59
|
|
|
62
|
-
or
|
|
60
|
+
or run specific commands with `npx`:
|
|
63
61
|
|
|
64
62
|
```bash
|
|
65
|
-
|
|
63
|
+
npx @semaphore-protocol/cli init my-app
|
|
66
64
|
```
|
|
67
65
|
|
|
68
66
|
## 📜 Usage
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
Usage: semaphore [options] [command]
|
|
70
|
+
|
|
71
|
+
A command line tool to set up your Semaphore project and get group data.
|
|
72
|
+
|
|
73
|
+
Options:
|
|
74
|
+
-v, --version Show Semaphore CLI version.
|
|
75
|
+
-h, --help Display this help.
|
|
76
|
+
|
|
77
|
+
Commands:
|
|
78
|
+
init <project-directory> Initialize a Semaphore project with a supported template.
|
|
79
|
+
get-groups [options] Get the list of groups from a supported network (Goerli or Arbitrum).
|
|
80
|
+
get-group [options] <group-id> Get the data of a group from a supported network (Goerli or Arbitrum).
|
|
81
|
+
help [command] Display help for a specific command.
|
|
82
|
+
```
|
package/dist/index.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @module @semaphore-protocol/cli
|
|
5
|
-
* @version 0.
|
|
6
|
-
* @file A command line tool to set up
|
|
5
|
+
* @version 0.3.0
|
|
6
|
+
* @file A command line tool to set up your Semaphore project and get group data.
|
|
7
7
|
* @copyright Ethereum Foundation 2022
|
|
8
8
|
* @license MIT
|
|
9
9
|
* @see [Github]{@link https://github.com/semaphore-protocol/semaphore/tree/main/packages/cli}
|
|
@@ -12,69 +12,138 @@
|
|
|
12
12
|
import { Subgraph } from '@semaphore-protocol/subgraph';
|
|
13
13
|
import chalk from 'chalk';
|
|
14
14
|
import { program } from 'commander';
|
|
15
|
+
import download from 'download';
|
|
15
16
|
import figlet from 'figlet';
|
|
16
|
-
import { readFileSync } from 'fs';
|
|
17
|
-
import
|
|
17
|
+
import { readFileSync, existsSync, renameSync } from 'fs';
|
|
18
|
+
import logSymbols from 'log-symbols';
|
|
18
19
|
import { dirname } from 'path';
|
|
19
20
|
import { fileURLToPath } from 'url';
|
|
21
|
+
import ora from 'ora';
|
|
22
|
+
|
|
23
|
+
class Spinner {
|
|
24
|
+
constructor(text) {
|
|
25
|
+
this.text = text;
|
|
26
|
+
}
|
|
27
|
+
start() {
|
|
28
|
+
console.info("");
|
|
29
|
+
this.ora = ora({
|
|
30
|
+
text: this.text,
|
|
31
|
+
indent: 1
|
|
32
|
+
}).start();
|
|
33
|
+
}
|
|
34
|
+
stop() {
|
|
35
|
+
this.ora.stop();
|
|
36
|
+
process.stdout.cursorTo(0);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
20
39
|
|
|
21
|
-
/* eslint-disable no-console */
|
|
22
40
|
const packagePath = `${dirname(fileURLToPath(import.meta.url))}/..`;
|
|
23
|
-
const { version } = JSON.parse(readFileSync(`${packagePath}/package.json`, "utf8"));
|
|
41
|
+
const { description, version } = JSON.parse(readFileSync(`${packagePath}/package.json`, "utf8"));
|
|
24
42
|
program
|
|
25
43
|
.name("semaphore")
|
|
26
|
-
.description(
|
|
44
|
+
.description(description)
|
|
27
45
|
.version(version, "-v, --version", "Show Semaphore CLI version.")
|
|
28
|
-
.addHelpText("before", `${figlet.textSync("Semaphore
|
|
46
|
+
.addHelpText("before", `${figlet.textSync("Semaphore")}\n`)
|
|
47
|
+
.addHelpText("after", "\r")
|
|
29
48
|
.helpOption(undefined, "Display this help.")
|
|
30
|
-
.addHelpCommand("help [command]", "Display help for a specific command.")
|
|
49
|
+
.addHelpCommand("help [command]", "Display help for a specific command.")
|
|
50
|
+
.configureOutput({
|
|
51
|
+
outputError: (message) => {
|
|
52
|
+
console.info(`\n ${logSymbols.error}`, message);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
program
|
|
56
|
+
.command("init")
|
|
57
|
+
.description("Initialize a Semaphore project with a supported template.")
|
|
58
|
+
.argument("<project-directory>", "Directory of the project.")
|
|
59
|
+
// .option("-t, --template <template-name>", "Supported Semaphore template.", "hardhat")
|
|
60
|
+
.action(async (projectDirectory) => {
|
|
61
|
+
const currentDirectory = process.cwd();
|
|
62
|
+
const spinner = new Spinner(`Creating your project in ${chalk.green(`./${projectDirectory}`)}`);
|
|
63
|
+
const templateURL = `https://registry.npmjs.org/@semaphore-protocol/cli-template-hardhat/-/cli-template-hardhat-${version}.tgz`;
|
|
64
|
+
if (existsSync(projectDirectory)) {
|
|
65
|
+
console.info(`\n ${logSymbols.error}`, `error: the '${projectDirectory}' folder already exists\n`);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
spinner.start();
|
|
69
|
+
await download(templateURL, currentDirectory, { extract: true });
|
|
70
|
+
renameSync(`${currentDirectory}/package`, `${currentDirectory}/${projectDirectory}`);
|
|
71
|
+
spinner.stop();
|
|
72
|
+
console.info(` ${logSymbols.success}`, `Your project is ready!\n`);
|
|
73
|
+
console.info(` Please, install your dependencies by running:\n`);
|
|
74
|
+
console.info(` ${chalk.cyan("cd")} ${projectDirectory}`);
|
|
75
|
+
console.info(` ${chalk.cyan("npm i")}\n`);
|
|
76
|
+
const { scripts } = JSON.parse(readFileSync(`${currentDirectory}/${projectDirectory}/package.json`, "utf8"));
|
|
77
|
+
if (scripts) {
|
|
78
|
+
console.info(` Available scripts:\n`);
|
|
79
|
+
console.info(`${Object.keys(scripts)
|
|
80
|
+
.map((s) => ` ${chalk.cyan(`npm run ${s}`)}`)
|
|
81
|
+
.join("\n")}\n`);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
program
|
|
85
|
+
.command("get-groups")
|
|
86
|
+
.description("Get the list of groups from a supported network (Goerli or Arbitrum).")
|
|
87
|
+
.option("-n, --network <network-name>", "Supported Ethereum network.", "goerli")
|
|
88
|
+
.action(async ({ network }) => {
|
|
89
|
+
const subgraph = new Subgraph(network);
|
|
90
|
+
const spinner = new Spinner("Fetching groups");
|
|
91
|
+
spinner.start();
|
|
92
|
+
try {
|
|
93
|
+
const groups = await subgraph.getGroups();
|
|
94
|
+
spinner.stop();
|
|
95
|
+
if (groups.length === 0) {
|
|
96
|
+
console.info(` ${logSymbols.error}`, "error: there are no groups in this network\n");
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const content = `${groups.map(({ id }) => ` - ${id}`).join("\n")}`;
|
|
100
|
+
console.info(`${content}\n`);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
spinner.stop();
|
|
104
|
+
console.info(` ${logSymbols.error}`, "error: unexpected error with the Semaphore subgraph");
|
|
105
|
+
}
|
|
106
|
+
});
|
|
31
107
|
program
|
|
32
108
|
.command("get-group")
|
|
33
|
-
.description("Get the data of a group from a supported network.")
|
|
109
|
+
.description("Get the data of a group from a supported network (Goerli or Arbitrum).")
|
|
34
110
|
.argument("<group-id>", "Identifier of the group.")
|
|
35
111
|
.option("-n, --network <network-name>", "Supported Ethereum network.", "goerli")
|
|
36
112
|
.option("--members", "Show group members.")
|
|
37
113
|
.option("--signals", "Show group signals.")
|
|
38
114
|
.action(async (groupId, { network, members, signals }) => {
|
|
39
115
|
const subgraph = new Subgraph(network);
|
|
40
|
-
const spinner =
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
content +=
|
|
54
|
-
|
|
55
|
-
|
|
116
|
+
const spinner = new Spinner(`Fetching group ${groupId}`);
|
|
117
|
+
spinner.start();
|
|
118
|
+
try {
|
|
119
|
+
const group = await subgraph.getGroup(groupId, { members, verifiedProofs: signals });
|
|
120
|
+
spinner.stop();
|
|
121
|
+
if (!group) {
|
|
122
|
+
console.info(` ${logSymbols.error}`, "error: the group does not exist\n");
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
let content = ` ${chalk.bold("Id")}: ${group.id}\n`;
|
|
126
|
+
content += ` ${chalk.bold("Admin")}: ${group.admin}\n`;
|
|
127
|
+
content += ` ${chalk.bold("Merkle tree")}:\n`;
|
|
128
|
+
content += ` Root: ${group.merkleTree.root}\n`;
|
|
129
|
+
content += ` Depth: ${group.merkleTree.depth}\n`;
|
|
130
|
+
content += ` Zero value: ${group.merkleTree.zeroValue}\n`;
|
|
131
|
+
content += ` Number of leaves: ${group.merkleTree.numberOfLeaves}`;
|
|
132
|
+
if (members) {
|
|
133
|
+
content += `\n\n ${chalk.bold("Members")}: \n${group.members
|
|
134
|
+
.map((member, i) => ` ${i}. ${member}`)
|
|
135
|
+
.join("\n")}`;
|
|
136
|
+
}
|
|
137
|
+
if (signals) {
|
|
138
|
+
content += `\n\n ${chalk.bold("Signals")}: \n${group.verifiedProofs
|
|
139
|
+
.map(({ signal }) => ` - ${signal}`)
|
|
140
|
+
.join("\n")}`;
|
|
141
|
+
}
|
|
142
|
+
console.info(`${content}\n`);
|
|
56
143
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
.join("\n")}`;
|
|
144
|
+
catch (error) {
|
|
145
|
+
spinner.stop();
|
|
146
|
+
console.info(` ${logSymbols.error}`, "error: unexpected error with the Semaphore subgraph");
|
|
61
147
|
}
|
|
62
|
-
spinner.stop();
|
|
63
|
-
console.log(`${content}\n`);
|
|
64
|
-
});
|
|
65
|
-
program
|
|
66
|
-
.command("get-groups")
|
|
67
|
-
.description("Get the list of groups from a supported network.")
|
|
68
|
-
.option("-n, --network <network-name>", "Supported Ethereum network.", "goerli")
|
|
69
|
-
.action(async ({ network }) => {
|
|
70
|
-
const subgraph = new Subgraph(network);
|
|
71
|
-
const spinner = ora({
|
|
72
|
-
text: `Fetching groups`,
|
|
73
|
-
indent: 1
|
|
74
|
-
}).start();
|
|
75
|
-
const groups = await subgraph.getGroups();
|
|
76
|
-
const content = `\n${groups.map(({ id }) => ` - ${id}`).join("\n")}`;
|
|
77
|
-
spinner.stop();
|
|
78
|
-
console.log(`${content}\n`);
|
|
79
148
|
});
|
|
80
149
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@semaphore-protocol/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
5
|
-
"description": "A command line tool to set up
|
|
4
|
+
"version": "0.3.0",
|
|
5
|
+
"description": "A command line tool to set up your Semaphore project and get group data.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
8
8
|
"semaphore": "dist/index.js"
|
|
@@ -40,9 +40,12 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@semaphore-protocol/subgraph": "2.6.1",
|
|
43
|
+
"@types/clear": "^0.1.2",
|
|
43
44
|
"chalk": "^5.1.2",
|
|
44
45
|
"commander": "^9.4.1",
|
|
46
|
+
"download": "^8.0.0",
|
|
45
47
|
"figlet": "^1.5.2",
|
|
48
|
+
"log-symbols": "^5.1.0",
|
|
46
49
|
"ora": "^6.1.2"
|
|
47
50
|
}
|
|
48
51
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,85 +1,152 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
1
|
import { Subgraph } from "@semaphore-protocol/subgraph"
|
|
3
2
|
import chalk from "chalk"
|
|
4
3
|
import { program } from "commander"
|
|
4
|
+
import download from "download"
|
|
5
5
|
import figlet from "figlet"
|
|
6
|
-
import { readFileSync } from "fs"
|
|
7
|
-
import
|
|
6
|
+
import { existsSync, readFileSync, renameSync } from "fs"
|
|
7
|
+
import logSymbols from "log-symbols"
|
|
8
8
|
import { dirname } from "path"
|
|
9
9
|
import { fileURLToPath } from "url"
|
|
10
|
+
import Spinner from "./spinner.js"
|
|
10
11
|
|
|
11
12
|
const packagePath = `${dirname(fileURLToPath(import.meta.url))}/..`
|
|
12
|
-
const { version } = JSON.parse(readFileSync(`${packagePath}/package.json`, "utf8"))
|
|
13
|
+
const { description, version } = JSON.parse(readFileSync(`${packagePath}/package.json`, "utf8"))
|
|
13
14
|
|
|
14
15
|
program
|
|
15
16
|
.name("semaphore")
|
|
16
|
-
.description(
|
|
17
|
+
.description(description)
|
|
17
18
|
.version(version, "-v, --version", "Show Semaphore CLI version.")
|
|
18
|
-
.addHelpText("before", `${figlet.textSync("Semaphore
|
|
19
|
+
.addHelpText("before", `${figlet.textSync("Semaphore")}\n`)
|
|
20
|
+
.addHelpText("after", "\r")
|
|
19
21
|
.helpOption(undefined, "Display this help.")
|
|
20
22
|
.addHelpCommand("help [command]", "Display help for a specific command.")
|
|
23
|
+
.configureOutput({
|
|
24
|
+
outputError: (message) => {
|
|
25
|
+
console.info(`\n ${logSymbols.error}`, message)
|
|
26
|
+
}
|
|
27
|
+
})
|
|
21
28
|
|
|
22
29
|
program
|
|
23
|
-
.command("
|
|
24
|
-
.description("
|
|
25
|
-
.argument("<
|
|
26
|
-
.option("-
|
|
27
|
-
.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}).start()
|
|
36
|
-
|
|
37
|
-
const group = await subgraph.getGroup(groupId, { members, verifiedProofs: signals })
|
|
38
|
-
|
|
39
|
-
let content = `\n ${chalk.bold("Id")}: ${group.id}\n`
|
|
40
|
-
content += ` ${chalk.bold("Admin")}: ${group.admin}\n`
|
|
41
|
-
content += ` ${chalk.bold("Merkle tree")}:\n`
|
|
42
|
-
content += ` Root: ${group.merkleTree.root}\n`
|
|
43
|
-
content += ` Depth: ${group.merkleTree.depth}\n`
|
|
44
|
-
content += ` Zero value: ${group.merkleTree.zeroValue}\n`
|
|
45
|
-
content += ` Number of leaves: ${group.merkleTree.numberOfLeaves}`
|
|
46
|
-
|
|
47
|
-
if (members) {
|
|
48
|
-
content += `\n\n ${chalk.bold("Members")}: \n${group.members
|
|
49
|
-
.map((member: string, i: number) => ` ${i}. ${member}`)
|
|
50
|
-
.join("\n")}`
|
|
30
|
+
.command("init")
|
|
31
|
+
.description("Initialize a Semaphore project with a supported template.")
|
|
32
|
+
.argument("<project-directory>", "Directory of the project.")
|
|
33
|
+
// .option("-t, --template <template-name>", "Supported Semaphore template.", "hardhat")
|
|
34
|
+
.action(async (projectDirectory) => {
|
|
35
|
+
const currentDirectory = process.cwd()
|
|
36
|
+
const spinner = new Spinner(`Creating your project in ${chalk.green(`./${projectDirectory}`)}`)
|
|
37
|
+
const templateURL = `https://registry.npmjs.org/@semaphore-protocol/cli-template-hardhat/-/cli-template-hardhat-${version}.tgz`
|
|
38
|
+
|
|
39
|
+
if (existsSync(projectDirectory)) {
|
|
40
|
+
console.info(`\n ${logSymbols.error}`, `error: the '${projectDirectory}' folder already exists\n`)
|
|
41
|
+
return
|
|
51
42
|
}
|
|
52
43
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
44
|
+
spinner.start()
|
|
45
|
+
|
|
46
|
+
await download(templateURL, currentDirectory, { extract: true })
|
|
47
|
+
|
|
48
|
+
renameSync(`${currentDirectory}/package`, `${currentDirectory}/${projectDirectory}`)
|
|
58
49
|
|
|
59
50
|
spinner.stop()
|
|
60
51
|
|
|
61
|
-
console.
|
|
52
|
+
console.info(` ${logSymbols.success}`, `Your project is ready!\n`)
|
|
53
|
+
console.info(` Please, install your dependencies by running:\n`)
|
|
54
|
+
console.info(` ${chalk.cyan("cd")} ${projectDirectory}`)
|
|
55
|
+
console.info(` ${chalk.cyan("npm i")}\n`)
|
|
56
|
+
|
|
57
|
+
const { scripts } = JSON.parse(readFileSync(`${currentDirectory}/${projectDirectory}/package.json`, "utf8"))
|
|
58
|
+
|
|
59
|
+
if (scripts) {
|
|
60
|
+
console.info(` Available scripts:\n`)
|
|
61
|
+
|
|
62
|
+
console.info(
|
|
63
|
+
`${Object.keys(scripts)
|
|
64
|
+
.map((s) => ` ${chalk.cyan(`npm run ${s}`)}`)
|
|
65
|
+
.join("\n")}\n`
|
|
66
|
+
)
|
|
67
|
+
}
|
|
62
68
|
})
|
|
63
69
|
|
|
64
70
|
program
|
|
65
71
|
.command("get-groups")
|
|
66
|
-
.description("Get the list of groups from a supported network.")
|
|
72
|
+
.description("Get the list of groups from a supported network (Goerli or Arbitrum).")
|
|
67
73
|
.option("-n, --network <network-name>", "Supported Ethereum network.", "goerli")
|
|
68
74
|
.action(async ({ network }) => {
|
|
69
75
|
const subgraph = new Subgraph(network)
|
|
76
|
+
const spinner = new Spinner("Fetching groups")
|
|
70
77
|
|
|
71
|
-
|
|
72
|
-
text: `Fetching groups`,
|
|
73
|
-
indent: 1
|
|
74
|
-
}).start()
|
|
78
|
+
spinner.start()
|
|
75
79
|
|
|
76
|
-
|
|
80
|
+
try {
|
|
81
|
+
const groups = await subgraph.getGroups()
|
|
77
82
|
|
|
78
|
-
|
|
83
|
+
spinner.stop()
|
|
79
84
|
|
|
80
|
-
|
|
85
|
+
if (groups.length === 0) {
|
|
86
|
+
console.info(` ${logSymbols.error}`, "error: there are no groups in this network\n")
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const content = `${groups.map(({ id }: any) => ` - ${id}`).join("\n")}`
|
|
91
|
+
|
|
92
|
+
console.info(`${content}\n`)
|
|
93
|
+
} catch (error) {
|
|
94
|
+
spinner.stop()
|
|
95
|
+
|
|
96
|
+
console.info(` ${logSymbols.error}`, "error: unexpected error with the Semaphore subgraph")
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
program
|
|
101
|
+
.command("get-group")
|
|
102
|
+
.description("Get the data of a group from a supported network (Goerli or Arbitrum).")
|
|
103
|
+
.argument("<group-id>", "Identifier of the group.")
|
|
104
|
+
.option("-n, --network <network-name>", "Supported Ethereum network.", "goerli")
|
|
105
|
+
.option("--members", "Show group members.")
|
|
106
|
+
.option("--signals", "Show group signals.")
|
|
107
|
+
.action(async (groupId, { network, members, signals }) => {
|
|
108
|
+
const subgraph = new Subgraph(network)
|
|
109
|
+
const spinner = new Spinner(`Fetching group ${groupId}`)
|
|
81
110
|
|
|
82
|
-
|
|
111
|
+
spinner.start()
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
const group = await subgraph.getGroup(groupId, { members, verifiedProofs: signals })
|
|
115
|
+
|
|
116
|
+
spinner.stop()
|
|
117
|
+
|
|
118
|
+
if (!group) {
|
|
119
|
+
console.info(` ${logSymbols.error}`, "error: the group does not exist\n")
|
|
120
|
+
|
|
121
|
+
return
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let content = ` ${chalk.bold("Id")}: ${group.id}\n`
|
|
125
|
+
content += ` ${chalk.bold("Admin")}: ${group.admin}\n`
|
|
126
|
+
content += ` ${chalk.bold("Merkle tree")}:\n`
|
|
127
|
+
content += ` Root: ${group.merkleTree.root}\n`
|
|
128
|
+
content += ` Depth: ${group.merkleTree.depth}\n`
|
|
129
|
+
content += ` Zero value: ${group.merkleTree.zeroValue}\n`
|
|
130
|
+
content += ` Number of leaves: ${group.merkleTree.numberOfLeaves}`
|
|
131
|
+
|
|
132
|
+
if (members) {
|
|
133
|
+
content += `\n\n ${chalk.bold("Members")}: \n${group.members
|
|
134
|
+
.map((member: string, i: number) => ` ${i}. ${member}`)
|
|
135
|
+
.join("\n")}`
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (signals) {
|
|
139
|
+
content += `\n\n ${chalk.bold("Signals")}: \n${group.verifiedProofs
|
|
140
|
+
.map(({ signal }: any) => ` - ${signal}`)
|
|
141
|
+
.join("\n")}`
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
console.info(`${content}\n`)
|
|
145
|
+
} catch (error) {
|
|
146
|
+
spinner.stop()
|
|
147
|
+
|
|
148
|
+
console.info(` ${logSymbols.error}`, "error: unexpected error with the Semaphore subgraph")
|
|
149
|
+
}
|
|
83
150
|
})
|
|
84
151
|
|
|
85
152
|
program.parse()
|
package/src/spinner.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import ora, { Ora } from "ora"
|
|
2
|
+
|
|
3
|
+
export default class Spinner {
|
|
4
|
+
private text: string
|
|
5
|
+
private ora: Ora
|
|
6
|
+
|
|
7
|
+
constructor(text: string) {
|
|
8
|
+
this.text = text
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
start() {
|
|
12
|
+
console.info("")
|
|
13
|
+
|
|
14
|
+
this.ora = ora({
|
|
15
|
+
text: this.text,
|
|
16
|
+
indent: 1
|
|
17
|
+
}).start()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
stop() {
|
|
21
|
+
this.ora.stop()
|
|
22
|
+
|
|
23
|
+
process.stdout.cursorTo(0)
|
|
24
|
+
}
|
|
25
|
+
}
|