@witnet/sdk 1.0.4 → 1.0.6
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/package.json +3 -4
- package/dist/src/bin/helpers.js +2 -2
- package/dist/src/index.js +1 -1
- package/dist/src/lib/crypto/account.d.ts +3 -1
- package/dist/src/lib/crypto/account.d.ts.map +1 -1
- package/dist/src/lib/crypto/account.js +7 -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.d.ts +2 -0
- package/dist/src/lib/crypto/interfaces.d.ts.map +1 -1
- package/dist/src/lib/crypto/interfaces.js +1 -1
- package/dist/src/lib/crypto/payloads/DataRequestPayload.js +1 -1
- 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.d.ts.map +1 -1
- package/dist/src/lib/crypto/payloads.js +12 -1
- package/dist/src/lib/crypto/signer.d.ts +1 -0
- package/dist/src/lib/crypto/signer.d.ts.map +1 -1
- package/dist/src/lib/crypto/signer.js +18 -1
- package/dist/src/lib/crypto/transmitters/DataRequests.js +1 -1
- 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.d.ts +1 -1
- package/dist/src/lib/crypto/transmitters.d.ts.map +1 -1
- package/dist/src/lib/crypto/transmitters.js +4 -4
- package/dist/src/lib/crypto/types.d.ts.map +1 -1
- package/dist/src/lib/crypto/types.js +2 -1
- package/dist/src/lib/crypto/utils.js +1 -1
- package/dist/src/lib/crypto/wallet.d.ts +3 -1
- package/dist/src/lib/crypto/wallet.d.ts.map +1 -1
- package/dist/src/lib/crypto/wallet.js +10 -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.js +1 -1
- package/dist/src/lib/radon/filters.js +1 -1
- package/dist/src/lib/radon/index.js +1 -1
- 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.js +1 -1
- package/dist/src/lib/rpc/types.d.ts +6 -4
- package/dist/src/lib/rpc/types.d.ts.map +1 -1
- package/dist/src/lib/rpc/types.js +1 -1
- package/dist/src/lib/types.d.ts +0 -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 +1 -1
- package/dist/witnet/assets/requests.js +1 -1
- package/package.json +3 -4
- package/src/bin/cli/history.js +31 -31
- package/src/bin/cli/inspect.js +405 -405
- package/src/bin/cli/network.js +594 -594
- package/src/bin/cli/nodes.js +364 -364
- package/src/bin/cli/radon.js +817 -815
- package/src/bin/cli/wallet.js +1121 -1117
- 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 -21
- package/witnet/assets/requests.js +95 -95
- package/dist/bin/helpers.d.ts +0 -88
- package/dist/bin/helpers.d.ts.map +0 -1
- package/dist/bin/helpers.js +0 -866
- package/dist/index.d.ts +0 -4
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -42
- package/dist/lib/crypto/account.d.ts +0 -18
- package/dist/lib/crypto/account.d.ts.map +0 -1
- package/dist/lib/crypto/account.js +0 -152
- package/dist/lib/crypto/coinbase.d.ts +0 -9
- package/dist/lib/crypto/coinbase.d.ts.map +0 -1
- package/dist/lib/crypto/coinbase.js +0 -39
- package/dist/lib/crypto/index.d.ts +0 -7
- package/dist/lib/crypto/index.d.ts.map +0 -1
- package/dist/lib/crypto/index.js +0 -28
- package/dist/lib/crypto/interfaces.d.ts +0 -80
- package/dist/lib/crypto/interfaces.d.ts.map +0 -1
- package/dist/lib/crypto/interfaces.js +0 -3
- package/dist/lib/crypto/payloads/DataRequestPayload.d.ts +0 -47
- package/dist/lib/crypto/payloads/DataRequestPayload.d.ts.map +0 -1
- package/dist/lib/crypto/payloads/DataRequestPayload.js +0 -384
- package/dist/lib/crypto/payloads/StakePayload.d.ts +0 -27
- package/dist/lib/crypto/payloads/StakePayload.d.ts.map +0 -1
- package/dist/lib/crypto/payloads/StakePayload.js +0 -184
- package/dist/lib/crypto/payloads/UnstakePayload.d.ts +0 -35
- package/dist/lib/crypto/payloads/UnstakePayload.d.ts.map +0 -1
- package/dist/lib/crypto/payloads/UnstakePayload.js +0 -244
- package/dist/lib/crypto/payloads/ValueTransferPayload.d.ts +0 -24
- package/dist/lib/crypto/payloads/ValueTransferPayload.d.ts.map +0 -1
- package/dist/lib/crypto/payloads/ValueTransferPayload.js +0 -182
- package/dist/lib/crypto/payloads.d.ts +0 -54
- package/dist/lib/crypto/payloads.d.ts.map +0 -1
- package/dist/lib/crypto/payloads.js +0 -224
- package/dist/lib/crypto/signer.d.ts +0 -26
- package/dist/lib/crypto/signer.d.ts.map +0 -1
- package/dist/lib/crypto/signer.js +0 -299
- package/dist/lib/crypto/transmitters/DataRequests.d.ts +0 -14
- package/dist/lib/crypto/transmitters/DataRequests.d.ts.map +0 -1
- package/dist/lib/crypto/transmitters/DataRequests.js +0 -62
- package/dist/lib/crypto/transmitters/StakeDeposits.d.ts +0 -11
- package/dist/lib/crypto/transmitters/StakeDeposits.d.ts.map +0 -1
- package/dist/lib/crypto/transmitters/StakeDeposits.js +0 -48
- package/dist/lib/crypto/transmitters/StakeWithdrawals.d.ts +0 -17
- package/dist/lib/crypto/transmitters/StakeWithdrawals.d.ts.map +0 -1
- package/dist/lib/crypto/transmitters/StakeWithdrawals.js +0 -115
- package/dist/lib/crypto/transmitters/ValueTransfers.d.ts +0 -10
- package/dist/lib/crypto/transmitters/ValueTransfers.d.ts.map +0 -1
- package/dist/lib/crypto/transmitters/ValueTransfers.js +0 -47
- package/dist/lib/crypto/transmitters.d.ts +0 -46
- package/dist/lib/crypto/transmitters.d.ts.map +0 -1
- package/dist/lib/crypto/transmitters.js +0 -506
- package/dist/lib/crypto/types.d.ts +0 -127
- package/dist/lib/crypto/types.d.ts.map +0 -1
- package/dist/lib/crypto/types.js +0 -261
- package/dist/lib/crypto/utils.d.ts +0 -10
- package/dist/lib/crypto/utils.d.ts.map +0 -1
- package/dist/lib/crypto/utils.js +0 -97
- package/dist/lib/crypto/wallet.d.ts +0 -26
- package/dist/lib/crypto/wallet.d.ts.map +0 -1
- package/dist/lib/crypto/wallet.js +0 -327
- package/dist/lib/helpers.d.ts +0 -90
- package/dist/lib/helpers.d.ts.map +0 -1
- package/dist/lib/helpers.js +0 -1031
- package/dist/lib/index.d.ts +0 -5
- package/dist/lib/index.d.ts.map +0 -1
- package/dist/lib/index.js +0 -21
- package/dist/lib/radon/artifacts.d.ts +0 -55
- package/dist/lib/radon/artifacts.d.ts.map +0 -1
- package/dist/lib/radon/artifacts.js +0 -347
- package/dist/lib/radon/ccdr/eth.d.ts +0 -100
- package/dist/lib/radon/ccdr/eth.d.ts.map +0 -1
- package/dist/lib/radon/ccdr/eth.js +0 -237
- package/dist/lib/radon/ccdr/index.d.ts +0 -34
- package/dist/lib/radon/ccdr/index.d.ts.map +0 -1
- package/dist/lib/radon/ccdr/index.js +0 -63
- package/dist/lib/radon/ccdr/wit.d.ts +0 -29
- package/dist/lib/radon/ccdr/wit.d.ts.map +0 -1
- package/dist/lib/radon/ccdr/wit.js +0 -60
- package/dist/lib/radon/filters.d.ts +0 -14
- package/dist/lib/radon/filters.d.ts.map +0 -1
- package/dist/lib/radon/filters.js +0 -47
- package/dist/lib/radon/index.d.ts +0 -36
- package/dist/lib/radon/index.d.ts.map +0 -1
- package/dist/lib/radon/index.js +0 -154
- package/dist/lib/radon/reducers.d.ts +0 -29
- package/dist/lib/radon/reducers.d.ts.map +0 -1
- package/dist/lib/radon/reducers.js +0 -101
- package/dist/lib/radon/retrievals.d.ts +0 -120
- package/dist/lib/radon/retrievals.d.ts.map +0 -1
- package/dist/lib/radon/retrievals.js +0 -358
- package/dist/lib/radon/sources.d.ts +0 -102
- package/dist/lib/radon/sources.d.ts.map +0 -1
- package/dist/lib/radon/sources.js +0 -294
- package/dist/lib/radon/types.d.ts +0 -521
- package/dist/lib/radon/types.d.ts.map +0 -1
- package/dist/lib/radon/types.js +0 -1066
- package/dist/lib/radon/utils.d.ts +0 -55
- package/dist/lib/radon/utils.d.ts.map +0 -1
- package/dist/lib/radon/utils.js +0 -181
- package/dist/lib/rpc/farm.d.ts +0 -66
- package/dist/lib/rpc/farm.d.ts.map +0 -1
- package/dist/lib/rpc/farm.js +0 -808
- package/dist/lib/rpc/index.d.ts +0 -3
- package/dist/lib/rpc/index.d.ts.map +0 -1
- package/dist/lib/rpc/index.js +0 -19
- package/dist/lib/rpc/node.d.ts +0 -38
- package/dist/lib/rpc/node.d.ts.map +0 -1
- package/dist/lib/rpc/node.js +0 -335
- package/dist/lib/rpc/nodes.d.ts +0 -40
- package/dist/lib/rpc/nodes.d.ts.map +0 -1
- package/dist/lib/rpc/nodes.js +0 -531
- package/dist/lib/rpc/provider.d.ts +0 -72
- package/dist/lib/rpc/provider.d.ts.map +0 -1
- package/dist/lib/rpc/provider.js +0 -402
- package/dist/lib/rpc/reporter.d.ts +0 -18
- package/dist/lib/rpc/reporter.d.ts.map +0 -1
- package/dist/lib/rpc/reporter.js +0 -99
- package/dist/lib/rpc/types.d.ts +0 -396
- package/dist/lib/rpc/types.d.ts.map +0 -1
- package/dist/lib/rpc/types.js +0 -81
- package/dist/lib/rpc/wallet.d.ts +0 -72
- package/dist/lib/rpc/wallet.d.ts.map +0 -1
- package/dist/lib/rpc/wallet.js +0 -41
- package/dist/lib/types.d.ts +0 -19
- package/dist/lib/types.d.ts.map +0 -1
- package/dist/lib/types.js +0 -7
- package/dist/lib/utils.d.ts +0 -5
- package/dist/lib/utils.d.ts.map +0 -1
- package/dist/lib/utils.js +0 -51
- package/dist/src/lib/rpc/reporter.d.ts +0 -17
- package/dist/src/lib/rpc/reporter.d.ts.map +0 -1
- package/dist/src/lib/rpc/reporter.js +0 -27
package/src/bin/cli/wallet.js
CHANGED
|
@@ -1,1117 +1,1121 @@
|
|
|
1
|
-
const qrcodes = require("qrcode-terminal")
|
|
2
|
-
const prompt = require("inquirer").createPromptModule()
|
|
3
|
-
|
|
4
|
-
const { utils, Witnet } = require("../../../dist/src")
|
|
5
|
-
|
|
6
|
-
const helpers = require("../helpers")
|
|
7
|
-
const { loadAssets } = require("./radon")
|
|
8
|
-
|
|
9
|
-
const { colors, whole_wits } = helpers
|
|
10
|
-
|
|
11
|
-
const options = {
|
|
12
|
-
await: {
|
|
13
|
-
hint: "Await any involved transaction to get eventually mined (default: false).",
|
|
14
|
-
},
|
|
15
|
-
confirmations: {
|
|
16
|
-
hint: "Number of epochs to await after any involved transaction gets mined (implies --await).",
|
|
17
|
-
param: "NUMBER",
|
|
18
|
-
},
|
|
19
|
-
fees: {
|
|
20
|
-
hint: "Specific transaction fees (supersedes --priority).",
|
|
21
|
-
param: "WITS",
|
|
22
|
-
},
|
|
23
|
-
force: {
|
|
24
|
-
hint: "Broadcast transaction/s without user's final confirmation.",
|
|
25
|
-
},
|
|
26
|
-
from: {
|
|
27
|
-
hint: "Specific wallet's address that will pay for the transaction, other than default.",
|
|
28
|
-
param: "WALLET_ADDRESS",
|
|
29
|
-
},
|
|
30
|
-
priority: {
|
|
31
|
-
hint: "Transaction priority: `stinky`, `low`, `medium`, `high`, `opulent`.",
|
|
32
|
-
param: "PRIORITY",
|
|
33
|
-
},
|
|
34
|
-
strategy: {
|
|
35
|
-
hint: "UTXOs selection strategy: `big-first`, `random`, `slim-fit`, `small-first` (default: `slim-fit`).",
|
|
36
|
-
param: "STRATEGY",
|
|
37
|
-
},
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
41
|
-
/// CLI SUBMODULE CONSTANTS ===========================================================================================
|
|
42
|
-
|
|
43
|
-
module.exports = {
|
|
44
|
-
envars: {
|
|
45
|
-
WITNET_SDK_PROVIDER_URL: "=> Wit/Oracle RPC provider(s) to connect to, if no otherwise specified.",
|
|
46
|
-
WITNET_SDK_WALLET_MASTER_KEY: "=> Wallet's master key in XPRV format, as exported from either a node, Sheikah or myWitWallet.",
|
|
47
|
-
},
|
|
48
|
-
flags: {
|
|
49
|
-
gap: {
|
|
50
|
-
hint: "Max indexing gap when searching for wallet accounts (default: 10).",
|
|
51
|
-
param: "NUMBER",
|
|
52
|
-
},
|
|
53
|
-
provider: {
|
|
54
|
-
hint: "Public Wit/Oracle JSON-RPC provider, other than default.",
|
|
55
|
-
param: "URL",
|
|
56
|
-
},
|
|
57
|
-
verbose: {
|
|
58
|
-
hint: "Outputs detailed information.",
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
router: {
|
|
62
|
-
accounts: {
|
|
63
|
-
hint: "List wallet's HD-accounts treasuring staked, locked or unlocked Wits.",
|
|
64
|
-
params: ["[WIT_ADDRESSES ...]"],
|
|
65
|
-
options: {
|
|
66
|
-
ethereum: {
|
|
67
|
-
hint: "Generate account ownership proofs verifiable in Ethereum networks.",
|
|
68
|
-
param: "EVM_ADDRESS"
|
|
69
|
-
},
|
|
70
|
-
limit: {
|
|
71
|
-
hint: "Max number of HD-accounts to derive.",
|
|
72
|
-
param: "LIMIT",
|
|
73
|
-
},
|
|
74
|
-
"no-funds": {
|
|
75
|
-
hint: "Derive accounts even if they hold no funds.",
|
|
76
|
-
},
|
|
77
|
-
qrcode: {
|
|
78
|
-
hint: "Prints QR codes for all selected accounts.",
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
// "create*": {
|
|
83
|
-
// hint: "Create some random master key.",
|
|
84
|
-
// options: {
|
|
85
|
-
// vanity: {
|
|
86
|
-
// hint: "Vanity prefix of the resulting public key hash address (e.g. `herrer0`)",
|
|
87
|
-
// param: "BECH32_PREFIX",
|
|
88
|
-
// },
|
|
89
|
-
// }
|
|
90
|
-
// },
|
|
91
|
-
coinbase: {
|
|
92
|
-
hint: "List withdrawers delegating stake into the coinbase address.",
|
|
93
|
-
options: {
|
|
94
|
-
authorize: {
|
|
95
|
-
hint: "Generate stake authorization code for the specified withdrawer address.",
|
|
96
|
-
param: "WIT_ADDRESS",
|
|
97
|
-
},
|
|
98
|
-
"node-master-key": {
|
|
99
|
-
hint: "Node's master key other than the one set up in environment.",
|
|
100
|
-
param: "XPRV",
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
},
|
|
104
|
-
decipherMasterKey: {
|
|
105
|
-
hint: "Decipher some master key as exported from myWitWallet.",
|
|
106
|
-
},
|
|
107
|
-
delegatees: {
|
|
108
|
-
hint: "List validators treasuring delegated stake from any of the wallet's accounts.",
|
|
109
|
-
},
|
|
110
|
-
notarize: {
|
|
111
|
-
hint: "Ask the Wit/Oracle to notarize and forever store the resolution to some Radon asset.",
|
|
112
|
-
params: ["RAD_BYTECODE | RAD_HASH | RADON_ASSET", "[RADON_ARGS]"],
|
|
113
|
-
options: {
|
|
114
|
-
...options,
|
|
115
|
-
fees: {
|
|
116
|
-
hint: "Specific unitary reward for every involved validator (supersedes --priority).",
|
|
117
|
-
param: "WITS",
|
|
118
|
-
},
|
|
119
|
-
module: {
|
|
120
|
-
hint: "NPM package where to search for Radon assets.",
|
|
121
|
-
param: "NPM_PACKAGE",
|
|
122
|
-
},
|
|
123
|
-
witnesses: {
|
|
124
|
-
hint: "Number of witnesses in the Witnet network required to attend the oracle query (default: 3).",
|
|
125
|
-
param: "NUMBER",
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
},
|
|
129
|
-
provider: {
|
|
130
|
-
hint: "Show the underlying Wit/Oracle RPC provider being used.",
|
|
131
|
-
},
|
|
132
|
-
signMessage: {
|
|
133
|
-
hint: "Prove ownership of a wallet address by signing some given message.",
|
|
134
|
-
param: "TEXT",
|
|
135
|
-
options: {
|
|
136
|
-
signer: {
|
|
137
|
-
hint: "Wallet's signer address other than wallet's default.",
|
|
138
|
-
param: "WALLET_ADDRESS",
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
},
|
|
142
|
-
verifyMessage: {
|
|
143
|
-
hint: "Verify authenticity of some given message and signature.",
|
|
144
|
-
param: "TEXT",
|
|
145
|
-
options: {
|
|
146
|
-
publicKey: {
|
|
147
|
-
hint: "Hexified public key of the alleged signer of the message.",
|
|
148
|
-
param: "<HEX_STRING>",
|
|
149
|
-
},
|
|
150
|
-
signature: {
|
|
151
|
-
hint: "Hexified signature produced with the signer's private key.",
|
|
152
|
-
param: "<HEX_STRING>",
|
|
153
|
-
},
|
|
154
|
-
},
|
|
155
|
-
},
|
|
156
|
-
stake: {
|
|
157
|
-
hint: "Stake specified amount of Wits by using some given authorization code.",
|
|
158
|
-
params: "AUTH_CODE",
|
|
159
|
-
options: {
|
|
160
|
-
...options,
|
|
161
|
-
value: {
|
|
162
|
-
hint: "Amount in Wits to stake into the validator that signed the authorization (min: 10 KWits).",
|
|
163
|
-
param: "WITS | `all`",
|
|
164
|
-
},
|
|
165
|
-
withdrawer: {
|
|
166
|
-
hint: "Wallet's address with rights to eventually withdraw the staked deposit, plus benefits.",
|
|
167
|
-
param: "WALLET_ADDRESS",
|
|
168
|
-
},
|
|
169
|
-
},
|
|
170
|
-
},
|
|
171
|
-
transfer: {
|
|
172
|
-
hint: "Transfer specified amount of Wits to given address.",
|
|
173
|
-
options: {
|
|
174
|
-
...options,
|
|
175
|
-
into: {
|
|
176
|
-
hint: "Recipient address.",
|
|
177
|
-
param: "WIT_ADDRESS",
|
|
178
|
-
},
|
|
179
|
-
metadata: {
|
|
180
|
-
hint: "Optional 20-byte metadata info.",
|
|
181
|
-
param: "HEX_STRING"
|
|
182
|
-
},
|
|
183
|
-
value: {
|
|
184
|
-
hint: "Amount in Wits to be transfered (e.g. `0.5` Wits).",
|
|
185
|
-
param: "WITS | `all`",
|
|
186
|
-
},
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
utxos: {
|
|
190
|
-
hint: "List currently available UTXOs on wallet's specified address, or on all funded accounts otherwise.",
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
ledger = wallet
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
throw Error(`--
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
console.info(`
|
|
283
|
-
console.info(`
|
|
284
|
-
console.info(
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
addrs = wallet.accounts
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
const
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
balance,
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
})
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
throw Error("No
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
const
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
if (
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
//
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
const
|
|
875
|
-
const
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
...(
|
|
892
|
-
? [record.
|
|
893
|
-
: []
|
|
894
|
-
),
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
if (
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
}
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
if (
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
"<
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
}
|
|
1
|
+
const qrcodes = require("qrcode-terminal")
|
|
2
|
+
const prompt = require("inquirer").createPromptModule()
|
|
3
|
+
|
|
4
|
+
const { utils, Witnet } = require("../../../dist/src")
|
|
5
|
+
|
|
6
|
+
const helpers = require("../helpers")
|
|
7
|
+
const { loadAssets } = require("./radon")
|
|
8
|
+
|
|
9
|
+
const { colors, whole_wits } = helpers
|
|
10
|
+
|
|
11
|
+
const options = {
|
|
12
|
+
await: {
|
|
13
|
+
hint: "Await any involved transaction to get eventually mined (default: false).",
|
|
14
|
+
},
|
|
15
|
+
confirmations: {
|
|
16
|
+
hint: "Number of epochs to await after any involved transaction gets mined (implies --await).",
|
|
17
|
+
param: "NUMBER",
|
|
18
|
+
},
|
|
19
|
+
fees: {
|
|
20
|
+
hint: "Specific transaction fees (supersedes --priority).",
|
|
21
|
+
param: "WITS",
|
|
22
|
+
},
|
|
23
|
+
force: {
|
|
24
|
+
hint: "Broadcast transaction/s without user's final confirmation.",
|
|
25
|
+
},
|
|
26
|
+
from: {
|
|
27
|
+
hint: "Specific wallet's address that will pay for the transaction, other than default.",
|
|
28
|
+
param: "WALLET_ADDRESS",
|
|
29
|
+
},
|
|
30
|
+
priority: {
|
|
31
|
+
hint: "Transaction priority: `stinky`, `low`, `medium`, `high`, `opulent`.",
|
|
32
|
+
param: "PRIORITY",
|
|
33
|
+
},
|
|
34
|
+
strategy: {
|
|
35
|
+
hint: "UTXOs selection strategy: `big-first`, `random`, `slim-fit`, `small-first` (default: `slim-fit`).",
|
|
36
|
+
param: "STRATEGY",
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
41
|
+
/// CLI SUBMODULE CONSTANTS ===========================================================================================
|
|
42
|
+
|
|
43
|
+
module.exports = {
|
|
44
|
+
envars: {
|
|
45
|
+
WITNET_SDK_PROVIDER_URL: "=> Wit/Oracle RPC provider(s) to connect to, if no otherwise specified.",
|
|
46
|
+
WITNET_SDK_WALLET_MASTER_KEY: "=> Wallet's master key in XPRV format, as exported from either a node, Sheikah or myWitWallet.",
|
|
47
|
+
},
|
|
48
|
+
flags: {
|
|
49
|
+
gap: {
|
|
50
|
+
hint: "Max indexing gap when searching for wallet accounts (default: 10).",
|
|
51
|
+
param: "NUMBER",
|
|
52
|
+
},
|
|
53
|
+
provider: {
|
|
54
|
+
hint: "Public Wit/Oracle JSON-RPC provider, other than default.",
|
|
55
|
+
param: "URL",
|
|
56
|
+
},
|
|
57
|
+
verbose: {
|
|
58
|
+
hint: "Outputs detailed information.",
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
router: {
|
|
62
|
+
accounts: {
|
|
63
|
+
hint: "List wallet's HD-accounts treasuring staked, locked or unlocked Wits.",
|
|
64
|
+
params: ["[WIT_ADDRESSES ...]"],
|
|
65
|
+
options: {
|
|
66
|
+
ethereum: {
|
|
67
|
+
hint: "Generate account ownership proofs verifiable in Ethereum networks.",
|
|
68
|
+
param: "EVM_ADDRESS"
|
|
69
|
+
},
|
|
70
|
+
limit: {
|
|
71
|
+
hint: "Max number of HD-accounts to derive.",
|
|
72
|
+
param: "LIMIT",
|
|
73
|
+
},
|
|
74
|
+
"no-funds": {
|
|
75
|
+
hint: "Derive accounts even if they hold no funds.",
|
|
76
|
+
},
|
|
77
|
+
qrcode: {
|
|
78
|
+
hint: "Prints QR codes for all selected accounts.",
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
// "create*": {
|
|
83
|
+
// hint: "Create some random master key.",
|
|
84
|
+
// options: {
|
|
85
|
+
// vanity: {
|
|
86
|
+
// hint: "Vanity prefix of the resulting public key hash address (e.g. `herrer0`)",
|
|
87
|
+
// param: "BECH32_PREFIX",
|
|
88
|
+
// },
|
|
89
|
+
// }
|
|
90
|
+
// },
|
|
91
|
+
coinbase: {
|
|
92
|
+
hint: "List withdrawers delegating stake into the coinbase address.",
|
|
93
|
+
options: {
|
|
94
|
+
authorize: {
|
|
95
|
+
hint: "Generate stake authorization code for the specified withdrawer address.",
|
|
96
|
+
param: "WIT_ADDRESS",
|
|
97
|
+
},
|
|
98
|
+
"node-master-key": {
|
|
99
|
+
hint: "Node's master key other than the one set up in environment.",
|
|
100
|
+
param: "XPRV",
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
decipherMasterKey: {
|
|
105
|
+
hint: "Decipher some master key as exported from myWitWallet.",
|
|
106
|
+
},
|
|
107
|
+
delegatees: {
|
|
108
|
+
hint: "List validators treasuring delegated stake from any of the wallet's accounts.",
|
|
109
|
+
},
|
|
110
|
+
notarize: {
|
|
111
|
+
hint: "Ask the Wit/Oracle to notarize and forever store the resolution to some Radon asset.",
|
|
112
|
+
params: ["RAD_BYTECODE | RAD_HASH | RADON_ASSET", "[RADON_ARGS]"],
|
|
113
|
+
options: {
|
|
114
|
+
...options,
|
|
115
|
+
fees: {
|
|
116
|
+
hint: "Specific unitary reward for every involved validator (supersedes --priority).",
|
|
117
|
+
param: "WITS",
|
|
118
|
+
},
|
|
119
|
+
module: {
|
|
120
|
+
hint: "NPM package where to search for Radon assets.",
|
|
121
|
+
param: "NPM_PACKAGE",
|
|
122
|
+
},
|
|
123
|
+
witnesses: {
|
|
124
|
+
hint: "Number of witnesses in the Witnet network required to attend the oracle query (default: 3).",
|
|
125
|
+
param: "NUMBER",
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
provider: {
|
|
130
|
+
hint: "Show the underlying Wit/Oracle RPC provider being used.",
|
|
131
|
+
},
|
|
132
|
+
signMessage: {
|
|
133
|
+
hint: "Prove ownership of a wallet address by signing some given message.",
|
|
134
|
+
param: "TEXT",
|
|
135
|
+
options: {
|
|
136
|
+
signer: {
|
|
137
|
+
hint: "Wallet's signer address other than wallet's default.",
|
|
138
|
+
param: "WALLET_ADDRESS",
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
verifyMessage: {
|
|
143
|
+
hint: "Verify authenticity of some given message and signature.",
|
|
144
|
+
param: "TEXT",
|
|
145
|
+
options: {
|
|
146
|
+
publicKey: {
|
|
147
|
+
hint: "Hexified public key of the alleged signer of the message.",
|
|
148
|
+
param: "<HEX_STRING>",
|
|
149
|
+
},
|
|
150
|
+
signature: {
|
|
151
|
+
hint: "Hexified signature produced with the signer's private key.",
|
|
152
|
+
param: "<HEX_STRING>",
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
stake: {
|
|
157
|
+
hint: "Stake specified amount of Wits by using some given authorization code.",
|
|
158
|
+
params: "AUTH_CODE",
|
|
159
|
+
options: {
|
|
160
|
+
...options,
|
|
161
|
+
value: {
|
|
162
|
+
hint: "Amount in Wits to stake into the validator that signed the authorization (min: 10 KWits).",
|
|
163
|
+
param: "WITS | `all`",
|
|
164
|
+
},
|
|
165
|
+
withdrawer: {
|
|
166
|
+
hint: "Wallet's address with rights to eventually withdraw the staked deposit, plus benefits.",
|
|
167
|
+
param: "WALLET_ADDRESS",
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
transfer: {
|
|
172
|
+
hint: "Transfer specified amount of Wits to given address.",
|
|
173
|
+
options: {
|
|
174
|
+
...options,
|
|
175
|
+
into: {
|
|
176
|
+
hint: "Recipient address.",
|
|
177
|
+
param: "WIT_ADDRESS",
|
|
178
|
+
},
|
|
179
|
+
metadata: {
|
|
180
|
+
hint: "Optional 20-byte metadata info.",
|
|
181
|
+
param: "HEX_STRING"
|
|
182
|
+
},
|
|
183
|
+
value: {
|
|
184
|
+
hint: "Amount in Wits to be transfered (e.g. `0.5` Wits).",
|
|
185
|
+
param: "WITS | `all`",
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
utxos: {
|
|
190
|
+
hint: "List currently available UTXOs on wallet's specified address, or on all funded accounts otherwise.",
|
|
191
|
+
params: "[WALLET_ADDRESS]",
|
|
192
|
+
options: {
|
|
193
|
+
...options,
|
|
194
|
+
from: {},
|
|
195
|
+
into: {
|
|
196
|
+
hint: "Alternative wallet address where to JOIN or SPLIT the selected UTXOs, other than default.",
|
|
197
|
+
param: "WALLET_ADDRESS",
|
|
198
|
+
},
|
|
199
|
+
join: { hint: "Join selected UTXOs together into a single UTXO (requires --value)." },
|
|
200
|
+
limit: {
|
|
201
|
+
hint: "Max number of HD-accounts to derive.",
|
|
202
|
+
param: "LIMIT",
|
|
203
|
+
},
|
|
204
|
+
splits: {
|
|
205
|
+
hint: "Number of UTXOs to split the target balance into (max: 50; requires --value).",
|
|
206
|
+
param: "NUMBER",
|
|
207
|
+
},
|
|
208
|
+
value: {
|
|
209
|
+
hint: "Amount in Wits to be either joined or split apart.",
|
|
210
|
+
param: "WITS | `all`",
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
withdraw: {
|
|
215
|
+
hint: "Withdraw specified amount of staked Wits from some given delegatee.",
|
|
216
|
+
options: {
|
|
217
|
+
await: options.await,
|
|
218
|
+
confirmations: options.confirmations,
|
|
219
|
+
force: options.force,
|
|
220
|
+
from: {
|
|
221
|
+
hint: "Validator address from whom to withdraw the specified amount.",
|
|
222
|
+
param: "DELEGATEE_PKH",
|
|
223
|
+
},
|
|
224
|
+
into: {
|
|
225
|
+
hint: "Wallet address with rights to withdraw from the delegatee (default: wallet's first account).",
|
|
226
|
+
param: "WALLET_ADDRESS",
|
|
227
|
+
},
|
|
228
|
+
value: {
|
|
229
|
+
hint: "Amount in Wits to withdraw (default: `all`).",
|
|
230
|
+
param: "WITS | `all`",
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
subcommands: {
|
|
236
|
+
accounts, coinbase, delegatees: validators,
|
|
237
|
+
notarize: resolve, stake, transfer, withdraw: unstake, utxos,
|
|
238
|
+
decipherMasterKey: decipher, provider,
|
|
239
|
+
signMessage, verifyMessage,
|
|
240
|
+
},
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
244
|
+
/// CLI SUBMODULE COMMANDS ============================================================================================
|
|
245
|
+
|
|
246
|
+
async function signMessage (options = {}, [...words]) {
|
|
247
|
+
const wallet = await _loadWallet({
|
|
248
|
+
...options,
|
|
249
|
+
limit: 1,
|
|
250
|
+
"no-funds": true,
|
|
251
|
+
})
|
|
252
|
+
if (!words.length) {
|
|
253
|
+
throw Error(`some message must be entered.`)
|
|
254
|
+
}
|
|
255
|
+
const text = words.join(" ")
|
|
256
|
+
let ledger
|
|
257
|
+
if (options?.signer) {
|
|
258
|
+
ledger = options.signer === wallet.coinbase.pkh ? wallet.coinbase : wallet.getAccount(options.signer)
|
|
259
|
+
} else {
|
|
260
|
+
ledger = wallet
|
|
261
|
+
}
|
|
262
|
+
if (!ledger) {
|
|
263
|
+
throw Error(`no private key available for signer address ${options?.signer}`)
|
|
264
|
+
}
|
|
265
|
+
console.info(ledger.getSigner().signMessage(text))
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
async function verifyMessage (options = {}, [...words]) {
|
|
269
|
+
if (!words.length) {
|
|
270
|
+
throw Error(`some text must be entered.`)
|
|
271
|
+
}
|
|
272
|
+
const text = words.join(" ")
|
|
273
|
+
const digest = utils.digestMessage(text)
|
|
274
|
+
let { publicKey, signature } = options
|
|
275
|
+
if (!publicKey) {
|
|
276
|
+
throw Error(`--publicKey must be specified.`)
|
|
277
|
+
} else if (!signature) {
|
|
278
|
+
throw Error(`--signature must be specified`)
|
|
279
|
+
}
|
|
280
|
+
if (publicKey.startsWith("0x")) publicKey = publicKey.slice(2);
|
|
281
|
+
if (signature.startsWith("0x")) signature = signature.slice(2);
|
|
282
|
+
console.info(`Message: "${text}"`)
|
|
283
|
+
console.info(`Digest: ${utils.toHexString(digest)}`)
|
|
284
|
+
console.info(`Public key: ${publicKey}`)
|
|
285
|
+
console.info(`Signature: ${signature}`)
|
|
286
|
+
console.info("-".repeat(120))
|
|
287
|
+
if (utils.ecdsaVerify(digest, publicKey, signature.slice(2))) {
|
|
288
|
+
console.info(
|
|
289
|
+
`^ Signed by ${
|
|
290
|
+
Witnet.PublicKey.fromUint8Array(utils.fromHexString(publicKey)).hash().toBech32("mainnet")
|
|
291
|
+
}.\n^ Message is authentic.`
|
|
292
|
+
);
|
|
293
|
+
} else {
|
|
294
|
+
console.error(`^ Invalid signature.`)
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
async function accounts (options = {}, args = []) {
|
|
299
|
+
const { ethereum, verbose } = options
|
|
300
|
+
|
|
301
|
+
let wallet
|
|
302
|
+
if (args.length === 0) {
|
|
303
|
+
wallet = await _loadWallet({
|
|
304
|
+
...options,
|
|
305
|
+
limit: options?.limit || (options["no-funds"] && 10),
|
|
306
|
+
"no-funds": options["no-funds"],
|
|
307
|
+
})
|
|
308
|
+
} else {
|
|
309
|
+
wallet = await _loadWallet({ provider: options?.provider, limit: 1 })
|
|
310
|
+
args.forEach(pkh => {
|
|
311
|
+
if (!wallet.getSigner(pkh)) {
|
|
312
|
+
throw Error(`Input address ${pkh} doesn't belong to the wallet`)
|
|
313
|
+
}
|
|
314
|
+
})
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (options?.qrcode) {
|
|
318
|
+
let addrs = []
|
|
319
|
+
if (args.length > 0) {
|
|
320
|
+
addrs = wallet.accounts.filter(account => args.includes(account.pkh))
|
|
321
|
+
} else {
|
|
322
|
+
addrs = wallet.accounts
|
|
323
|
+
}
|
|
324
|
+
addrs.forEach(account => {
|
|
325
|
+
qrcodes.generate(account.pkh)
|
|
326
|
+
console.info(`Wallet account #${account.index + 1}: ${colors.lmagenta(account.pkh)}\n`)
|
|
327
|
+
})
|
|
328
|
+
return
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const coinbaseWithdrawers = await wallet.coinbase.getWithdrawers()
|
|
332
|
+
const coinbaseBalance = await wallet.coinbase.getBalance()
|
|
333
|
+
const coinbaseColor = utils.totalCoins(coinbaseBalance).pedros > 0n ? colors.mred : (coinbaseWithdrawers.length > 0 ? colors.mcyan : colors.cyan)
|
|
334
|
+
const coinbase = coinbaseWithdrawers.length > 0 || utils.totalCoins(coinbaseBalance).pedros > 0n || utils.totalCoins(await wallet.getBalance()).pedros === 0n
|
|
335
|
+
|
|
336
|
+
const records = []
|
|
337
|
+
|
|
338
|
+
if (coinbase) {
|
|
339
|
+
const coinbaseUtxos = await wallet.coinbase.getUtxos()
|
|
340
|
+
records.push([0, coinbaseColor(wallet.coinbase.pkh), coinbaseUtxos.length, coinbaseBalance])
|
|
341
|
+
}
|
|
342
|
+
records.push(
|
|
343
|
+
...await Promise.all(
|
|
344
|
+
wallet.accounts.map(async account => {
|
|
345
|
+
const balance = await account.getBalance()
|
|
346
|
+
const utxos = await account.getUtxos()
|
|
347
|
+
return [
|
|
348
|
+
account.index + 1,
|
|
349
|
+
balance.unlocked > 0 ? colors.mmagenta(account.pkh) : colors.magenta(account.pkh),
|
|
350
|
+
utxos.length,
|
|
351
|
+
balance,
|
|
352
|
+
...(ethereum ? [
|
|
353
|
+
account.getSigner().authorizeEvmAddress(ethereum),
|
|
354
|
+
// utils.toHexString(account.publicKey.hash().toBytes20(), true)
|
|
355
|
+
] : [])
|
|
356
|
+
]
|
|
357
|
+
}),
|
|
358
|
+
)
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
let unlocked = 0n
|
|
362
|
+
helpers.traceTable(
|
|
363
|
+
records.map(([index, pkh, count, balance, signature]) => {
|
|
364
|
+
unlocked += balance.unlocked
|
|
365
|
+
return [
|
|
366
|
+
index, pkh,
|
|
367
|
+
...(ethereum ? [ signature ] : (
|
|
368
|
+
verbose
|
|
369
|
+
? [
|
|
370
|
+
count,
|
|
371
|
+
Witnet.Coins.fromNanowits(balance.locked).wits.toFixed(2),
|
|
372
|
+
Witnet.Coins.fromNanowits(balance.staked).wits.toFixed(2),
|
|
373
|
+
Witnet.Coins.fromNanowits(balance.unlocked).wits.toFixed(2),
|
|
374
|
+
utils.totalCoins(balance).wits.toFixed(2),
|
|
375
|
+
]
|
|
376
|
+
: [
|
|
377
|
+
count,
|
|
378
|
+
Witnet.Coins.fromNanowits(balance.unlocked).wits.toFixed(2),
|
|
379
|
+
]
|
|
380
|
+
)
|
|
381
|
+
),
|
|
382
|
+
]
|
|
383
|
+
}), {
|
|
384
|
+
headlines: [
|
|
385
|
+
"INDEX", `:WITNET WALLET ${wallet.network.toUpperCase()} ACCOUNTS`,
|
|
386
|
+
...(ethereum ? [`ETHEREUM ${wallet.network.toUpperCase()} WRAPPING AUTHORIZATION CODE [${ethereum}]`] : (
|
|
387
|
+
verbose
|
|
388
|
+
? ["# UTXOS", "Locked ($WIT)", "Staked ($WIT)", "Available ($WIT)", "BALANCE ($WIT)"]
|
|
389
|
+
: ["# UTXOS", "Available ($WIT)"]
|
|
390
|
+
)
|
|
391
|
+
)
|
|
392
|
+
],
|
|
393
|
+
humanizers: [
|
|
394
|
+
helpers.commas,,
|
|
395
|
+
...(ethereum
|
|
396
|
+
? [,]
|
|
397
|
+
: [helpers.commas, helpers.commas, helpers.commas, helpers.commas, helpers.commas]
|
|
398
|
+
),
|
|
399
|
+
],
|
|
400
|
+
colors: [
|
|
401
|
+
,,
|
|
402
|
+
...(ethereum ? [colors.mblue, colors.gray] : (
|
|
403
|
+
verbose
|
|
404
|
+
? [colors.white, colors.gray, colors.yellow, colors.myellow, colors.lyellow]
|
|
405
|
+
: [colors.white, colors.myellow]
|
|
406
|
+
)
|
|
407
|
+
),
|
|
408
|
+
],
|
|
409
|
+
maxColumnWidth: 132,
|
|
410
|
+
}
|
|
411
|
+
)
|
|
412
|
+
console.info(`^ Available balance: ${colors.lyellow(whole_wits(unlocked, 2))}`)
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
async function coinbase (options = {}) {
|
|
416
|
+
const masterWallet = await _loadWallet({ ...options })
|
|
417
|
+
let wallet
|
|
418
|
+
if (options["node-master-key"]) {
|
|
419
|
+
utils.parseXprv(options["node-master-key"])
|
|
420
|
+
wallet = await _loadWallet({ provider: options?.provider, limit: 1, xprv: options["node-master-key"] })
|
|
421
|
+
} else {
|
|
422
|
+
wallet = masterWallet
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
const coinbaseColor = utils.totalCoins(await wallet.coinbase.getBalance()) > 0 ? colors.mred : colors.lcyan
|
|
426
|
+
console.info(`> ${options["node-master-key"] ? "Coinbase " : "Wallet's coinbase"} address: ${coinbaseColor(wallet.coinbase.pkh)}`)
|
|
427
|
+
|
|
428
|
+
if (options?.authorize) {
|
|
429
|
+
const withdrawer = options.authorize
|
|
430
|
+
const authcode = wallet.coinbase.authorizeStake(withdrawer)
|
|
431
|
+
qrcodes.generate(authcode)
|
|
432
|
+
console.info(`${colors.white(authcode)}`)
|
|
433
|
+
console.info("^ Withdrawer address:", colors.mmagenta(withdrawer))
|
|
434
|
+
} else {
|
|
435
|
+
const records = await wallet.coinbase.getWithdrawers({ by: Witnet.StakesOrderBy.Coins, reverse: true })
|
|
436
|
+
if (records.length > 0) {
|
|
437
|
+
const { verbose } = options
|
|
438
|
+
let staked = 0
|
|
439
|
+
helpers.traceTable(
|
|
440
|
+
records.map((record, index) => {
|
|
441
|
+
staked += record.value.coins
|
|
442
|
+
const withdrawer = (record.key.withdrawer === wallet.coinbase.pkh || record.key.withdrawer === masterWallet.coinbase.PublicKeyHash
|
|
443
|
+
? (record.value.epochs.witnessing > record.value.nonce || record.value.epochs.mining > record.value.nonce
|
|
444
|
+
? colors.mred(record.key.withdrawer)
|
|
445
|
+
: colors.red(record.key.withdrawer)
|
|
446
|
+
)
|
|
447
|
+
: (record.value.epochs.witnessing > record.value.nonce || record.value.epochs.mining > record.value.nonce
|
|
448
|
+
? (masterWallet.getSigner(record.key.withdrawer) ? colors.mgreen(record.key.withdrawer) : colors.mmagenta(record.key.withdrawer))
|
|
449
|
+
: (masterWallet.getSigner(record.key.withdrawer) ? colors.green(record.key.withdrawer) : colors.magenta(record.key.withdrawer))
|
|
450
|
+
)
|
|
451
|
+
)
|
|
452
|
+
const nonce = (record.value.epochs.witnessing > record.value.nonce || record.value.epochs.mining > record.value.nonce
|
|
453
|
+
? record.value.nonce
|
|
454
|
+
: colors.gray(record.value.nonce || "")
|
|
455
|
+
)
|
|
456
|
+
return [
|
|
457
|
+
index + 1,
|
|
458
|
+
withdrawer,
|
|
459
|
+
nonce,
|
|
460
|
+
...(verbose
|
|
461
|
+
? [record.value.epochs.witnessing || "", record.value.epochs.mining || ""]
|
|
462
|
+
: []
|
|
463
|
+
),
|
|
464
|
+
colors.yellow(Witnet.Coins.fromNanowits(record.value.coins).wits),
|
|
465
|
+
]
|
|
466
|
+
}), {
|
|
467
|
+
headlines: [
|
|
468
|
+
"RANK",
|
|
469
|
+
"STAKE WITHDRAWERS",
|
|
470
|
+
...(verbose
|
|
471
|
+
? ["Nonce", "LW_Epoch", "LM_Epoch"]
|
|
472
|
+
: ["Nonce"]
|
|
473
|
+
),
|
|
474
|
+
"STAKED ($WIT)",
|
|
475
|
+
],
|
|
476
|
+
humanizers: [
|
|
477
|
+
,, ...(verbose
|
|
478
|
+
? [helpers.commas, helpers.commas, helpers.commas]
|
|
479
|
+
: [helpers.commas]
|
|
480
|
+
),
|
|
481
|
+
helpers.commas,
|
|
482
|
+
],
|
|
483
|
+
colors: [
|
|
484
|
+
,,, ...(verbose
|
|
485
|
+
? [colors.magenta, colors.cyan, colors.myellow]
|
|
486
|
+
: [colors.myellow]
|
|
487
|
+
),
|
|
488
|
+
],
|
|
489
|
+
}
|
|
490
|
+
)
|
|
491
|
+
console.info(`^ Total stake: ${colors.lyellow(whole_wits(staked, 2))}`)
|
|
492
|
+
} else {
|
|
493
|
+
console.info("> Holds no delegated stake.")
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
async function decipher () {
|
|
499
|
+
const user = await prompt([
|
|
500
|
+
{
|
|
501
|
+
message: "Enter XPRV:",
|
|
502
|
+
name: "xprv",
|
|
503
|
+
}, {
|
|
504
|
+
type: "password",
|
|
505
|
+
mask: "*",
|
|
506
|
+
message: "Enter password:",
|
|
507
|
+
name: "passwd",
|
|
508
|
+
},
|
|
509
|
+
])
|
|
510
|
+
console.info(utils.decipherXprv(user.xprv, user.passwd))
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
async function provider (options = {}) {
|
|
514
|
+
const wallet = await _loadWallet({ unlocked: true, limit: 1, ...options })
|
|
515
|
+
wallet.provider.endpoints.forEach(url => {
|
|
516
|
+
console.info(helpers.colors.colors.magenta(url))
|
|
517
|
+
})
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
async function resolve (options = {}, [pattern, ...args]) {
|
|
521
|
+
const wallet = await _loadWallet({ ...options })
|
|
522
|
+
const ledger = (
|
|
523
|
+
options?.from
|
|
524
|
+
? (options.from === wallet.coinbase.pkh ? wallet.coinbase : wallet.getAccount(options.from))
|
|
525
|
+
: wallet
|
|
526
|
+
)
|
|
527
|
+
if (!ledger) {
|
|
528
|
+
throw Error("--from address not found in wallet")
|
|
529
|
+
}
|
|
530
|
+
const request = await _loadRadonRequest({ ...options, pattern, args })
|
|
531
|
+
// console.log(request)
|
|
532
|
+
await helpers.traceTransaction(
|
|
533
|
+
Witnet.DataRequests.from(ledger, request), {
|
|
534
|
+
headline: "DATA REQUEST TRANSACTION",
|
|
535
|
+
color: colors.bgreen,
|
|
536
|
+
...await _loadTransactionParams({ ...options }),
|
|
537
|
+
}
|
|
538
|
+
)
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
async function stake (options = {}, [authorization]) {
|
|
542
|
+
if (!authorization) {
|
|
543
|
+
throw Error("No authorization code was provided")
|
|
544
|
+
} else if (!options?.value) {
|
|
545
|
+
throw Error("No --value was specified")
|
|
546
|
+
} else if (!options?.withdrawer) {
|
|
547
|
+
throw Error("No --withdrawer was specified")
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
const wallet = await _loadWallet({ ...options })
|
|
551
|
+
|
|
552
|
+
// determine ledger and available funds
|
|
553
|
+
let available = 0; let ledger
|
|
554
|
+
if (options?.from) {
|
|
555
|
+
ledger = options.from === wallet.coinbase.pkh ? wallet.coinbase : wallet.getAccount(options.from)
|
|
556
|
+
if (ledger) available = (await ledger.getBalance()).unlocked
|
|
557
|
+
} else {
|
|
558
|
+
ledger = wallet
|
|
559
|
+
available = (await wallet.getBalance()).unlocked + (await wallet.coinbase.getBalance()).unlocked
|
|
560
|
+
}
|
|
561
|
+
if (!ledger) {
|
|
562
|
+
throw Error(`--from address ${options?.from} doesn't belong to the wallet`)
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// validate withdrawer address
|
|
566
|
+
const withdrawer = Witnet.PublicKeyHash.fromBech32(options?.withdrawer).toBech32(wallet.network)
|
|
567
|
+
if (!wallet.getAccount(withdrawer) && withdrawer !== wallet.coinbase.pkh && !options?.force) {
|
|
568
|
+
const user = await prompt([{
|
|
569
|
+
message: `Withdrawer ${withdrawer} doesn't belong to the wallet. Proceed anyway?`,
|
|
570
|
+
name: "continue",
|
|
571
|
+
type: "confirm",
|
|
572
|
+
default: false,
|
|
573
|
+
}])
|
|
574
|
+
if (!user.continue) {
|
|
575
|
+
throw Error(`--withdrawer address ${withdrawer} not found in wallet`)
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// determine stake value
|
|
580
|
+
const params = await _loadTransactionParams({ ...options })
|
|
581
|
+
const coins = params?.value === "all" ? Witnet.Coins.fromPedros(available - params.fees.pedros) : Witnet.Coins.fromWits(params?.value)
|
|
582
|
+
if (available < coins.pedros) {
|
|
583
|
+
throw Error(`Insufficient funds ${options?.from ? `on address ${options.from}.` : "on wallet."}`)
|
|
584
|
+
} else if (params?.fees && coins.pedros <= params.fees.pedros) {
|
|
585
|
+
throw Error(`Fees equal or greater than value: ${params.fees.pedros} >= ${coins.pedros}`)
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
// todo: validate withdrawer matches delegatee's withdrawer
|
|
589
|
+
|
|
590
|
+
// deposit stake
|
|
591
|
+
await helpers.traceTransaction(
|
|
592
|
+
Witnet.StakeDeposits.from(ledger), {
|
|
593
|
+
headline: "STAKE DEPOSIT TRANSACTION",
|
|
594
|
+
color: colors.bcyan,
|
|
595
|
+
...options,
|
|
596
|
+
authorization,
|
|
597
|
+
value: coins,
|
|
598
|
+
withdrawer,
|
|
599
|
+
}
|
|
600
|
+
)
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
async function transfer (options = {}) {
|
|
604
|
+
if (!options?.value) {
|
|
605
|
+
throw Error("No --value was specified")
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
const wallet = await _loadWallet({ ...options })
|
|
609
|
+
|
|
610
|
+
// determine ledger and available funds
|
|
611
|
+
let available = 0n;
|
|
612
|
+
let ledger
|
|
613
|
+
if (options?.from) {
|
|
614
|
+
ledger = options.from === wallet.coinbase.pkh ? wallet.coinbase : wallet.getAccount(options.from)
|
|
615
|
+
} else {
|
|
616
|
+
ledger = wallet
|
|
617
|
+
}
|
|
618
|
+
if (!ledger) {
|
|
619
|
+
throw Error(`--from address ${options?.from} doesn't belong to the wallet`)
|
|
620
|
+
} else {
|
|
621
|
+
const balance = await ledger.getBalance()
|
|
622
|
+
available = balance.unlocked
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// validate metadata info, if specified
|
|
626
|
+
let metadata
|
|
627
|
+
if (options?.metadata) {
|
|
628
|
+
if (!utils.isHexStringOfLength(options.metadata, 20)) {
|
|
629
|
+
throw Error(`--metadata must be a 20-byte hex string`)
|
|
630
|
+
}
|
|
631
|
+
metadata = Witnet.PublicKeyHash.fromHexString(options.metadata).toBech32(wallet.network)
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
// validate recipient address
|
|
635
|
+
if (!options?.into) {
|
|
636
|
+
throw Error("--into address must be specified")
|
|
637
|
+
}
|
|
638
|
+
const into = Witnet.PublicKeyHash.fromBech32(options?.into).toBech32(wallet.network)
|
|
639
|
+
|
|
640
|
+
// determine transfer params
|
|
641
|
+
const params = await _loadTransactionParams({ ...options })
|
|
642
|
+
const coins = params?.value === "all"
|
|
643
|
+
? Witnet.Coins.fromPedros(BigInt(available - params.fees.pedros - BigInt(options?.metadata ? 1: 0)))
|
|
644
|
+
: Witnet.Coins.fromWits(params?.value)
|
|
645
|
+
if (available < coins.pedros) {
|
|
646
|
+
throw Error(`Insufficient funds ${options?.from ? `on address ${options.from}.` : "on wallet."}`)
|
|
647
|
+
} else if (params?.fees && coins.pedros <= params.fees.pedros) {
|
|
648
|
+
throw Error(`Fees equal or greater than value: ${params.fees.pedros} >= ${coins.pedros}`)
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
// transfer value
|
|
652
|
+
const recipients = options?.metadata
|
|
653
|
+
? [[into, coins], [metadata, Witnet.Coins.fromPedros(1n)]]
|
|
654
|
+
: [[into, coins]]
|
|
655
|
+
await helpers.traceTransaction(
|
|
656
|
+
Witnet.ValueTransfers.from(ledger), {
|
|
657
|
+
headline: "VALUE TRANSFER TRANSACTION",
|
|
658
|
+
color: colors.bblue,
|
|
659
|
+
...params,
|
|
660
|
+
recipients,
|
|
661
|
+
}
|
|
662
|
+
)
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
async function unstake (options = {}) {
|
|
666
|
+
|
|
667
|
+
// load wallet:
|
|
668
|
+
const wallet = await _loadWallet({ ...options })
|
|
669
|
+
|
|
670
|
+
// determine validator address:
|
|
671
|
+
let validator
|
|
672
|
+
if (options?.from) {
|
|
673
|
+
validator = Witnet.PublicKeyHash.fromBech32(options?.from).toBech32(wallet.network)
|
|
674
|
+
|
|
675
|
+
} else {
|
|
676
|
+
const delegatees =
|
|
677
|
+
(await wallet.getDelegatees({ by: Witnet.StakesOrderBy.Coins, reverse: true }, false))
|
|
678
|
+
.filter(entry => !options?.into || entry.key.withdrawer === options?.into)
|
|
679
|
+
if (delegatees.length === 0) throw new Error(`No delegatees to withdraw from.`);
|
|
680
|
+
else if (delegatees.length === 1) validator = delegatees[0].key.validator;
|
|
681
|
+
else {
|
|
682
|
+
const choices = delegatees
|
|
683
|
+
.map(entry => `${colors.mcyan(entry.key.validator)}`)
|
|
684
|
+
.filter((pkh, index, array) => index === array.indexOf(pkh))
|
|
685
|
+
const user = await prompt([{
|
|
686
|
+
choices,
|
|
687
|
+
message: "Validator address ?",
|
|
688
|
+
name: "key",
|
|
689
|
+
type: "list",
|
|
690
|
+
pageSize: 24,
|
|
691
|
+
}]);
|
|
692
|
+
validator = helpers.colorstrip(user.key.split(' ')[0])
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
// determine withdrawer address:
|
|
697
|
+
let withdrawer
|
|
698
|
+
if (options?.into) {
|
|
699
|
+
withdrawer = Witnet.PublicKeyHash.fromBech32(options?.into).toBech32(wallet.network)
|
|
700
|
+
|
|
701
|
+
} else {
|
|
702
|
+
const stakes = (await wallet.provider.stakes({ filter: { validator }})).filter(entry => wallet.getSigner(entry.key.withdrawer) !== undefined);
|
|
703
|
+
if (stakes.length === 0) throw new Error(`Nothing to withdraw from validator ${validator}.`);
|
|
704
|
+
else if (stakes.length === 1) withdrawer = stakes[0].key.withdrawer;
|
|
705
|
+
else {
|
|
706
|
+
const choices = stakes.map(entry => `${colors.mmagenta(entry.key.withdrawer)} [${colors.yellow(Witnet.Coins.fromPedros(entry.value.coins).toString(2))}]`);
|
|
707
|
+
const user = await prompt([{
|
|
708
|
+
choices,
|
|
709
|
+
message: "Withdrawer address ?",
|
|
710
|
+
name: "key",
|
|
711
|
+
type: "list",
|
|
712
|
+
pageSize: 24,
|
|
713
|
+
}]);
|
|
714
|
+
withdrawer = helpers.colorstrip(user.key.split(' ')[0])
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// validate withdrawer address
|
|
719
|
+
const ledger = await wallet.getSigner(withdrawer)
|
|
720
|
+
if (!ledger) {
|
|
721
|
+
throw Error(`--into address ${withdrawer} doesn't belong to the wallet`)
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// valite delegatee address:
|
|
725
|
+
const delegatee = (await ledger.getDelegatees()).find(stake =>
|
|
726
|
+
stake.key.validator === validator && stake.key.withdrawer === withdrawer
|
|
727
|
+
)
|
|
728
|
+
if (!delegatee) {
|
|
729
|
+
throw Error(`Nothing to withdraw from ${validator} into ${withdrawer}`)
|
|
730
|
+
}
|
|
731
|
+
const available = BigInt(delegatee.value.coins)
|
|
732
|
+
|
|
733
|
+
// determine withdrawal value:
|
|
734
|
+
const params = await _loadTransactionParams({ ...options, fees: 0n })
|
|
735
|
+
|
|
736
|
+
const value = (params?.value || `all`) === "all"
|
|
737
|
+
? Witnet.Coins.fromPedros(available - params.fees.pedros)
|
|
738
|
+
: Witnet.Coins.fromWits(params?.value)
|
|
739
|
+
|
|
740
|
+
// validate withdrawal amount:
|
|
741
|
+
if (available < value.pedros + params?.fees.pedros) {
|
|
742
|
+
throw Error(`Cannot withdraw that much: ${value.pedros} > ${available}`)
|
|
743
|
+
} else if (params?.fees && value.pedros <= params.fees.pedros) {
|
|
744
|
+
throw Error(`Fees equal or greater than value: ${params.fees.pedros} >= ${value.pedros}`)
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
// withdraw deposit from validator into withdrawer:
|
|
748
|
+
await helpers.traceTransaction(
|
|
749
|
+
Witnet.StakeWithdrawals.from(ledger), {
|
|
750
|
+
headline: "STAKE WITHDRAWAL TRANSACTION",
|
|
751
|
+
...params,
|
|
752
|
+
validator,
|
|
753
|
+
value,
|
|
754
|
+
}
|
|
755
|
+
)
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
async function utxos (options = {}, [from]) {
|
|
759
|
+
const wallet = await _loadWallet({ ...options })
|
|
760
|
+
|
|
761
|
+
// determine ledger and available funds
|
|
762
|
+
let ledger
|
|
763
|
+
let available = 0n;
|
|
764
|
+
if (from) {
|
|
765
|
+
ledger = from === wallet.coinbase.pkh ? wallet.coinbase : wallet.getAccount(from)
|
|
766
|
+
if (ledger) available = (await ledger.getBalance()).unlocked;
|
|
767
|
+
} else {
|
|
768
|
+
ledger = wallet
|
|
769
|
+
available = (await wallet.getBalance()).unlocked + (await wallet.coinbase.getBalance()).unlocked
|
|
770
|
+
}
|
|
771
|
+
if (!ledger) {
|
|
772
|
+
throw Error(`Address ${from} doesn't belong to the wallet`)
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
// determine into address
|
|
776
|
+
let into = options?.into
|
|
777
|
+
if (into) {
|
|
778
|
+
if (into !== from && !wallet.getAccount(into) && into !== wallet.coinbase.pkh && !options?.force) {
|
|
779
|
+
const user = await prompt([{
|
|
780
|
+
message: `Recipient address ${into} doesn't belong to the wallet. Proceed anyway?`,
|
|
781
|
+
name: "continue",
|
|
782
|
+
type: "input",
|
|
783
|
+
}])
|
|
784
|
+
if (!user.continue.toLowerCase().startsWith("y")) {
|
|
785
|
+
throw Error(`--into address ${into} not found in wallet`)
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
} else {
|
|
789
|
+
into = wallet.pkh
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
// determine if --value is required
|
|
793
|
+
if ((options?.join || options?.split) && !options?.value) {
|
|
794
|
+
throw Error("--value must be specified on JOIN and SPLITS operations.")
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// extract transaction params
|
|
798
|
+
const params = await _loadTransactionParams({
|
|
799
|
+
...options,
|
|
800
|
+
force: options?.force || (!options?.join && !options?.splits),
|
|
801
|
+
})
|
|
802
|
+
|
|
803
|
+
// select utxos of either the from account (if specified) or from all funded accounts in the wallet (including the coinbase)
|
|
804
|
+
let value = params?.value === "all"
|
|
805
|
+
? Witnet.Coins.fromPedros(available - params.fees.pedros)
|
|
806
|
+
: (params?.value ? Witnet.Coins.fromWits(params?.value) : Witnet.Coins.fromPedros(available))
|
|
807
|
+
if (available < value.pedros) {
|
|
808
|
+
throw Error(`Insufficient funds ${from ? `on address ${from}.` : "on wallet."}`)
|
|
809
|
+
} else if (params?.fees && value.pedros <= params.fees.pedros) {
|
|
810
|
+
throw Error(`Fees equal or greater than value: ${params.fees.pedros} >= ${value.pedros}`)
|
|
811
|
+
}
|
|
812
|
+
const utxos = await ledger.selectUtxos({ value })
|
|
813
|
+
const covered = utxos.map(utxo => BigInt(utxo.value))?.reduce((prev, curr) => prev + curr, 0n) || 0n
|
|
814
|
+
// if (value && covered < value.pedros) {
|
|
815
|
+
// console.log(value, covered)
|
|
816
|
+
// throw Error(`Insufficient unlocked UTXOs in ${from ? `wallet account ${ledger.pkh}` : "wallet"}`)
|
|
817
|
+
// }
|
|
818
|
+
|
|
819
|
+
// only if at least one utxo is selected, proceed with report and other operations, if any
|
|
820
|
+
if (utxos.length > 0) {
|
|
821
|
+
if (options?.verbose || (!options?.join && !options?.splits)) {
|
|
822
|
+
helpers.traceTable(
|
|
823
|
+
utxos.map((utxo, index) => [
|
|
824
|
+
index + 1,
|
|
825
|
+
utxo.signer === wallet.coinbase.pkh ? colors.mcyan(utxo.signer) : colors.mmagenta(utxo.signer),
|
|
826
|
+
utxo?.internal ? colors.green(utxo.output_pointer) : colors.mgreen(utxo.output_pointer),
|
|
827
|
+
utxo.value,
|
|
828
|
+
]), {
|
|
829
|
+
headlines: ["INDEX", `WITNET WALLET ${wallet.network.toUpperCase()} ADDRESSES`, ":Unlocked UTXO pointers", "UTXO value ($pedros)"],
|
|
830
|
+
humanizers: [helpers.commas,,, helpers.commas],
|
|
831
|
+
colors: [,,, colors.myellow],
|
|
832
|
+
}
|
|
833
|
+
)
|
|
834
|
+
console.info(`^ Available balance: ${colors.lyellow(whole_wits(covered, 2))}`)
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
const valueTransfer = Witnet.ValueTransfers.from(ledger)
|
|
838
|
+
|
|
839
|
+
if (options?.join) {
|
|
840
|
+
const recipients = [[
|
|
841
|
+
// if a split is expected, join utxos into selected account or wallet
|
|
842
|
+
options?.splits ? ledger.pkh : into,
|
|
843
|
+
value,
|
|
844
|
+
]]
|
|
845
|
+
await helpers.traceTransaction(valueTransfer, {
|
|
846
|
+
headline: `JOINING UTXOs: ${utxos.length} -> ${value.pedros < covered ? 2 : 1}`,
|
|
847
|
+
...params,
|
|
848
|
+
await: params?.await || options?.splits !== undefined,
|
|
849
|
+
recipients,
|
|
850
|
+
})
|
|
851
|
+
}
|
|
852
|
+
if (options?.splits) {
|
|
853
|
+
const recipients = []
|
|
854
|
+
const splits = parseInt(options.splits)
|
|
855
|
+
if (splits > 50) {
|
|
856
|
+
throw Error("Not possible to split into more than 50 UTXOs")
|
|
857
|
+
}
|
|
858
|
+
value = Witnet.Coins.fromPedros(BigInt(Math.floor(Number(value.pedros) / splits)))
|
|
859
|
+
recipients.push(...Array(splits).fill([into, value]))
|
|
860
|
+
await helpers.traceTransaction(
|
|
861
|
+
valueTransfer, {
|
|
862
|
+
headline: `SPLITTING UTXOs: ${utxos.length} -> ${Number(value.pedros) * splits < covered ? splits + 1 : splits}`,
|
|
863
|
+
...params,
|
|
864
|
+
recipients,
|
|
865
|
+
reload: options?.join,
|
|
866
|
+
})
|
|
867
|
+
}
|
|
868
|
+
} else {
|
|
869
|
+
console.info("> No available UTXOs at the moment.")
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
async function validators (options = {}) {
|
|
874
|
+
const { verbose } = options
|
|
875
|
+
const wallet = await _loadWallet({ ...options })
|
|
876
|
+
const order = { by: Witnet.StakesOrderBy.Coins, reverse: true }
|
|
877
|
+
|
|
878
|
+
const coinbaseBalance = await wallet.coinbase.getBalance()
|
|
879
|
+
const coinbase = coinbaseBalance.staked > 0n
|
|
880
|
+
|
|
881
|
+
const records = await wallet.getDelegatees(order, true)
|
|
882
|
+
if (records.length > 0) {
|
|
883
|
+
let staked = 0n
|
|
884
|
+
helpers.traceTable(
|
|
885
|
+
records.map(record => {
|
|
886
|
+
staked += BigInt(record.value.coins)
|
|
887
|
+
return [
|
|
888
|
+
record.key.withdrawer === wallet.coinbase.pkh
|
|
889
|
+
? colors.mred(record.key.withdrawer)
|
|
890
|
+
: (record.key.validator !== "" ? colors.mmagenta(record.key.withdrawer) : colors.magenta(record.key.withdrawer)),
|
|
891
|
+
...(record.value.epochs.witnessing > record.value.nonce || record.value.epochs.mining > record.value.nonce
|
|
892
|
+
? [colors.mcyan(record.key.validator), record.value.nonce]
|
|
893
|
+
: [colors.cyan(record.key.validator), colors.gray(record.value.nonce || "")]
|
|
894
|
+
),
|
|
895
|
+
...(verbose
|
|
896
|
+
? [record.value.epochs.witnessing || "", record.value.epochs.mining || ""]
|
|
897
|
+
: []
|
|
898
|
+
),
|
|
899
|
+
colors.yellow(record.value.coins),
|
|
900
|
+
]
|
|
901
|
+
}), {
|
|
902
|
+
headlines: [
|
|
903
|
+
// "INDEX",
|
|
904
|
+
coinbase ? "WITNET WALLET COINBASE" : `WITNET WALLET ${wallet.network.toUpperCase()} ACCOUNTS`,
|
|
905
|
+
"STAKE DELEGATEES",
|
|
906
|
+
...(verbose
|
|
907
|
+
? ["Nonce", "LW_Epoch", "LM_Epoch"]
|
|
908
|
+
: ["Nonce"]
|
|
909
|
+
),
|
|
910
|
+
"STAKED ($pedros)",
|
|
911
|
+
],
|
|
912
|
+
humanizers: [
|
|
913
|
+
,, ...(verbose
|
|
914
|
+
? [helpers.commas, helpers.commas, helpers.commas]
|
|
915
|
+
: [helpers.commas]
|
|
916
|
+
),
|
|
917
|
+
helpers.commas,
|
|
918
|
+
],
|
|
919
|
+
colors: [
|
|
920
|
+
,,, ...(verbose
|
|
921
|
+
? [colors.magenta, colors.cyan, colors.myellow]
|
|
922
|
+
: [colors.myellow]
|
|
923
|
+
),
|
|
924
|
+
],
|
|
925
|
+
}
|
|
926
|
+
)
|
|
927
|
+
console.info(`^ Total deposits: ${colors.lyellow(whole_wits(staked, 2))}`)
|
|
928
|
+
} else {
|
|
929
|
+
console.info("> No delegatees found.")
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
/// ===================================================================================================================
|
|
934
|
+
/// --- Internal functions --------------------------------------------------------------------------------------------
|
|
935
|
+
|
|
936
|
+
async function _loadRadonRequest (options = {}) {
|
|
937
|
+
const args = options?.args || []
|
|
938
|
+
if (options?.pattern && typeof options.pattern === 'string' && utils.isHexString(options.pattern)) {
|
|
939
|
+
// if (utils.isHexStringOfLength(options.pattern, 32)) {
|
|
940
|
+
// throw `Searching RADON_BYTECODE by RAD_HASH not yet supported.`
|
|
941
|
+
// } else
|
|
942
|
+
try {
|
|
943
|
+
return Witnet.Radon.RadonRequest.fromBytecode(options.pattern)
|
|
944
|
+
} catch (e) {
|
|
945
|
+
throw Error(`Invalid RADON_BYTECODE: ${e}`)
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
// load Radon assets from environment
|
|
950
|
+
let assets = utils.searchRadonAssets(
|
|
951
|
+
{
|
|
952
|
+
assets: loadAssets(options),
|
|
953
|
+
pattern: options?.pattern,
|
|
954
|
+
},
|
|
955
|
+
(key, pattern) => key.toLowerCase().indexOf(pattern.toLowerCase()) >= 0
|
|
956
|
+
)
|
|
957
|
+
|
|
958
|
+
if (args.length > 0) {
|
|
959
|
+
// ignore RadonRequests if args were passed from the CLI
|
|
960
|
+
assets = assets.filter(([, artifact]) => !(artifact instanceof Witnet.Radon.RadonRequest))
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
// sort Radon assets alphabetically
|
|
964
|
+
assets = assets.sort((a, b) => {
|
|
965
|
+
if (a[0] < b[0]) return -1
|
|
966
|
+
else if (a[0] > b[0]) return 1
|
|
967
|
+
else return 0
|
|
968
|
+
})
|
|
969
|
+
|
|
970
|
+
let artifact, key
|
|
971
|
+
if (Object.keys(assets).length === 0) {
|
|
972
|
+
if (options?.pattern) {
|
|
973
|
+
throw Error(`No Radon assets named after "${options.pattern}"`)
|
|
974
|
+
} else {
|
|
975
|
+
throw Error("No Radon assets declared yet")
|
|
976
|
+
}
|
|
977
|
+
} else if (Object.keys(assets).length > 1) {
|
|
978
|
+
const user = await prompt([{
|
|
979
|
+
choices: assets.map(([key]) => key),
|
|
980
|
+
message: "Please, select a Radon asset:",
|
|
981
|
+
name: "key",
|
|
982
|
+
type: "list",
|
|
983
|
+
pageSize: 24,
|
|
984
|
+
}]);
|
|
985
|
+
[key, artifact] = assets.find(([key]) => key === user.key)
|
|
986
|
+
} else {
|
|
987
|
+
[key, artifact] = Object.values(assets)[0]
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
if (!(artifact instanceof Witnet.Radon.RadonRequest)) {
|
|
991
|
+
let templateArgs = []
|
|
992
|
+
if (args.length === 0 && artifact?.samples) {
|
|
993
|
+
const sample = await prompt([{
|
|
994
|
+
choices: Object.keys(artifact.samples),
|
|
995
|
+
message: "Select pre-settled Radon args: ",
|
|
996
|
+
name: "key",
|
|
997
|
+
type: "list",
|
|
998
|
+
}])
|
|
999
|
+
templateArgs = artifact.samples[sample.key]
|
|
1000
|
+
} else if (args.length === 1 && artifact?.samples) {
|
|
1001
|
+
const sample = Object.keys(artifact.samples).find(sample => sample.toLowerCase() === args[0].toLowerCase())
|
|
1002
|
+
if (sample) templateArgs = artifact.samples[sample]
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
if (artifact instanceof Witnet.Radon.RadonRetrieval) {
|
|
1006
|
+
if (templateArgs.length === 0) templateArgs = [...args]
|
|
1007
|
+
if (templateArgs.length < artifact.argsCount) {
|
|
1008
|
+
throw Error(`${key}: missing ${artifact.argsCount - templateArgs.length} out of ${artifact.argsCount} parameters`)
|
|
1009
|
+
}
|
|
1010
|
+
artifact = new Witnet.Radon.RadonRequest({ sources: artifact.foldArgs(templateArgs) })
|
|
1011
|
+
} else {
|
|
1012
|
+
if (artifact instanceof Witnet.Radon.RadonModal) {
|
|
1013
|
+
if (templateArgs.length === 0) templateArgs = [...args]
|
|
1014
|
+
if (templateArgs.length === 0 && templateArgs.length < artifact.argsCount + 1) {
|
|
1015
|
+
throw Error(`${key}: missing ${artifact.argsCount + 1 - templateArgs.length} out of ${artifact.argsCount + 1} parameters.`)
|
|
1016
|
+
}
|
|
1017
|
+
artifact.providers = templateArgs.splice(0, 1)[0].split(";")
|
|
1018
|
+
artifact = artifact.buildRadonRequest(templateArgs)
|
|
1019
|
+
} else if (artifact instanceof Witnet.Radon.RadonTemplate) {
|
|
1020
|
+
if (templateArgs.length === 0) {
|
|
1021
|
+
templateArgs = new Array(artifact.sources.length)
|
|
1022
|
+
artifact.sources.forEach((retrieval, index) => {
|
|
1023
|
+
templateArgs[index] = args.splice(0, retrieval.argsCount)
|
|
1024
|
+
if (templateArgs[index].length < retrieval.argsCount) {
|
|
1025
|
+
throw Error(`${key}: missing ${
|
|
1026
|
+
retrieval.argsCount - templateArgs[index].length
|
|
1027
|
+
} out of ${
|
|
1028
|
+
retrieval.argsCount
|
|
1029
|
+
} expected args for template source #${index + 1}`)
|
|
1030
|
+
}
|
|
1031
|
+
})
|
|
1032
|
+
}
|
|
1033
|
+
artifact = artifact.buildRadonRequest(templateArgs)
|
|
1034
|
+
} else {
|
|
1035
|
+
throw Error(`${key}: unsupported Radon asset type ${artifact?.constructor.name}`)
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
return artifact
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
async function _loadTransactionParams (options = {}) {
|
|
1043
|
+
const confirmations = options?.confirmations ? parseInt(options?.confirmations) : (options?.await ? 0 : undefined)
|
|
1044
|
+
let fees = options?.fees ? Witnet.Coins.fromWits(options.fees) : (options?.fees === 0n ? Witnet.Coins.zero() : undefined)
|
|
1045
|
+
const value = options?.value ? (options?.value.toLowerCase() === "all" ? "all" : options.value) : undefined
|
|
1046
|
+
if (fees === undefined) {
|
|
1047
|
+
if (value === "all") {
|
|
1048
|
+
throw Error("--fees must be specified if --value is set to `all`")
|
|
1049
|
+
}
|
|
1050
|
+
let priority = (!options?.priority && options?.force) ? Witnet.TransactionPriority.Medium : options?.priority
|
|
1051
|
+
if (!priority) {
|
|
1052
|
+
const priorities = {
|
|
1053
|
+
"< 60 seconds": Witnet.TransactionPriority.Opulent,
|
|
1054
|
+
"< 5 minutes": Witnet.TransactionPriority.High,
|
|
1055
|
+
"< 15 minutes": Witnet.TransactionPriority.Medium,
|
|
1056
|
+
"< 1 hour": Witnet.TransactionPriority.Low,
|
|
1057
|
+
"< 6 hours": Witnet.TransactionPriority.Stinky,
|
|
1058
|
+
}
|
|
1059
|
+
const user = await prompt([{
|
|
1060
|
+
choices: Object.keys(priorities),
|
|
1061
|
+
message: "Please, select time to block expectancy:",
|
|
1062
|
+
name: "priority",
|
|
1063
|
+
type: "list",
|
|
1064
|
+
}])
|
|
1065
|
+
priority = priorities[user.priority]
|
|
1066
|
+
} else if (!Object.values(Witnet.TransactionPriority).includes(priority)) {
|
|
1067
|
+
throw Error(`Invalid priority "${priority}"`)
|
|
1068
|
+
}
|
|
1069
|
+
fees = Witnet.TransactionPriority[priority.charAt(0).toUpperCase() + priority.slice(1)]
|
|
1070
|
+
}
|
|
1071
|
+
return {
|
|
1072
|
+
await: options?.await,
|
|
1073
|
+
confirmations,
|
|
1074
|
+
fees,
|
|
1075
|
+
from: options?.from,
|
|
1076
|
+
force: options?.force,
|
|
1077
|
+
value,
|
|
1078
|
+
verbose: options?.verbose,
|
|
1079
|
+
witnesses: options?.witnesses,
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
async function _loadWallet (options = {}) {
|
|
1084
|
+
if (!process.env.WITNET_SDK_WALLET_MASTER_KEY) {
|
|
1085
|
+
throw Error("No WITNET_SDK_WALLET_MASTER_KEY is settled in environment")
|
|
1086
|
+
} else {
|
|
1087
|
+
const provider = new Witnet.JsonRpcProvider(options?.provider)
|
|
1088
|
+
const strategies = {
|
|
1089
|
+
"small-first": Witnet.UtxoSelectionStrategy.SmallFirst,
|
|
1090
|
+
"slim-fit": Witnet.UtxoSelectionStrategy.SlimFit,
|
|
1091
|
+
"big-first": Witnet.UtxoSelectionStrategy.BigFirst,
|
|
1092
|
+
random: Witnet.UtxoSelectionStrategy.Random,
|
|
1093
|
+
}
|
|
1094
|
+
if (options?.strategy && !strategies[options.strategy]) {
|
|
1095
|
+
throw Error(`Unrecognised UTXO selection strategy "${options.strategy}"`)
|
|
1096
|
+
}
|
|
1097
|
+
const strategy = strategies[options?.strategy || "slim-fit"] || Witnet.UtxoSelectionStrategy.SlimFit
|
|
1098
|
+
const gap = options?.gap || 10
|
|
1099
|
+
let wallet; const xprv = options?.xprv || process.env.WITNET_SDK_WALLET_MASTER_KEY
|
|
1100
|
+
if (xprv.length === 293) {
|
|
1101
|
+
const user = await prompt([{ type: "password", mask: "*", message: "Enter password:", name: "passwd" }])
|
|
1102
|
+
wallet = Witnet.Wallet.fromEncryptedXprv(xprv, user.passwd, {
|
|
1103
|
+
gap,
|
|
1104
|
+
provider,
|
|
1105
|
+
strategy,
|
|
1106
|
+
limit: options?.limit,
|
|
1107
|
+
onlyWithFunds: !options["no-funds"],
|
|
1108
|
+
})
|
|
1109
|
+
} else {
|
|
1110
|
+
wallet = Witnet.Wallet.fromXprv(xprv, {
|
|
1111
|
+
gap,
|
|
1112
|
+
provider,
|
|
1113
|
+
strategy,
|
|
1114
|
+
limit: options?.limit,
|
|
1115
|
+
onlyWithFunds: !options["no-funds"],
|
|
1116
|
+
})
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
return options["no-funds"] ? await wallet : await helpers.prompter(wallet)
|
|
1120
|
+
}
|
|
1121
|
+
}
|