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