@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.
- package/.env_witnet +6 -6
- package/LICENSE +21 -21
- package/README.md +103 -103
- package/dist/bin/helpers.d.ts +88 -0
- package/dist/bin/helpers.d.ts.map +1 -0
- package/dist/bin/helpers.js +866 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/lib/crypto/account.d.ts +18 -0
- package/dist/lib/crypto/account.d.ts.map +1 -0
- package/dist/lib/crypto/account.js +152 -0
- package/dist/lib/crypto/coinbase.d.ts +9 -0
- package/dist/lib/crypto/coinbase.d.ts.map +1 -0
- package/dist/lib/crypto/coinbase.js +39 -0
- package/dist/lib/crypto/index.d.ts +7 -0
- package/dist/lib/crypto/index.d.ts.map +1 -0
- package/dist/lib/crypto/index.js +28 -0
- package/dist/lib/crypto/interfaces.d.ts +80 -0
- package/dist/lib/crypto/interfaces.d.ts.map +1 -0
- package/dist/lib/crypto/interfaces.js +3 -0
- package/dist/lib/crypto/payloads/DataRequestPayload.d.ts +47 -0
- package/dist/lib/crypto/payloads/DataRequestPayload.d.ts.map +1 -0
- package/dist/lib/crypto/payloads/DataRequestPayload.js +384 -0
- package/dist/lib/crypto/payloads/StakePayload.d.ts +27 -0
- package/dist/lib/crypto/payloads/StakePayload.d.ts.map +1 -0
- package/dist/lib/crypto/payloads/StakePayload.js +184 -0
- package/dist/lib/crypto/payloads/UnstakePayload.d.ts +35 -0
- package/dist/lib/crypto/payloads/UnstakePayload.d.ts.map +1 -0
- package/dist/lib/crypto/payloads/UnstakePayload.js +244 -0
- package/dist/lib/crypto/payloads/ValueTransferPayload.d.ts +24 -0
- package/dist/lib/crypto/payloads/ValueTransferPayload.d.ts.map +1 -0
- package/dist/lib/crypto/payloads/ValueTransferPayload.js +182 -0
- package/dist/lib/crypto/payloads.d.ts +54 -0
- package/dist/lib/crypto/payloads.d.ts.map +1 -0
- package/dist/lib/crypto/payloads.js +224 -0
- package/dist/lib/crypto/signer.d.ts +26 -0
- package/dist/lib/crypto/signer.d.ts.map +1 -0
- package/dist/lib/crypto/signer.js +299 -0
- package/dist/lib/crypto/transmitters/DataRequests.d.ts +14 -0
- package/dist/lib/crypto/transmitters/DataRequests.d.ts.map +1 -0
- package/dist/lib/crypto/transmitters/DataRequests.js +62 -0
- package/dist/lib/crypto/transmitters/StakeDeposits.d.ts +11 -0
- package/dist/lib/crypto/transmitters/StakeDeposits.d.ts.map +1 -0
- package/dist/lib/crypto/transmitters/StakeDeposits.js +48 -0
- package/dist/lib/crypto/transmitters/StakeWithdrawals.d.ts +17 -0
- package/dist/lib/crypto/transmitters/StakeWithdrawals.d.ts.map +1 -0
- package/dist/lib/crypto/transmitters/StakeWithdrawals.js +115 -0
- package/dist/lib/crypto/transmitters/ValueTransfers.d.ts +10 -0
- package/dist/lib/crypto/transmitters/ValueTransfers.d.ts.map +1 -0
- package/dist/lib/crypto/transmitters/ValueTransfers.js +47 -0
- package/dist/lib/crypto/transmitters.d.ts +46 -0
- package/dist/lib/crypto/transmitters.d.ts.map +1 -0
- package/dist/lib/crypto/transmitters.js +506 -0
- package/dist/lib/crypto/types.d.ts +127 -0
- package/dist/lib/crypto/types.d.ts.map +1 -0
- package/dist/lib/crypto/types.js +261 -0
- package/dist/lib/crypto/utils.d.ts +10 -0
- package/dist/lib/crypto/utils.d.ts.map +1 -0
- package/dist/lib/crypto/utils.js +97 -0
- package/dist/lib/crypto/wallet.d.ts +26 -0
- package/dist/lib/crypto/wallet.d.ts.map +1 -0
- package/dist/lib/crypto/wallet.js +327 -0
- package/dist/lib/helpers.d.ts +90 -0
- package/dist/lib/helpers.d.ts.map +1 -0
- package/dist/lib/helpers.js +1031 -0
- package/dist/lib/index.d.ts +5 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +21 -0
- package/dist/lib/radon/artifacts.d.ts +55 -0
- package/dist/lib/radon/artifacts.d.ts.map +1 -0
- package/dist/lib/radon/artifacts.js +347 -0
- package/dist/lib/radon/ccdr/eth.d.ts +100 -0
- package/dist/lib/radon/ccdr/eth.d.ts.map +1 -0
- package/dist/lib/radon/ccdr/eth.js +237 -0
- package/dist/lib/radon/ccdr/index.d.ts +34 -0
- package/dist/lib/radon/ccdr/index.d.ts.map +1 -0
- package/dist/lib/radon/ccdr/index.js +63 -0
- package/dist/lib/radon/ccdr/wit.d.ts +29 -0
- package/dist/lib/radon/ccdr/wit.d.ts.map +1 -0
- package/dist/lib/radon/ccdr/wit.js +60 -0
- package/dist/lib/radon/filters.d.ts +14 -0
- package/dist/lib/radon/filters.d.ts.map +1 -0
- package/dist/lib/radon/filters.js +47 -0
- package/dist/lib/radon/index.d.ts +36 -0
- package/dist/lib/radon/index.d.ts.map +1 -0
- package/dist/lib/radon/index.js +154 -0
- package/dist/lib/radon/reducers.d.ts +29 -0
- package/dist/lib/radon/reducers.d.ts.map +1 -0
- package/dist/lib/radon/reducers.js +101 -0
- package/dist/lib/radon/retrievals.d.ts +120 -0
- package/dist/lib/radon/retrievals.d.ts.map +1 -0
- package/dist/lib/radon/retrievals.js +358 -0
- package/dist/lib/radon/sources.d.ts +102 -0
- package/dist/lib/radon/sources.d.ts.map +1 -0
- package/dist/lib/radon/sources.js +294 -0
- package/dist/lib/radon/types.d.ts +521 -0
- package/dist/lib/radon/types.d.ts.map +1 -0
- package/dist/lib/radon/types.js +1066 -0
- package/dist/lib/radon/utils.d.ts +55 -0
- package/dist/lib/radon/utils.d.ts.map +1 -0
- package/dist/lib/radon/utils.js +181 -0
- package/dist/lib/rpc/farm.d.ts +66 -0
- package/dist/lib/rpc/farm.d.ts.map +1 -0
- package/dist/lib/rpc/farm.js +808 -0
- package/dist/lib/rpc/index.d.ts +3 -0
- package/dist/lib/rpc/index.d.ts.map +1 -0
- package/dist/lib/rpc/index.js +19 -0
- package/dist/lib/rpc/node.d.ts +38 -0
- package/dist/lib/rpc/node.d.ts.map +1 -0
- package/dist/lib/rpc/node.js +335 -0
- package/dist/lib/rpc/nodes.d.ts +40 -0
- package/dist/lib/rpc/nodes.d.ts.map +1 -0
- package/dist/lib/rpc/nodes.js +531 -0
- package/dist/lib/rpc/provider.d.ts +72 -0
- package/dist/lib/rpc/provider.d.ts.map +1 -0
- package/dist/lib/rpc/provider.js +402 -0
- package/dist/lib/rpc/reporter.d.ts +18 -0
- package/dist/lib/rpc/reporter.d.ts.map +1 -0
- package/dist/lib/rpc/reporter.js +99 -0
- package/dist/lib/rpc/types.d.ts +396 -0
- package/dist/lib/rpc/types.d.ts.map +1 -0
- package/dist/lib/rpc/types.js +81 -0
- package/dist/lib/rpc/wallet.d.ts +72 -0
- package/dist/lib/rpc/wallet.d.ts.map +1 -0
- package/dist/lib/rpc/wallet.js +41 -0
- package/dist/lib/types.d.ts +19 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +7 -0
- package/dist/lib/utils.d.ts +5 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +51 -0
- package/dist/package.json +1 -1
- package/dist/src/bin/helpers.js +2 -2
- package/dist/src/index.js +1 -1
- package/dist/src/lib/crypto/account.js +1 -1
- package/dist/src/lib/crypto/coinbase.js +1 -1
- package/dist/src/lib/crypto/index.js +1 -1
- package/dist/src/lib/crypto/interfaces.js +1 -1
- package/dist/src/lib/crypto/payloads/DataRequestPayload.d.ts +2 -2
- package/dist/src/lib/crypto/payloads/DataRequestPayload.d.ts.map +1 -1
- package/dist/src/lib/crypto/payloads/DataRequestPayload.js +8 -8
- package/dist/src/lib/crypto/payloads/StakePayload.js +1 -1
- package/dist/src/lib/crypto/payloads/UnstakePayload.js +1 -1
- package/dist/src/lib/crypto/payloads/ValueTransferPayload.js +1 -1
- package/dist/src/lib/crypto/payloads.js +1 -1
- package/dist/src/lib/crypto/signer.js +1 -1
- package/dist/src/lib/crypto/transmitters/DataRequests.d.ts +0 -1
- package/dist/src/lib/crypto/transmitters/DataRequests.d.ts.map +1 -1
- package/dist/src/lib/crypto/transmitters/DataRequests.js +1 -2
- package/dist/src/lib/crypto/transmitters/StakeDeposits.js +1 -1
- package/dist/src/lib/crypto/transmitters/StakeWithdrawals.js +1 -1
- package/dist/src/lib/crypto/transmitters/ValueTransfers.js +1 -1
- package/dist/src/lib/crypto/transmitters.js +1 -1
- package/dist/src/lib/crypto/types.js +1 -1
- package/dist/src/lib/crypto/utils.js +1 -1
- package/dist/src/lib/crypto/wallet.js +1 -1
- package/dist/src/lib/index.js +1 -1
- package/dist/src/lib/radon/ccdr/eth.js +1 -1
- package/dist/src/lib/radon/ccdr/index.js +1 -1
- package/dist/src/lib/radon/ccdr/wit.d.ts +11 -0
- package/dist/src/lib/radon/ccdr/wit.d.ts.map +1 -1
- package/dist/src/lib/radon/ccdr/wit.js +17 -2
- package/dist/src/lib/radon/filters.js +1 -1
- package/dist/src/lib/radon/index.d.ts +1 -1
- package/dist/src/lib/radon/index.d.ts.map +1 -1
- package/dist/src/lib/radon/index.js +9 -3
- package/dist/src/lib/radon/reducers.js +1 -1
- package/dist/src/lib/radon/types.js +1 -1
- package/dist/src/lib/radon/utils.js +1 -1
- package/dist/src/lib/rpc/index.js +1 -1
- package/dist/src/lib/rpc/nodes.js +1 -1
- package/dist/src/lib/rpc/provider.d.ts +5 -3
- package/dist/src/lib/rpc/provider.d.ts.map +1 -1
- package/dist/src/lib/rpc/provider.js +14 -3
- package/dist/src/lib/rpc/reporter.d.ts +2 -3
- package/dist/src/lib/rpc/reporter.d.ts.map +1 -1
- package/dist/src/lib/rpc/reporter.js +1 -4
- package/dist/src/lib/rpc/types.d.ts +49 -24
- package/dist/src/lib/rpc/types.d.ts.map +1 -1
- package/dist/src/lib/rpc/types.js +3 -1
- package/dist/src/lib/types.d.ts +1 -1
- package/dist/src/lib/types.d.ts.map +1 -1
- package/dist/src/lib/types.js +1 -1
- package/dist/src/lib/utils.js +1 -1
- package/dist/witnet/assets/index.js +1 -1
- package/dist/witnet/assets/modals/index.js +1 -1
- package/dist/witnet/assets/modals/web3/eth.js +1 -1
- package/dist/witnet/assets/modals/web3/ipfs.js +1 -1
- package/dist/witnet/assets/modals/web3/wit.js +4 -7
- package/dist/witnet/assets/requests.js +1 -1
- package/package.json +1 -1
- package/src/bin/cli/history.js +31 -31
- package/src/bin/cli/inspect.js +405 -359
- package/src/bin/cli/network.js +594 -592
- package/src/bin/cli/nodes.js +364 -364
- package/src/bin/cli/radon.js +815 -815
- package/src/bin/cli/wallet.js +1117 -1094
- package/src/bin/helpers.js +840 -840
- package/src/bin/postinstall.js +9 -9
- package/src/bin/toolkit.js +295 -295
- package/witnet/assets/_index.js +8 -8
- package/witnet/assets/_requests.js +25 -25
- package/witnet/assets/_sources.js +36 -36
- package/witnet/assets/_templates.js +36 -36
- package/witnet/assets/index.js +4 -4
- package/witnet/assets/modals/index.js +9 -9
- package/witnet/assets/modals/web3/eth.js +29 -29
- package/witnet/assets/modals/web3/ipfs.js +19 -19
- package/witnet/assets/modals/web3/wit.js +21 -23
- package/witnet/assets/requests.js +95 -95
package/src/bin/helpers.js
CHANGED
|
@@ -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
|
+
}
|