@witnet/sdk 1.0.1 → 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 (211) 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 +2 -2
  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.d.ts +2 -2
  141. package/dist/src/lib/crypto/payloads/DataRequestPayload.d.ts.map +1 -1
  142. package/dist/src/lib/crypto/payloads/DataRequestPayload.js +8 -8
  143. package/dist/src/lib/crypto/payloads/StakePayload.js +1 -1
  144. package/dist/src/lib/crypto/payloads/UnstakePayload.js +1 -1
  145. package/dist/src/lib/crypto/payloads/ValueTransferPayload.js +1 -1
  146. package/dist/src/lib/crypto/payloads.js +1 -1
  147. package/dist/src/lib/crypto/signer.js +1 -1
  148. package/dist/src/lib/crypto/transmitters/DataRequests.d.ts +0 -1
  149. package/dist/src/lib/crypto/transmitters/DataRequests.d.ts.map +1 -1
  150. package/dist/src/lib/crypto/transmitters/DataRequests.js +1 -2
  151. package/dist/src/lib/crypto/transmitters/StakeDeposits.js +1 -1
  152. package/dist/src/lib/crypto/transmitters/StakeWithdrawals.js +1 -1
  153. package/dist/src/lib/crypto/transmitters/ValueTransfers.js +1 -1
  154. package/dist/src/lib/crypto/transmitters.js +1 -1
  155. package/dist/src/lib/crypto/types.js +1 -1
  156. package/dist/src/lib/crypto/utils.js +1 -1
  157. package/dist/src/lib/crypto/wallet.js +1 -1
  158. package/dist/src/lib/index.js +1 -1
  159. package/dist/src/lib/radon/ccdr/eth.js +1 -1
  160. package/dist/src/lib/radon/ccdr/index.js +1 -1
  161. package/dist/src/lib/radon/ccdr/wit.d.ts +11 -0
  162. package/dist/src/lib/radon/ccdr/wit.d.ts.map +1 -1
  163. package/dist/src/lib/radon/ccdr/wit.js +17 -2
  164. package/dist/src/lib/radon/filters.js +1 -1
  165. package/dist/src/lib/radon/index.d.ts +1 -1
  166. package/dist/src/lib/radon/index.d.ts.map +1 -1
  167. package/dist/src/lib/radon/index.js +9 -3
  168. package/dist/src/lib/radon/reducers.js +1 -1
  169. package/dist/src/lib/radon/types.js +1 -1
  170. package/dist/src/lib/radon/utils.js +1 -1
  171. package/dist/src/lib/rpc/index.js +1 -1
  172. package/dist/src/lib/rpc/nodes.js +1 -1
  173. package/dist/src/lib/rpc/provider.d.ts +5 -3
  174. package/dist/src/lib/rpc/provider.d.ts.map +1 -1
  175. package/dist/src/lib/rpc/provider.js +14 -3
  176. package/dist/src/lib/rpc/reporter.d.ts +2 -3
  177. package/dist/src/lib/rpc/reporter.d.ts.map +1 -1
  178. package/dist/src/lib/rpc/reporter.js +1 -4
  179. package/dist/src/lib/rpc/types.d.ts +49 -24
  180. package/dist/src/lib/rpc/types.d.ts.map +1 -1
  181. package/dist/src/lib/rpc/types.js +3 -1
  182. package/dist/src/lib/types.d.ts +1 -1
  183. package/dist/src/lib/types.d.ts.map +1 -1
  184. package/dist/src/lib/types.js +1 -1
  185. package/dist/src/lib/utils.js +1 -1
  186. package/dist/witnet/assets/index.js +1 -1
  187. package/dist/witnet/assets/modals/index.js +1 -1
  188. package/dist/witnet/assets/modals/web3/eth.js +1 -1
  189. package/dist/witnet/assets/modals/web3/ipfs.js +1 -1
  190. package/dist/witnet/assets/modals/web3/wit.js +4 -7
  191. package/dist/witnet/assets/requests.js +1 -1
  192. package/package.json +1 -1
  193. package/src/bin/cli/history.js +31 -31
  194. package/src/bin/cli/inspect.js +405 -359
  195. package/src/bin/cli/network.js +594 -592
  196. package/src/bin/cli/nodes.js +364 -364
  197. package/src/bin/cli/radon.js +815 -815
  198. package/src/bin/cli/wallet.js +1117 -1094
  199. package/src/bin/helpers.js +840 -840
  200. package/src/bin/postinstall.js +9 -9
  201. package/src/bin/toolkit.js +295 -295
  202. package/witnet/assets/_index.js +8 -8
  203. package/witnet/assets/_requests.js +25 -25
  204. package/witnet/assets/_sources.js +36 -36
  205. package/witnet/assets/_templates.js +36 -36
  206. package/witnet/assets/index.js +4 -4
  207. package/witnet/assets/modals/index.js +9 -9
  208. package/witnet/assets/modals/web3/eth.js +29 -29
  209. package/witnet/assets/modals/web3/ipfs.js +19 -19
  210. package/witnet/assets/modals/web3/wit.js +21 -23
  211. package/witnet/assets/requests.js +95 -95
@@ -1,840 +1,840 @@
1
- const { exec } = require("child_process")
2
- const moment = require("moment")
3
- const net = require("net")
4
- const os = require("os")
5
- const readline = require("readline")
6
-
7
- const colorstrip = (str) => str.replace(
8
- /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, ""
9
- )
10
-
11
- const commas = (number) => {
12
- const parts = number.toString().split(".")
13
- const result = parts.length <= 1
14
- ? `${parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",")}`
15
- : `${parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",")}.${parts[1]}`
16
- return result
17
- }
18
-
19
- function toFixedTrunc (x, n) {
20
- const v = (typeof x === "string" ? x : x.toString()).split(".")
21
- if (n <= 0) return v[0]
22
- let f = v[1] || ""
23
- if (f.length > n) return `${v[0]}.${f.substr(0, n)}`
24
- while (f.length < n) f += "0"
25
- return `${v[0]}.${f}`
26
- };
27
-
28
- const whole_wits = (number, digits) => {
29
- const lookup = [
30
- { value: 1n, symbol: "pedros" },
31
- { value: 10n ** 6n, symbol: "mWits" },
32
- { value: 10n ** 9n, symbol: " Wits" },
33
- { value: 10n ** 12n, symbol: "KWits" },
34
- { value: 10n ** 15n, symbol: "MWits" },
35
- ]
36
- // const regexp = /\.0+$|(?<=\.[0-9])0+$/
37
- const item = lookup.findLast(item => number >= item.value)
38
- const quotient = item ? Number(BigInt(number) / item.value) : number.toString()
39
- const decimals = item ? (item.value + BigInt(number) - BigInt(quotient) * item.value).toString().slice(1) : ""
40
- return item ? `${commas(quotient)}${decimals !== "" ? `.${decimals.slice(0, digits)}` : ""} ${item.symbol}` : "(no coins)"
41
- }
42
-
43
- const bblue = (str) => `\x1b[1;98;44m${str}\x1b[0;0;0m`
44
- const bcyan = (str) => `\x1b[38;46m${str}\x1b[0;0m`
45
- const bgreen = (str) => `\x1b[30;42m${str}\x1b[0;0m`
46
- const bred = (str) => `\x1b[30;41m${str}\x1b[0;0m`
47
- const bviolet = (str) => `\x1b[30;45m${str}\x1b[0;0m`
48
-
49
- const lcyan = (str) => `\x1b[1;96m${str}\x1b[0m`
50
- const lgray = (str) => `\x1b[1;90m${str}\x1b[0m`
51
- const lgreen = (str) => `\x1b[1;92m${str}\x1b[0m`
52
- const lmagenta = (str) => `\x1b[1;95m${str}\x1b[0m`
53
- const lyellow = (str) => `\x1b[1;93m${str}\x1b[0m`
54
- const mblue = (str) => `\x1b[94m${str}\x1b[0m`
55
- const mcyan = (str) => `\x1b[96m${str}\x1b[0m`
56
- const mgreen = (str) => `\x1b[92m${str}\x1b[0m`
57
- const mmagenta = (str) => `\x1b[0;95m${str}\x1b[0m`
58
- const mred = (str) => `\x1b[91m${str}\x1b[0m`
59
- const myellow = (str) => `\x1b[93m${str}\x1b[0m`
60
-
61
- const blue = (str) => `\x1b[34m${str}\x1b[0m`
62
- const cyan = (str) => `\x1b[36m${str}\x1b[0m`
63
- const gray = (str) => `\x1b[90m${str}\x1b[0m`
64
- const green = (str) => `\x1b[32m${str}\x1b[0m`
65
- const magenta = (str) => `\x1b[0;35m${str}\x1b[0m`
66
- const normal = (str) => `\x1b[98m${str}\x1b[0m`
67
- const red = (str) => `\x1b[31m${str}\x1b[0m`
68
- const white = (str) => `\x1b[1;98m${str}\x1b[0m`
69
- const yellow = (str) => `\x1b[33m${str}\x1b[0m`
70
-
71
- function countLeaves (t, obj) {
72
- if (!obj || typeof obj === "string") return 0
73
- if (obj instanceof t) return 1
74
- if (Array.isArray(obj)) return obj.reduce((sum, item) => sum + countLeaves(t, item), 0)
75
- else return Object.values(obj).reduce((sum, item) => sum + countLeaves(t, item), 0)
76
- }
77
-
78
- function deleteExtraFlags (args) {
79
- return args.filter(arg => !arg.startsWith("--"))
80
- }
81
-
82
- function cmd (...command) {
83
- return new Promise((resolve, reject) => {
84
- exec(command.join(" "), { maxBuffer: 1024 * 1024 * 10 }, (error, stdout, stderr) => {
85
- if (error) {
86
- reject(error)
87
- }
88
- if (stderr) {
89
- reject(stderr)
90
- }
91
- resolve(stdout)
92
- })
93
- })
94
- };
95
-
96
- async function execRadonBytecode (bytecode, ...flags) {
97
- if (!isHexString(bytecode)) {
98
- throw EvalError("invalid hex string")
99
- } else {
100
- const npx = os.type() === "Windows_NT" ? "npx.cmd" : "npx"
101
- return cmd(npx, "witnet", "radon", "dryrun", bytecode, ...flags)
102
- // .catch((err) => {
103
- // let errorMessage = err.message.split('\n').slice(1).join('\n').trim()
104
- // const errorRegex = /.*^error: (?<message>.*)$.*/gm
105
- // const matched = errorRegex.exec(err.message)
106
- // if (matched) {
107
- // errorMessage = matched.groups.message
108
- // }
109
- // console.log(errorMessage || err)
110
- // console.error(errorMessage || err)
111
- // })
112
- }
113
- }
114
-
115
- function extractFromArgs (args, flags) {
116
- const curated = {}
117
- if (args && flags) {
118
- Object.keys(flags).forEach(flag => {
119
- const flagIndex = args.indexOf(`--${flag}`)
120
- if (flagIndex >= 0) {
121
- if (flags[flag].param) {
122
- curated[flag] = args[flagIndex]
123
- if (!args[flagIndex + 1] || args[flagIndex + 1].startsWith("--")) {
124
- throw Error(`Missing required parameter for --${flag}`)
125
- } else {
126
- curated[flag] = args[flagIndex + 1]
127
- args.splice(flagIndex, 2)
128
- }
129
- } else {
130
- curated[flag] = true
131
- args.splice(flagIndex, 1)
132
- }
133
- }
134
- })
135
- }
136
- return [args, curated]
137
- }
138
-
139
- function fromHexString (hexString) {
140
- if (hexString.startsWith("0x")) hexString = hexString.slice(2)
141
- return Uint8Array.from(hexString.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)))
142
- }
143
-
144
- function ipIsPrivateOrLocalhost (ip) {
145
- if (ip.substring(0, 7) === "::ffff:") { ip = ip.substring(7) }
146
-
147
- if (net.isIPv4(ip)) {
148
- // check localhost
149
- if (ip === "127.0.0.1") { return true }
150
-
151
- // 10.0.0.0 - 10.255.255.255 || 172.16.0.0 - 172.31.255.255 || 192.168.0.0 - 192.168.255.255
152
- return /^(10)\.(.*)\.(.*)\.(.*)$/.test(ip) || /^(172)\.(1[6-9]|2[0-9]|3[0-1])\.(.*)\.(.*)$/.test(ip) || /^(192)\.(168)\.(.*)\.(.*)$/.test(ip)
153
- }
154
-
155
- // else: ip is IPv6
156
- const firstWord = ip.split(":").find(el => !!el) // get first not empty word
157
-
158
- // equivalent of 127.0.0.1 in IPv6
159
- if (ip === "::1") return true
160
-
161
- // The original IPv6 Site Local addresses (fec0::/10) are deprecated. Range: fec0 - feff
162
- else if (/^fe[c-f][0-f]$/.test(firstWord)) return true
163
-
164
- // These days Unique Local Addresses (ULA) are used in place of Site Local.
165
- // Range: fc00 - fcff
166
- else if (/^fc[0-f]{2}$/.test(firstWord)) return true
167
-
168
- // Range: fd00 - fcff
169
- else if (/^fd[0-f]{2}$/.test(firstWord)) return true
170
-
171
- // Link local addresses (prefixed with fe80) are not routable
172
- else if (firstWord === "fe80") return true
173
-
174
- // Discard Prefix
175
- else if (firstWord === "100") return true
176
-
177
- // Any other IP address is not Unique Local Address (ULA)
178
- return false
179
- }
180
-
181
- function isHexStringOfLength (str, length) {
182
- return (isHexString(str) &&
183
- (
184
- (str.startsWith("0x") && str.slice(2).length === length * 2) ||
185
- str.length === length * 2
186
- )
187
- ) || isWildcard(str)
188
- }
189
-
190
- function isHexString (str) {
191
- return (
192
- typeof str === "string" &&
193
- (
194
- (str.startsWith("0x") && /^[a-fA-F0-9]+$/i.test(str.slice(2))) ||
195
- /^[a-fA-F0-9]+$/i.test(str)
196
- )
197
- ) || isWildcard(str)
198
- }
199
-
200
- function toHexString (buffer, prefix0x = false) {
201
- if (buffer instanceof Uint8Array) buffer = Buffer.from(buffer)
202
- return (prefix0x ? "0x" : "") + Array.prototype.map.call(buffer, x => ("00" + x.toString(16)).slice(-2))
203
- .join("")
204
- .match(/[a-fA-F0-9]{2}/g)
205
- .join("")
206
- }
207
-
208
- function parseURL (url) {
209
- try {
210
- const parsedUrl = new URL(url)
211
- return [
212
- parsedUrl.protocol + "//",
213
- parsedUrl.host,
214
- parsedUrl.pathname.slice(1),
215
- parsedUrl.search.slice(1),
216
- ]
217
- } catch {
218
- throw new TypeError(`Invalid URL was provided: ${url}`)
219
- }
220
- }
221
-
222
- function showUsage (cmd, module) {
223
- showUsageHeadline(cmd)
224
- showUsageOptions({ ...module?.flags })
225
- showUsageFlags({ ...module?.flags })
226
- showUsageRouter({ ...module?.router })
227
- showUsageEnvars({ ...module?.envars })
228
- }
229
-
230
- function showUsageRouter (router) {
231
- const cmds = Object.entries(router)
232
- if (cmds.length > 0) {
233
- console.info("\nSUBCOMMANDS:")
234
- const maxLength = Math.max(...cmds.map(([cmd]) => cmd.length))
235
- cmds.forEach(cmd => {
236
- console.info(" ", `${cmd[0]}${" ".repeat(maxLength - cmd[0].length)}`, " ", cmd[1].hint)
237
- })
238
- }
239
- }
240
-
241
- function showUsageError (cmd, subcmd, module, error, flags) {
242
- showUsageSubcommand(cmd, subcmd, module, error)
243
- if (error) {
244
- console.info("\nERROR:")
245
- if (flags?.debug) {
246
- console.error(error)
247
- } else {
248
- console.error(error?.stack?.split("\n")[0] || error)
249
- }
250
- }
251
- }
252
-
253
- function showUsageEnvars (envars) {
254
- if (envars) {
255
- envars = Object.entries(envars)
256
- if (envars.length > 0) {
257
- console.info("\nENVARS:")
258
- const maxWidth = Math.max(...envars.map(([envar]) => envar.length))
259
- envars.forEach(([envar, hint]) => {
260
- if (envar.toUpperCase().indexOf("KEY") < 0 && process.env[envar]) {
261
- console.info(" ", `${yellow(envar.toUpperCase())}${" ".repeat(maxWidth - envar.length)}`, ` => Settled to "${myellow(process.env[envar])}"`)
262
- } else {
263
- console.info(" ", `${yellow(envar.toUpperCase())}${" ".repeat(maxWidth - envar.length)}`, ` ${hint}`)
264
- }
265
- })
266
- }
267
- }
268
- }
269
-
270
- function showUsageFlags (flags) {
271
- if (flags) {
272
- flags = Object.entries(flags).filter(([, flag]) => !flag?.param).sort(([a], [b]) => {
273
- if (a < b) return -1
274
- else if (a > b) return 1
275
- else return 0
276
- })
277
- if (flags.length > 0) {
278
- console.info("\nFLAGS:")
279
- const maxLength = Math.max(...flags.filter(([, { hint }]) => hint).map(([key, { param }]) => param ? key.length + param.length + 3 : key.length))
280
- flags.forEach(flag => {
281
- const str = `${flag[0]}${flag[1].param ? gray(` <${flag[1].param}>`) : ""}`
282
- if (flag[1].hint) {
283
- console.info(" ", `--${str}${" ".repeat(maxLength - colorstrip(str).length)}`, " ", flag[1].hint)
284
- }
285
- })
286
- }
287
- }
288
- }
289
-
290
- function showUsageHeadline (cmd, subcmd, module) {
291
- console.info("USAGE:")
292
- if (subcmd) {
293
- let params = module.router[subcmd]?.params
294
- // const options = module.router[subcmd]?.options
295
- if (params) {
296
- const optionalize = (str) => str.endsWith(" ...]")
297
- ? `[<${str.slice(1, -5)}> ...]`
298
- : (
299
- str[0] === "[" ? `[<${str.slice(1, -1)}>]` : `<${str}>`
300
- )
301
- if (Array.isArray(params)) {
302
- params = params.map(param => optionalize(param)).join(" ") + " "
303
- } else {
304
- params = optionalize(params)
305
- }
306
- }
307
- console.info(` ${white(`npx witnet ${cmd}`)} ${white(subcmd)} ${params ? green(params) + " " : ""}[OPTIONS] [FLAGS]`)
308
- if (module?.router[subcmd]?.hint) {
309
- console.info("\nDESCRIPTION:")
310
- console.info(` ${module.router[subcmd].hint}`)
311
- }
312
- } else {
313
- console.info(` ${white(`npx witnet ${cmd}`)} <SUBCOMMAND> ... [OPTIONS] [FLAGS]`)
314
- }
315
- }
316
-
317
- function showUsageOptions (options) {
318
- options = Object.entries(options).filter(([, option]) => option?.param).sort(([a], [b]) => {
319
- if (a < b) return -1
320
- else if (a > b) return 1
321
- else return 0
322
- })
323
- if (options.length > 0) {
324
- console.info("\nOPTIONS:")
325
- const maxLength = options
326
- .map(option => option[1].param ? option[1].param.length + option[0].length + 3 : option[0].length)
327
- .reduce((prev, curr) => curr > prev ? curr : prev)
328
- options.forEach(option => {
329
- if (option[1].hint) {
330
- const str = `${option[0]}${option[1].param ? gray(` <${option[1].param}>`) : ""}`
331
- console.info(" ", `--${str}${" ".repeat(maxLength - colorstrip(str).length)}`, " ", option[1].hint)
332
- }
333
- })
334
- }
335
- }
336
-
337
- function showUsageSubcommand (cmd, subcmd, module) {
338
- showUsageHeadline(cmd, subcmd, module)
339
- showUsageOptions({ ...module?.flags, ...module.router[subcmd]?.options })
340
- showUsageFlags({ ...module?.flags, ...module.router[subcmd]?.options })
341
- showUsageEnvars(module.router[subcmd]?.envars || module?.envars)
342
- }
343
-
344
- function showVersion () {
345
- console.info(`${mcyan(`Witnet SDK v${require("../../package.json").version}`)}`)
346
- }
347
-
348
- function getWildcardsCountFromString (str) {
349
- let maxArgsIndex = 0
350
- if (str) {
351
- let match
352
- const regexp = /\\\d\\/g
353
- while ((match = regexp.exec(str)) !== null) {
354
- const argsIndex = parseInt(match[0][1]) + 1
355
- if (argsIndex > maxArgsIndex) maxArgsIndex = argsIndex
356
- }
357
- }
358
- return maxArgsIndex
359
- }
360
-
361
- function checkRpcWildcards (wildcards) {
362
- if (typeof wildcards === "object") {
363
- Object.values(wildcards).forEach(wildcard => {
364
- if (Array.isArray(wildcard)) wildcard.forEach(item => checkRpcWildcards(item))
365
- else checkRpcWildcards(wildcard)
366
- })
367
- } else if (Array.isArray(wildcards)) {
368
- wildcards.forEach(wildcard => checkRpcWildcards(wildcard))
369
- } else if (typeof wildcards === "string") {
370
- if (isWildcard(wildcards)) {
371
- const char = wildcards.charAt(1)
372
- if (char < "1" || char > "9") {
373
- throw Error("RPC: wildcards not in range [1 .. 9]")
374
- }
375
- }
376
- }
377
- }
378
-
379
- function isWildcard (str) {
380
- return str.length === 3 && /\\\d\\/g.test(str)
381
- }
382
-
383
- function replaceWildcards (obj, args) {
384
- if (args.length > 10) args = args.slice(0, 10)
385
- if (obj && typeof obj === "string") {
386
- for (let argIndex = 0; argIndex < args.length; argIndex++) {
387
- const wildcard = `\\${argIndex}\\`
388
- obj = obj.replaceAll(wildcard, args[argIndex])
389
- }
390
- } else if (obj && Array.isArray(obj)) {
391
- obj = obj.map(value => typeof value === "string" || Array.isArray(value)
392
- ? replaceWildcards(value, args)
393
- : value
394
- )
395
- }
396
- return obj
397
- }
398
-
399
- function spliceWildcard (obj, argIndex, argValue, argsCount) {
400
- if (obj && typeof obj === "string") {
401
- const wildcard = `\\${argIndex}\\`
402
- obj = obj.replaceAll(wildcard, argValue)
403
- for (let j = argIndex + 1; j < argsCount; j++) {
404
- obj = obj.replaceAll(`\\${j}\\`, `\\${j - 1}\\`)
405
- }
406
- } else if (obj && Array.isArray(obj)) {
407
- obj = obj.map(value => typeof value === "string" || Array.isArray(value)
408
- ? spliceWildcard(value, argIndex, argValue, argsCount)
409
- : value
410
- )
411
- }
412
- return obj
413
- }
414
-
415
- async function toolkitRun (settings, args) {
416
- const cmd = `${settings.paths.toolkitBinPath} ${args.join(" ")}`
417
- return new Promise((resolve, reject) => {
418
- exec(cmd, { maxBuffer: 1024 * 1024 * 10 }, (error, stdout, stderr) => {
419
- if (error) {
420
- reject(error)
421
- }
422
- if (stderr) {
423
- reject(stderr)
424
- }
425
- resolve(stdout)
426
- })
427
- })
428
- }
429
-
430
- function toUpperCamelCase (str) {
431
- return str.replace(/\b(\w)/g, function (match, capture) {
432
- return capture.toUpperCase()
433
- }).replace(/\s+/g, "")
434
- }
435
-
436
- function toUtf16Bytes(str) {
437
- const bytes = new Uint8Array(str.length * 2);
438
- for (let i = 0; i < str.length; i++) {
439
- const code = str.charCodeAt(i);
440
- bytes[i * 2] = code >> 8;
441
- bytes[i * 2 + 1] = code & 0xff;
442
- }
443
- return bytes;
444
- }
445
-
446
- function toUtf8Array (str) {
447
- const utf8 = []
448
- for (let i = 0; i < str.length; i++) {
449
- let charcode = str.charCodeAt(i)
450
- if (charcode < 0x80) utf8.push(charcode)
451
- else if (charcode < 0x800) {
452
- utf8.push(0xc0 | (charcode >> 6),
453
- 0x80 | (charcode & 0x3f))
454
- } else if (charcode < 0xd800 || charcode >= 0xe000) {
455
- utf8.push(0xe0 | (charcode >> 12),
456
- 0x80 | ((charcode >> 6) & 0x3f),
457
- 0x80 | (charcode & 0x3f))
458
- } else { // surrogate pair
459
- i++
460
- // UTF-16 encodes 0x10000-0x10FFFF by
461
- // subtracting 0x10000 and splitting the
462
- // 20 bits of 0x0-0xFFFFF into two halves
463
- charcode = 0x10000 + (((charcode & 0x3ff) << 10) |
464
- (str.charCodeAt(i) & 0x3ff))
465
- utf8.push(0xf0 | (charcode >> 18),
466
- 0x80 | ((charcode >> 12) & 0x3f),
467
- 0x80 | ((charcode >> 6) & 0x3f),
468
- 0x80 | (charcode & 0x3f))
469
- }
470
- }
471
- return utf8
472
- }
473
-
474
- function utf8ArrayToStr (array) {
475
- const len = array.length
476
- let out = ""; let i = 0; let c
477
- let char2, char3
478
- while (i < len) {
479
- c = array[i++]
480
- switch (c >> 4) {
481
- case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
482
- // 0xxxxxxx
483
- out += String.fromCharCode(c)
484
- break
485
- case 12: case 13:
486
- // 110x xxxx 10xx xxxx
487
- char2 = array[i++]
488
- out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F))
489
- break
490
- case 14:
491
- // 1110 xxxx 10xx xxxx 10xx xxxx
492
- char2 = array[i++]
493
- char3 = array[i++]
494
- out += String.fromCharCode(((c & 0x0F) << 12) |
495
- ((char2 & 0x3F) << 6) |
496
- ((char3 & 0x3F) << 0))
497
- break
498
- }
499
- }
500
- return out
501
- }
502
-
503
- async function prompt (question) {
504
- const readlineInterface = readline.createInterface({
505
- input: process.stdin,
506
- output: process.stdout,
507
- })
508
- return new Promise((resolve, reject) => {
509
- readlineInterface.question(`${question} `, (response) => {
510
- readlineInterface.close()
511
- resolve(response.trim())
512
- })
513
- })
514
- }
515
-
516
- async function prompter (promise) {
517
- const loading = (() => {
518
- const h = ["|", "/", "-", "\\"]
519
- let i = 0
520
- return setInterval(() => {
521
- i = (i > 3) ? 0 : i
522
- process.stdout.write(`\b\b${h[i]} `)
523
- i++
524
- }, 50)
525
- })()
526
- return promise
527
- .then(result => {
528
- clearInterval(loading)
529
- process.stdout.write("\b\b")
530
- return result
531
- })
532
- }
533
-
534
- function traceChecklists (checklists) {
535
- if (checklists && Object.keys(checklists).length > 0) {
536
- const headlines = ["NODES", ...Object.keys(checklists).map(key => `:${key}`)]
537
- checklists = Object.values(checklists)
538
- const urls = Object.keys(checklists[0])
539
- const records = urls.map(url => {
540
- const errors = checklists.filter(checklist => checklist[url] instanceof Error).length
541
- return [
542
- errors === checklists.length ? red(url) : (errors > 0 ? myellow(url) : mcyan(url)),
543
- ...checklists.map(checklist => checklist[url] instanceof Error
544
- ? red(checklist[url])
545
- : (checklist[url] === true ? lcyan("Aye") : cyan("Nay"))
546
- ),
547
- ]
548
- })
549
- traceTable(records, {
550
- headlines,
551
- maxColumnWidth: 31,
552
- })
553
- }
554
- }
555
-
556
- function traceHeader (headline, color = normal, indent = "",) {
557
- console.info(`${indent}┌─${"─".repeat(headline.length)}─┐`)
558
- console.info(`${indent}│ ${color(headline)} │`)
559
- console.info(`${indent}└─${"─".repeat(headline.length)}─┘`)
560
- }
561
-
562
- function traceTable (records, options) {
563
- const stringify = (data, humanizers, index) => humanizers && humanizers[index] ? humanizers[index](data).toString() : data?.toString() ?? ""
564
- const max = (a, b) => a > b ? a : b
565
- const reduceMax = (numbers) => numbers.reduce((curr, prev) => prev > curr ? prev : curr, 0)
566
- if (!options) options = {}
567
- const indent = options?.indent || ""
568
- const numColumns = reduceMax(records.map(record => record?.length || 1))
569
- const maxColumnWidth = options?.maxColumnWidth || 80
570
- const table = transpose(records, numColumns)
571
- options.widths = options?.widths || table.map((column, index) => {
572
- let maxWidth = reduceMax(column.map(field => colorstrip(stringify(field, options?.humanizers, index)).length))
573
- if (options?.headlines && options.headlines[index]) {
574
- maxWidth = max(maxWidth, colorstrip(options.headlines[index].replaceAll(":", "")).length)
575
- }
576
- return Math.min(maxWidth, maxColumnWidth)
577
- })
578
- let headline = options.widths.map(maxWidth => "─".repeat(maxWidth))
579
- console.info(`${indent}┌─${headline.join("─┬─")}─┐`)
580
- if (options?.headlines) {
581
- headline = options.widths.map((maxWidth, index) => {
582
- const caption = options.headlines[index].replaceAll(":", "")
583
- const captionLength = colorstrip(caption).length
584
- return `${white(caption)}${" ".repeat(maxWidth - captionLength)}`
585
- })
586
- console.info(`${indent}│ ${headline.join(" │ ")} │`)
587
- headline = options.widths.map(maxWidth => "─".repeat(maxWidth))
588
- console.info(`${indent}├─${headline.join("─┼─")}─┤`)
589
- }
590
- for (let i = 0; i < records.length; i++) {
591
- let line = ""
592
- for (let j = 0; j < numColumns; j++) {
593
- let data = table[j][i]
594
- let color
595
- if (options?.colors && options.colors[j]) {
596
- color = options.colors[j]
597
- } else {
598
- color = typeof data === "string"
599
- ? green
600
- : (Number(data) === data && data % 1 !== 0 // is float number?
601
- ? yellow
602
- : (x) => x
603
- )
604
- }
605
- data = stringify(data, options?.humanizers, j)
606
- if (colorstrip(data).length > maxColumnWidth) {
607
- while (colorstrip(data).length > maxColumnWidth - 3) {
608
- data = data.slice(0, -1)
609
- }
610
- data += "..."
611
- }
612
- const dataLength = colorstrip(data).length
613
- if (options?.headlines && options.headlines[j][0] === ":") {
614
- data = `${color(data)}${" ".repeat(options.widths[j] - dataLength)}`
615
- } else {
616
- data = `${" ".repeat(options.widths[j] - dataLength)}${color(data)}`
617
- }
618
- line += `│ ${data} `
619
- }
620
- console.info(`${indent}${line}│`)
621
- }
622
- headline = options.widths.map(maxWidth => "─".repeat(maxWidth))
623
- console.info(`${indent}└─${headline.join("─┴─")}─┘`)
624
- }
625
-
626
- function transpose (records, numColumns) {
627
- const columns = []
628
- for (let index = 0; index < numColumns; index++) {
629
- columns.push(records.map(row => row[index]))
630
- }
631
- return columns
632
- }
633
-
634
- function txJsonReplacer (key, value) {
635
- switch (key) {
636
- case "bytes":
637
- case "der":
638
- return toHexString(value, true)
639
- case "tx":
640
- return JSON.stringify(value, txJsonReplacer)
641
- case "change":
642
- case "fees":
643
- case "value":
644
- return parseInt(value) / 10 ** 9
645
- default:
646
- return value
647
- }
648
- }
649
-
650
- function txReceiptJsonReplacer (key, value) {
651
- switch (key) {
652
- case "bytes":
653
- case "der":
654
- return toHexString(value, true)
655
- case "tx":
656
- return JSON.stringify(value, txJsonReplacer)
657
- case "change":
658
- case "fees":
659
- case "value":
660
- return parseInt(value?.pedros) / 10 ** 9
661
- case "timestamp":
662
- return moment.unix(value).format("MMMM Do YYYY, h:mm:ss a")
663
- default:
664
- return value
665
- }
666
- }
667
-
668
- function traceTransactionOnCheckpoint (receipt) {
669
- if (receipt?.confirmations) {
670
- console.info(` > Checkpoint #${commas(receipt.confirmations)}...`)
671
- }
672
- }
673
-
674
- function traceTransactionOnStatusChange (receipt) {
675
- const captions = {
676
- pending: "Awaiting relay...",
677
- // confirmed: "Transaction confirmed:",
678
- // finalized: "Transaction finalized:",
679
- relayed: "Awaiting inclusion...",
680
- mined: "Awaiting confirmations...",
681
- }
682
- const caption = captions[receipt.status]
683
- if (caption) console.info(` > ${captions[receipt.status]}`)
684
- if (["finalized", "confirmed"].includes(receipt.status)) {
685
- console.info(` > Block hash: ${gray(receipt?.blockHash)}`)
686
- console.info(` > Block miner: ${cyan(receipt?.blockMiner)}`);
687
- console.info(` > Block epoch: ${white(commas(receipt?.blockEpoch))}`)
688
- console.info(` > Included at: ${green(moment.unix(receipt?.blockTimestamp).format("MMMM Do YYYY, h:mm:ss a"))}`)
689
- console.info(` > ${receipt.status[0].toUpperCase() + receipt.status.slice(1)} at: ${mgreen(moment.unix(receipt.timestamp).format("MMMM Do YYYY, h:mm:ss a"))}`)
690
- }
691
- }
692
-
693
- function traceTransactionReceipt (receipt) {
694
- const captions = {
695
- DataRequest: " > DRT hash: ",
696
- ValueTransfer: " > VTT hash: ",
697
- }
698
- console.info(`${captions[receipt.type] || " > TX hash: "}${white(receipt.hash)}`)
699
- if (receipt?.droHash) console.info(` > DRO hash: ${green(receipt.droHash)}`)
700
- if (receipt?.radHash) console.info(` > RAD hash: ${mgreen(receipt.radHash)}`)
701
- if (receipt?.droSLA) console.info(` > SLA params: ${JSON.stringify(receipt.droSLA)}`)
702
- if (receipt?.withdrawer) {
703
- if (receipt?.validator) {
704
- console.info(` > Validator: ${mcyan(receipt.validator)}`)
705
- }
706
- console.info(` > Withdrawer: ${mmagenta(receipt.withdrawer)}`)
707
- } else {
708
- const signers = Array.isArray(receipt.from) ? receipt.from : [receipt.from]
709
- console.info(` > Signer/s: ${mmagenta(signers[0])}`)
710
- signers.slice(1).forEach(signer => {
711
- console.info(` ${mmagenta(signer)}`)
712
- })
713
- }
714
- if (receipt?.recipients) {
715
- console.info(` > Recipient/s: ${
716
- mblue(receipt.recipients.filter((pkh, index, array) => index === array.indexOf(pkh)))
717
- }`)
718
- }
719
- if (receipt?.fees) console.info(` > Fee: ${yellow(receipt.fees.toString(2))}`)
720
- if (receipt?.value) console.info(` > Value: ${myellow(receipt.value.toString(2))}`)
721
- if (receipt?.weight) console.info(` > Weight: ${mgreen(commas(receipt.weight))}`)
722
- if (receipt?.witnesses) {
723
- console.info(` > Witnesses: ${receipt.witnesses}`)
724
- }
725
- }
726
-
727
- async function traceTransaction (transmitter, options) {
728
- const color = options?.color || ((x) => `\x1b[30;45m${x}\x1b[0m`)
729
- let receipt = await transmitter.signTransaction(options, options?.reload)
730
- if (options?.verbose) {
731
- console.info(
732
- `\n${gray(JSON.stringify(receipt.tx, txJsonReplacer))}`
733
- )
734
- }
735
- if (options?.headline) {
736
- console.info(`\n ${color(` ${options.headline} `)}\n`)
737
- }
738
- traceTransactionReceipt(receipt)
739
- if (!options?.force) {
740
- // prompt user confirmation
741
- console.info()
742
- const answer = await require("inquirer").createPromptModule()([{
743
- message: "Send transaction?",
744
- type: "confirm",
745
- name: "continue",
746
- default: false,
747
- }])
748
- if (!answer.continue) {
749
- return receipt
750
- }
751
- }
752
- try {
753
- console.info()
754
- receipt = await transmitter.sendTransaction()
755
- if (options?.await || options?.confirmations !== undefined) {
756
- receipt = await transmitter.confirmTransaction(receipt.hash, {
757
- confirmations: options?.confirmations || 0,
758
- onCheckpoint: traceTransactionOnCheckpoint,
759
- onStatusChange: traceTransactionOnStatusChange,
760
- })
761
- } else {
762
- const data = { status: receipt?.status, timestamp: receipt?.timestamp || Math.floor(Date.now() / 1000) }
763
- console.info(data)
764
- }
765
- } catch (err) {
766
- if (err?.inFlight && err.inFlight) {
767
- console.info(`\n${gray(JSON.stringify(err.inFligt?.message, txReceiptJsonReplacer))}`)
768
- }
769
- throw err
770
- }
771
- return receipt
772
- }
773
-
774
- module.exports = {
775
- colors: {
776
- bblue,
777
- bcyan,
778
- bgreen,
779
- blue,
780
- bred,
781
- bviolet,
782
- cyan,
783
- gray,
784
- green,
785
- magenta,
786
- red,
787
- white,
788
- yellow,
789
- normal,
790
- lcyan,
791
- lgray,
792
- lgreen,
793
- lmagenta,
794
- lyellow,
795
- mblue,
796
- mcyan,
797
- mgreen,
798
- mmagenta,
799
- mred,
800
- myellow,
801
- },
802
- colorstrip,
803
- commas,
804
- whole_wits,
805
- toFixedTrunc,
806
- countLeaves,
807
- execRadonBytecode,
808
- deleteExtraFlags,
809
- extractFromArgs,
810
- fromHexString,
811
- isHexString,
812
- isHexStringOfLength,
813
- toHexString,
814
- parseURL,
815
- ipIsPrivateOrLocalhost,
816
- showUsage,
817
- showUsageError,
818
- showUsageSubcommand,
819
- showVersion,
820
- toolkitRun,
821
- toUpperCamelCase,
822
- toUtf16Bytes,
823
- toUtf8Array,
824
- utf8ArrayToStr,
825
- prompt,
826
- prompter,
827
- traceChecklists,
828
- traceHeader,
829
- traceTable,
830
- traceTransaction,
831
- traceTransactionOnStatusChange,
832
- traceTransactionOnCheckpoint,
833
- traceTransactionReceipt,
834
- checkRpcWildcards,
835
- isWildcard,
836
- getWildcardsCountFromString,
837
- replaceWildcards,
838
- spliceWildcard,
839
- txJsonReplacer,
840
- }
1
+ const { exec } = require("child_process")
2
+ const moment = require("moment")
3
+ const net = require("net")
4
+ const os = require("os")
5
+ const readline = require("readline")
6
+
7
+ const colorstrip = (str) => str.replace(
8
+ /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, ""
9
+ )
10
+
11
+ const commas = (number) => {
12
+ const parts = number.toString().split(".")
13
+ const result = parts.length <= 1
14
+ ? `${parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",")}`
15
+ : `${parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",")}.${parts[1]}`
16
+ return result
17
+ }
18
+
19
+ function toFixedTrunc (x, n) {
20
+ const v = (typeof x === "string" ? x : x.toString()).split(".")
21
+ if (n <= 0) return v[0]
22
+ let f = v[1] || ""
23
+ if (f.length > n) return `${v[0]}.${f.substr(0, n)}`
24
+ while (f.length < n) f += "0"
25
+ return `${v[0]}.${f}`
26
+ };
27
+
28
+ const whole_wits = (number, digits) => {
29
+ const lookup = [
30
+ { value: 1n, symbol: "pedros" },
31
+ { value: 10n ** 6n, symbol: "mWits" },
32
+ { value: 10n ** 9n, symbol: " Wits" },
33
+ { value: 10n ** 12n, symbol: "KWits" },
34
+ { value: 10n ** 15n, symbol: "MWits" },
35
+ ]
36
+ // const regexp = /\.0+$|(?<=\.[0-9])0+$/
37
+ const item = lookup.findLast(item => number >= item.value)
38
+ const quotient = item ? Number(BigInt(number) / item.value) : number.toString()
39
+ const decimals = item ? (item.value + BigInt(number) - BigInt(quotient) * item.value).toString().slice(1) : ""
40
+ return item ? `${commas(quotient)}${decimals !== "" ? `.${decimals.slice(0, digits)}` : ""} ${item.symbol}` : "(no coins)"
41
+ }
42
+
43
+ const bblue = (str) => `\x1b[1;98;44m${str}\x1b[0;0;0m`
44
+ const bcyan = (str) => `\x1b[38;46m${str}\x1b[0;0m`
45
+ const bgreen = (str) => `\x1b[30;42m${str}\x1b[0;0m`
46
+ const bred = (str) => `\x1b[30;41m${str}\x1b[0;0m`
47
+ const bviolet = (str) => `\x1b[30;45m${str}\x1b[0;0m`
48
+
49
+ const lcyan = (str) => `\x1b[1;96m${str}\x1b[0m`
50
+ const lgray = (str) => `\x1b[1;90m${str}\x1b[0m`
51
+ const lgreen = (str) => `\x1b[1;92m${str}\x1b[0m`
52
+ const lmagenta = (str) => `\x1b[1;95m${str}\x1b[0m`
53
+ const lyellow = (str) => `\x1b[1;93m${str}\x1b[0m`
54
+ const mblue = (str) => `\x1b[94m${str}\x1b[0m`
55
+ const mcyan = (str) => `\x1b[96m${str}\x1b[0m`
56
+ const mgreen = (str) => `\x1b[92m${str}\x1b[0m`
57
+ const mmagenta = (str) => `\x1b[0;95m${str}\x1b[0m`
58
+ const mred = (str) => `\x1b[91m${str}\x1b[0m`
59
+ const myellow = (str) => `\x1b[93m${str}\x1b[0m`
60
+
61
+ const blue = (str) => `\x1b[34m${str}\x1b[0m`
62
+ const cyan = (str) => `\x1b[36m${str}\x1b[0m`
63
+ const gray = (str) => `\x1b[90m${str}\x1b[0m`
64
+ const green = (str) => `\x1b[32m${str}\x1b[0m`
65
+ const magenta = (str) => `\x1b[0;35m${str}\x1b[0m`
66
+ const normal = (str) => `\x1b[98m${str}\x1b[0m`
67
+ const red = (str) => `\x1b[31m${str}\x1b[0m`
68
+ const white = (str) => `\x1b[1;98m${str}\x1b[0m`
69
+ const yellow = (str) => `\x1b[33m${str}\x1b[0m`
70
+
71
+ function countLeaves (t, obj) {
72
+ if (!obj || typeof obj === "string") return 0
73
+ if (obj instanceof t) return 1
74
+ if (Array.isArray(obj)) return obj.reduce((sum, item) => sum + countLeaves(t, item), 0)
75
+ else return Object.values(obj).reduce((sum, item) => sum + countLeaves(t, item), 0)
76
+ }
77
+
78
+ function deleteExtraFlags (args) {
79
+ return args.filter(arg => !arg.startsWith("--"))
80
+ }
81
+
82
+ function cmd (...command) {
83
+ return new Promise((resolve, reject) => {
84
+ exec(command.join(" "), { maxBuffer: 1024 * 1024 * 10 }, (error, stdout, stderr) => {
85
+ if (error) {
86
+ reject(error)
87
+ }
88
+ if (stderr) {
89
+ reject(stderr)
90
+ }
91
+ resolve(stdout)
92
+ })
93
+ })
94
+ };
95
+
96
+ async function execRadonBytecode (bytecode, ...flags) {
97
+ if (!isHexString(bytecode)) {
98
+ throw EvalError("invalid hex string")
99
+ } else {
100
+ const npx = os.type() === "Windows_NT" ? "npx.cmd" : "npx"
101
+ return cmd(npx, "witnet", "radon", "dryrun", bytecode, ...flags)
102
+ // .catch((err) => {
103
+ // let errorMessage = err.message.split('\n').slice(1).join('\n').trim()
104
+ // const errorRegex = /.*^error: (?<message>.*)$.*/gm
105
+ // const matched = errorRegex.exec(err.message)
106
+ // if (matched) {
107
+ // errorMessage = matched.groups.message
108
+ // }
109
+ // console.log(errorMessage || err)
110
+ // console.error(errorMessage || err)
111
+ // })
112
+ }
113
+ }
114
+
115
+ function extractFromArgs (args, flags) {
116
+ const curated = {}
117
+ if (args && flags) {
118
+ Object.keys(flags).forEach(flag => {
119
+ const flagIndex = args.indexOf(`--${flag}`)
120
+ if (flagIndex >= 0) {
121
+ if (flags[flag].param) {
122
+ curated[flag] = args[flagIndex]
123
+ if (!args[flagIndex + 1] || args[flagIndex + 1].startsWith("--")) {
124
+ throw Error(`Missing required parameter for --${flag}`)
125
+ } else {
126
+ curated[flag] = args[flagIndex + 1]
127
+ args.splice(flagIndex, 2)
128
+ }
129
+ } else {
130
+ curated[flag] = true
131
+ args.splice(flagIndex, 1)
132
+ }
133
+ }
134
+ })
135
+ }
136
+ return [args, curated]
137
+ }
138
+
139
+ function fromHexString (hexString) {
140
+ if (hexString.startsWith("0x")) hexString = hexString.slice(2)
141
+ return Uint8Array.from(hexString.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)))
142
+ }
143
+
144
+ function ipIsPrivateOrLocalhost (ip) {
145
+ if (ip.substring(0, 7) === "::ffff:") { ip = ip.substring(7) }
146
+
147
+ if (net.isIPv4(ip)) {
148
+ // check localhost
149
+ if (ip === "127.0.0.1") { return true }
150
+
151
+ // 10.0.0.0 - 10.255.255.255 || 172.16.0.0 - 172.31.255.255 || 192.168.0.0 - 192.168.255.255
152
+ return /^(10)\.(.*)\.(.*)\.(.*)$/.test(ip) || /^(172)\.(1[6-9]|2[0-9]|3[0-1])\.(.*)\.(.*)$/.test(ip) || /^(192)\.(168)\.(.*)\.(.*)$/.test(ip)
153
+ }
154
+
155
+ // else: ip is IPv6
156
+ const firstWord = ip.split(":").find(el => !!el) // get first not empty word
157
+
158
+ // equivalent of 127.0.0.1 in IPv6
159
+ if (ip === "::1") return true
160
+
161
+ // The original IPv6 Site Local addresses (fec0::/10) are deprecated. Range: fec0 - feff
162
+ else if (/^fe[c-f][0-f]$/.test(firstWord)) return true
163
+
164
+ // These days Unique Local Addresses (ULA) are used in place of Site Local.
165
+ // Range: fc00 - fcff
166
+ else if (/^fc[0-f]{2}$/.test(firstWord)) return true
167
+
168
+ // Range: fd00 - fcff
169
+ else if (/^fd[0-f]{2}$/.test(firstWord)) return true
170
+
171
+ // Link local addresses (prefixed with fe80) are not routable
172
+ else if (firstWord === "fe80") return true
173
+
174
+ // Discard Prefix
175
+ else if (firstWord === "100") return true
176
+
177
+ // Any other IP address is not Unique Local Address (ULA)
178
+ return false
179
+ }
180
+
181
+ function isHexStringOfLength (str, length) {
182
+ return (isHexString(str) &&
183
+ (
184
+ (str.startsWith("0x") && str.slice(2).length === length * 2) ||
185
+ str.length === length * 2
186
+ )
187
+ ) || isWildcard(str)
188
+ }
189
+
190
+ function isHexString (str) {
191
+ return (
192
+ typeof str === "string" &&
193
+ (
194
+ (str.startsWith("0x") && /^[a-fA-F0-9]+$/i.test(str.slice(2))) ||
195
+ /^[a-fA-F0-9]+$/i.test(str)
196
+ )
197
+ ) || isWildcard(str)
198
+ }
199
+
200
+ function toHexString (buffer, prefix0x = false) {
201
+ if (buffer instanceof Uint8Array) buffer = Buffer.from(buffer)
202
+ return (prefix0x ? "0x" : "") + Array.prototype.map.call(buffer, x => ("00" + x.toString(16)).slice(-2))
203
+ .join("")
204
+ .match(/[a-fA-F0-9]{2}/g)
205
+ .join("")
206
+ }
207
+
208
+ function parseURL (url) {
209
+ try {
210
+ const parsedUrl = new URL(url)
211
+ return [
212
+ parsedUrl.protocol + "//",
213
+ parsedUrl.host,
214
+ parsedUrl.pathname.slice(1),
215
+ parsedUrl.search.slice(1),
216
+ ]
217
+ } catch {
218
+ throw new TypeError(`Invalid URL was provided: ${url}`)
219
+ }
220
+ }
221
+
222
+ function showUsage (cmd, module) {
223
+ showUsageHeadline(cmd)
224
+ showUsageOptions({ ...module?.flags })
225
+ showUsageFlags({ ...module?.flags })
226
+ showUsageRouter({ ...module?.router })
227
+ showUsageEnvars({ ...module?.envars })
228
+ }
229
+
230
+ function showUsageRouter (router) {
231
+ const cmds = Object.entries(router)
232
+ if (cmds.length > 0) {
233
+ console.info("\nSUBCOMMANDS:")
234
+ const maxLength = Math.max(...cmds.map(([cmd]) => cmd.length))
235
+ cmds.forEach(cmd => {
236
+ console.info(" ", `${cmd[0]}${" ".repeat(maxLength - cmd[0].length)}`, " ", cmd[1].hint)
237
+ })
238
+ }
239
+ }
240
+
241
+ function showUsageError (cmd, subcmd, module, error, flags) {
242
+ showUsageSubcommand(cmd, subcmd, module, error)
243
+ if (error) {
244
+ console.info("\nERROR:")
245
+ if (flags?.debug) {
246
+ console.error(error)
247
+ } else {
248
+ console.error(error?.stack?.split("\n")[0] || error)
249
+ }
250
+ }
251
+ }
252
+
253
+ function showUsageEnvars (envars) {
254
+ if (envars) {
255
+ envars = Object.entries(envars)
256
+ if (envars.length > 0) {
257
+ console.info("\nENVARS:")
258
+ const maxWidth = Math.max(...envars.map(([envar]) => envar.length))
259
+ envars.forEach(([envar, hint]) => {
260
+ if (envar.toUpperCase().indexOf("KEY") < 0 && process.env[envar]) {
261
+ console.info(" ", `${yellow(envar.toUpperCase())}${" ".repeat(maxWidth - envar.length)}`, ` => Settled to "${myellow(process.env[envar])}"`)
262
+ } else {
263
+ console.info(" ", `${yellow(envar.toUpperCase())}${" ".repeat(maxWidth - envar.length)}`, ` ${hint}`)
264
+ }
265
+ })
266
+ }
267
+ }
268
+ }
269
+
270
+ function showUsageFlags (flags) {
271
+ if (flags) {
272
+ flags = Object.entries(flags).filter(([, flag]) => !flag?.param).sort(([a], [b]) => {
273
+ if (a < b) return -1
274
+ else if (a > b) return 1
275
+ else return 0
276
+ })
277
+ if (flags.length > 0) {
278
+ console.info("\nFLAGS:")
279
+ const maxLength = Math.max(...flags.filter(([, { hint }]) => hint).map(([key, { param }]) => param ? key.length + param.length + 3 : key.length))
280
+ flags.forEach(flag => {
281
+ const str = `${flag[0]}${flag[1].param ? gray(` <${flag[1].param}>`) : ""}`
282
+ if (flag[1].hint) {
283
+ console.info(" ", `--${str}${" ".repeat(maxLength - colorstrip(str).length)}`, " ", flag[1].hint)
284
+ }
285
+ })
286
+ }
287
+ }
288
+ }
289
+
290
+ function showUsageHeadline (cmd, subcmd, module) {
291
+ console.info("USAGE:")
292
+ if (subcmd) {
293
+ let params = module.router[subcmd]?.params
294
+ // const options = module.router[subcmd]?.options
295
+ if (params) {
296
+ const optionalize = (str) => str.endsWith(" ...]")
297
+ ? `[<${str.slice(1, -5)}> ...]`
298
+ : (
299
+ str[0] === "[" ? `[<${str.slice(1, -1)}>]` : `<${str}>`
300
+ )
301
+ if (Array.isArray(params)) {
302
+ params = params.map(param => optionalize(param)).join(" ") + " "
303
+ } else {
304
+ params = optionalize(params)
305
+ }
306
+ }
307
+ console.info(` ${white(`npx witnet ${cmd}`)} ${white(subcmd)} ${params ? green(params) + " " : ""}[OPTIONS] [FLAGS]`)
308
+ if (module?.router[subcmd]?.hint) {
309
+ console.info("\nDESCRIPTION:")
310
+ console.info(` ${module.router[subcmd].hint}`)
311
+ }
312
+ } else {
313
+ console.info(` ${white(`npx witnet ${cmd}`)} <SUBCOMMAND> ... [OPTIONS] [FLAGS]`)
314
+ }
315
+ }
316
+
317
+ function showUsageOptions (options) {
318
+ options = Object.entries(options).filter(([, option]) => option?.param).sort(([a], [b]) => {
319
+ if (a < b) return -1
320
+ else if (a > b) return 1
321
+ else return 0
322
+ })
323
+ if (options.length > 0) {
324
+ console.info("\nOPTIONS:")
325
+ const maxLength = options
326
+ .map(option => option[1].param ? option[1].param.length + option[0].length + 3 : option[0].length)
327
+ .reduce((prev, curr) => curr > prev ? curr : prev)
328
+ options.forEach(option => {
329
+ if (option[1].hint) {
330
+ const str = `${option[0]}${option[1].param ? gray(` <${option[1].param}>`) : ""}`
331
+ console.info(" ", `--${str}${" ".repeat(maxLength - colorstrip(str).length)}`, " ", option[1].hint)
332
+ }
333
+ })
334
+ }
335
+ }
336
+
337
+ function showUsageSubcommand (cmd, subcmd, module) {
338
+ showUsageHeadline(cmd, subcmd, module)
339
+ showUsageOptions({ ...module?.flags, ...module.router[subcmd]?.options })
340
+ showUsageFlags({ ...module?.flags, ...module.router[subcmd]?.options })
341
+ showUsageEnvars(module.router[subcmd]?.envars || module?.envars)
342
+ }
343
+
344
+ function showVersion () {
345
+ console.info(`${mcyan(`Witnet SDK v${require("../../package.json").version}`)}`)
346
+ }
347
+
348
+ function getWildcardsCountFromString (str) {
349
+ let maxArgsIndex = 0
350
+ if (str && typeof str === 'string') {
351
+ let match
352
+ const regexp = /\\\d\\/g
353
+ while ((match = regexp.exec(str)) !== null) {
354
+ const argsIndex = parseInt(match[0][1]) + 1
355
+ if (argsIndex > maxArgsIndex) maxArgsIndex = argsIndex
356
+ }
357
+ }
358
+ return maxArgsIndex
359
+ }
360
+
361
+ function checkRpcWildcards (wildcards) {
362
+ if (typeof wildcards === "object") {
363
+ Object.values(wildcards).forEach(wildcard => {
364
+ if (Array.isArray(wildcard)) wildcard.forEach(item => checkRpcWildcards(item))
365
+ else checkRpcWildcards(wildcard)
366
+ })
367
+ } else if (Array.isArray(wildcards)) {
368
+ wildcards.forEach(wildcard => checkRpcWildcards(wildcard))
369
+ } else if (typeof wildcards === "string") {
370
+ if (isWildcard(wildcards)) {
371
+ const char = wildcards.charAt(1)
372
+ if (char < "1" || char > "9") {
373
+ throw Error("RPC: wildcards not in range [1 .. 9]")
374
+ }
375
+ }
376
+ }
377
+ }
378
+
379
+ function isWildcard (str) {
380
+ return str.length === 3 && /\\\d\\/g.test(str)
381
+ }
382
+
383
+ function replaceWildcards (obj, args) {
384
+ if (args.length > 10) args = args.slice(0, 10)
385
+ if (obj && typeof obj === "string") {
386
+ for (let argIndex = 0; argIndex < args.length; argIndex++) {
387
+ const wildcard = `\\${argIndex}\\`
388
+ obj = obj.replaceAll(wildcard, args[argIndex])
389
+ }
390
+ } else if (obj && Array.isArray(obj)) {
391
+ obj = obj.map(value => typeof value === "string" || Array.isArray(value)
392
+ ? replaceWildcards(value, args)
393
+ : value
394
+ )
395
+ }
396
+ return obj
397
+ }
398
+
399
+ function spliceWildcard (obj, argIndex, argValue, argsCount) {
400
+ if (obj && typeof obj === "string") {
401
+ const wildcard = `\\${argIndex}\\`
402
+ obj = obj.replaceAll(wildcard, argValue)
403
+ for (let j = argIndex + 1; j < argsCount; j++) {
404
+ obj = obj.replaceAll(`\\${j}\\`, `\\${j - 1}\\`)
405
+ }
406
+ } else if (obj && Array.isArray(obj)) {
407
+ obj = obj.map(value => typeof value === "string" || Array.isArray(value)
408
+ ? spliceWildcard(value, argIndex, argValue, argsCount)
409
+ : value
410
+ )
411
+ }
412
+ return obj
413
+ }
414
+
415
+ async function toolkitRun (settings, args) {
416
+ const cmd = `${settings.paths.toolkitBinPath} ${args.join(" ")}`
417
+ return new Promise((resolve, reject) => {
418
+ exec(cmd, { maxBuffer: 1024 * 1024 * 10 }, (error, stdout, stderr) => {
419
+ if (error) {
420
+ reject(error)
421
+ }
422
+ if (stderr) {
423
+ reject(stderr)
424
+ }
425
+ resolve(stdout)
426
+ })
427
+ })
428
+ }
429
+
430
+ function toUpperCamelCase (str) {
431
+ return str.replace(/\b(\w)/g, function (match, capture) {
432
+ return capture.toUpperCase()
433
+ }).replace(/\s+/g, "")
434
+ }
435
+
436
+ function toUtf16Bytes(str) {
437
+ const bytes = new Uint8Array(str.length * 2);
438
+ for (let i = 0; i < str.length; i++) {
439
+ const code = str.charCodeAt(i);
440
+ bytes[i * 2] = code >> 8;
441
+ bytes[i * 2 + 1] = code & 0xff;
442
+ }
443
+ return bytes;
444
+ }
445
+
446
+ function toUtf8Array (str) {
447
+ const utf8 = []
448
+ for (let i = 0; i < str.length; i++) {
449
+ let charcode = str.charCodeAt(i)
450
+ if (charcode < 0x80) utf8.push(charcode)
451
+ else if (charcode < 0x800) {
452
+ utf8.push(0xc0 | (charcode >> 6),
453
+ 0x80 | (charcode & 0x3f))
454
+ } else if (charcode < 0xd800 || charcode >= 0xe000) {
455
+ utf8.push(0xe0 | (charcode >> 12),
456
+ 0x80 | ((charcode >> 6) & 0x3f),
457
+ 0x80 | (charcode & 0x3f))
458
+ } else { // surrogate pair
459
+ i++
460
+ // UTF-16 encodes 0x10000-0x10FFFF by
461
+ // subtracting 0x10000 and splitting the
462
+ // 20 bits of 0x0-0xFFFFF into two halves
463
+ charcode = 0x10000 + (((charcode & 0x3ff) << 10) |
464
+ (str.charCodeAt(i) & 0x3ff))
465
+ utf8.push(0xf0 | (charcode >> 18),
466
+ 0x80 | ((charcode >> 12) & 0x3f),
467
+ 0x80 | ((charcode >> 6) & 0x3f),
468
+ 0x80 | (charcode & 0x3f))
469
+ }
470
+ }
471
+ return utf8
472
+ }
473
+
474
+ function utf8ArrayToStr (array) {
475
+ const len = array.length
476
+ let out = ""; let i = 0; let c
477
+ let char2, char3
478
+ while (i < len) {
479
+ c = array[i++]
480
+ switch (c >> 4) {
481
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
482
+ // 0xxxxxxx
483
+ out += String.fromCharCode(c)
484
+ break
485
+ case 12: case 13:
486
+ // 110x xxxx 10xx xxxx
487
+ char2 = array[i++]
488
+ out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F))
489
+ break
490
+ case 14:
491
+ // 1110 xxxx 10xx xxxx 10xx xxxx
492
+ char2 = array[i++]
493
+ char3 = array[i++]
494
+ out += String.fromCharCode(((c & 0x0F) << 12) |
495
+ ((char2 & 0x3F) << 6) |
496
+ ((char3 & 0x3F) << 0))
497
+ break
498
+ }
499
+ }
500
+ return out
501
+ }
502
+
503
+ async function prompt (question) {
504
+ const readlineInterface = readline.createInterface({
505
+ input: process.stdin,
506
+ output: process.stdout,
507
+ })
508
+ return new Promise((resolve, reject) => {
509
+ readlineInterface.question(`${question} `, (response) => {
510
+ readlineInterface.close()
511
+ resolve(response.trim())
512
+ })
513
+ })
514
+ }
515
+
516
+ async function prompter (promise) {
517
+ const loading = (() => {
518
+ const h = ["|", "/", "-", "\\"]
519
+ let i = 0
520
+ return setInterval(() => {
521
+ i = (i > 3) ? 0 : i
522
+ process.stdout.write(`\b\b${h[i]} `)
523
+ i++
524
+ }, 50)
525
+ })()
526
+ return promise
527
+ .then(result => {
528
+ clearInterval(loading)
529
+ process.stdout.write("\b\b")
530
+ return result
531
+ })
532
+ }
533
+
534
+ function traceChecklists (checklists) {
535
+ if (checklists && Object.keys(checklists).length > 0) {
536
+ const headlines = ["NODES", ...Object.keys(checklists).map(key => `:${key}`)]
537
+ checklists = Object.values(checklists)
538
+ const urls = Object.keys(checklists[0])
539
+ const records = urls.map(url => {
540
+ const errors = checklists.filter(checklist => checklist[url] instanceof Error).length
541
+ return [
542
+ errors === checklists.length ? red(url) : (errors > 0 ? myellow(url) : mcyan(url)),
543
+ ...checklists.map(checklist => checklist[url] instanceof Error
544
+ ? red(checklist[url])
545
+ : (checklist[url] === true ? lcyan("Aye") : cyan("Nay"))
546
+ ),
547
+ ]
548
+ })
549
+ traceTable(records, {
550
+ headlines,
551
+ maxColumnWidth: 31,
552
+ })
553
+ }
554
+ }
555
+
556
+ function traceHeader (headline, color = normal, indent = "",) {
557
+ console.info(`${indent}┌─${"─".repeat(headline.length)}─┐`)
558
+ console.info(`${indent}│ ${color(headline)} │`)
559
+ console.info(`${indent}└─${"─".repeat(headline.length)}─┘`)
560
+ }
561
+
562
+ function traceTable (records, options) {
563
+ const stringify = (data, humanizers, index) => humanizers && humanizers[index] ? humanizers[index](data).toString() : data?.toString() ?? ""
564
+ const max = (a, b) => a > b ? a : b
565
+ const reduceMax = (numbers) => numbers.reduce((curr, prev) => prev > curr ? prev : curr, 0)
566
+ if (!options) options = {}
567
+ const indent = options?.indent || ""
568
+ const numColumns = reduceMax(records.map(record => record?.length || 1))
569
+ const maxColumnWidth = options?.maxColumnWidth || 80
570
+ const table = transpose(records, numColumns)
571
+ options.widths = options?.widths || table.map((column, index) => {
572
+ let maxWidth = reduceMax(column.map(field => colorstrip(stringify(field, options?.humanizers, index)).length))
573
+ if (options?.headlines && options.headlines[index]) {
574
+ maxWidth = max(maxWidth, colorstrip(options.headlines[index].replaceAll(":", "")).length)
575
+ }
576
+ return Math.min(maxWidth, maxColumnWidth)
577
+ })
578
+ let headline = options.widths.map(maxWidth => "─".repeat(maxWidth))
579
+ console.info(`${indent}┌─${headline.join("─┬─")}─┐`)
580
+ if (options?.headlines) {
581
+ headline = options.widths.map((maxWidth, index) => {
582
+ const caption = options.headlines[index].replaceAll(":", "")
583
+ const captionLength = colorstrip(caption).length
584
+ return `${white(caption)}${" ".repeat(maxWidth - captionLength)}`
585
+ })
586
+ console.info(`${indent}│ ${headline.join(" │ ")} │`)
587
+ headline = options.widths.map(maxWidth => "─".repeat(maxWidth))
588
+ console.info(`${indent}├─${headline.join("─┼─")}─┤`)
589
+ }
590
+ for (let i = 0; i < records.length; i++) {
591
+ let line = ""
592
+ for (let j = 0; j < numColumns; j++) {
593
+ let data = table[j][i]
594
+ let color
595
+ if (options?.colors && options.colors[j]) {
596
+ color = options.colors[j]
597
+ } else {
598
+ color = typeof data === "string"
599
+ ? green
600
+ : (Number(data) === data && data % 1 !== 0 // is float number?
601
+ ? yellow
602
+ : (x) => x
603
+ )
604
+ }
605
+ data = stringify(data, options?.humanizers, j)
606
+ if (colorstrip(data).length > maxColumnWidth) {
607
+ while (colorstrip(data).length > maxColumnWidth - 3) {
608
+ data = data.slice(0, -1)
609
+ }
610
+ data += "..."
611
+ }
612
+ const dataLength = colorstrip(data).length
613
+ if (options?.headlines && options.headlines[j][0] === ":") {
614
+ data = `${color(data)}${" ".repeat(options.widths[j] - dataLength)}`
615
+ } else {
616
+ data = `${" ".repeat(options.widths[j] - dataLength)}${color(data)}`
617
+ }
618
+ line += `│ ${data} `
619
+ }
620
+ console.info(`${indent}${line}│`)
621
+ }
622
+ headline = options.widths.map(maxWidth => "─".repeat(maxWidth))
623
+ console.info(`${indent}└─${headline.join("─┴─")}─┘`)
624
+ }
625
+
626
+ function transpose (records, numColumns) {
627
+ const columns = []
628
+ for (let index = 0; index < numColumns; index++) {
629
+ columns.push(records.map(row => row[index]))
630
+ }
631
+ return columns
632
+ }
633
+
634
+ function txJsonReplacer (key, value) {
635
+ switch (key) {
636
+ case "bytes":
637
+ case "der":
638
+ return toHexString(value, true)
639
+ case "tx":
640
+ return JSON.stringify(value, txJsonReplacer)
641
+ case "change":
642
+ case "fees":
643
+ case "value":
644
+ return parseInt(value) / 10 ** 9
645
+ default:
646
+ return value
647
+ }
648
+ }
649
+
650
+ function txReceiptJsonReplacer (key, value) {
651
+ switch (key) {
652
+ case "bytes":
653
+ case "der":
654
+ return toHexString(value, true)
655
+ case "tx":
656
+ return JSON.stringify(value, txJsonReplacer)
657
+ case "change":
658
+ case "fees":
659
+ case "value":
660
+ return parseInt(value?.pedros) / 10 ** 9
661
+ case "timestamp":
662
+ return moment.unix(value).format("MMMM Do YYYY, h:mm:ss a")
663
+ default:
664
+ return value
665
+ }
666
+ }
667
+
668
+ function traceTransactionOnCheckpoint (receipt) {
669
+ if (receipt?.confirmations) {
670
+ console.info(` > Checkpoint #${commas(receipt.confirmations)}...`)
671
+ }
672
+ }
673
+
674
+ function traceTransactionOnStatusChange (receipt) {
675
+ const captions = {
676
+ pending: "Awaiting relay...",
677
+ // confirmed: "Transaction confirmed:",
678
+ // finalized: "Transaction finalized:",
679
+ relayed: "Awaiting inclusion...",
680
+ mined: "Awaiting confirmations...",
681
+ }
682
+ const caption = captions[receipt.status]
683
+ if (caption) console.info(` > ${captions[receipt.status]}`)
684
+ if (["finalized", "confirmed"].includes(receipt.status)) {
685
+ console.info(` > Block hash: ${gray(receipt?.blockHash)}`)
686
+ console.info(` > Block miner: ${cyan(receipt?.blockMiner)}`);
687
+ console.info(` > Block epoch: ${white(commas(receipt?.blockEpoch))}`)
688
+ console.info(` > Included at: ${green(moment.unix(receipt?.blockTimestamp).format("MMMM Do YYYY, h:mm:ss a"))}`)
689
+ console.info(` > ${receipt.status[0].toUpperCase() + receipt.status.slice(1)} at: ${mgreen(moment.unix(receipt.timestamp).format("MMMM Do YYYY, h:mm:ss a"))}`)
690
+ }
691
+ }
692
+
693
+ function traceTransactionReceipt (receipt) {
694
+ const captions = {
695
+ DataRequest: " > DRT hash: ",
696
+ ValueTransfer: " > VTT hash: ",
697
+ }
698
+ console.info(`${captions[receipt.type] || " > TX hash: "}${white(receipt.hash)}`)
699
+ if (receipt?.droHash) console.info(` > DRO hash: ${green(receipt.droHash)}`)
700
+ if (receipt?.radHash) console.info(` > RAD hash: ${mgreen(receipt.radHash)}`)
701
+ if (receipt?.droSLA) console.info(` > SLA params: ${JSON.stringify(receipt.droSLA)}`)
702
+ if (receipt?.withdrawer) {
703
+ if (receipt?.validator) {
704
+ console.info(` > Validator: ${mcyan(receipt.validator)}`)
705
+ }
706
+ console.info(` > Withdrawer: ${mmagenta(receipt.withdrawer)}`)
707
+ } else {
708
+ const signers = Array.isArray(receipt.from) ? receipt.from : [receipt.from]
709
+ console.info(` > Signer/s: ${mmagenta(signers[0])}`)
710
+ signers.slice(1).forEach(signer => {
711
+ console.info(` ${mmagenta(signer)}`)
712
+ })
713
+ }
714
+ if (receipt?.recipients) {
715
+ console.info(` > Recipient/s: ${
716
+ mblue(receipt.recipients.filter((pkh, index, array) => index === array.indexOf(pkh)))
717
+ }`)
718
+ }
719
+ if (receipt?.fees) console.info(` > Fee: ${yellow(receipt.fees.toString(2))}`)
720
+ if (receipt?.value) console.info(` > Value: ${myellow(receipt.value.toString(2))}`)
721
+ if (receipt?.weight) console.info(` > Weight: ${mgreen(commas(receipt.weight))}`)
722
+ if (receipt?.witnesses) {
723
+ console.info(` > Witnesses: ${receipt.witnesses}`)
724
+ }
725
+ }
726
+
727
+ async function traceTransaction (transmitter, options) {
728
+ const color = options?.color || ((x) => `\x1b[30;45m${x}\x1b[0m`)
729
+ let receipt = await transmitter.signTransaction(options, options?.reload)
730
+ if (options?.verbose) {
731
+ console.info(
732
+ `\n${gray(JSON.stringify(receipt.tx, txJsonReplacer))}`
733
+ )
734
+ }
735
+ if (options?.headline) {
736
+ console.info(`\n ${color(` ${options.headline} `)}\n`)
737
+ }
738
+ traceTransactionReceipt(receipt)
739
+ if (!options?.force) {
740
+ // prompt user confirmation
741
+ console.info()
742
+ const answer = await require("inquirer").createPromptModule()([{
743
+ message: "Send transaction?",
744
+ type: "confirm",
745
+ name: "continue",
746
+ default: false,
747
+ }])
748
+ if (!answer.continue) {
749
+ return receipt
750
+ }
751
+ }
752
+ try {
753
+ console.info()
754
+ receipt = await transmitter.sendTransaction()
755
+ if (options?.await || options?.confirmations !== undefined) {
756
+ receipt = await transmitter.confirmTransaction(receipt.hash, {
757
+ confirmations: options?.confirmations || 0,
758
+ onCheckpoint: traceTransactionOnCheckpoint,
759
+ onStatusChange: traceTransactionOnStatusChange,
760
+ })
761
+ } else {
762
+ const data = { status: receipt?.status, timestamp: receipt?.timestamp || Math.floor(Date.now() / 1000) }
763
+ console.info(data)
764
+ }
765
+ } catch (err) {
766
+ if (err?.inFlight && err.inFlight) {
767
+ console.info(`\n${gray(JSON.stringify(err.inFligt?.message, txReceiptJsonReplacer))}`)
768
+ }
769
+ throw err
770
+ }
771
+ return receipt
772
+ }
773
+
774
+ module.exports = {
775
+ colors: {
776
+ bblue,
777
+ bcyan,
778
+ bgreen,
779
+ blue,
780
+ bred,
781
+ bviolet,
782
+ cyan,
783
+ gray,
784
+ green,
785
+ magenta,
786
+ red,
787
+ white,
788
+ yellow,
789
+ normal,
790
+ lcyan,
791
+ lgray,
792
+ lgreen,
793
+ lmagenta,
794
+ lyellow,
795
+ mblue,
796
+ mcyan,
797
+ mgreen,
798
+ mmagenta,
799
+ mred,
800
+ myellow,
801
+ },
802
+ colorstrip,
803
+ commas,
804
+ whole_wits,
805
+ toFixedTrunc,
806
+ countLeaves,
807
+ execRadonBytecode,
808
+ deleteExtraFlags,
809
+ extractFromArgs,
810
+ fromHexString,
811
+ isHexString,
812
+ isHexStringOfLength,
813
+ toHexString,
814
+ parseURL,
815
+ ipIsPrivateOrLocalhost,
816
+ showUsage,
817
+ showUsageError,
818
+ showUsageSubcommand,
819
+ showVersion,
820
+ toolkitRun,
821
+ toUpperCamelCase,
822
+ toUtf16Bytes,
823
+ toUtf8Array,
824
+ utf8ArrayToStr,
825
+ prompt,
826
+ prompter,
827
+ traceChecklists,
828
+ traceHeader,
829
+ traceTable,
830
+ traceTransaction,
831
+ traceTransactionOnStatusChange,
832
+ traceTransactionOnCheckpoint,
833
+ traceTransactionReceipt,
834
+ checkRpcWildcards,
835
+ isWildcard,
836
+ getWildcardsCountFromString,
837
+ replaceWildcards,
838
+ spliceWildcard,
839
+ txJsonReplacer,
840
+ }