dcp-client 5.1.11 → 5.3.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/bin/dcp-bank +269 -0
- package/build/bundle +1 -1
- package/dist/dcp-client-bundle.js +1 -1
- package/dist/dcp-client-bundle.js.map +1 -1
- package/index.js +6 -5
- package/lib/getopt.js +94 -0
- package/package.json +6 -4
- package/windows-registry.js +154 -156
package/bin/dcp-bank
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @file dcp-bank - command-line utility for working with the DCP bank
|
|
4
|
+
* @author Wes Garland, wes@distributive.network
|
|
5
|
+
* @date Dec 2025
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
|
|
10
|
+
process.exitCode = 3;
|
|
11
|
+
require('../index').init().then(main).catch(reportError);
|
|
12
|
+
|
|
13
|
+
function usage()
|
|
14
|
+
{
|
|
15
|
+
console.log(`
|
|
16
|
+
DCP Bank Utility. Copyright (c) 2025 Distributive Corp.
|
|
17
|
+
Released under the terms of the MIT License.
|
|
18
|
+
|
|
19
|
+
Usage:
|
|
20
|
+
dcp-bank transfer <amount> [--from=] <--to=>
|
|
21
|
+
dcp-bank balance [--from=]
|
|
22
|
+
Where:
|
|
23
|
+
amount is the number of Distributive Compute Credits to transfer
|
|
24
|
+
--to specifies the bank account in which to deposit funds. The account may
|
|
25
|
+
be specified by address, wallet label, keystore JSON, or keystore
|
|
26
|
+
filename.
|
|
27
|
+
--from specifies the bank account from which to withdraw funds. The account
|
|
28
|
+
may be specified by private key, wallet label, keystore, or keystore
|
|
29
|
+
filename.
|
|
30
|
+
`);
|
|
31
|
+
process.exit();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function userError(...args)
|
|
35
|
+
{
|
|
36
|
+
console.error(...args);
|
|
37
|
+
process.exit(2);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function reportError(error)
|
|
41
|
+
{
|
|
42
|
+
console.error(error.message + (error.code ? ` (${error.code})` : ''));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function argAddress(optarg)
|
|
46
|
+
{
|
|
47
|
+
const wallet = require('dcp/wallet');
|
|
48
|
+
const utils = require('dcp/utils');
|
|
49
|
+
|
|
50
|
+
try
|
|
51
|
+
{
|
|
52
|
+
return { address: new wallet.Address(optarg) };
|
|
53
|
+
}
|
|
54
|
+
catch(error){} // eslint-disable-line
|
|
55
|
+
|
|
56
|
+
try
|
|
57
|
+
{
|
|
58
|
+
const pk = new wallet.PrivateKey(optarg);
|
|
59
|
+
return { address: pk.address };
|
|
60
|
+
}
|
|
61
|
+
catch(error){} // eslint-disable-line
|
|
62
|
+
|
|
63
|
+
try
|
|
64
|
+
{
|
|
65
|
+
const ks = JSON.parse(optarg);
|
|
66
|
+
if (typeof ks === 'object')
|
|
67
|
+
return { address: ks.address, label: ks.label };
|
|
68
|
+
}
|
|
69
|
+
catch(error){} // eslint-disable-line
|
|
70
|
+
|
|
71
|
+
try
|
|
72
|
+
{
|
|
73
|
+
const ks = await wallet.get(optarg);
|
|
74
|
+
if (typeof ks === 'object')
|
|
75
|
+
return { address: ks.address, label: ks.label };
|
|
76
|
+
}
|
|
77
|
+
catch(error){} // eslint-disable-line
|
|
78
|
+
|
|
79
|
+
try
|
|
80
|
+
{
|
|
81
|
+
const ks = JSON.parse(fs.readFileSync(utils.expandPath(optarg), 'utf-8'));
|
|
82
|
+
if (typeof ks === 'object')
|
|
83
|
+
return { address: ks.address, label: ks.label };
|
|
84
|
+
}
|
|
85
|
+
catch(error){} // eslint-disable-line
|
|
86
|
+
|
|
87
|
+
userError('invalid address specifier:', optarg);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function argPrivateKey(optarg)
|
|
91
|
+
{
|
|
92
|
+
const wallet = require('dcp/wallet');
|
|
93
|
+
const utils = require('dcp/utils');
|
|
94
|
+
|
|
95
|
+
try
|
|
96
|
+
{
|
|
97
|
+
return { key: new wallet.PrivateKey(optarg) };
|
|
98
|
+
}
|
|
99
|
+
catch(error){} // eslint-disable-line
|
|
100
|
+
|
|
101
|
+
try
|
|
102
|
+
{
|
|
103
|
+
const ks = JSON.parse(optarg);
|
|
104
|
+
if (typeof ks === 'object')
|
|
105
|
+
{
|
|
106
|
+
const keystore = await (new wallet.BankAccountKeystore(optarg));
|
|
107
|
+
return { key: await keystore.getPrivateKey(), label: keystore.label };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch(error){} // eslint-disable-line
|
|
111
|
+
|
|
112
|
+
try
|
|
113
|
+
{
|
|
114
|
+
const ks = await wallet.get(optarg);
|
|
115
|
+
if (typeof ks === 'object')
|
|
116
|
+
return { key: await ks.getPrivateKey(), label: ks.label };
|
|
117
|
+
}
|
|
118
|
+
catch(error){} // eslint-disable-line
|
|
119
|
+
|
|
120
|
+
try
|
|
121
|
+
{
|
|
122
|
+
const ks = JSON.parse(fs.readFileSync(utils.expandPath(optarg), 'utf-8'));
|
|
123
|
+
if (typeof ks === 'object')
|
|
124
|
+
{
|
|
125
|
+
const keystore = await (new wallet.BankAccountKeystore(ks, ''));
|
|
126
|
+
return { key: await keystore.getPrivateKey(), label: keystore.label };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch(error){} // eslint-disable-line
|
|
130
|
+
|
|
131
|
+
userError('invalid address specifier:', optarg);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function short(address)
|
|
135
|
+
{
|
|
136
|
+
return String(address).slice(0, 10);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function fmtLabel(label)
|
|
140
|
+
{
|
|
141
|
+
if (!label)
|
|
142
|
+
return '';
|
|
143
|
+
|
|
144
|
+
return `[${label}] `;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async function main()
|
|
148
|
+
{
|
|
149
|
+
const { Connection } = require('dcp/protocol');
|
|
150
|
+
|
|
151
|
+
var toLabel, fromLabel, toAccount, fromKey, amount, req;
|
|
152
|
+
var successHandler = () => console.log('success');
|
|
153
|
+
const argv = process.argv.slice(2);
|
|
154
|
+
const mode = argv.shift();
|
|
155
|
+
|
|
156
|
+
switch (mode)
|
|
157
|
+
{
|
|
158
|
+
case '-h': case '--help':
|
|
159
|
+
case undefined:
|
|
160
|
+
usage();
|
|
161
|
+
break;
|
|
162
|
+
case 'transfer':
|
|
163
|
+
amount = argv.shift();
|
|
164
|
+
break;
|
|
165
|
+
case 'balance':
|
|
166
|
+
break;
|
|
167
|
+
default:
|
|
168
|
+
userError('invalid mode:', mode);
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
for (let { option, optarg } of
|
|
173
|
+
require('../lib/getopt').parse(argv, 'h(help)t:(to)f:(from)'))
|
|
174
|
+
{
|
|
175
|
+
switch (option)
|
|
176
|
+
{
|
|
177
|
+
case 'h':
|
|
178
|
+
usage();
|
|
179
|
+
break;
|
|
180
|
+
default:
|
|
181
|
+
throw new Error(`defined but unspecified option: -${option}` + (optarg ? `=${optarg}` : ''));
|
|
182
|
+
case '?':
|
|
183
|
+
process.exit(1);
|
|
184
|
+
break;
|
|
185
|
+
case 't':
|
|
186
|
+
{
|
|
187
|
+
const ret = await argAddress(optarg);
|
|
188
|
+
toLabel = ret.label;
|
|
189
|
+
toAccount = ret.address;
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
case 'f':
|
|
193
|
+
{
|
|
194
|
+
const ret = await argPrivateKey(optarg);
|
|
195
|
+
fromLabel = ret.label;
|
|
196
|
+
fromKey = ret.key || false; /* ensure from is never undefined when --from */
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (typeof fromKey === 'undefined') /* no --from */
|
|
203
|
+
{
|
|
204
|
+
const ks = await require('dcp/wallet').get('default');
|
|
205
|
+
fromKey = await ks.getPrivateKey();
|
|
206
|
+
fromLabel = ks.label;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
toLabel = fmtLabel(toLabel);
|
|
210
|
+
fromLabel = fmtLabel(fromLabel);
|
|
211
|
+
|
|
212
|
+
const bankTeller = new Connection(dcpConfig.bank.services.bankTeller);
|
|
213
|
+
try
|
|
214
|
+
{
|
|
215
|
+
switch(mode)
|
|
216
|
+
{
|
|
217
|
+
case 'balance':
|
|
218
|
+
{
|
|
219
|
+
if (!fromKey)
|
|
220
|
+
userError('missing balance check from account key');
|
|
221
|
+
|
|
222
|
+
req = new bankTeller.Request('viewAccounts', {
|
|
223
|
+
address: [fromKey.address]
|
|
224
|
+
});
|
|
225
|
+
await req.authorize(fromKey.address, fromKey);
|
|
226
|
+
successHandler = (res) => {
|
|
227
|
+
console.log(`Balance of ${fromLabel}${short(fromKey.address)} is ${res.payload.accounts[0].balance}\u2287`);
|
|
228
|
+
};
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
case 'transfer':
|
|
232
|
+
{
|
|
233
|
+
const bnAmount = require('dcp/internal/bignumber.js')(amount);
|
|
234
|
+
if (isNaN(bnAmount))
|
|
235
|
+
userError(`invalid amount '${amount}'`);
|
|
236
|
+
if (!toAccount)
|
|
237
|
+
userError('missing transfer to account address');
|
|
238
|
+
if (!fromKey)
|
|
239
|
+
userError('missing transfer from account key');
|
|
240
|
+
process.stdout.write(`Transfering ${amount}\u2287 from ${fromLabel}${short(fromKey.address)} to ${toLabel}${short(toAccount)}...`);
|
|
241
|
+
req = new bankTeller.Request('transfer@1', { toAccount, amount,
|
|
242
|
+
fromAccount: fromKey.address, /* remove this property after DCP MR-3143 on bank */
|
|
243
|
+
});
|
|
244
|
+
await req.authorize(fromKey);
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
const res = await req.send();
|
|
249
|
+
if (res.success === true)
|
|
250
|
+
{
|
|
251
|
+
successHandler(res);
|
|
252
|
+
process.exitCode = 0;
|
|
253
|
+
}
|
|
254
|
+
else
|
|
255
|
+
{
|
|
256
|
+
console.error(JSON.stringify(res.payload));
|
|
257
|
+
console.error('FAIL');
|
|
258
|
+
if (res.payload.message)
|
|
259
|
+
reportError(res.payload);
|
|
260
|
+
else
|
|
261
|
+
console.error(res);
|
|
262
|
+
process.exitCode = 4;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
finally
|
|
266
|
+
{
|
|
267
|
+
bankTeller.close();
|
|
268
|
+
}
|
|
269
|
+
}
|
package/build/bundle
CHANGED
|
@@ -174,7 +174,7 @@ fi
|
|
|
174
174
|
NO_LOG=1 \
|
|
175
175
|
SKIP_SUDO_CHECK=1 \
|
|
176
176
|
DCP_LOCAL_CONFIG_EXTRAS="${BUNDLE_TMP}/local-config.incl" \
|
|
177
|
-
"${DCP_SRC}/install.sh" -
|
|
177
|
+
"${DCP_SRC}/install.sh" -N ${DCP_INSTALL_FLAGS} build-dcp-client
|
|
178
178
|
|
|
179
179
|
EXIT_CODE="$?"
|
|
180
180
|
if [ "$EXIT_CODE" != "0" ]; then
|