@witnet/sdk 1.0.3 → 1.0.4

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 (197) hide show
  1. package/.env_witnet +6 -6
  2. package/LICENSE +21 -21
  3. package/README.md +103 -103
  4. package/dist/bin/helpers.d.ts +88 -0
  5. package/dist/bin/helpers.d.ts.map +1 -0
  6. package/dist/bin/helpers.js +866 -0
  7. package/dist/index.d.ts +4 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +42 -0
  10. package/dist/lib/crypto/account.d.ts +18 -0
  11. package/dist/lib/crypto/account.d.ts.map +1 -0
  12. package/dist/lib/crypto/account.js +152 -0
  13. package/dist/lib/crypto/coinbase.d.ts +9 -0
  14. package/dist/lib/crypto/coinbase.d.ts.map +1 -0
  15. package/dist/lib/crypto/coinbase.js +39 -0
  16. package/dist/lib/crypto/index.d.ts +7 -0
  17. package/dist/lib/crypto/index.d.ts.map +1 -0
  18. package/dist/lib/crypto/index.js +28 -0
  19. package/dist/lib/crypto/interfaces.d.ts +80 -0
  20. package/dist/lib/crypto/interfaces.d.ts.map +1 -0
  21. package/dist/lib/crypto/interfaces.js +3 -0
  22. package/dist/lib/crypto/payloads/DataRequestPayload.d.ts +47 -0
  23. package/dist/lib/crypto/payloads/DataRequestPayload.d.ts.map +1 -0
  24. package/dist/lib/crypto/payloads/DataRequestPayload.js +384 -0
  25. package/dist/lib/crypto/payloads/StakePayload.d.ts +27 -0
  26. package/dist/lib/crypto/payloads/StakePayload.d.ts.map +1 -0
  27. package/dist/lib/crypto/payloads/StakePayload.js +184 -0
  28. package/dist/lib/crypto/payloads/UnstakePayload.d.ts +35 -0
  29. package/dist/lib/crypto/payloads/UnstakePayload.d.ts.map +1 -0
  30. package/dist/lib/crypto/payloads/UnstakePayload.js +244 -0
  31. package/dist/lib/crypto/payloads/ValueTransferPayload.d.ts +24 -0
  32. package/dist/lib/crypto/payloads/ValueTransferPayload.d.ts.map +1 -0
  33. package/dist/lib/crypto/payloads/ValueTransferPayload.js +182 -0
  34. package/dist/lib/crypto/payloads.d.ts +54 -0
  35. package/dist/lib/crypto/payloads.d.ts.map +1 -0
  36. package/dist/lib/crypto/payloads.js +224 -0
  37. package/dist/lib/crypto/signer.d.ts +26 -0
  38. package/dist/lib/crypto/signer.d.ts.map +1 -0
  39. package/dist/lib/crypto/signer.js +299 -0
  40. package/dist/lib/crypto/transmitters/DataRequests.d.ts +14 -0
  41. package/dist/lib/crypto/transmitters/DataRequests.d.ts.map +1 -0
  42. package/dist/lib/crypto/transmitters/DataRequests.js +62 -0
  43. package/dist/lib/crypto/transmitters/StakeDeposits.d.ts +11 -0
  44. package/dist/lib/crypto/transmitters/StakeDeposits.d.ts.map +1 -0
  45. package/dist/lib/crypto/transmitters/StakeDeposits.js +48 -0
  46. package/dist/lib/crypto/transmitters/StakeWithdrawals.d.ts +17 -0
  47. package/dist/lib/crypto/transmitters/StakeWithdrawals.d.ts.map +1 -0
  48. package/dist/lib/crypto/transmitters/StakeWithdrawals.js +115 -0
  49. package/dist/lib/crypto/transmitters/ValueTransfers.d.ts +10 -0
  50. package/dist/lib/crypto/transmitters/ValueTransfers.d.ts.map +1 -0
  51. package/dist/lib/crypto/transmitters/ValueTransfers.js +47 -0
  52. package/dist/lib/crypto/transmitters.d.ts +46 -0
  53. package/dist/lib/crypto/transmitters.d.ts.map +1 -0
  54. package/dist/lib/crypto/transmitters.js +506 -0
  55. package/dist/lib/crypto/types.d.ts +127 -0
  56. package/dist/lib/crypto/types.d.ts.map +1 -0
  57. package/dist/lib/crypto/types.js +261 -0
  58. package/dist/lib/crypto/utils.d.ts +10 -0
  59. package/dist/lib/crypto/utils.d.ts.map +1 -0
  60. package/dist/lib/crypto/utils.js +97 -0
  61. package/dist/lib/crypto/wallet.d.ts +26 -0
  62. package/dist/lib/crypto/wallet.d.ts.map +1 -0
  63. package/dist/lib/crypto/wallet.js +327 -0
  64. package/dist/lib/helpers.d.ts +90 -0
  65. package/dist/lib/helpers.d.ts.map +1 -0
  66. package/dist/lib/helpers.js +1031 -0
  67. package/dist/lib/index.d.ts +5 -0
  68. package/dist/lib/index.d.ts.map +1 -0
  69. package/dist/lib/index.js +21 -0
  70. package/dist/lib/radon/artifacts.d.ts +55 -0
  71. package/dist/lib/radon/artifacts.d.ts.map +1 -0
  72. package/dist/lib/radon/artifacts.js +347 -0
  73. package/dist/lib/radon/ccdr/eth.d.ts +100 -0
  74. package/dist/lib/radon/ccdr/eth.d.ts.map +1 -0
  75. package/dist/lib/radon/ccdr/eth.js +237 -0
  76. package/dist/lib/radon/ccdr/index.d.ts +34 -0
  77. package/dist/lib/radon/ccdr/index.d.ts.map +1 -0
  78. package/dist/lib/radon/ccdr/index.js +63 -0
  79. package/dist/lib/radon/ccdr/wit.d.ts +29 -0
  80. package/dist/lib/radon/ccdr/wit.d.ts.map +1 -0
  81. package/dist/lib/radon/ccdr/wit.js +60 -0
  82. package/dist/lib/radon/filters.d.ts +14 -0
  83. package/dist/lib/radon/filters.d.ts.map +1 -0
  84. package/dist/lib/radon/filters.js +47 -0
  85. package/dist/lib/radon/index.d.ts +36 -0
  86. package/dist/lib/radon/index.d.ts.map +1 -0
  87. package/dist/lib/radon/index.js +154 -0
  88. package/dist/lib/radon/reducers.d.ts +29 -0
  89. package/dist/lib/radon/reducers.d.ts.map +1 -0
  90. package/dist/lib/radon/reducers.js +101 -0
  91. package/dist/lib/radon/retrievals.d.ts +120 -0
  92. package/dist/lib/radon/retrievals.d.ts.map +1 -0
  93. package/dist/lib/radon/retrievals.js +358 -0
  94. package/dist/lib/radon/sources.d.ts +102 -0
  95. package/dist/lib/radon/sources.d.ts.map +1 -0
  96. package/dist/lib/radon/sources.js +294 -0
  97. package/dist/lib/radon/types.d.ts +521 -0
  98. package/dist/lib/radon/types.d.ts.map +1 -0
  99. package/dist/lib/radon/types.js +1066 -0
  100. package/dist/lib/radon/utils.d.ts +55 -0
  101. package/dist/lib/radon/utils.d.ts.map +1 -0
  102. package/dist/lib/radon/utils.js +181 -0
  103. package/dist/lib/rpc/farm.d.ts +66 -0
  104. package/dist/lib/rpc/farm.d.ts.map +1 -0
  105. package/dist/lib/rpc/farm.js +808 -0
  106. package/dist/lib/rpc/index.d.ts +3 -0
  107. package/dist/lib/rpc/index.d.ts.map +1 -0
  108. package/dist/lib/rpc/index.js +19 -0
  109. package/dist/lib/rpc/node.d.ts +38 -0
  110. package/dist/lib/rpc/node.d.ts.map +1 -0
  111. package/dist/lib/rpc/node.js +335 -0
  112. package/dist/lib/rpc/nodes.d.ts +40 -0
  113. package/dist/lib/rpc/nodes.d.ts.map +1 -0
  114. package/dist/lib/rpc/nodes.js +531 -0
  115. package/dist/lib/rpc/provider.d.ts +72 -0
  116. package/dist/lib/rpc/provider.d.ts.map +1 -0
  117. package/dist/lib/rpc/provider.js +402 -0
  118. package/dist/lib/rpc/reporter.d.ts +18 -0
  119. package/dist/lib/rpc/reporter.d.ts.map +1 -0
  120. package/dist/lib/rpc/reporter.js +99 -0
  121. package/dist/lib/rpc/types.d.ts +396 -0
  122. package/dist/lib/rpc/types.d.ts.map +1 -0
  123. package/dist/lib/rpc/types.js +81 -0
  124. package/dist/lib/rpc/wallet.d.ts +72 -0
  125. package/dist/lib/rpc/wallet.d.ts.map +1 -0
  126. package/dist/lib/rpc/wallet.js +41 -0
  127. package/dist/lib/types.d.ts +19 -0
  128. package/dist/lib/types.d.ts.map +1 -0
  129. package/dist/lib/types.js +7 -0
  130. package/dist/lib/utils.d.ts +5 -0
  131. package/dist/lib/utils.d.ts.map +1 -0
  132. package/dist/lib/utils.js +51 -0
  133. package/dist/package.json +1 -1
  134. package/dist/src/bin/helpers.js +1 -1
  135. package/dist/src/index.js +1 -1
  136. package/dist/src/lib/crypto/account.js +1 -1
  137. package/dist/src/lib/crypto/coinbase.js +1 -1
  138. package/dist/src/lib/crypto/index.js +1 -1
  139. package/dist/src/lib/crypto/interfaces.js +1 -1
  140. package/dist/src/lib/crypto/payloads/DataRequestPayload.js +1 -1
  141. package/dist/src/lib/crypto/payloads/StakePayload.js +1 -1
  142. package/dist/src/lib/crypto/payloads/UnstakePayload.js +1 -1
  143. package/dist/src/lib/crypto/payloads/ValueTransferPayload.js +1 -1
  144. package/dist/src/lib/crypto/payloads.js +1 -1
  145. package/dist/src/lib/crypto/signer.js +1 -1
  146. package/dist/src/lib/crypto/transmitters/DataRequests.js +1 -1
  147. package/dist/src/lib/crypto/transmitters/StakeDeposits.js +1 -1
  148. package/dist/src/lib/crypto/transmitters/StakeWithdrawals.js +1 -1
  149. package/dist/src/lib/crypto/transmitters/ValueTransfers.js +1 -1
  150. package/dist/src/lib/crypto/transmitters.js +1 -1
  151. package/dist/src/lib/crypto/types.js +1 -1
  152. package/dist/src/lib/crypto/utils.js +1 -1
  153. package/dist/src/lib/crypto/wallet.js +1 -1
  154. package/dist/src/lib/index.js +1 -1
  155. package/dist/src/lib/radon/ccdr/eth.js +1 -1
  156. package/dist/src/lib/radon/ccdr/index.js +1 -1
  157. package/dist/src/lib/radon/ccdr/wit.js +1 -1
  158. package/dist/src/lib/radon/filters.js +1 -1
  159. package/dist/src/lib/radon/index.js +1 -1
  160. package/dist/src/lib/radon/reducers.js +1 -1
  161. package/dist/src/lib/radon/types.js +1 -1
  162. package/dist/src/lib/radon/utils.js +1 -1
  163. package/dist/src/lib/rpc/index.js +1 -1
  164. package/dist/src/lib/rpc/nodes.js +1 -1
  165. package/dist/src/lib/rpc/provider.js +1 -1
  166. package/dist/src/lib/rpc/reporter.js +1 -1
  167. package/dist/src/lib/rpc/types.js +1 -1
  168. package/dist/src/lib/types.d.ts +1 -1
  169. package/dist/src/lib/types.d.ts.map +1 -1
  170. package/dist/src/lib/types.js +1 -1
  171. package/dist/src/lib/utils.js +1 -1
  172. package/dist/witnet/assets/index.js +1 -1
  173. package/dist/witnet/assets/modals/index.js +1 -1
  174. package/dist/witnet/assets/modals/web3/eth.js +1 -1
  175. package/dist/witnet/assets/modals/web3/ipfs.js +1 -1
  176. package/dist/witnet/assets/modals/web3/wit.js +1 -1
  177. package/dist/witnet/assets/requests.js +1 -1
  178. package/package.json +1 -1
  179. package/src/bin/cli/history.js +31 -31
  180. package/src/bin/cli/inspect.js +405 -405
  181. package/src/bin/cli/network.js +594 -594
  182. package/src/bin/cli/nodes.js +364 -364
  183. package/src/bin/cli/radon.js +815 -815
  184. package/src/bin/cli/wallet.js +1117 -1117
  185. package/src/bin/helpers.js +840 -840
  186. package/src/bin/postinstall.js +9 -9
  187. package/src/bin/toolkit.js +295 -295
  188. package/witnet/assets/_index.js +8 -8
  189. package/witnet/assets/_requests.js +25 -25
  190. package/witnet/assets/_sources.js +36 -36
  191. package/witnet/assets/_templates.js +36 -36
  192. package/witnet/assets/index.js +4 -4
  193. package/witnet/assets/modals/index.js +9 -9
  194. package/witnet/assets/modals/web3/eth.js +29 -29
  195. package/witnet/assets/modals/web3/ipfs.js +19 -19
  196. package/witnet/assets/modals/web3/wit.js +21 -21
  197. package/witnet/assets/requests.js +95 -95
@@ -1,364 +1,364 @@
1
- const qrcode = require("qrcode-terminal")
2
- const helpers = require("../helpers")
3
- const { Witnet } = require("../../../dist/src")
4
-
5
- const { cyan, gray, green, red, yellow, white, mcyan, mgreen, mmagenta, mred, myellow, lcyan, lgreen, lmagenta, lyellow } = helpers.colors
6
-
7
- /// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8
- /// CLI SUBMODULE CONSTANTS ===========================================================================================
9
-
10
- module.exports = {
11
- envars: {
12
- WITNET_TOOLKIT_FARM_NODES: "=> URLs to your own nodes' HTTP/JSON private endpoints, if no otherwise specified.",
13
- },
14
- flags: {
15
- nodes: {
16
- hint: "Private URLs to your node's HTTP/JSON endpoints, other than default.",
17
- param: "JSON_HTTP_URL[;..]",
18
- },
19
- },
20
- router: {
21
- authorize: {
22
- hint: "Generate stake authorization codes for given withdrawer.",
23
- params: "WITHDRAWER",
24
- options: {
25
- qrcodes: {
26
- hint: "Print authorization QR codes, scannable from myWitWallet.",
27
- },
28
- },
29
- },
30
- balance: {
31
- hint: "List endpoints that connect to your nodes, addresses and available balances.",
32
- },
33
- masterKeys: {
34
- hint: "Export nodes' master keys.",
35
- },
36
- publicKeys: {
37
- hint: "Export nodes' public keys.",
38
- },
39
- peers: {
40
- hint: "List and manage node farm's peers.",
41
- options: {
42
- add: {
43
- hint: "Add new peer addresses for the nodes to try to connect to.",
44
- param: "P2P_IP:PORT[;..]",
45
- },
46
- "clear-buckets": {
47
- hint: "Clear out all peering buckets.",
48
- },
49
- reset: {
50
- hint: "Clear all peers from the buckets and initialize to those in config.",
51
- },
52
- },
53
- },
54
- rankings: {
55
- hint: "Sort identities by their current mining power ranking.",
56
- options: {
57
- witnessing: { hint: "Sort by witnessing power ranking instead." },
58
- },
59
- },
60
- rewind: {
61
- hint: "Rewind blockchain state on farm nodes to this epoch.",
62
- params: "EPOCH",
63
- },
64
- stats: {
65
- hint: "Report farm stats.",
66
- },
67
- syncStatus: {
68
- hint: "Report current sync status for every node in the farm.",
69
- },
70
- withdrawers: {
71
- hint: "List withdrawers and stake entries currently delegating to the farm nodes.",
72
- },
73
- },
74
- subcommands: {
75
- addresses,
76
- authorize,
77
- balance,
78
- masterKeys,
79
- publicKeys,
80
- peers,
81
- rankings,
82
- rewind,
83
- stats,
84
- syncStatus,
85
- withdrawers,
86
- },
87
- }
88
-
89
- /// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
90
- /// CLI SUBMODULE COMMANDS ============================================================================================
91
-
92
- async function _initializeFarm (options = {}) {
93
- return new Witnet.JsonRpcNodeFarm(options?.nodes)
94
- }
95
-
96
- async function addresses (options = {}) {
97
- const farm = await _initializeFarm(options)
98
- const addresses = Object.entries(await farm.addresses())
99
- if (addresses.length === 1 && !(addresses[0][1] instanceof Error)) {
100
- console.info(lcyan(addresses[0][1]))
101
- qrcode.generate(addresses[0][1])
102
- } else {
103
- helpers.traceTable(
104
- addresses.map(([url, pkh]) => [
105
- pkh instanceof Error ? red(url) : mcyan(url),
106
- pkh instanceof Error ? red(pkh) : lcyan(pkh),
107
- ]), {
108
- headlines: ["NODES", ":Public Key Hash"],
109
- },
110
- )
111
- }
112
- }
113
-
114
- async function authorize (options = {}, args = []) {
115
- if (args.length === 0) {
116
- throw Error("Withdrawer address must be specified")
117
- } else {
118
- Witnet.PublicKeyHash.fromBech32(args[0])
119
- const farm = await _initializeFarm(options)
120
- const authcodes = await farm.authorizeStakes(args[0].toLowerCase())
121
- Object.entries(authcodes).forEach(([url, [validator, authcode]]) => {
122
- if (url instanceof Error) {
123
- console.error(url)
124
- } else if (validator instanceof Error) {
125
- console.error("Endpoint:", url)
126
- console.error(validator)
127
- } else if (authcode instanceof Error) {
128
- console.info("Validator address: ", mcyan(validator))
129
- console.error(authcode)
130
- } else {
131
- console.info("Validator address: ", mcyan(validator))
132
- console.info(`${white(authcode)}`)
133
- if (options?.qrcodes) qrcode.generate(authcode)
134
- }
135
- console.info()
136
- })
137
- if (options?.qrcodes) {
138
- console.info("=".repeat(102))
139
- console.info("^ Withdrawer address:", lmagenta(args[0].toLowerCase()))
140
- } else {
141
- console.info("Withdrawer address:", lmagenta(args[0].toLowerCase()))
142
- }
143
- }
144
- }
145
-
146
- async function balance (options = {}) {
147
- const farm = await _initializeFarm(options)
148
- const balances = await farm.balances()
149
- helpers.traceTable(
150
- Object.entries(balances).map(([url, [pkh, balance]]) => [
151
- pkh instanceof Error ? red(url) : mcyan(url),
152
- pkh instanceof Error ? red(pkh) : lcyan(pkh),
153
- ...(balance instanceof Error
154
- ? new Array(4).fill(gray("n/a"))
155
- : [
156
- gray(Witnet.Coins.fromNanowits(balance.locked).wits),
157
- yellow(Witnet.Coins.fromNanowits(balance.staked).wits),
158
- myellow(Witnet.Coins.fromNanowits(balance.unlocked).wits),
159
- lyellow(Witnet.Coins.fromNanowits(balance.locked + balance.staked + balance.unlocked).wits),
160
- ]
161
- ),
162
- ]), {
163
- headlines: ["NODES", ":Validator address", "Locked ($WIT)", "Staked ($WIT)", "Available ($WIT)", "BALANCE ($WIT)"],
164
- humanizers: [,, helpers.commas, helpers.commas, helpers.commas, helpers.commas],
165
- maxColumnWidth: 48,
166
- },
167
- )
168
- }
169
-
170
- async function masterKeys (options = {}) {
171
- const farm = await _initializeFarm(options)
172
- const masterKeys = await farm.masterKeys()
173
- helpers.traceTable(
174
- Object.entries(masterKeys).map(([, [pkh, masterKey]]) => [
175
- // pkh instanceof Error ? cyan(url) : mcyan(url),
176
- pkh instanceof Error ? red(pkh) : mcyan(pkh),
177
- masterKey instanceof Error ? mred(masterKey) : cyan(masterKey),
178
- ]), {
179
- headlines: [":Public key hash", "Secret key"],
180
- maxColumnWidth: 120,
181
- },
182
- )
183
- }
184
-
185
- async function peers (options = {}) {
186
- const farm = await _initializeFarm(options)
187
- const checklists = {}
188
- if (options.reset) {
189
- checklists["Reset peers"] = await farm.initializePeers()
190
- } else if (options["clear-buckets"]) {
191
- checklists["Clear buckets"] = await farm.clearPeers()
192
- }
193
- if (options.add) {
194
- const morePeers = options.add.replaceAll(",", ";").split(";")
195
- checklists["Add peers"] = await farm.addPeers(morePeers)
196
- }
197
- helpers.traceChecklists(checklists)
198
- const peers = await farm.peers()
199
- if (peers.length > 0) {
200
- console.log(peers)
201
- }
202
- }
203
-
204
- async function publicKeys (options = {}) {
205
- const farm = await _initializeFarm(options)
206
- const publicKeys = await farm.publicKeys()
207
- helpers.traceTable(
208
- Object.entries(publicKeys).map(([, [pkh, publicKey]]) => [
209
- pkh instanceof Error ? red(pkh) : mcyan(pkh),
210
- publicKey instanceof Error ? mred(publicKey.toString()) : cyan(publicKey.toString()),
211
- ]), {
212
- headlines: [":Public key hash", "Public key"],
213
- maxColumnWidth: 120,
214
- },
215
- )
216
- }
217
-
218
- async function rankings (options = {}) {
219
- const farm = await _initializeFarm(options)
220
- const addresses = Object.entries(await farm.addresses())
221
- const validators = []
222
- let provider
223
- addresses.forEach(([url, pkh]) => {
224
- if (pkh instanceof Error) {
225
- console.error(`> Skipping node ${url}: ${pkh}`)
226
- } else {
227
- if (!provider) provider = new Witnet.JsonRpcProvider(url)
228
- validators.push(pkh)
229
- }
230
- })
231
- if (validators.length > 0 && provider) {
232
- const query = {
233
- distinct: true,
234
- orderBy: options?.witnessing ? "witnessing" : "mining",
235
- }
236
- const capability = query.orderBy.toUpperCase()
237
- const records = await provider.powers(query)
238
- if (records.length > 0) {
239
- helpers.traceTable(
240
- records
241
- .filter(record => validators.includes(record.validator))
242
- .map(({ power, ranking, validator, withdrawer }) => [
243
- validator,
244
- withdrawer,
245
- power,
246
- ranking,
247
- ]),
248
- {
249
- headlines: [
250
- "VALIDATORS",
251
- "Withdrawer",
252
- `${capability} POWER`,
253
- "G_RANK",
254
- ],
255
- humanizers: [
256
- ,, helpers.commas, helpers.commas,
257
- ],
258
- colors: [
259
- lcyan, mmagenta, green, lgreen,
260
- ],
261
- },
262
- )
263
- } else {
264
- console.info(`> No ${capability} power is currently treasured on the farm.`)
265
- }
266
- } else {
267
- console.info("> No nodes currently available to interact with.")
268
- }
269
- }
270
-
271
- async function rewind (options = {}, args = []) {
272
- if (!args || args.length === 0) {
273
- throw Error("No rewind epoch was provided")
274
- }
275
- if (!options?.force) {
276
- const will = await helpers.prompt("Rewinding will reset some stats. Do you want to proceed anyways? (y/N)")
277
- // Abort if not confirmed
278
- if (!["y"].includes(will.toLowerCase())) {
279
- console.error("Aborted by user.")
280
- return
281
- }
282
- }
283
- const farm = await _initializeFarm(options)
284
- const epoch = parseInt(args[0])
285
- helpers.traceChecklists({
286
- "Rewind chain": await farm.rewind(epoch),
287
- })
288
- syncStatus(options)
289
- }
290
-
291
- async function stats (options = {}) {
292
- const farm = await _initializeFarm(options)
293
- const stats = await farm.stats()
294
- helpers.traceTable(
295
- Object.entries(stats).map(([url, stats]) => [
296
- ...(stats instanceof Error
297
- ? [red(url), gray("n/a"), gray("n/a"), gray("n/a"), gray("n/a"), gray("n/a"), gray("n/a")]
298
- : [
299
- mcyan(url),
300
- stats.block_mined_count,
301
- stats.commits_count,
302
- (stats.block_mined_count / stats.block_proposed_count).toFixed(3),
303
- (stats.commits_count / stats.commits_proposed_count).toFixed(3),
304
- ((stats.dr_eligibility_count - stats.commits_proposed_count) / stats.dr_eligibility_count).toFixed(3),
305
- (stats.slashed_count / stats.commits_count).toFixed(3),
306
- ]
307
- ),
308
- ]), {
309
- headlines: [
310
- "NODES",
311
- "Mined blocks",
312
- "Witnessed DRs",
313
- "M_Acceptancy",
314
- "W_Acceptancy",
315
- "W_Reluctancy",
316
- "W_Falsity",
317
- ],
318
- humanizers: [, helpers.commas, helpers.commas,,,,],
319
- },
320
- )
321
- }
322
-
323
- async function syncStatus (options) {
324
- const farm = await _initializeFarm(options)
325
- const syncStatus = await farm.syncStatus()
326
- helpers.traceTable(
327
- Object.entries(syncStatus).map(([url, status]) => [
328
- status instanceof Error ? red(url) : mcyan(url),
329
- ...(status instanceof Error
330
- ? [red(status), "", "", ""]
331
- : [
332
- status.node_state.trim() === "Synced" ? mgreen(status.node_state) : myellow(status.node_state),
333
- status.current_epoch,
334
- status.chain_beacon.checkpoint,
335
- status.chain_beacon.hashPrevBlock,
336
- ]),
337
- ]), {
338
- headlines: [":NODES", ":Status", "Current epoch", "Checkpoint epoch", ":Checkpoint block hash"],
339
- humanizers: [,, helpers.commas, helpers.commas],
340
- colors: [,, white,, gray], // gray, gray ],
341
- }
342
- )
343
- }
344
-
345
- async function withdrawers (options = {}) {
346
- const farm = await _initializeFarm(options)
347
- const records = await farm.withdrawers()
348
- if (records && Object.keys(records).length > 0) {
349
- helpers.traceTable(
350
- Object.entries(records).map(([withdrawer, [coins, nonce]]) => [
351
- withdrawer,
352
- nonce,
353
- Witnet.Coins.fromNanowits(coins).wits,
354
- ]),
355
- {
356
- headlines: ["WITHDRAWERS", "Latest nonce", "Total staked ($WIT)"],
357
- humanizers: [, helpers.commas, helpers.commas],
358
- colors: [mmagenta,, myellow],
359
- },
360
- )
361
- } else {
362
- console.info("> No withdrawers delegating on the farm at the moment.")
363
- }
364
- }
1
+ const qrcode = require("qrcode-terminal")
2
+ const helpers = require("../helpers")
3
+ const { Witnet } = require("../../../dist/src")
4
+
5
+ const { cyan, gray, green, red, yellow, white, mcyan, mgreen, mmagenta, mred, myellow, lcyan, lgreen, lmagenta, lyellow } = helpers.colors
6
+
7
+ /// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8
+ /// CLI SUBMODULE CONSTANTS ===========================================================================================
9
+
10
+ module.exports = {
11
+ envars: {
12
+ WITNET_TOOLKIT_FARM_NODES: "=> URLs to your own nodes' HTTP/JSON private endpoints, if no otherwise specified.",
13
+ },
14
+ flags: {
15
+ nodes: {
16
+ hint: "Private URLs to your node's HTTP/JSON endpoints, other than default.",
17
+ param: "JSON_HTTP_URL[;..]",
18
+ },
19
+ },
20
+ router: {
21
+ authorize: {
22
+ hint: "Generate stake authorization codes for given withdrawer.",
23
+ params: "WITHDRAWER",
24
+ options: {
25
+ qrcodes: {
26
+ hint: "Print authorization QR codes, scannable from myWitWallet.",
27
+ },
28
+ },
29
+ },
30
+ balance: {
31
+ hint: "List endpoints that connect to your nodes, addresses and available balances.",
32
+ },
33
+ masterKeys: {
34
+ hint: "Export nodes' master keys.",
35
+ },
36
+ publicKeys: {
37
+ hint: "Export nodes' public keys.",
38
+ },
39
+ peers: {
40
+ hint: "List and manage node farm's peers.",
41
+ options: {
42
+ add: {
43
+ hint: "Add new peer addresses for the nodes to try to connect to.",
44
+ param: "P2P_IP:PORT[;..]",
45
+ },
46
+ "clear-buckets": {
47
+ hint: "Clear out all peering buckets.",
48
+ },
49
+ reset: {
50
+ hint: "Clear all peers from the buckets and initialize to those in config.",
51
+ },
52
+ },
53
+ },
54
+ rankings: {
55
+ hint: "Sort identities by their current mining power ranking.",
56
+ options: {
57
+ witnessing: { hint: "Sort by witnessing power ranking instead." },
58
+ },
59
+ },
60
+ rewind: {
61
+ hint: "Rewind blockchain state on farm nodes to this epoch.",
62
+ params: "EPOCH",
63
+ },
64
+ stats: {
65
+ hint: "Report farm stats.",
66
+ },
67
+ syncStatus: {
68
+ hint: "Report current sync status for every node in the farm.",
69
+ },
70
+ withdrawers: {
71
+ hint: "List withdrawers and stake entries currently delegating to the farm nodes.",
72
+ },
73
+ },
74
+ subcommands: {
75
+ addresses,
76
+ authorize,
77
+ balance,
78
+ masterKeys,
79
+ publicKeys,
80
+ peers,
81
+ rankings,
82
+ rewind,
83
+ stats,
84
+ syncStatus,
85
+ withdrawers,
86
+ },
87
+ }
88
+
89
+ /// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
90
+ /// CLI SUBMODULE COMMANDS ============================================================================================
91
+
92
+ async function _initializeFarm (options = {}) {
93
+ return new Witnet.JsonRpcNodeFarm(options?.nodes)
94
+ }
95
+
96
+ async function addresses (options = {}) {
97
+ const farm = await _initializeFarm(options)
98
+ const addresses = Object.entries(await farm.addresses())
99
+ if (addresses.length === 1 && !(addresses[0][1] instanceof Error)) {
100
+ console.info(lcyan(addresses[0][1]))
101
+ qrcode.generate(addresses[0][1])
102
+ } else {
103
+ helpers.traceTable(
104
+ addresses.map(([url, pkh]) => [
105
+ pkh instanceof Error ? red(url) : mcyan(url),
106
+ pkh instanceof Error ? red(pkh) : lcyan(pkh),
107
+ ]), {
108
+ headlines: ["NODES", ":Public Key Hash"],
109
+ },
110
+ )
111
+ }
112
+ }
113
+
114
+ async function authorize (options = {}, args = []) {
115
+ if (args.length === 0) {
116
+ throw Error("Withdrawer address must be specified")
117
+ } else {
118
+ Witnet.PublicKeyHash.fromBech32(args[0])
119
+ const farm = await _initializeFarm(options)
120
+ const authcodes = await farm.authorizeStakes(args[0].toLowerCase())
121
+ Object.entries(authcodes).forEach(([url, [validator, authcode]]) => {
122
+ if (url instanceof Error) {
123
+ console.error(url)
124
+ } else if (validator instanceof Error) {
125
+ console.error("Endpoint:", url)
126
+ console.error(validator)
127
+ } else if (authcode instanceof Error) {
128
+ console.info("Validator address: ", mcyan(validator))
129
+ console.error(authcode)
130
+ } else {
131
+ console.info("Validator address: ", mcyan(validator))
132
+ console.info(`${white(authcode)}`)
133
+ if (options?.qrcodes) qrcode.generate(authcode)
134
+ }
135
+ console.info()
136
+ })
137
+ if (options?.qrcodes) {
138
+ console.info("=".repeat(102))
139
+ console.info("^ Withdrawer address:", lmagenta(args[0].toLowerCase()))
140
+ } else {
141
+ console.info("Withdrawer address:", lmagenta(args[0].toLowerCase()))
142
+ }
143
+ }
144
+ }
145
+
146
+ async function balance (options = {}) {
147
+ const farm = await _initializeFarm(options)
148
+ const balances = await farm.balances()
149
+ helpers.traceTable(
150
+ Object.entries(balances).map(([url, [pkh, balance]]) => [
151
+ pkh instanceof Error ? red(url) : mcyan(url),
152
+ pkh instanceof Error ? red(pkh) : lcyan(pkh),
153
+ ...(balance instanceof Error
154
+ ? new Array(4).fill(gray("n/a"))
155
+ : [
156
+ gray(Witnet.Coins.fromNanowits(balance.locked).wits),
157
+ yellow(Witnet.Coins.fromNanowits(balance.staked).wits),
158
+ myellow(Witnet.Coins.fromNanowits(balance.unlocked).wits),
159
+ lyellow(Witnet.Coins.fromNanowits(balance.locked + balance.staked + balance.unlocked).wits),
160
+ ]
161
+ ),
162
+ ]), {
163
+ headlines: ["NODES", ":Validator address", "Locked ($WIT)", "Staked ($WIT)", "Available ($WIT)", "BALANCE ($WIT)"],
164
+ humanizers: [,, helpers.commas, helpers.commas, helpers.commas, helpers.commas],
165
+ maxColumnWidth: 48,
166
+ },
167
+ )
168
+ }
169
+
170
+ async function masterKeys (options = {}) {
171
+ const farm = await _initializeFarm(options)
172
+ const masterKeys = await farm.masterKeys()
173
+ helpers.traceTable(
174
+ Object.entries(masterKeys).map(([, [pkh, masterKey]]) => [
175
+ // pkh instanceof Error ? cyan(url) : mcyan(url),
176
+ pkh instanceof Error ? red(pkh) : mcyan(pkh),
177
+ masterKey instanceof Error ? mred(masterKey) : cyan(masterKey),
178
+ ]), {
179
+ headlines: [":Public key hash", "Secret key"],
180
+ maxColumnWidth: 120,
181
+ },
182
+ )
183
+ }
184
+
185
+ async function peers (options = {}) {
186
+ const farm = await _initializeFarm(options)
187
+ const checklists = {}
188
+ if (options.reset) {
189
+ checklists["Reset peers"] = await farm.initializePeers()
190
+ } else if (options["clear-buckets"]) {
191
+ checklists["Clear buckets"] = await farm.clearPeers()
192
+ }
193
+ if (options.add) {
194
+ const morePeers = options.add.replaceAll(",", ";").split(";")
195
+ checklists["Add peers"] = await farm.addPeers(morePeers)
196
+ }
197
+ helpers.traceChecklists(checklists)
198
+ const peers = await farm.peers()
199
+ if (peers.length > 0) {
200
+ console.log(peers)
201
+ }
202
+ }
203
+
204
+ async function publicKeys (options = {}) {
205
+ const farm = await _initializeFarm(options)
206
+ const publicKeys = await farm.publicKeys()
207
+ helpers.traceTable(
208
+ Object.entries(publicKeys).map(([, [pkh, publicKey]]) => [
209
+ pkh instanceof Error ? red(pkh) : mcyan(pkh),
210
+ publicKey instanceof Error ? mred(publicKey.toString()) : cyan(publicKey.toString()),
211
+ ]), {
212
+ headlines: [":Public key hash", "Public key"],
213
+ maxColumnWidth: 120,
214
+ },
215
+ )
216
+ }
217
+
218
+ async function rankings (options = {}) {
219
+ const farm = await _initializeFarm(options)
220
+ const addresses = Object.entries(await farm.addresses())
221
+ const validators = []
222
+ let provider
223
+ addresses.forEach(([url, pkh]) => {
224
+ if (pkh instanceof Error) {
225
+ console.error(`> Skipping node ${url}: ${pkh}`)
226
+ } else {
227
+ if (!provider) provider = new Witnet.JsonRpcProvider(url)
228
+ validators.push(pkh)
229
+ }
230
+ })
231
+ if (validators.length > 0 && provider) {
232
+ const query = {
233
+ distinct: true,
234
+ orderBy: options?.witnessing ? "witnessing" : "mining",
235
+ }
236
+ const capability = query.orderBy.toUpperCase()
237
+ const records = await provider.powers(query)
238
+ if (records.length > 0) {
239
+ helpers.traceTable(
240
+ records
241
+ .filter(record => validators.includes(record.validator))
242
+ .map(({ power, ranking, validator, withdrawer }) => [
243
+ validator,
244
+ withdrawer,
245
+ power,
246
+ ranking,
247
+ ]),
248
+ {
249
+ headlines: [
250
+ "VALIDATORS",
251
+ "Withdrawer",
252
+ `${capability} POWER`,
253
+ "G_RANK",
254
+ ],
255
+ humanizers: [
256
+ ,, helpers.commas, helpers.commas,
257
+ ],
258
+ colors: [
259
+ lcyan, mmagenta, green, lgreen,
260
+ ],
261
+ },
262
+ )
263
+ } else {
264
+ console.info(`> No ${capability} power is currently treasured on the farm.`)
265
+ }
266
+ } else {
267
+ console.info("> No nodes currently available to interact with.")
268
+ }
269
+ }
270
+
271
+ async function rewind (options = {}, args = []) {
272
+ if (!args || args.length === 0) {
273
+ throw Error("No rewind epoch was provided")
274
+ }
275
+ if (!options?.force) {
276
+ const will = await helpers.prompt("Rewinding will reset some stats. Do you want to proceed anyways? (y/N)")
277
+ // Abort if not confirmed
278
+ if (!["y"].includes(will.toLowerCase())) {
279
+ console.error("Aborted by user.")
280
+ return
281
+ }
282
+ }
283
+ const farm = await _initializeFarm(options)
284
+ const epoch = parseInt(args[0])
285
+ helpers.traceChecklists({
286
+ "Rewind chain": await farm.rewind(epoch),
287
+ })
288
+ syncStatus(options)
289
+ }
290
+
291
+ async function stats (options = {}) {
292
+ const farm = await _initializeFarm(options)
293
+ const stats = await farm.stats()
294
+ helpers.traceTable(
295
+ Object.entries(stats).map(([url, stats]) => [
296
+ ...(stats instanceof Error
297
+ ? [red(url), gray("n/a"), gray("n/a"), gray("n/a"), gray("n/a"), gray("n/a"), gray("n/a")]
298
+ : [
299
+ mcyan(url),
300
+ stats.block_mined_count,
301
+ stats.commits_count,
302
+ (stats.block_mined_count / stats.block_proposed_count).toFixed(3),
303
+ (stats.commits_count / stats.commits_proposed_count).toFixed(3),
304
+ ((stats.dr_eligibility_count - stats.commits_proposed_count) / stats.dr_eligibility_count).toFixed(3),
305
+ (stats.slashed_count / stats.commits_count).toFixed(3),
306
+ ]
307
+ ),
308
+ ]), {
309
+ headlines: [
310
+ "NODES",
311
+ "Mined blocks",
312
+ "Witnessed DRs",
313
+ "M_Acceptancy",
314
+ "W_Acceptancy",
315
+ "W_Reluctancy",
316
+ "W_Falsity",
317
+ ],
318
+ humanizers: [, helpers.commas, helpers.commas,,,,],
319
+ },
320
+ )
321
+ }
322
+
323
+ async function syncStatus (options) {
324
+ const farm = await _initializeFarm(options)
325
+ const syncStatus = await farm.syncStatus()
326
+ helpers.traceTable(
327
+ Object.entries(syncStatus).map(([url, status]) => [
328
+ status instanceof Error ? red(url) : mcyan(url),
329
+ ...(status instanceof Error
330
+ ? [red(status), "", "", ""]
331
+ : [
332
+ status.node_state.trim() === "Synced" ? mgreen(status.node_state) : myellow(status.node_state),
333
+ status.current_epoch,
334
+ status.chain_beacon.checkpoint,
335
+ status.chain_beacon.hashPrevBlock,
336
+ ]),
337
+ ]), {
338
+ headlines: [":NODES", ":Status", "Current epoch", "Checkpoint epoch", ":Checkpoint block hash"],
339
+ humanizers: [,, helpers.commas, helpers.commas],
340
+ colors: [,, white,, gray], // gray, gray ],
341
+ }
342
+ )
343
+ }
344
+
345
+ async function withdrawers (options = {}) {
346
+ const farm = await _initializeFarm(options)
347
+ const records = await farm.withdrawers()
348
+ if (records && Object.keys(records).length > 0) {
349
+ helpers.traceTable(
350
+ Object.entries(records).map(([withdrawer, [coins, nonce]]) => [
351
+ withdrawer,
352
+ nonce,
353
+ Witnet.Coins.fromNanowits(coins).wits,
354
+ ]),
355
+ {
356
+ headlines: ["WITHDRAWERS", "Latest nonce", "Total staked ($WIT)"],
357
+ humanizers: [, helpers.commas, helpers.commas],
358
+ colors: [mmagenta,, myellow],
359
+ },
360
+ )
361
+ } else {
362
+ console.info("> No withdrawers delegating on the farm at the moment.")
363
+ }
364
+ }