@shelby-protocol/cli 0.0.15 → 0.0.16
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/entry.js +1778 -335
- package/package.json +8 -4
package/bin/entry.js
CHANGED
|
@@ -1,15 +1,519 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
9
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
|
|
28
|
+
// assets/hasura_metadata.txt
|
|
29
|
+
var require_hasura_metadata = __commonJS({
|
|
30
|
+
"assets/hasura_metadata.txt"(exports, module) {
|
|
31
|
+
module.exports = '{\n "resource_version": 15,\n "metadata": {\n "version": 3,\n "sources": [\n {\n "name": "processordb",\n "kind": "postgres",\n "tables": [\n {\n "table": {\n "name": "blob_activities",\n "schema": "public"\n },\n "select_permissions": [\n {\n "role": "anonymous",\n "permission": {\n "columns": [\n "transaction_hash",\n "event_index",\n "transaction_version",\n "blob_name",\n "event_type",\n "timestamp"\n ],\n "filter": {},\n "limit": 100,\n "allow_aggregations": true\n },\n "comment": ""\n }\n ]\n },\n {\n "table": {\n "name": "blobs",\n "schema": "public"\n },\n "array_relationships": [\n {\n "name": "placement_group_slots",\n "using": {\n "manual_configuration": {\n "column_mapping": {\n "placement_group": "placement_group"\n },\n "insertion_order": null,\n "remote_table": {\n "name": "placement_group_slots",\n "schema": "public"\n }\n }\n }\n }\n ],\n "select_permissions": [\n {\n "role": "anonymous",\n "permission": {\n "columns": [\n "owner",\n "placement_group",\n "slice_address",\n "created_at",\n "expires_at",\n "is_deleted",\n "is_written",\n "num_chunksets",\n "size",\n "updated_at",\n "blob_commitment",\n "blob_name"\n ],\n "filter": {},\n "limit": 200,\n "allow_aggregations": true\n },\n "comment": ""\n }\n ]\n },\n {\n "table": {\n "name": "placement_group_slots",\n "schema": "public"\n },\n "select_permissions": [\n {\n "role": "anonymous",\n "permission": {\n "columns": [\n "placement_group",\n "storage_provider",\n "slot_index",\n "updated_at",\n "status"\n ],\n "filter": {}\n },\n "comment": ""\n }\n ]\n },\n {\n "table": {\n "name": "processor_status",\n "schema": "public"\n },\n "select_permissions": [\n {\n "role": "anonymous",\n "permission": {\n "columns": [\n "last_success_version",\n "last_transaction_timestamp",\n "last_updated"\n ],\n "filter": {},\n "limit": 10\n }\n }\n ]\n }\n ],\n "configuration": {\n "connection_info": {\n "database_url": {\n "from_env": "PROCESSOR_DATABASE_URL"\n },\n "isolation_level": "read-committed",\n "pool_settings": {\n "connection_lifetime": 600,\n "max_connections": 120\n },\n "use_prepared_statements": false\n }\n }\n }\n ]\n }\n}';
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// assets/shelby_internal.txt
|
|
36
|
+
var require_shelby_internal = __commonJS({
|
|
37
|
+
"assets/shelby_internal.txt"(exports, module) {
|
|
38
|
+
module.exports = `# This common_config is designed to work with the localnet setup in ts-cibuild.sh
|
|
39
|
+
common_config:
|
|
40
|
+
health_check_port: 7654
|
|
41
|
+
write_rate_limit_config:
|
|
42
|
+
num_bytes: 500000000
|
|
43
|
+
num_seconds: 300
|
|
44
|
+
transaction_stream_config:
|
|
45
|
+
# The node and its txn stream run on the host. In a Linux Docker environment,
|
|
46
|
+
# docker.host.internal is not normally available and you have to use
|
|
47
|
+
# 172.17.0.1 instead, but we add a hosts entry when running the containers to
|
|
48
|
+
# make it available.
|
|
49
|
+
indexer_grpc_data_service_address: "http://host.docker.internal:50051"
|
|
50
|
+
auth_token: notusedforlocalnet
|
|
51
|
+
request_name_header: "remapping-processor"
|
|
52
|
+
db_config:
|
|
53
|
+
# The domain we use is the name of the database in the localnet Docker network. The
|
|
54
|
+
# remapping processor needs its own database, so we use "postgres" rather than the
|
|
55
|
+
# "local_testnet" database used by the localnet's core processors. We use port 5432
|
|
56
|
+
# because that's the port postgres runs at inside the Docker network, even though we
|
|
57
|
+
# expose it to the outside world at 5433.
|
|
58
|
+
postgres_connection_string: postgresql://postgres:postgres@local-testnet-postgres:5432/postgres
|
|
59
|
+
custom_config:
|
|
60
|
+
db_schema:
|
|
61
|
+
blob_activities:
|
|
62
|
+
blob_name:
|
|
63
|
+
column_type:
|
|
64
|
+
column_type: "string"
|
|
65
|
+
type: "move_type"
|
|
66
|
+
default_value: null
|
|
67
|
+
is_index: false
|
|
68
|
+
is_nullable: false
|
|
69
|
+
is_option: false
|
|
70
|
+
is_primary_key: false
|
|
71
|
+
is_vec: false
|
|
72
|
+
event_index:
|
|
73
|
+
column_type:
|
|
74
|
+
column_type: "event_index"
|
|
75
|
+
type: "event_metadata"
|
|
76
|
+
default_value: null
|
|
77
|
+
is_index: false
|
|
78
|
+
is_nullable: false
|
|
79
|
+
is_option: false
|
|
80
|
+
is_primary_key: true
|
|
81
|
+
is_vec: false
|
|
82
|
+
event_type:
|
|
83
|
+
column_type:
|
|
84
|
+
column_type: "event_type"
|
|
85
|
+
type: "event_metadata"
|
|
86
|
+
default_value: null
|
|
87
|
+
is_index: false
|
|
88
|
+
is_nullable: false
|
|
89
|
+
is_option: false
|
|
90
|
+
is_primary_key: true
|
|
91
|
+
is_vec: false
|
|
92
|
+
timestamp:
|
|
93
|
+
column_type:
|
|
94
|
+
column_type: "timestamp"
|
|
95
|
+
type: "transaction_metadata"
|
|
96
|
+
default_value: null
|
|
97
|
+
is_index: false
|
|
98
|
+
is_nullable: false
|
|
99
|
+
is_option: false
|
|
100
|
+
is_primary_key: false
|
|
101
|
+
is_vec: false
|
|
102
|
+
transaction_hash:
|
|
103
|
+
column_type:
|
|
104
|
+
column_type: "hash"
|
|
105
|
+
type: "transaction_metadata"
|
|
106
|
+
default_value: null
|
|
107
|
+
is_index: false
|
|
108
|
+
is_nullable: false
|
|
109
|
+
is_option: false
|
|
110
|
+
is_primary_key: true
|
|
111
|
+
is_vec: false
|
|
112
|
+
transaction_version:
|
|
113
|
+
column_type:
|
|
114
|
+
column_type: "version"
|
|
115
|
+
type: "transaction_metadata"
|
|
116
|
+
default_value: null
|
|
117
|
+
is_index: false
|
|
118
|
+
is_nullable: false
|
|
119
|
+
is_option: false
|
|
120
|
+
is_primary_key: false
|
|
121
|
+
is_vec: false
|
|
122
|
+
blobs:
|
|
123
|
+
blob_commitment:
|
|
124
|
+
column_type:
|
|
125
|
+
column_type: "string"
|
|
126
|
+
type: "move_type"
|
|
127
|
+
default_value: null
|
|
128
|
+
is_index: false
|
|
129
|
+
is_nullable: false
|
|
130
|
+
is_option: false
|
|
131
|
+
is_primary_key: false
|
|
132
|
+
is_vec: false
|
|
133
|
+
blob_name:
|
|
134
|
+
column_type:
|
|
135
|
+
column_type: "string"
|
|
136
|
+
type: "move_type"
|
|
137
|
+
default_value: null
|
|
138
|
+
is_index: false
|
|
139
|
+
is_nullable: false
|
|
140
|
+
is_option: false
|
|
141
|
+
is_primary_key: true
|
|
142
|
+
is_vec: false
|
|
143
|
+
created_at:
|
|
144
|
+
column_type:
|
|
145
|
+
column_type: "u64"
|
|
146
|
+
type: "move_type"
|
|
147
|
+
default_value: null
|
|
148
|
+
is_index: false
|
|
149
|
+
is_nullable: false
|
|
150
|
+
is_option: false
|
|
151
|
+
is_primary_key: false
|
|
152
|
+
is_vec: false
|
|
153
|
+
expires_at:
|
|
154
|
+
column_type:
|
|
155
|
+
column_type: "u64"
|
|
156
|
+
type: "move_type"
|
|
157
|
+
default_value: null
|
|
158
|
+
is_index: false
|
|
159
|
+
is_nullable: false
|
|
160
|
+
is_option: false
|
|
161
|
+
is_primary_key: false
|
|
162
|
+
is_vec: false
|
|
163
|
+
is_deleted:
|
|
164
|
+
column_type:
|
|
165
|
+
column_type: "u8"
|
|
166
|
+
type: "move_type"
|
|
167
|
+
default_value: null
|
|
168
|
+
is_index: false
|
|
169
|
+
is_nullable: false
|
|
170
|
+
is_option: false
|
|
171
|
+
is_primary_key: false
|
|
172
|
+
is_vec: false
|
|
173
|
+
is_written:
|
|
174
|
+
column_type:
|
|
175
|
+
column_type: "u8"
|
|
176
|
+
type: "move_type"
|
|
177
|
+
default_value: null
|
|
178
|
+
is_index: false
|
|
179
|
+
is_nullable: false
|
|
180
|
+
is_option: false
|
|
181
|
+
is_primary_key: false
|
|
182
|
+
is_vec: false
|
|
183
|
+
num_chunksets:
|
|
184
|
+
column_type:
|
|
185
|
+
column_type: "u32"
|
|
186
|
+
type: "move_type"
|
|
187
|
+
default_value: null
|
|
188
|
+
is_index: false
|
|
189
|
+
is_nullable: false
|
|
190
|
+
is_option: false
|
|
191
|
+
is_primary_key: false
|
|
192
|
+
is_vec: false
|
|
193
|
+
owner:
|
|
194
|
+
column_type:
|
|
195
|
+
column_type: "address"
|
|
196
|
+
type: "move_type"
|
|
197
|
+
default_value: null
|
|
198
|
+
is_index: true
|
|
199
|
+
is_nullable: false
|
|
200
|
+
is_option: false
|
|
201
|
+
is_primary_key: false
|
|
202
|
+
is_vec: false
|
|
203
|
+
placement_group:
|
|
204
|
+
column_type:
|
|
205
|
+
column_type: "address"
|
|
206
|
+
type: "move_type"
|
|
207
|
+
default_value: null
|
|
208
|
+
is_index: false
|
|
209
|
+
is_nullable: false
|
|
210
|
+
is_option: false
|
|
211
|
+
is_primary_key: false
|
|
212
|
+
is_vec: false
|
|
213
|
+
size:
|
|
214
|
+
column_type:
|
|
215
|
+
column_type: "u64"
|
|
216
|
+
type: "move_type"
|
|
217
|
+
default_value: null
|
|
218
|
+
is_index: false
|
|
219
|
+
is_nullable: false
|
|
220
|
+
is_option: false
|
|
221
|
+
is_primary_key: false
|
|
222
|
+
is_vec: false
|
|
223
|
+
slice_address:
|
|
224
|
+
column_type:
|
|
225
|
+
column_type: "address"
|
|
226
|
+
type: "move_type"
|
|
227
|
+
default_value: null
|
|
228
|
+
is_index: false
|
|
229
|
+
is_nullable: false
|
|
230
|
+
is_option: false
|
|
231
|
+
is_primary_key: false
|
|
232
|
+
is_vec: false
|
|
233
|
+
updated_at:
|
|
234
|
+
column_type:
|
|
235
|
+
column_type: "u64"
|
|
236
|
+
type: "move_type"
|
|
237
|
+
default_value: null
|
|
238
|
+
is_index: false
|
|
239
|
+
is_nullable: false
|
|
240
|
+
is_option: false
|
|
241
|
+
is_primary_key: false
|
|
242
|
+
is_vec: false
|
|
243
|
+
placement_group_slots:
|
|
244
|
+
placement_group:
|
|
245
|
+
column_type:
|
|
246
|
+
column_type: "address"
|
|
247
|
+
type: "move_type"
|
|
248
|
+
default_value: null
|
|
249
|
+
is_index: false
|
|
250
|
+
is_nullable: false
|
|
251
|
+
is_option: false
|
|
252
|
+
is_primary_key: true
|
|
253
|
+
is_vec: false
|
|
254
|
+
slot_index:
|
|
255
|
+
column_type:
|
|
256
|
+
column_type: "u64"
|
|
257
|
+
type: "move_type"
|
|
258
|
+
default_value: null
|
|
259
|
+
is_index: false
|
|
260
|
+
is_nullable: false
|
|
261
|
+
is_option: false
|
|
262
|
+
is_primary_key: true
|
|
263
|
+
is_vec: false
|
|
264
|
+
status:
|
|
265
|
+
column_type:
|
|
266
|
+
column_type: "string"
|
|
267
|
+
type: "move_type"
|
|
268
|
+
default_value: null
|
|
269
|
+
is_index: false
|
|
270
|
+
is_nullable: false
|
|
271
|
+
is_option: false
|
|
272
|
+
is_primary_key: false
|
|
273
|
+
is_vec: false
|
|
274
|
+
storage_provider:
|
|
275
|
+
column_type:
|
|
276
|
+
column_type: "address"
|
|
277
|
+
type: "move_type"
|
|
278
|
+
default_value: null
|
|
279
|
+
is_index: false
|
|
280
|
+
is_nullable: false
|
|
281
|
+
is_option: false
|
|
282
|
+
is_primary_key: false
|
|
283
|
+
is_vec: false
|
|
284
|
+
updated_at:
|
|
285
|
+
column_type:
|
|
286
|
+
column_type: "u64"
|
|
287
|
+
type: "move_type"
|
|
288
|
+
default_value: null
|
|
289
|
+
is_index: false
|
|
290
|
+
is_nullable: false
|
|
291
|
+
is_option: false
|
|
292
|
+
is_primary_key: false
|
|
293
|
+
is_vec: false
|
|
294
|
+
events:
|
|
295
|
+
0xc63d6a5efb0080a6029403131715bd4971e1149f7cc099aac69bb0069b3ddbf5::blob_metadata::BlobDeletedEvent:
|
|
296
|
+
constant_values:
|
|
297
|
+
- column: "is_deleted"
|
|
298
|
+
table: "blobs"
|
|
299
|
+
value: 1
|
|
300
|
+
event_fields:
|
|
301
|
+
$.blob_name:
|
|
302
|
+
- column: "blob_name"
|
|
303
|
+
table: "blobs"
|
|
304
|
+
- column: "blob_name"
|
|
305
|
+
table: "blob_activities"
|
|
306
|
+
$.deleted_at_micros:
|
|
307
|
+
- column: "updated_at"
|
|
308
|
+
table: "blobs"
|
|
309
|
+
event_metadata:
|
|
310
|
+
account_address: []
|
|
311
|
+
creation_number: []
|
|
312
|
+
event_index:
|
|
313
|
+
- column: "event_index"
|
|
314
|
+
table: "blob_activities"
|
|
315
|
+
event_type:
|
|
316
|
+
- column: "event_type"
|
|
317
|
+
table: "blob_activities"
|
|
318
|
+
sequence_number: []
|
|
319
|
+
0xc63d6a5efb0080a6029403131715bd4971e1149f7cc099aac69bb0069b3ddbf5::blob_metadata::BlobExpirationExtendedEvent:
|
|
320
|
+
constant_values: []
|
|
321
|
+
event_fields:
|
|
322
|
+
$.blob_name:
|
|
323
|
+
- column: "blob_name"
|
|
324
|
+
table: "blobs"
|
|
325
|
+
- column: "blob_name"
|
|
326
|
+
table: "blob_activities"
|
|
327
|
+
$.new_expiration_micros:
|
|
328
|
+
- column: "expires_at"
|
|
329
|
+
table: "blobs"
|
|
330
|
+
$.updated_at_micros:
|
|
331
|
+
- column: "updated_at"
|
|
332
|
+
table: "blobs"
|
|
333
|
+
event_metadata:
|
|
334
|
+
account_address: []
|
|
335
|
+
creation_number: []
|
|
336
|
+
event_index:
|
|
337
|
+
- column: "event_index"
|
|
338
|
+
table: "blob_activities"
|
|
339
|
+
event_type:
|
|
340
|
+
- column: "event_type"
|
|
341
|
+
table: "blob_activities"
|
|
342
|
+
sequence_number: []
|
|
343
|
+
0xc63d6a5efb0080a6029403131715bd4971e1149f7cc099aac69bb0069b3ddbf5::blob_metadata::BlobRegisteredEvent:
|
|
344
|
+
constant_values:
|
|
345
|
+
- column: "is_deleted"
|
|
346
|
+
table: "blobs"
|
|
347
|
+
value: 0
|
|
348
|
+
- column: "is_written"
|
|
349
|
+
table: "blobs"
|
|
350
|
+
value: 0
|
|
351
|
+
event_fields:
|
|
352
|
+
$.blob_commitment:
|
|
353
|
+
- column: "blob_commitment"
|
|
354
|
+
table: "blobs"
|
|
355
|
+
$.blob_name:
|
|
356
|
+
- column: "blob_name"
|
|
357
|
+
table: "blobs"
|
|
358
|
+
- column: "blob_name"
|
|
359
|
+
table: "blob_activities"
|
|
360
|
+
$.blob_size:
|
|
361
|
+
- column: "size"
|
|
362
|
+
table: "blobs"
|
|
363
|
+
$.chunkset_count:
|
|
364
|
+
- column: "num_chunksets"
|
|
365
|
+
table: "blobs"
|
|
366
|
+
$.creation_micros:
|
|
367
|
+
- column: "created_at"
|
|
368
|
+
table: "blobs"
|
|
369
|
+
- column: "updated_at"
|
|
370
|
+
table: "blobs"
|
|
371
|
+
$.expiration_micros:
|
|
372
|
+
- column: "expires_at"
|
|
373
|
+
table: "blobs"
|
|
374
|
+
$.owner:
|
|
375
|
+
- column: "owner"
|
|
376
|
+
table: "blobs"
|
|
377
|
+
$.placement_group_address:
|
|
378
|
+
- column: "placement_group"
|
|
379
|
+
table: "blobs"
|
|
380
|
+
$.slice_address:
|
|
381
|
+
- column: "slice_address"
|
|
382
|
+
table: "blobs"
|
|
383
|
+
event_metadata:
|
|
384
|
+
account_address: []
|
|
385
|
+
creation_number: []
|
|
386
|
+
event_index:
|
|
387
|
+
- column: "event_index"
|
|
388
|
+
table: "blob_activities"
|
|
389
|
+
event_type:
|
|
390
|
+
- column: "event_type"
|
|
391
|
+
table: "blob_activities"
|
|
392
|
+
sequence_number: []
|
|
393
|
+
0xc63d6a5efb0080a6029403131715bd4971e1149f7cc099aac69bb0069b3ddbf5::blob_metadata::BlobWrittenEvent:
|
|
394
|
+
constant_values:
|
|
395
|
+
- column: "is_written"
|
|
396
|
+
table: "blobs"
|
|
397
|
+
value: 1
|
|
398
|
+
event_fields:
|
|
399
|
+
$.blob_name:
|
|
400
|
+
- column: "blob_name"
|
|
401
|
+
table: "blobs"
|
|
402
|
+
- column: "blob_name"
|
|
403
|
+
table: "blob_activities"
|
|
404
|
+
$.written_at_micros:
|
|
405
|
+
- column: "updated_at"
|
|
406
|
+
table: "blobs"
|
|
407
|
+
event_metadata:
|
|
408
|
+
account_address: []
|
|
409
|
+
creation_number: []
|
|
410
|
+
event_index:
|
|
411
|
+
- column: "event_index"
|
|
412
|
+
table: "blob_activities"
|
|
413
|
+
event_type:
|
|
414
|
+
- column: "event_type"
|
|
415
|
+
table: "blob_activities"
|
|
416
|
+
sequence_number: []
|
|
417
|
+
0xc63d6a5efb0080a6029403131715bd4971e1149f7cc099aac69bb0069b3ddbf5::placement_group::StorageProviderActivatedEvent:
|
|
418
|
+
constant_values:
|
|
419
|
+
- column: "status"
|
|
420
|
+
table: "placement_group_slots"
|
|
421
|
+
value: "active"
|
|
422
|
+
event_fields:
|
|
423
|
+
$.activated_at:
|
|
424
|
+
- column: "updated_at"
|
|
425
|
+
table: "placement_group_slots"
|
|
426
|
+
$.placement_group_address:
|
|
427
|
+
- column: "placement_group"
|
|
428
|
+
table: "placement_group_slots"
|
|
429
|
+
$.slot_index:
|
|
430
|
+
- column: "slot_index"
|
|
431
|
+
table: "placement_group_slots"
|
|
432
|
+
$.storage_provider_address:
|
|
433
|
+
- column: "storage_provider"
|
|
434
|
+
table: "placement_group_slots"
|
|
435
|
+
event_metadata:
|
|
436
|
+
account_address: []
|
|
437
|
+
creation_number: []
|
|
438
|
+
event_index: []
|
|
439
|
+
event_type: []
|
|
440
|
+
sequence_number: []
|
|
441
|
+
0xc63d6a5efb0080a6029403131715bd4971e1149f7cc099aac69bb0069b3ddbf5::placement_group::StorageProviderAssignedEvent:
|
|
442
|
+
constant_values:
|
|
443
|
+
- column: "status"
|
|
444
|
+
table: "placement_group_slots"
|
|
445
|
+
value: "joining"
|
|
446
|
+
event_fields:
|
|
447
|
+
$.assigned_at:
|
|
448
|
+
- column: "updated_at"
|
|
449
|
+
table: "placement_group_slots"
|
|
450
|
+
$.placement_group_address:
|
|
451
|
+
- column: "placement_group"
|
|
452
|
+
table: "placement_group_slots"
|
|
453
|
+
$.slot_index:
|
|
454
|
+
- column: "slot_index"
|
|
455
|
+
table: "placement_group_slots"
|
|
456
|
+
$.storage_provider_address:
|
|
457
|
+
- column: "storage_provider"
|
|
458
|
+
table: "placement_group_slots"
|
|
459
|
+
event_metadata:
|
|
460
|
+
account_address: []
|
|
461
|
+
creation_number: []
|
|
462
|
+
event_index: []
|
|
463
|
+
event_type: []
|
|
464
|
+
sequence_number: []
|
|
465
|
+
0xc63d6a5efb0080a6029403131715bd4971e1149f7cc099aac69bb0069b3ddbf5::placement_group::StorageProviderLeftEvent:
|
|
466
|
+
constant_values:
|
|
467
|
+
- column: "status"
|
|
468
|
+
table: "placement_group_slots"
|
|
469
|
+
value: "left"
|
|
470
|
+
event_fields:
|
|
471
|
+
$.left_at:
|
|
472
|
+
- column: "updated_at"
|
|
473
|
+
table: "placement_group_slots"
|
|
474
|
+
$.placement_group_address:
|
|
475
|
+
- column: "placement_group"
|
|
476
|
+
table: "placement_group_slots"
|
|
477
|
+
$.slot_index:
|
|
478
|
+
- column: "slot_index"
|
|
479
|
+
table: "placement_group_slots"
|
|
480
|
+
$.storage_provider_address:
|
|
481
|
+
- column: "storage_provider"
|
|
482
|
+
table: "placement_group_slots"
|
|
483
|
+
event_metadata:
|
|
484
|
+
account_address: []
|
|
485
|
+
creation_number: []
|
|
486
|
+
event_index: []
|
|
487
|
+
event_type: []
|
|
488
|
+
sequence_number: []
|
|
489
|
+
payload: {}
|
|
490
|
+
transaction_metadata:
|
|
491
|
+
block_height: []
|
|
492
|
+
epoch: []
|
|
493
|
+
hash:
|
|
494
|
+
- column: "transaction_hash"
|
|
495
|
+
table: "blob_activities"
|
|
496
|
+
timestamp:
|
|
497
|
+
- column: "timestamp"
|
|
498
|
+
table: "blob_activities"
|
|
499
|
+
version:
|
|
500
|
+
- column: "transaction_version"
|
|
501
|
+
table: "blob_activities"
|
|
502
|
+
`;
|
|
503
|
+
}
|
|
504
|
+
});
|
|
2
505
|
|
|
3
506
|
// src/cli.tsx
|
|
4
|
-
import { Command } from "commander";
|
|
507
|
+
import { Command } from "@commander-js/extra-typings";
|
|
5
508
|
|
|
6
509
|
// package.json
|
|
7
510
|
var name = "@shelby-protocol/cli";
|
|
8
|
-
var version = "0.0.
|
|
511
|
+
var version = "0.0.16";
|
|
9
512
|
|
|
10
513
|
// src/commands/account.tsx
|
|
11
514
|
import readline from "readline";
|
|
12
515
|
import { Account as Account3, AptosApiError as AptosApiError2, Ed25519PrivateKey as Ed25519PrivateKey4 } from "@aptos-labs/ts-sdk";
|
|
516
|
+
import { Option } from "@commander-js/extra-typings";
|
|
13
517
|
|
|
14
518
|
// ../../packages/sdk/dist/chunk-RBFWGDMY.mjs
|
|
15
519
|
import { AptosConfig, Network } from "@aptos-labs/ts-sdk";
|
|
@@ -229,10 +733,10 @@ var GraphQLError = class _GraphQLError extends Error {
|
|
|
229
733
|
*/
|
|
230
734
|
constructor(message, ...rawArgs) {
|
|
231
735
|
var _this$nodes, _nodeLocations$, _ref;
|
|
232
|
-
const { nodes, source, positions, path:
|
|
736
|
+
const { nodes, source, positions, path: path10, originalError, extensions } = toNormalizedOptions(rawArgs);
|
|
233
737
|
super(message);
|
|
234
738
|
this.name = "GraphQLError";
|
|
235
|
-
this.path =
|
|
739
|
+
this.path = path10 !== null && path10 !== void 0 ? path10 : void 0;
|
|
236
740
|
this.originalError = originalError !== null && originalError !== void 0 ? originalError : void 0;
|
|
237
741
|
this.nodes = undefinedIfEmpty(
|
|
238
742
|
Array.isArray(nodes) ? nodes : nodes ? [nodes] : void 0
|
|
@@ -2800,14 +3304,14 @@ function visit(root, visitor, visitorKeys = QueryDocumentKeys) {
|
|
|
2800
3304
|
let node = root;
|
|
2801
3305
|
let key = void 0;
|
|
2802
3306
|
let parent = void 0;
|
|
2803
|
-
const
|
|
3307
|
+
const path10 = [];
|
|
2804
3308
|
const ancestors = [];
|
|
2805
3309
|
do {
|
|
2806
3310
|
index++;
|
|
2807
3311
|
const isLeaving = index === keys.length;
|
|
2808
3312
|
const isEdited = isLeaving && edits.length !== 0;
|
|
2809
3313
|
if (isLeaving) {
|
|
2810
|
-
key = ancestors.length === 0 ? void 0 :
|
|
3314
|
+
key = ancestors.length === 0 ? void 0 : path10[path10.length - 1];
|
|
2811
3315
|
node = parent;
|
|
2812
3316
|
parent = ancestors.pop();
|
|
2813
3317
|
if (isEdited) {
|
|
@@ -2841,20 +3345,20 @@ function visit(root, visitor, visitorKeys = QueryDocumentKeys) {
|
|
|
2841
3345
|
if (node === null || node === void 0) {
|
|
2842
3346
|
continue;
|
|
2843
3347
|
}
|
|
2844
|
-
|
|
3348
|
+
path10.push(key);
|
|
2845
3349
|
}
|
|
2846
3350
|
let result;
|
|
2847
3351
|
if (!Array.isArray(node)) {
|
|
2848
3352
|
var _enterLeaveMap$get, _enterLeaveMap$get2;
|
|
2849
3353
|
isNode(node) || devAssert(false, `Invalid AST Node: ${inspect(node)}.`);
|
|
2850
3354
|
const visitFn = isLeaving ? (_enterLeaveMap$get = enterLeaveMap.get(node.kind)) === null || _enterLeaveMap$get === void 0 ? void 0 : _enterLeaveMap$get.leave : (_enterLeaveMap$get2 = enterLeaveMap.get(node.kind)) === null || _enterLeaveMap$get2 === void 0 ? void 0 : _enterLeaveMap$get2.enter;
|
|
2851
|
-
result = visitFn === null || visitFn === void 0 ? void 0 : visitFn.call(visitor, node, key, parent,
|
|
3355
|
+
result = visitFn === null || visitFn === void 0 ? void 0 : visitFn.call(visitor, node, key, parent, path10, ancestors);
|
|
2852
3356
|
if (result === BREAK) {
|
|
2853
3357
|
break;
|
|
2854
3358
|
}
|
|
2855
3359
|
if (result === false) {
|
|
2856
3360
|
if (!isLeaving) {
|
|
2857
|
-
|
|
3361
|
+
path10.pop();
|
|
2858
3362
|
continue;
|
|
2859
3363
|
}
|
|
2860
3364
|
} else if (result !== void 0) {
|
|
@@ -2863,7 +3367,7 @@ function visit(root, visitor, visitorKeys = QueryDocumentKeys) {
|
|
|
2863
3367
|
if (isNode(result)) {
|
|
2864
3368
|
node = result;
|
|
2865
3369
|
} else {
|
|
2866
|
-
|
|
3370
|
+
path10.pop();
|
|
2867
3371
|
continue;
|
|
2868
3372
|
}
|
|
2869
3373
|
}
|
|
@@ -2873,7 +3377,7 @@ function visit(root, visitor, visitorKeys = QueryDocumentKeys) {
|
|
|
2873
3377
|
edits.push([key, node]);
|
|
2874
3378
|
}
|
|
2875
3379
|
if (isLeaving) {
|
|
2876
|
-
|
|
3380
|
+
path10.pop();
|
|
2877
3381
|
} else {
|
|
2878
3382
|
var _node$kind;
|
|
2879
3383
|
stack = {
|
|
@@ -3970,10 +4474,10 @@ function isReadableStream(value) {
|
|
|
3970
4474
|
function toUint8Array(view) {
|
|
3971
4475
|
return view instanceof Uint8Array ? view : new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
|
|
3972
4476
|
}
|
|
3973
|
-
function buildRequestUrl(
|
|
4477
|
+
function buildRequestUrl(path10, baseUrl) {
|
|
3974
4478
|
const baseHasSlash = baseUrl.endsWith("/");
|
|
3975
4479
|
const safeBase = baseHasSlash ? baseUrl : `${baseUrl}/`;
|
|
3976
|
-
const safePath =
|
|
4480
|
+
const safePath = path10.replace(/^\/+/, "");
|
|
3977
4481
|
return new URL(safePath, safeBase);
|
|
3978
4482
|
}
|
|
3979
4483
|
function getBlobNameSuffix(blobName) {
|
|
@@ -5011,7 +5515,7 @@ var ShelbyBlobClient = class _ShelbyBlobClient {
|
|
|
5011
5515
|
}
|
|
5012
5516
|
};
|
|
5013
5517
|
|
|
5014
|
-
// ../../packages/sdk/dist/chunk-
|
|
5518
|
+
// ../../packages/sdk/dist/chunk-AUGZMI6U.mjs
|
|
5015
5519
|
import {
|
|
5016
5520
|
Aptos as Aptos3
|
|
5017
5521
|
} from "@aptos-labs/ts-sdk";
|
|
@@ -5153,7 +5657,7 @@ function validateConcurrency(concurrency) {
|
|
|
5153
5657
|
}
|
|
5154
5658
|
}
|
|
5155
5659
|
|
|
5156
|
-
// ../../packages/sdk/dist/chunk-
|
|
5660
|
+
// ../../packages/sdk/dist/chunk-AUGZMI6U.mjs
|
|
5157
5661
|
var ShelbyClient = class {
|
|
5158
5662
|
/**
|
|
5159
5663
|
* The coordination client is used to interact with the Aptos blockchain which handles the commitments
|
|
@@ -5386,17 +5890,52 @@ var ShelbyClient = class {
|
|
|
5386
5890
|
async download(params) {
|
|
5387
5891
|
return await this.rpc.getBlob(params);
|
|
5388
5892
|
}
|
|
5893
|
+
/**
|
|
5894
|
+
*
|
|
5895
|
+
* Funds an account with ShelbyUSD tokens.
|
|
5896
|
+
*
|
|
5897
|
+
* @param params.address - The address to fund.
|
|
5898
|
+
* @param params.amount - The amount to fund.
|
|
5899
|
+
* @returns The transaction hash of the funded account.
|
|
5900
|
+
*
|
|
5901
|
+
* @example
|
|
5902
|
+
* ```typescript
|
|
5903
|
+
* const hash = await client.fundAccount({
|
|
5904
|
+
* address: "0x1",
|
|
5905
|
+
* amount: 100000000,
|
|
5906
|
+
* });
|
|
5907
|
+
* ```
|
|
5908
|
+
*/
|
|
5909
|
+
async fundAccount(params) {
|
|
5910
|
+
const { address, amount } = params;
|
|
5911
|
+
try {
|
|
5912
|
+
const faucet = this.config.faucet ?? "https://faucet.shelbynet.shelby.xyz/fund?asset=shelbyusd";
|
|
5913
|
+
const response = await fetch(`${faucet}`, {
|
|
5914
|
+
method: "POST",
|
|
5915
|
+
body: JSON.stringify({ address, amount }),
|
|
5916
|
+
headers: {
|
|
5917
|
+
"Content-Type": "application/json"
|
|
5918
|
+
}
|
|
5919
|
+
});
|
|
5920
|
+
if (!response.ok) {
|
|
5921
|
+
throw new Error("Failed to fund account");
|
|
5922
|
+
}
|
|
5923
|
+
return response.json();
|
|
5924
|
+
} catch (error) {
|
|
5925
|
+
throw new Error("Failed to fund account: " + error);
|
|
5926
|
+
}
|
|
5927
|
+
}
|
|
5389
5928
|
};
|
|
5390
5929
|
|
|
5391
|
-
// ../../packages/sdk/dist/chunk-
|
|
5930
|
+
// ../../packages/sdk/dist/chunk-GZJ5IOCG.mjs
|
|
5392
5931
|
var ShelbyNodeClient = class extends ShelbyClient {
|
|
5393
5932
|
};
|
|
5394
5933
|
|
|
5395
5934
|
// ../../packages/sdk/dist/chunk-7P6ASYW6.mjs
|
|
5396
|
-
var
|
|
5935
|
+
var __defProp2 = Object.defineProperty;
|
|
5397
5936
|
var __export = (target, all) => {
|
|
5398
5937
|
for (var name2 in all)
|
|
5399
|
-
|
|
5938
|
+
__defProp2(target, name2, { get: all[name2], enumerable: true });
|
|
5400
5939
|
};
|
|
5401
5940
|
|
|
5402
5941
|
// ../../packages/sdk/dist/chunk-A4IG6GSE.mjs
|
|
@@ -5498,7 +6037,7 @@ var DEFAULT_CHUNK_SIZE_BYTES2 = 2 * 1024 * 1024;
|
|
|
5498
6037
|
import chalk2 from "chalk";
|
|
5499
6038
|
import { filesize } from "filesize";
|
|
5500
6039
|
import { render } from "ink";
|
|
5501
|
-
import { z as
|
|
6040
|
+
import { z as z11 } from "zod";
|
|
5502
6041
|
|
|
5503
6042
|
// src/components/AccountWizard.tsx
|
|
5504
6043
|
import { Box, Text } from "ink";
|
|
@@ -5506,8 +6045,8 @@ import TextInput from "ink-text-input";
|
|
|
5506
6045
|
import { useEffect, useState } from "react";
|
|
5507
6046
|
|
|
5508
6047
|
// src/utils/config.ts
|
|
5509
|
-
import
|
|
5510
|
-
import
|
|
6048
|
+
import os2 from "os";
|
|
6049
|
+
import path2 from "path";
|
|
5511
6050
|
import {
|
|
5512
6051
|
Aptos as Aptos4,
|
|
5513
6052
|
AptosConfig as AptosConfig3,
|
|
@@ -5515,9 +6054,9 @@ import {
|
|
|
5515
6054
|
Ed25519PrivateKey,
|
|
5516
6055
|
NetworkToNetworkName
|
|
5517
6056
|
} from "@aptos-labs/ts-sdk";
|
|
5518
|
-
import
|
|
5519
|
-
import
|
|
5520
|
-
import { z as
|
|
6057
|
+
import fs2 from "fs-extra";
|
|
6058
|
+
import YAML2 from "yaml";
|
|
6059
|
+
import { z as z7 } from "zod";
|
|
5521
6060
|
|
|
5522
6061
|
// src/schemas/AptosNetworkSchema.ts
|
|
5523
6062
|
import { z as z4 } from "zod";
|
|
@@ -5548,111 +6087,150 @@ var ShelbyNetworkSchema = z5.object({
|
|
|
5548
6087
|
deployer_address: z5.string().optional()
|
|
5549
6088
|
});
|
|
5550
6089
|
|
|
5551
|
-
// src/utils/
|
|
5552
|
-
import
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
import
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
function createContextForNetwork(network) {
|
|
5563
|
-
return {
|
|
5564
|
-
aptos_network: {
|
|
5565
|
-
name: network,
|
|
5566
|
-
fullnode: NetworkToNodeAPI[network],
|
|
5567
|
-
faucet: NetworkToFaucetAPI[network],
|
|
5568
|
-
indexer: NetworkToIndexerAPI[network],
|
|
5569
|
-
pepper: NetworkToPepperAPI[network],
|
|
5570
|
-
prover: NetworkToProverAPI[network]
|
|
5571
|
-
},
|
|
5572
|
-
shelby_network: {
|
|
5573
|
-
rpc_endpoint: NetworkToShelbyRPCBaseUrl[network]
|
|
5574
|
-
}
|
|
5575
|
-
};
|
|
5576
|
-
}
|
|
5577
|
-
|
|
5578
|
-
// src/utils/constants.ts
|
|
5579
|
-
var DEFAULT_CONFIG_PATH = "~/.shelby/config.yaml";
|
|
5580
|
-
var DEFAULT_CONFIG = {
|
|
5581
|
-
contexts: {
|
|
5582
|
-
[Network7.LOCAL]: {
|
|
5583
|
-
...createContextForNetwork(Network7.LOCAL),
|
|
5584
|
-
// Override shelby_network for local
|
|
5585
|
-
shelby_network: { rpc_endpoint: "http://localhost:9090/" }
|
|
5586
|
-
},
|
|
5587
|
-
[Network7.SHELBYNET]: createContextForNetwork(Network7.SHELBYNET)
|
|
5588
|
-
},
|
|
5589
|
-
accounts: {},
|
|
5590
|
-
default_context: Network7.SHELBYNET,
|
|
5591
|
-
default_account: ""
|
|
6090
|
+
// src/utils/global-config.ts
|
|
6091
|
+
import os from "os";
|
|
6092
|
+
import path from "path";
|
|
6093
|
+
import fs from "fs-extra";
|
|
6094
|
+
import YAML from "yaml";
|
|
6095
|
+
import { z as z6 } from "zod";
|
|
6096
|
+
var GlobalConfigSchema = z6.object({
|
|
6097
|
+
config_location_behavior: z6.enum(["global", "walk"])
|
|
6098
|
+
});
|
|
6099
|
+
var DEFAULT_GLOBAL_CONFIG = {
|
|
6100
|
+
config_location_behavior: "global"
|
|
5592
6101
|
};
|
|
5593
|
-
var
|
|
5594
|
-
|
|
6102
|
+
var GLOBAL_CONFIG_PATH = path.join(
|
|
6103
|
+
os.homedir(),
|
|
6104
|
+
".shelby",
|
|
6105
|
+
"global-config.yaml"
|
|
5595
6106
|
);
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
symbol: "APT",
|
|
5600
|
-
asset: APTOS_COIN,
|
|
5601
|
-
decimals: DEFAULT_DECIMALS
|
|
5602
|
-
},
|
|
5603
|
-
{
|
|
5604
|
-
symbol: SHELBYUSD_TOKEN_NAME,
|
|
5605
|
-
asset: SHELBYUSD_FA_METADATA_ADDRESS,
|
|
5606
|
-
fallbackDecimals: DEFAULT_DECIMALS
|
|
6107
|
+
function loadGlobalConfig() {
|
|
6108
|
+
if (!fs.existsSync(GLOBAL_CONFIG_PATH)) {
|
|
6109
|
+
return DEFAULT_GLOBAL_CONFIG;
|
|
5607
6110
|
}
|
|
5608
|
-
|
|
6111
|
+
const raw = fs.readFileSync(GLOBAL_CONFIG_PATH, "utf8");
|
|
6112
|
+
let parsed;
|
|
6113
|
+
try {
|
|
6114
|
+
parsed = YAML.parse(raw);
|
|
6115
|
+
} catch {
|
|
6116
|
+
throw new Error("Invalid global config file");
|
|
6117
|
+
}
|
|
6118
|
+
try {
|
|
6119
|
+
return GlobalConfigSchema.parse(parsed);
|
|
6120
|
+
} catch (err) {
|
|
6121
|
+
throw new Error(
|
|
6122
|
+
`Invalid global config file at ${GLOBAL_CONFIG_PATH}: ${err.message}`
|
|
6123
|
+
);
|
|
6124
|
+
}
|
|
6125
|
+
}
|
|
6126
|
+
function saveGlobalConfig(config) {
|
|
6127
|
+
fs.mkdirpSync(path.dirname(GLOBAL_CONFIG_PATH));
|
|
6128
|
+
GlobalConfigSchema.parse(config);
|
|
6129
|
+
fs.writeFileSync(GLOBAL_CONFIG_PATH, YAML.stringify(config), "utf8");
|
|
6130
|
+
}
|
|
5609
6131
|
|
|
5610
6132
|
// src/utils/config.ts
|
|
5611
|
-
var ContextSchema =
|
|
5612
|
-
api_key:
|
|
6133
|
+
var ContextSchema = z7.object({
|
|
6134
|
+
api_key: z7.string().optional(),
|
|
5613
6135
|
aptos_network: AptosNetworkSchema,
|
|
5614
6136
|
shelby_network: ShelbyNetworkSchema.optional()
|
|
5615
6137
|
});
|
|
5616
|
-
var AccountNameSchema =
|
|
6138
|
+
var AccountNameSchema = z7.string().min(1, "Account name cannot be empty").regex(
|
|
5617
6139
|
/^[a-zA-Z0-9_-]+$/,
|
|
5618
6140
|
"Account name must contain only alphanumeric characters, underscores, and hyphens"
|
|
5619
6141
|
);
|
|
5620
|
-
var ConfigSchema =
|
|
5621
|
-
contexts:
|
|
5622
|
-
accounts:
|
|
6142
|
+
var ConfigSchema = z7.object({
|
|
6143
|
+
contexts: z7.record(ContextSchema),
|
|
6144
|
+
accounts: z7.record(
|
|
5623
6145
|
AccountNameSchema,
|
|
5624
|
-
|
|
5625
|
-
address:
|
|
5626
|
-
private_key:
|
|
6146
|
+
z7.object({
|
|
6147
|
+
address: z7.string().optional(),
|
|
6148
|
+
private_key: z7.string({ message: "private_key must be provided" })
|
|
5627
6149
|
})
|
|
5628
6150
|
),
|
|
5629
|
-
default_context:
|
|
6151
|
+
default_context: z7.string(),
|
|
5630
6152
|
// Can be empty string if no account is set up
|
|
5631
|
-
default_account:
|
|
6153
|
+
default_account: z7.string()
|
|
5632
6154
|
});
|
|
6155
|
+
function getPathForNewConfig() {
|
|
6156
|
+
const globalConfig = loadGlobalConfig();
|
|
6157
|
+
if (globalConfig.config_location_behavior === "global") {
|
|
6158
|
+
return path2.join(os2.homedir(), ".shelby", "config.yaml");
|
|
6159
|
+
}
|
|
6160
|
+
return path2.join(process.cwd(), ".shelby", "config.yaml");
|
|
6161
|
+
}
|
|
6162
|
+
function loadConfigOrExit(configFile) {
|
|
6163
|
+
let configPath;
|
|
6164
|
+
try {
|
|
6165
|
+
configPath = resolveConfigPath(configFile ?? findExistingConfigPath());
|
|
6166
|
+
if (!fs2.existsSync(configPath)) {
|
|
6167
|
+
console.error("\u274C No configuration file found");
|
|
6168
|
+
console.error(
|
|
6169
|
+
" Please run `shelby init` to create a configuration file."
|
|
6170
|
+
);
|
|
6171
|
+
process.exit(1);
|
|
6172
|
+
}
|
|
6173
|
+
return { configPath, config: loadConfig(configPath) };
|
|
6174
|
+
} catch (err) {
|
|
6175
|
+
console.error("\u274C Failed to load configuration file");
|
|
6176
|
+
if (configPath !== void 0) {
|
|
6177
|
+
console.error(` Path: ${configPath}`);
|
|
6178
|
+
}
|
|
6179
|
+
console.error("");
|
|
6180
|
+
console.error(
|
|
6181
|
+
` Error: ${err instanceof Error ? err.message : String(err)}`
|
|
6182
|
+
);
|
|
6183
|
+
console.error("");
|
|
6184
|
+
console.error(
|
|
6185
|
+
" Please fix the configuration file or run `shelby init` to recreate it."
|
|
6186
|
+
);
|
|
6187
|
+
process.exit(1);
|
|
6188
|
+
}
|
|
6189
|
+
}
|
|
6190
|
+
function findExistingConfigPath() {
|
|
6191
|
+
const globalConfig = loadGlobalConfig();
|
|
6192
|
+
const homeConfig = path2.join(os2.homedir(), ".shelby", "config.yaml");
|
|
6193
|
+
if (globalConfig.config_location_behavior === "global") {
|
|
6194
|
+
return homeConfig;
|
|
6195
|
+
}
|
|
6196
|
+
const foundPath = walkConfigPath(process.cwd());
|
|
6197
|
+
if (foundPath) {
|
|
6198
|
+
const homeDir = os2.homedir();
|
|
6199
|
+
const displayPath = foundPath.startsWith(homeDir) ? foundPath.replace(homeDir, "~") : path2.relative(process.cwd(), foundPath);
|
|
6200
|
+
console.log(`\u{1F4C1} Using config found by walking up to ${displayPath}`);
|
|
6201
|
+
return foundPath;
|
|
6202
|
+
}
|
|
6203
|
+
console.log(
|
|
6204
|
+
`\u{1F4C1} Could not find config by walking up. Using config file at ${homeConfig.replace(os2.homedir(), "~")}`
|
|
6205
|
+
);
|
|
6206
|
+
return homeConfig;
|
|
6207
|
+
}
|
|
6208
|
+
function walkConfigPath(startDir) {
|
|
6209
|
+
let currentDir = path2.resolve(startDir);
|
|
6210
|
+
while (true) {
|
|
6211
|
+
const candidate = path2.join(currentDir, ".shelby", "config.yaml");
|
|
6212
|
+
if (fs2.existsSync(candidate)) {
|
|
6213
|
+
return candidate;
|
|
6214
|
+
}
|
|
6215
|
+
const parent = path2.dirname(currentDir);
|
|
6216
|
+
if (parent === currentDir) {
|
|
6217
|
+
return null;
|
|
6218
|
+
}
|
|
6219
|
+
currentDir = parent;
|
|
6220
|
+
}
|
|
6221
|
+
}
|
|
5633
6222
|
function resolveConfigPath(configPath) {
|
|
5634
6223
|
if (configPath.startsWith("~")) {
|
|
5635
|
-
return
|
|
6224
|
+
return path2.join(os2.homedir(), configPath.slice(1));
|
|
5636
6225
|
}
|
|
5637
6226
|
return configPath;
|
|
5638
6227
|
}
|
|
5639
|
-
function
|
|
5640
|
-
const resolvedPath = resolveConfigPath(configPath);
|
|
5641
|
-
return fs.existsSync(resolvedPath);
|
|
5642
|
-
}
|
|
5643
|
-
function loadConfig(configPath = DEFAULT_CONFIG_PATH) {
|
|
6228
|
+
function loadConfig(configPath) {
|
|
5644
6229
|
const resolvedPath = resolveConfigPath(configPath);
|
|
5645
|
-
const
|
|
5646
|
-
if (!fs.existsSync(resolvedPath)) {
|
|
5647
|
-
fs.mkdirpSync(dir);
|
|
5648
|
-
const yamlText = YAML.stringify(DEFAULT_CONFIG);
|
|
5649
|
-
fs.writeFileSync(resolvedPath, yamlText, "utf8");
|
|
5650
|
-
return DEFAULT_CONFIG;
|
|
5651
|
-
}
|
|
5652
|
-
const raw = fs.readFileSync(resolvedPath, "utf8");
|
|
6230
|
+
const raw = fs2.readFileSync(resolvedPath, "utf8");
|
|
5653
6231
|
let parsed;
|
|
5654
6232
|
try {
|
|
5655
|
-
parsed =
|
|
6233
|
+
parsed = YAML2.parse(raw);
|
|
5656
6234
|
} catch {
|
|
5657
6235
|
throw new Error("Invalid config file");
|
|
5658
6236
|
}
|
|
@@ -5662,11 +6240,11 @@ function loadConfig(configPath = DEFAULT_CONFIG_PATH) {
|
|
|
5662
6240
|
throw new Error(`Invalid config file: ${err.message}`);
|
|
5663
6241
|
}
|
|
5664
6242
|
}
|
|
5665
|
-
function saveConfig(config, configPath
|
|
6243
|
+
function saveConfig(config, configPath) {
|
|
5666
6244
|
const resolvedPath = resolveConfigPath(configPath);
|
|
5667
|
-
|
|
6245
|
+
fs2.mkdirpSync(path2.dirname(resolvedPath));
|
|
5668
6246
|
ConfigSchema.parse(config);
|
|
5669
|
-
|
|
6247
|
+
fs2.writeFileSync(resolvedPath, YAML2.stringify(config), "utf8");
|
|
5670
6248
|
}
|
|
5671
6249
|
function getCurrentContext(config, contextName) {
|
|
5672
6250
|
const name2 = contextName || config.default_context;
|
|
@@ -5683,11 +6261,15 @@ function getCurrentContext(config, contextName) {
|
|
|
5683
6261
|
function getCurrentAccount(config, accountName) {
|
|
5684
6262
|
const name2 = accountName || config.default_account;
|
|
5685
6263
|
if (!name2) {
|
|
5686
|
-
throw new Error(
|
|
6264
|
+
throw new Error(
|
|
6265
|
+
`Account with name '${name2}' not found in config. Set --account to a valid account name.`
|
|
6266
|
+
);
|
|
5687
6267
|
}
|
|
5688
6268
|
const account = config.accounts[name2];
|
|
5689
6269
|
if (!account) {
|
|
5690
|
-
throw new Error(
|
|
6270
|
+
throw new Error(
|
|
6271
|
+
`Account '${name2}' not found in config. Set --account to a valid account name.`
|
|
6272
|
+
);
|
|
5691
6273
|
}
|
|
5692
6274
|
let privateKey;
|
|
5693
6275
|
if (account.private_key) {
|
|
@@ -5737,7 +6319,7 @@ function getCurrentShelbyConfig(config, opts = { context: config.default_context
|
|
|
5737
6319
|
const selectedContext = config.contexts[context ?? config.default_context];
|
|
5738
6320
|
if (!selectedContext) {
|
|
5739
6321
|
throw new Error(
|
|
5740
|
-
`Context '${context ?? config.default_context}' not found in config
|
|
6322
|
+
`Context '${context ?? config.default_context}' not found in config. Set --context to a valid context name.`
|
|
5741
6323
|
);
|
|
5742
6324
|
}
|
|
5743
6325
|
const shelby = getShelbyConfigFromContext(selectedContext);
|
|
@@ -5764,7 +6346,7 @@ import {
|
|
|
5764
6346
|
Secp256k1PrivateKey,
|
|
5765
6347
|
SigningSchemeInput
|
|
5766
6348
|
} from "@aptos-labs/ts-sdk";
|
|
5767
|
-
import { z as
|
|
6349
|
+
import { z as z8 } from "zod";
|
|
5768
6350
|
function generateEd25519Account() {
|
|
5769
6351
|
const account = Account.generate({
|
|
5770
6352
|
scheme: SigningSchemeInput.Ed25519,
|
|
@@ -5784,7 +6366,7 @@ function isValidAddress(address) {
|
|
|
5784
6366
|
return AccountAddress6.isValid({ input: address }).valid;
|
|
5785
6367
|
}
|
|
5786
6368
|
var ED25519_NAME = "ed25519";
|
|
5787
|
-
var SignatureSchemeSchema =
|
|
6369
|
+
var SignatureSchemeSchema = z8.enum([ED25519_NAME]);
|
|
5788
6370
|
|
|
5789
6371
|
// src/components/AccountWizard.tsx
|
|
5790
6372
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -5926,11 +6508,11 @@ import { useEffect as useEffect3, useState as useState4 } from "react";
|
|
|
5926
6508
|
|
|
5927
6509
|
// src/components/ContextReviewWizard.tsx
|
|
5928
6510
|
import {
|
|
5929
|
-
NetworkToFaucetAPI
|
|
5930
|
-
NetworkToIndexerAPI
|
|
5931
|
-
NetworkToNodeAPI
|
|
5932
|
-
NetworkToPepperAPI
|
|
5933
|
-
NetworkToProverAPI
|
|
6511
|
+
NetworkToFaucetAPI,
|
|
6512
|
+
NetworkToIndexerAPI,
|
|
6513
|
+
NetworkToNodeAPI,
|
|
6514
|
+
NetworkToPepperAPI,
|
|
6515
|
+
NetworkToProverAPI
|
|
5934
6516
|
} from "@aptos-labs/ts-sdk";
|
|
5935
6517
|
import { Box as Box4, Text as Text4 } from "ink";
|
|
5936
6518
|
import SelectInput2 from "ink-select-input";
|
|
@@ -6012,7 +6594,7 @@ var SHELBY_CONFIG_FIELDS = [
|
|
|
6012
6594
|
import { Box as Box3, Text as Text3 } from "ink";
|
|
6013
6595
|
import TextInput2 from "ink-text-input";
|
|
6014
6596
|
import { useState as useState2 } from "react";
|
|
6015
|
-
import
|
|
6597
|
+
import z9 from "zod";
|
|
6016
6598
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
6017
6599
|
function FormTextInput({
|
|
6018
6600
|
type,
|
|
@@ -6042,7 +6624,7 @@ function FormTextInput({
|
|
|
6042
6624
|
return;
|
|
6043
6625
|
}
|
|
6044
6626
|
if (value2) {
|
|
6045
|
-
if (type === "url" && !
|
|
6627
|
+
if (type === "url" && !z9.string().url().safeParse(value2).success) {
|
|
6046
6628
|
setError("The field must be a valid URL");
|
|
6047
6629
|
return;
|
|
6048
6630
|
}
|
|
@@ -6103,11 +6685,11 @@ var ContextReviewWizard = ({
|
|
|
6103
6685
|
return void 0;
|
|
6104
6686
|
}
|
|
6105
6687
|
const fallbackValue = {
|
|
6106
|
-
fullnode:
|
|
6107
|
-
indexer:
|
|
6108
|
-
faucet:
|
|
6109
|
-
pepper:
|
|
6110
|
-
prover:
|
|
6688
|
+
fullnode: NetworkToNodeAPI[aptosNetwork.name],
|
|
6689
|
+
indexer: NetworkToIndexerAPI[aptosNetwork.name],
|
|
6690
|
+
faucet: NetworkToFaucetAPI[aptosNetwork.name],
|
|
6691
|
+
pepper: NetworkToPepperAPI[aptosNetwork.name],
|
|
6692
|
+
prover: NetworkToProverAPI[aptosNetwork.name]
|
|
6111
6693
|
}[key];
|
|
6112
6694
|
return fallbackValue ? { value: fallbackValue, source: "default" } : void 0;
|
|
6113
6695
|
};
|
|
@@ -6442,6 +7024,66 @@ import {
|
|
|
6442
7024
|
AccountAddress as AccountAddress7,
|
|
6443
7025
|
AptosApiError
|
|
6444
7026
|
} from "@aptos-labs/ts-sdk";
|
|
7027
|
+
|
|
7028
|
+
// src/utils/constants.ts
|
|
7029
|
+
import { APTOS_COIN, Network as Network7 } from "@aptos-labs/ts-sdk";
|
|
7030
|
+
|
|
7031
|
+
// src/utils/context-helpers.ts
|
|
7032
|
+
import {
|
|
7033
|
+
NetworkToFaucetAPI as NetworkToFaucetAPI2,
|
|
7034
|
+
NetworkToIndexerAPI as NetworkToIndexerAPI2,
|
|
7035
|
+
NetworkToNodeAPI as NetworkToNodeAPI2,
|
|
7036
|
+
NetworkToPepperAPI as NetworkToPepperAPI2,
|
|
7037
|
+
NetworkToProverAPI as NetworkToProverAPI2
|
|
7038
|
+
} from "@aptos-labs/ts-sdk";
|
|
7039
|
+
function createContextForNetwork(network) {
|
|
7040
|
+
return {
|
|
7041
|
+
aptos_network: {
|
|
7042
|
+
name: network,
|
|
7043
|
+
fullnode: NetworkToNodeAPI2[network],
|
|
7044
|
+
faucet: NetworkToFaucetAPI2[network],
|
|
7045
|
+
indexer: NetworkToIndexerAPI2[network],
|
|
7046
|
+
pepper: NetworkToPepperAPI2[network],
|
|
7047
|
+
prover: NetworkToProverAPI2[network]
|
|
7048
|
+
},
|
|
7049
|
+
shelby_network: {
|
|
7050
|
+
rpc_endpoint: NetworkToShelbyRPCBaseUrl[network]
|
|
7051
|
+
}
|
|
7052
|
+
};
|
|
7053
|
+
}
|
|
7054
|
+
|
|
7055
|
+
// src/utils/constants.ts
|
|
7056
|
+
var DEFAULT_CONFIG = {
|
|
7057
|
+
contexts: {
|
|
7058
|
+
[Network7.LOCAL]: {
|
|
7059
|
+
...createContextForNetwork(Network7.LOCAL),
|
|
7060
|
+
// Override shelby_network for local
|
|
7061
|
+
shelby_network: { rpc_endpoint: "http://localhost:9090/" }
|
|
7062
|
+
},
|
|
7063
|
+
[Network7.SHELBYNET]: createContextForNetwork(Network7.SHELBYNET)
|
|
7064
|
+
},
|
|
7065
|
+
accounts: {},
|
|
7066
|
+
default_context: Network7.SHELBYNET,
|
|
7067
|
+
default_account: ""
|
|
7068
|
+
};
|
|
7069
|
+
var STANDARD_CONTEXT_NAMES = Object.keys(DEFAULT_CONFIG.contexts).join(
|
|
7070
|
+
", "
|
|
7071
|
+
);
|
|
7072
|
+
var DEFAULT_DECIMALS = 8;
|
|
7073
|
+
var BALANCE_TARGETS = [
|
|
7074
|
+
{
|
|
7075
|
+
symbol: "APT",
|
|
7076
|
+
asset: APTOS_COIN,
|
|
7077
|
+
decimals: DEFAULT_DECIMALS
|
|
7078
|
+
},
|
|
7079
|
+
{
|
|
7080
|
+
symbol: SHELBYUSD_TOKEN_NAME,
|
|
7081
|
+
asset: SHELBYUSD_FA_METADATA_ADDRESS,
|
|
7082
|
+
fallbackDecimals: DEFAULT_DECIMALS
|
|
7083
|
+
}
|
|
7084
|
+
];
|
|
7085
|
+
|
|
7086
|
+
// src/utils/balance.ts
|
|
6445
7087
|
var InvalidAccountAddressError = class extends Error {
|
|
6446
7088
|
constructor(address) {
|
|
6447
7089
|
super(
|
|
@@ -6599,8 +7241,8 @@ function assetTypeToString(asset) {
|
|
|
6599
7241
|
}
|
|
6600
7242
|
|
|
6601
7243
|
// src/utils/cache.ts
|
|
6602
|
-
import
|
|
6603
|
-
import
|
|
7244
|
+
import path3 from "path";
|
|
7245
|
+
import fs3 from "fs-extra";
|
|
6604
7246
|
var Cache = class {
|
|
6605
7247
|
cachePath;
|
|
6606
7248
|
schema;
|
|
@@ -6614,10 +7256,10 @@ var Cache = class {
|
|
|
6614
7256
|
*/
|
|
6615
7257
|
read() {
|
|
6616
7258
|
try {
|
|
6617
|
-
if (!
|
|
7259
|
+
if (!fs3.existsSync(this.cachePath)) {
|
|
6618
7260
|
return null;
|
|
6619
7261
|
}
|
|
6620
|
-
const data =
|
|
7262
|
+
const data = fs3.readFileSync(this.cachePath, "utf-8");
|
|
6621
7263
|
const parsed = JSON.parse(data);
|
|
6622
7264
|
const result = this.schema.safeParse(parsed);
|
|
6623
7265
|
if (!result.success) {
|
|
@@ -6635,9 +7277,9 @@ var Cache = class {
|
|
|
6635
7277
|
write(data) {
|
|
6636
7278
|
try {
|
|
6637
7279
|
const validated = this.schema.parse(data);
|
|
6638
|
-
const cacheDir =
|
|
6639
|
-
|
|
6640
|
-
|
|
7280
|
+
const cacheDir = path3.dirname(this.cachePath);
|
|
7281
|
+
fs3.mkdirpSync(cacheDir);
|
|
7282
|
+
fs3.writeFileSync(
|
|
6641
7283
|
this.cachePath,
|
|
6642
7284
|
JSON.stringify(validated, null, 2),
|
|
6643
7285
|
"utf-8"
|
|
@@ -6652,8 +7294,8 @@ var Cache = class {
|
|
|
6652
7294
|
*/
|
|
6653
7295
|
clear() {
|
|
6654
7296
|
try {
|
|
6655
|
-
if (
|
|
6656
|
-
|
|
7297
|
+
if (fs3.existsSync(this.cachePath)) {
|
|
7298
|
+
fs3.unlinkSync(this.cachePath);
|
|
6657
7299
|
}
|
|
6658
7300
|
return true;
|
|
6659
7301
|
} catch {
|
|
@@ -6664,7 +7306,7 @@ var Cache = class {
|
|
|
6664
7306
|
* Check if cache exists
|
|
6665
7307
|
*/
|
|
6666
7308
|
exists() {
|
|
6667
|
-
return
|
|
7309
|
+
return fs3.existsSync(this.cachePath);
|
|
6668
7310
|
}
|
|
6669
7311
|
/**
|
|
6670
7312
|
* Get the resolved cache file path
|
|
@@ -6679,13 +7321,13 @@ import boxen from "boxen";
|
|
|
6679
7321
|
import chalk from "chalk";
|
|
6680
7322
|
import { getLatestVersion } from "fast-npm-meta";
|
|
6681
7323
|
import * as semver from "semver";
|
|
6682
|
-
import { z as
|
|
7324
|
+
import { z as z10 } from "zod";
|
|
6683
7325
|
var CHECK_INTERVAL = 1e3 * 60 * 60 * 24;
|
|
6684
7326
|
var NOTIFY_INTERVAL = CHECK_INTERVAL;
|
|
6685
|
-
var VersionCacheSchema =
|
|
6686
|
-
lastChecked:
|
|
6687
|
-
latestVersion:
|
|
6688
|
-
lastNotified:
|
|
7327
|
+
var VersionCacheSchema = z10.object({
|
|
7328
|
+
lastChecked: z10.number(),
|
|
7329
|
+
latestVersion: z10.string(),
|
|
7330
|
+
lastNotified: z10.number().optional()
|
|
6689
7331
|
});
|
|
6690
7332
|
var versionCache = new Cache("version-check.json", VersionCacheSchema);
|
|
6691
7333
|
async function fetchLatestVersion() {
|
|
@@ -6760,9 +7402,9 @@ function getErasureCodingProvider() {
|
|
|
6760
7402
|
}
|
|
6761
7403
|
|
|
6762
7404
|
// src/utils/paths.ts
|
|
6763
|
-
import
|
|
7405
|
+
import path4 from "path";
|
|
6764
7406
|
function endsWithDirectorySeparator(filePath) {
|
|
6765
|
-
return filePath.endsWith("/") || filePath.endsWith("\\") || filePath.endsWith(
|
|
7407
|
+
return filePath.endsWith("/") || filePath.endsWith("\\") || filePath.endsWith(path4.sep);
|
|
6766
7408
|
}
|
|
6767
7409
|
function normBlobName(pathModule, inputDirectoryName, filename, blobPrefix) {
|
|
6768
7410
|
const blobNameWithoutInputDir = pathModule.relative(
|
|
@@ -6775,7 +7417,7 @@ function normBlobName(pathModule, inputDirectoryName, filename, blobPrefix) {
|
|
|
6775
7417
|
);
|
|
6776
7418
|
const blobNameNormalized = pathModule.normalize(blobNameWithPrefix);
|
|
6777
7419
|
const parts = blobNameNormalized.split(pathModule.sep);
|
|
6778
|
-
return
|
|
7420
|
+
return path4.posix.join(...parts);
|
|
6779
7421
|
}
|
|
6780
7422
|
function denormBlobName(pathModule, blobPrefix, blobName, outputPrefix) {
|
|
6781
7423
|
if (!pathModule.isAbsolute(outputPrefix)) {
|
|
@@ -7040,8 +7682,8 @@ function getAptosCliVersionInfo(minVersion = MIN_APTOS_CLI_VERSION) {
|
|
|
7040
7682
|
// src/components/InitWizard.tsx
|
|
7041
7683
|
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
7042
7684
|
var InitWizard = ({
|
|
7043
|
-
existingConfig,
|
|
7044
7685
|
configPath,
|
|
7686
|
+
existingConfig,
|
|
7045
7687
|
onComplete,
|
|
7046
7688
|
onCancel
|
|
7047
7689
|
}) => {
|
|
@@ -7128,7 +7770,7 @@ var InitWizard = ({
|
|
|
7128
7770
|
] }),
|
|
7129
7771
|
/* @__PURE__ */ jsxs6(Text6, { color: "cyan", children: [
|
|
7130
7772
|
" ",
|
|
7131
|
-
configPath
|
|
7773
|
+
configPath
|
|
7132
7774
|
] }),
|
|
7133
7775
|
/* @__PURE__ */ jsxs6(Text6, { color: "red", children: [
|
|
7134
7776
|
"\n",
|
|
@@ -7515,10 +8157,10 @@ var handleError = (error) => {
|
|
|
7515
8157
|
|
|
7516
8158
|
// src/commands/account.tsx
|
|
7517
8159
|
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
7518
|
-
var CreateAccountOptionsSchema =
|
|
7519
|
-
name:
|
|
7520
|
-
privateKey:
|
|
7521
|
-
address:
|
|
8160
|
+
var CreateAccountOptionsSchema = z11.object({
|
|
8161
|
+
name: z11.string().optional(),
|
|
8162
|
+
privateKey: z11.string().optional(),
|
|
8163
|
+
address: z11.string().optional(),
|
|
7522
8164
|
scheme: SignatureSchemeSchema.optional()
|
|
7523
8165
|
});
|
|
7524
8166
|
var allSchemes = SignatureSchemeSchema.options.join(", ");
|
|
@@ -7545,33 +8187,29 @@ async function promptForAccountName(config) {
|
|
|
7545
8187
|
return answer;
|
|
7546
8188
|
}
|
|
7547
8189
|
}
|
|
7548
|
-
var ListAccountOptionsSchema =
|
|
7549
|
-
var UseAccountOptionsSchema =
|
|
7550
|
-
accountName:
|
|
8190
|
+
var ListAccountOptionsSchema = z11.object({});
|
|
8191
|
+
var UseAccountOptionsSchema = z11.object({
|
|
8192
|
+
accountName: z11.string()
|
|
7551
8193
|
});
|
|
7552
|
-
var DeleteAccountOptionsSchema =
|
|
7553
|
-
accountName:
|
|
8194
|
+
var DeleteAccountOptionsSchema = z11.object({
|
|
8195
|
+
accountName: z11.string()
|
|
7554
8196
|
});
|
|
7555
8197
|
function accountCommand(program) {
|
|
7556
8198
|
const account = program.command("account").description("Manage signing accounts (addresses & keys)");
|
|
7557
|
-
account.command("create").description("Create a new account").option("--name <account-name>", "Name of the account").
|
|
7558
|
-
|
|
7559
|
-
|
|
8199
|
+
account.command("create").description("Create a new account").option("--name <account-name>", "Name of the account").addOption(
|
|
8200
|
+
new Option(
|
|
8201
|
+
"--scheme <signature-scheme>",
|
|
8202
|
+
"Signature scheme of the private key"
|
|
8203
|
+
).choices(Object.values(SignatureSchemeSchema.Enum))
|
|
7560
8204
|
).option("--private-key <key>", "Raw private key").option(
|
|
7561
8205
|
"--address <account-address>",
|
|
7562
8206
|
"Aptos account address (hex-encoded)"
|
|
7563
8207
|
).action(async (options) => {
|
|
7564
8208
|
CreateAccountOptionsSchema.parse(options);
|
|
7565
8209
|
const { name: name2, privateKey, address, scheme } = options;
|
|
7566
|
-
const configPath =
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
config = loadConfig(configPath);
|
|
7570
|
-
} catch (err) {
|
|
7571
|
-
throw new Error(
|
|
7572
|
-
`${err.message}. Please ensure you've first initialized the config by doing \`shelby init\``
|
|
7573
|
-
);
|
|
7574
|
-
}
|
|
8210
|
+
const { config, configPath } = loadConfigOrExit(
|
|
8211
|
+
program.opts().configFile
|
|
8212
|
+
);
|
|
7575
8213
|
const targetName = options.name ?? null;
|
|
7576
8214
|
if (privateKey && !scheme) {
|
|
7577
8215
|
console.error(
|
|
@@ -7579,7 +8217,9 @@ function accountCommand(program) {
|
|
|
7579
8217
|
);
|
|
7580
8218
|
process.exit(1);
|
|
7581
8219
|
}
|
|
7582
|
-
if (scheme && !SignatureSchemeSchema.
|
|
8220
|
+
if (scheme && !Object.values(SignatureSchemeSchema.Enum).includes(
|
|
8221
|
+
scheme
|
|
8222
|
+
)) {
|
|
7583
8223
|
console.error(
|
|
7584
8224
|
`\u274C Unsupported signature scheme. Only "${allSchemes}" is supported.`
|
|
7585
8225
|
);
|
|
@@ -7647,14 +8287,7 @@ function accountCommand(program) {
|
|
|
7647
8287
|
}
|
|
7648
8288
|
});
|
|
7649
8289
|
account.command("list").description("List all accounts in a table view").action(() => {
|
|
7650
|
-
const
|
|
7651
|
-
let config;
|
|
7652
|
-
try {
|
|
7653
|
-
config = loadConfig(configPath);
|
|
7654
|
-
} catch (err) {
|
|
7655
|
-
console.error(`Error listing accounts: ${err.message}`);
|
|
7656
|
-
process.exit(1);
|
|
7657
|
-
}
|
|
8290
|
+
const { config } = loadConfigOrExit(program.opts().configFile);
|
|
7658
8291
|
const accounts = Object.entries(config.accounts);
|
|
7659
8292
|
if (accounts.length === 0) {
|
|
7660
8293
|
console.log("No accounts found.");
|
|
@@ -7680,9 +8313,10 @@ function accountCommand(program) {
|
|
|
7680
8313
|
console.log(table.toString());
|
|
7681
8314
|
});
|
|
7682
8315
|
account.command("use").description("Set the default account").argument("<account-name>", "Name of the account to use").action((accountName) => {
|
|
7683
|
-
const configPath = program.opts().configFile;
|
|
7684
8316
|
try {
|
|
7685
|
-
const config =
|
|
8317
|
+
const { config, configPath } = loadConfigOrExit(
|
|
8318
|
+
program.opts().configFile
|
|
8319
|
+
);
|
|
7686
8320
|
if (!config.accounts[accountName]) {
|
|
7687
8321
|
console.error(`Error: Account '${accountName}' not found`);
|
|
7688
8322
|
process.exit(1);
|
|
@@ -7696,9 +8330,10 @@ function accountCommand(program) {
|
|
|
7696
8330
|
}
|
|
7697
8331
|
});
|
|
7698
8332
|
account.command("delete").description("Delete an account").argument("<account-name>", "Name of the account to delete").action((accountName) => {
|
|
7699
|
-
const configPath = program.opts().configFile;
|
|
7700
8333
|
try {
|
|
7701
|
-
const config =
|
|
8334
|
+
const { config, configPath } = loadConfigOrExit(
|
|
8335
|
+
program.opts().configFile
|
|
8336
|
+
);
|
|
7702
8337
|
if (!config.accounts[accountName]) {
|
|
7703
8338
|
console.error(`Error: Account '${accountName}' not found`);
|
|
7704
8339
|
process.exit(1);
|
|
@@ -7724,8 +8359,7 @@ function accountCommand(program) {
|
|
|
7724
8359
|
"-a, --account <account-name>",
|
|
7725
8360
|
"Name of the account to list blobs for"
|
|
7726
8361
|
).action(async () => {
|
|
7727
|
-
const
|
|
7728
|
-
const config = loadConfig(configPath);
|
|
8362
|
+
const { config } = loadConfigOrExit(program.opts().configFile);
|
|
7729
8363
|
try {
|
|
7730
8364
|
const accountName = program.opts().account || config.default_account;
|
|
7731
8365
|
const shelbyConfig = getCurrentShelbyConfig(config, {
|
|
@@ -7804,8 +8438,7 @@ function accountCommand(program) {
|
|
|
7804
8438
|
try {
|
|
7805
8439
|
const globalOpts = program.opts();
|
|
7806
8440
|
verbose = Boolean(globalOpts.verbose);
|
|
7807
|
-
const
|
|
7808
|
-
const config = loadConfig(configPath);
|
|
8441
|
+
const { config } = loadConfigOrExit(globalOpts.configFile);
|
|
7809
8442
|
const contextName = globalOpts.context || config.default_context;
|
|
7810
8443
|
const context = getCurrentContext(config, contextName);
|
|
7811
8444
|
const aptos = getAptosFromContext(context);
|
|
@@ -7915,21 +8548,21 @@ function accountCommand(program) {
|
|
|
7915
8548
|
}
|
|
7916
8549
|
|
|
7917
8550
|
// src/commands/commitment.ts
|
|
7918
|
-
import * as
|
|
8551
|
+
import * as fs4 from "fs";
|
|
7919
8552
|
import * as fsP from "fs/promises";
|
|
7920
8553
|
import { Readable } from "stream";
|
|
7921
|
-
import { z as
|
|
7922
|
-
var CommitmentOptionsSchema =
|
|
7923
|
-
input:
|
|
7924
|
-
async (
|
|
7925
|
-
const stat4 = await fsP.stat(
|
|
8554
|
+
import { z as z12 } from "zod";
|
|
8555
|
+
var CommitmentOptionsSchema = z12.object({
|
|
8556
|
+
input: z12.string().nonempty("`--input` is required").refine(
|
|
8557
|
+
async (path10) => {
|
|
8558
|
+
const stat4 = await fsP.stat(path10);
|
|
7926
8559
|
return stat4.isFile();
|
|
7927
8560
|
},
|
|
7928
8561
|
{
|
|
7929
8562
|
message: "`--input` must be a file"
|
|
7930
8563
|
}
|
|
7931
8564
|
),
|
|
7932
|
-
output:
|
|
8565
|
+
output: z12.string().nonempty("`--output` is required")
|
|
7933
8566
|
});
|
|
7934
8567
|
function commitmentCommand(program) {
|
|
7935
8568
|
program.command("commitment <input> <output>").description(
|
|
@@ -7939,7 +8572,7 @@ function commitmentCommand(program) {
|
|
|
7939
8572
|
input,
|
|
7940
8573
|
output
|
|
7941
8574
|
});
|
|
7942
|
-
const inputFile =
|
|
8575
|
+
const inputFile = fs4.createReadStream(validatedOptions.input);
|
|
7943
8576
|
const provider = await getErasureCodingProvider();
|
|
7944
8577
|
const commitment = await generateCommitments(
|
|
7945
8578
|
provider,
|
|
@@ -7949,31 +8582,110 @@ function commitmentCommand(program) {
|
|
|
7949
8582
|
});
|
|
7950
8583
|
}
|
|
7951
8584
|
|
|
8585
|
+
// src/commands/config.tsx
|
|
8586
|
+
import fs5 from "fs-extra";
|
|
8587
|
+
import YAML3 from "yaml";
|
|
8588
|
+
function configCommand(program) {
|
|
8589
|
+
const config = program.command("config").description("Manage CLI configuration");
|
|
8590
|
+
config.command("set-global-config").description(
|
|
8591
|
+
"Set global configuration, such as where to load the .shelby/config.yaml file from"
|
|
8592
|
+
).requiredOption(
|
|
8593
|
+
"--config-location-behavior <behavior>",
|
|
8594
|
+
"Config location. If set to 'global', the CLI will load the config from ~/.shelby/config.yaml. If set to 'walk', the CLI will try to load the config from .shelby/config.yaml, then its parents, and finally the global ~/.shelby/config.yaml"
|
|
8595
|
+
).action((options) => {
|
|
8596
|
+
const behavior = options.configLocationBehavior;
|
|
8597
|
+
if (behavior !== "global" && behavior !== "walk") {
|
|
8598
|
+
console.error(
|
|
8599
|
+
"\u274C Error: --config-location-behavior must be either 'global' or 'walk'"
|
|
8600
|
+
);
|
|
8601
|
+
process.exit(1);
|
|
8602
|
+
}
|
|
8603
|
+
const globalConfig = {
|
|
8604
|
+
config_location_behavior: behavior
|
|
8605
|
+
};
|
|
8606
|
+
try {
|
|
8607
|
+
saveGlobalConfig(globalConfig);
|
|
8608
|
+
console.log(
|
|
8609
|
+
`\u2705 Global config updated: config_location_behavior = '${behavior}'`
|
|
8610
|
+
);
|
|
8611
|
+
console.log(
|
|
8612
|
+
behavior === "global" ? " The CLI will now load the config from ~/.shelby/config.yaml" : " The CLI will now try to load the config from .shelby/config.yaml, its parents, and finally the global .shelby/config.yaml"
|
|
8613
|
+
);
|
|
8614
|
+
} catch (err) {
|
|
8615
|
+
console.error(
|
|
8616
|
+
`\u274C Error saving global config: ${err instanceof Error ? err.message : String(err)}`
|
|
8617
|
+
);
|
|
8618
|
+
process.exit(1);
|
|
8619
|
+
}
|
|
8620
|
+
});
|
|
8621
|
+
config.command("describe-global-config").description("Describe the current global configuration").action(() => {
|
|
8622
|
+
try {
|
|
8623
|
+
const globalConfig = loadGlobalConfig();
|
|
8624
|
+
console.log("Global config:");
|
|
8625
|
+
console.log(
|
|
8626
|
+
` config_location_behavior: ${globalConfig.config_location_behavior}`
|
|
8627
|
+
);
|
|
8628
|
+
console.log(
|
|
8629
|
+
globalConfig.config_location_behavior === "global" ? " Loading config from: ~/.shelby/config.yaml" : " Loading config from: .shelby/config.yaml, its parents, and finally the global .shelby/config.yaml"
|
|
8630
|
+
);
|
|
8631
|
+
} catch (err) {
|
|
8632
|
+
console.error(
|
|
8633
|
+
`\u274C Error loading global config: ${err instanceof Error ? err.message : String(err)}`
|
|
8634
|
+
);
|
|
8635
|
+
process.exit(1);
|
|
8636
|
+
}
|
|
8637
|
+
});
|
|
8638
|
+
config.command("get-global-config").description("Display the global config file content as YAML").action(() => {
|
|
8639
|
+
try {
|
|
8640
|
+
if (!fs5.existsSync(GLOBAL_CONFIG_PATH)) {
|
|
8641
|
+
console.log("No global config file found.");
|
|
8642
|
+
console.log(`Expected location: ${GLOBAL_CONFIG_PATH}`);
|
|
8643
|
+
return;
|
|
8644
|
+
}
|
|
8645
|
+
const content = fs5.readFileSync(GLOBAL_CONFIG_PATH, "utf8");
|
|
8646
|
+
const parsed = YAML3.parse(content);
|
|
8647
|
+
const prettyYaml = YAML3.stringify(parsed, {
|
|
8648
|
+
indent: 2,
|
|
8649
|
+
lineWidth: 0
|
|
8650
|
+
});
|
|
8651
|
+
console.log(`Global config file: ${GLOBAL_CONFIG_PATH}`);
|
|
8652
|
+
console.log("");
|
|
8653
|
+
console.log(prettyYaml.trim());
|
|
8654
|
+
} catch (err) {
|
|
8655
|
+
console.error(
|
|
8656
|
+
`\u274C Error reading global config file: ${err instanceof Error ? err.message : String(err)}`
|
|
8657
|
+
);
|
|
8658
|
+
console.error(` Path: ${GLOBAL_CONFIG_PATH}`);
|
|
8659
|
+
process.exit(1);
|
|
8660
|
+
}
|
|
8661
|
+
});
|
|
8662
|
+
}
|
|
8663
|
+
|
|
7952
8664
|
// src/commands/context.tsx
|
|
7953
8665
|
import { render as render2 } from "ink";
|
|
7954
|
-
import { z as
|
|
8666
|
+
import { z as z14 } from "zod";
|
|
7955
8667
|
|
|
7956
8668
|
// src/utils/commands.ts
|
|
7957
|
-
import
|
|
7958
|
-
var AptosCommandOptionsSchema =
|
|
7959
|
-
aptosNetwork:
|
|
8669
|
+
import z13 from "zod";
|
|
8670
|
+
var AptosCommandOptionsSchema = z13.object({
|
|
8671
|
+
aptosNetwork: z13.string().optional(),
|
|
7960
8672
|
// predefined network name
|
|
7961
|
-
aptosFullnode:
|
|
7962
|
-
aptosFaucet:
|
|
7963
|
-
aptosIndexer:
|
|
7964
|
-
aptosPepper:
|
|
7965
|
-
aptosProver:
|
|
7966
|
-
aptosApiKey:
|
|
8673
|
+
aptosFullnode: z13.string().url().optional(),
|
|
8674
|
+
aptosFaucet: z13.string().url().optional(),
|
|
8675
|
+
aptosIndexer: z13.string().url().optional(),
|
|
8676
|
+
aptosPepper: z13.string().url().optional(),
|
|
8677
|
+
aptosProver: z13.string().url().optional(),
|
|
8678
|
+
aptosApiKey: z13.string().optional()
|
|
7967
8679
|
});
|
|
7968
8680
|
var addAptosCommandOptions = (context) => context.option(
|
|
7969
8681
|
"--aptos-network <network>",
|
|
7970
8682
|
`Aptos network (${shelbyNetworks.join(", ")})`
|
|
7971
8683
|
).option("--aptos-fullnode <url>", "Aptos fullnode URL").option("--aptos-faucet <url>", "Aptos faucet URL").option("--aptos-indexer <url>", "Aptos indexer URL").option("--aptos-pepper <url>", "Aptos pepper URL").option("--aptos-prover <url>", "Aptos prover URL").option("--aptos-api-key <key>", "Aptos API key");
|
|
7972
|
-
var ShelbyCommandOptionsSchema =
|
|
8684
|
+
var ShelbyCommandOptionsSchema = z13.object({
|
|
7973
8685
|
shelbyRpcEndpoint: EndpointSchema.optional(),
|
|
7974
8686
|
shelbyIndexerEndpoint: EndpointSchema.optional(),
|
|
7975
|
-
shelbyRpcApiKey:
|
|
7976
|
-
shelbyIndexerApiKey:
|
|
8687
|
+
shelbyRpcApiKey: z13.string().optional(),
|
|
8688
|
+
shelbyIndexerApiKey: z13.string().optional()
|
|
7977
8689
|
});
|
|
7978
8690
|
var addShelbyCommandOptions = (context) => context.option("--shelby-rpc-endpoint <url>", "Shelby RPC endpoint").option("--shelby-indexer-endpoint <url>", "Shelby indexer endpoint").option("--shelby-rpc-api-key <key>", "Shelby RPC API key").option("--shelby-indexer-api-key <key>", "Shelby indexer API key");
|
|
7979
8691
|
|
|
@@ -8010,8 +8722,8 @@ function getShelbyNetworkFromOptions(options) {
|
|
|
8010
8722
|
indexer_api_key: options.shelbyIndexerApiKey
|
|
8011
8723
|
};
|
|
8012
8724
|
}
|
|
8013
|
-
var CreateContextOptionsSchema =
|
|
8014
|
-
var UpdateContextOptionsSchema =
|
|
8725
|
+
var CreateContextOptionsSchema = z14.object({ name: z14.string().optional() }).merge(AptosCommandOptionsSchema).merge(ShelbyCommandOptionsSchema);
|
|
8726
|
+
var UpdateContextOptionsSchema = z14.object({}).merge(ShelbyCommandOptionsSchema).merge(AptosCommandOptionsSchema);
|
|
8015
8727
|
function contextCommand(program) {
|
|
8016
8728
|
const context = program.command("context").description("Manage network contexts (Shelby RPC & Aptos endpoints)");
|
|
8017
8729
|
addShelbyCommandOptions(addAptosCommandOptions(context.command("create"))).description("Create a new context").option("--name <context-name>", "Name of the context").action((options) => {
|
|
@@ -8019,7 +8731,9 @@ function contextCommand(program) {
|
|
|
8019
8731
|
const { name: name2 } = options;
|
|
8020
8732
|
const aptosNetwork = getAptosNetworkFromOptions(options);
|
|
8021
8733
|
const shelbyNetwork = getShelbyNetworkFromOptions(options);
|
|
8022
|
-
const configPath =
|
|
8734
|
+
const configPath = resolveConfigPath(
|
|
8735
|
+
program.opts().configFile ?? findExistingConfigPath()
|
|
8736
|
+
);
|
|
8023
8737
|
let config;
|
|
8024
8738
|
try {
|
|
8025
8739
|
config = loadConfig(configPath);
|
|
@@ -8027,8 +8741,8 @@ function contextCommand(program) {
|
|
|
8027
8741
|
config = {
|
|
8028
8742
|
contexts: {},
|
|
8029
8743
|
accounts: {},
|
|
8030
|
-
default_context: name2 ||
|
|
8031
|
-
default_account:
|
|
8744
|
+
default_context: name2 || DEFAULT_CONTEXT,
|
|
8745
|
+
default_account: DEFAULT_ACCOUNT
|
|
8032
8746
|
};
|
|
8033
8747
|
}
|
|
8034
8748
|
const hasShelbyNetworkChanges = Object.values(shelbyNetwork).some(
|
|
@@ -8083,14 +8797,9 @@ function contextCommand(program) {
|
|
|
8083
8797
|
UpdateContextOptionsSchema.parse(options);
|
|
8084
8798
|
const aptosNetwork = getAptosNetworkFromOptions(options);
|
|
8085
8799
|
const shelbyNetwork = getShelbyNetworkFromOptions(options);
|
|
8086
|
-
const configPath =
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
config = loadConfig(configPath);
|
|
8090
|
-
} catch (error) {
|
|
8091
|
-
console.error(`Error loading config: ${error.message}`);
|
|
8092
|
-
process.exit(1);
|
|
8093
|
-
}
|
|
8800
|
+
const { config, configPath } = loadConfigOrExit(
|
|
8801
|
+
program.opts().configFile
|
|
8802
|
+
);
|
|
8094
8803
|
const currentContext = config.contexts[contextName];
|
|
8095
8804
|
if (!currentContext) {
|
|
8096
8805
|
console.error(`Error: Context '${contextName}' not found`);
|
|
@@ -8153,14 +8862,7 @@ function contextCommand(program) {
|
|
|
8153
8862
|
);
|
|
8154
8863
|
});
|
|
8155
8864
|
context.command("list").description("List all contexts in a table").action(() => {
|
|
8156
|
-
const
|
|
8157
|
-
let config;
|
|
8158
|
-
try {
|
|
8159
|
-
config = loadConfig(configPath);
|
|
8160
|
-
} catch (err) {
|
|
8161
|
-
console.error(`Error listing contexts: ${err.message}`);
|
|
8162
|
-
process.exit(1);
|
|
8163
|
-
}
|
|
8865
|
+
const { config } = loadConfigOrExit(program.opts().configFile);
|
|
8164
8866
|
if (Object.keys(config.contexts).length === 0) {
|
|
8165
8867
|
console.log("No contexts found.");
|
|
8166
8868
|
process.exit(0);
|
|
@@ -8237,9 +8939,10 @@ function contextCommand(program) {
|
|
|
8237
8939
|
console.log(shelbyConfigTable.toString());
|
|
8238
8940
|
});
|
|
8239
8941
|
context.command("use").description("Set the default context").argument("<context-name>", "Name of the context to use").action((contextName) => {
|
|
8240
|
-
const configPath =
|
|
8942
|
+
const { config, configPath } = loadConfigOrExit(
|
|
8943
|
+
program.opts().configFile
|
|
8944
|
+
);
|
|
8241
8945
|
try {
|
|
8242
|
-
const config = loadConfig(configPath);
|
|
8243
8946
|
if (!config.contexts[contextName]) {
|
|
8244
8947
|
console.error(`Error: Context '${contextName}' not found`);
|
|
8245
8948
|
process.exit(1);
|
|
@@ -8253,9 +8956,10 @@ function contextCommand(program) {
|
|
|
8253
8956
|
}
|
|
8254
8957
|
});
|
|
8255
8958
|
context.command("delete").description("Delete a context").argument("<context-name>", "Name of the context to delete").action((contextName) => {
|
|
8256
|
-
const configPath =
|
|
8959
|
+
const { config, configPath } = loadConfigOrExit(
|
|
8960
|
+
program.opts().configFile
|
|
8961
|
+
);
|
|
8257
8962
|
try {
|
|
8258
|
-
const config = loadConfig(configPath);
|
|
8259
8963
|
if (!config.contexts[contextName]) {
|
|
8260
8964
|
console.error(`Error: Context '${contextName}' not found`);
|
|
8261
8965
|
process.exit(1);
|
|
@@ -8281,22 +8985,22 @@ function contextCommand(program) {
|
|
|
8281
8985
|
|
|
8282
8986
|
// src/commands/download.tsx
|
|
8283
8987
|
import * as fsS from "fs";
|
|
8284
|
-
import * as
|
|
8285
|
-
import * as
|
|
8988
|
+
import * as fs6 from "fs/promises";
|
|
8989
|
+
import * as path5 from "path";
|
|
8286
8990
|
import { Readable as Readable2, Transform } from "stream";
|
|
8287
8991
|
import { pipeline } from "stream/promises";
|
|
8288
8992
|
import ora from "ora";
|
|
8289
|
-
import { z as
|
|
8290
|
-
var denormBlobName2 = (a, b, c) => denormBlobName(
|
|
8291
|
-
var DownloadOptionsSchema =
|
|
8292
|
-
source:
|
|
8993
|
+
import { z as z15 } from "zod";
|
|
8994
|
+
var denormBlobName2 = (a, b, c) => denormBlobName(path5, a, b, c);
|
|
8995
|
+
var DownloadOptionsSchema = z15.object({
|
|
8996
|
+
source: z15.string({
|
|
8293
8997
|
required_error: "\n\u274C Missing Required Argument\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\u26A0\uFE0F Missing source blob name or prefix (first argument)\n\n\u{1F4A1} Usage:\n shelby download <source-blob-name> <destination-path> [options]\n\n\u{1F4DD} Examples:\n shelby download my-blob.txt ./myfile.txt\n shelby download my-folder/ ./my-folder/ -r\n"
|
|
8294
8998
|
}).min(1, "Source blob name or directory prefix is required").describe("Blob name or directory prefix to download"),
|
|
8295
|
-
destination:
|
|
8999
|
+
destination: z15.string({
|
|
8296
9000
|
required_error: "\n\u274C Missing Required Argument\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\u26A0\uFE0F Missing destination path (second argument)\n\n\u{1F4A1} Usage:\n shelby download <source-blob-name> <destination-path> [options]\n\n\u{1F4DD} Example:\n shelby download my-blob.txt ./myfile.txt\n"
|
|
8297
9001
|
}).min(1, "`destination` must be a valid filepath").describe("Local path where to save the downloaded content"),
|
|
8298
|
-
recursive:
|
|
8299
|
-
force:
|
|
9002
|
+
recursive: z15.boolean().default(false).describe("Download assuming canonical directory layout and recurse"),
|
|
9003
|
+
force: z15.boolean().default(false).describe("Overwrite the destination if it already exists")
|
|
8300
9004
|
}).refine(
|
|
8301
9005
|
(data) => {
|
|
8302
9006
|
if (data.recursive) {
|
|
@@ -8369,9 +9073,9 @@ var DownloadOptionsSchema = z14.object({
|
|
|
8369
9073
|
}
|
|
8370
9074
|
);
|
|
8371
9075
|
async function validateOutput(options) {
|
|
8372
|
-
const parentDir =
|
|
9076
|
+
const parentDir = path5.dirname(options.destination);
|
|
8373
9077
|
try {
|
|
8374
|
-
const parentStats = await
|
|
9078
|
+
const parentStats = await fs6.stat(parentDir);
|
|
8375
9079
|
if (!parentStats.isDirectory()) {
|
|
8376
9080
|
throw new Error(
|
|
8377
9081
|
`Parent path '${parentDir}' exists but is not a directory. Cannot create destination ${options.recursive ? "directory" : "file"} '${options.destination}'.`
|
|
@@ -8388,7 +9092,7 @@ async function validateOutput(options) {
|
|
|
8388
9092
|
if (options.force) return;
|
|
8389
9093
|
let outputStats;
|
|
8390
9094
|
try {
|
|
8391
|
-
outputStats = await
|
|
9095
|
+
outputStats = await fs6.stat(options.destination);
|
|
8392
9096
|
} catch (error) {
|
|
8393
9097
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
8394
9098
|
return;
|
|
@@ -8407,7 +9111,7 @@ async function validateOutput(options) {
|
|
|
8407
9111
|
);
|
|
8408
9112
|
}
|
|
8409
9113
|
if (options.recursive) {
|
|
8410
|
-
const entries = await
|
|
9114
|
+
const entries = await fs6.readdir(options.destination);
|
|
8411
9115
|
if (entries.length > 0) {
|
|
8412
9116
|
throw new Error(
|
|
8413
9117
|
`Directory '${options.destination}' exists and is not empty. Use --force to overwrite or choose an empty directory.`
|
|
@@ -8474,12 +9178,12 @@ async function createFileList(options, nodeClient, account) {
|
|
|
8474
9178
|
async function createOutputDirectories(fileList) {
|
|
8475
9179
|
const uniqueDirectories = /* @__PURE__ */ new Set();
|
|
8476
9180
|
for (const fileEntry of fileList) {
|
|
8477
|
-
const parentDir =
|
|
9181
|
+
const parentDir = path5.dirname(fileEntry.filename);
|
|
8478
9182
|
uniqueDirectories.add(parentDir);
|
|
8479
9183
|
}
|
|
8480
9184
|
for (const dir of uniqueDirectories) {
|
|
8481
9185
|
try {
|
|
8482
|
-
await
|
|
9186
|
+
await fs6.mkdir(dir, { recursive: true });
|
|
8483
9187
|
} catch (error) {
|
|
8484
9188
|
throw new Error(
|
|
8485
9189
|
`Failed to create directory '${dir}': ${error instanceof Error ? error.message : error}`
|
|
@@ -8505,8 +9209,9 @@ function createProgressTransform(totalBytes, reporter) {
|
|
|
8505
9209
|
function downloadCommand(program) {
|
|
8506
9210
|
program.command("download").description("Download a file or directory from Shelby RPC").argument("[source]", "Source blob name or prefix").argument("[destination]", "Destination path").option(
|
|
8507
9211
|
"-r, --recursive",
|
|
8508
|
-
"Download assuming canonical directory layout using '/' as separators. Produces a directory."
|
|
8509
|
-
|
|
9212
|
+
"Download assuming canonical directory layout using '/' as separators. Produces a directory.",
|
|
9213
|
+
false
|
|
9214
|
+
).option("-f, --force", "Overwrite the destination", false).action(
|
|
8510
9215
|
async (source, destination, rawOptions) => {
|
|
8511
9216
|
let options;
|
|
8512
9217
|
try {
|
|
@@ -8516,7 +9221,7 @@ function downloadCommand(program) {
|
|
|
8516
9221
|
destination
|
|
8517
9222
|
});
|
|
8518
9223
|
} catch (error) {
|
|
8519
|
-
if (error instanceof
|
|
9224
|
+
if (error instanceof z15.ZodError) {
|
|
8520
9225
|
const firstIssue = error.issues[0];
|
|
8521
9226
|
if (firstIssue) {
|
|
8522
9227
|
console.log(firstIssue.message);
|
|
@@ -8530,7 +9235,7 @@ function downloadCommand(program) {
|
|
|
8530
9235
|
}
|
|
8531
9236
|
process.exit(1);
|
|
8532
9237
|
}
|
|
8533
|
-
options.destination =
|
|
9238
|
+
options.destination = path5.resolve(options.destination);
|
|
8534
9239
|
let config;
|
|
8535
9240
|
let spinner;
|
|
8536
9241
|
const handleSigint = () => {
|
|
@@ -8538,8 +9243,7 @@ function downloadCommand(program) {
|
|
|
8538
9243
|
process.exit(1);
|
|
8539
9244
|
};
|
|
8540
9245
|
try {
|
|
8541
|
-
|
|
8542
|
-
config = loadConfig(configPath);
|
|
9246
|
+
({ config } = loadConfigOrExit(program.opts().configFile));
|
|
8543
9247
|
const shelbyConfig = getCurrentShelbyConfig(config, {
|
|
8544
9248
|
context: program.opts().context
|
|
8545
9249
|
});
|
|
@@ -8559,13 +9263,13 @@ function downloadCommand(program) {
|
|
|
8559
9263
|
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
8560
9264
|
for (let i = 0; i < fileList.length; i++) {
|
|
8561
9265
|
const fileEntry = fileList[i];
|
|
8562
|
-
const blobBaseName =
|
|
9266
|
+
const blobBaseName = path5.basename(fileEntry.blobname);
|
|
8563
9267
|
console.log(`${i + 1}. ${blobBaseName} \u2192 ${fileEntry.filename}`);
|
|
8564
9268
|
}
|
|
8565
9269
|
console.log();
|
|
8566
9270
|
if (options.force) {
|
|
8567
9271
|
console.log(`--force was set, so deleting ${options.destination}`);
|
|
8568
|
-
await
|
|
9272
|
+
await fs6.rm(options.destination, { recursive: true, force: true });
|
|
8569
9273
|
}
|
|
8570
9274
|
process.removeAllListeners("SIGINT");
|
|
8571
9275
|
process.on("SIGINT", handleSigint);
|
|
@@ -8583,7 +9287,7 @@ function downloadCommand(program) {
|
|
|
8583
9287
|
const formatProgressPercent = () => totalSize > 0 ? (100 * (amountDownloaded / totalSize)).toFixed(2) : "0.00";
|
|
8584
9288
|
for (const fileEntry of fileList) {
|
|
8585
9289
|
const out = fsS.createWriteStream(fileEntry.filename);
|
|
8586
|
-
const fileName =
|
|
9290
|
+
const fileName = path5.basename(fileEntry.blobname);
|
|
8587
9291
|
const { readable } = await nodeClient.rpc.getBlob({
|
|
8588
9292
|
account: activeAccount.accountAddress,
|
|
8589
9293
|
blobName: fileEntry.blobname
|
|
@@ -8673,18 +9377,28 @@ function downloadCommand(program) {
|
|
|
8673
9377
|
|
|
8674
9378
|
// src/commands/faucet.tsx
|
|
8675
9379
|
import { Network as Network9 } from "@aptos-labs/ts-sdk";
|
|
9380
|
+
import { Option as Option2 } from "@commander-js/extra-typings";
|
|
8676
9381
|
import { execaSync } from "execa";
|
|
8677
|
-
import { z as
|
|
8678
|
-
var FaucetOptionsSchema =
|
|
8679
|
-
network:
|
|
8680
|
-
open:
|
|
9382
|
+
import { z as z16 } from "zod";
|
|
9383
|
+
var FaucetOptionsSchema = z16.object({
|
|
9384
|
+
network: z16.enum([Network9.SHELBYNET]).optional(),
|
|
9385
|
+
open: z16.boolean().optional().default(true)
|
|
8681
9386
|
});
|
|
8682
9387
|
function faucetCommand(program) {
|
|
8683
|
-
program.command("faucet").description("Open the Shelby faucet web page to request tokens").
|
|
9388
|
+
program.command("faucet").description("Open the Shelby faucet web page to request tokens").addOption(
|
|
9389
|
+
new Option2(
|
|
9390
|
+
"--network <network>",
|
|
9391
|
+
"Network to request tokens for (shelbynet)"
|
|
9392
|
+
).choices(Object.values(Network9))
|
|
9393
|
+
).addOption(
|
|
9394
|
+
new Option2(
|
|
9395
|
+
"--no-open",
|
|
9396
|
+
"Don't automatically open browser, just print the URL"
|
|
9397
|
+
)
|
|
9398
|
+
).action((options) => {
|
|
8684
9399
|
try {
|
|
8685
9400
|
const validatedOptions = FaucetOptionsSchema.parse(options);
|
|
8686
|
-
const
|
|
8687
|
-
const config = loadConfig(configPath);
|
|
9401
|
+
const { config } = loadConfigOrExit(program.opts().configFile);
|
|
8688
9402
|
const accountName = program.opts().account || config.default_account;
|
|
8689
9403
|
const { account } = getCurrentAccount(config, accountName);
|
|
8690
9404
|
const network = validatedOptions.network || Network9.SHELBYNET;
|
|
@@ -8748,9 +9462,9 @@ function openBrowser(url) {
|
|
|
8748
9462
|
}
|
|
8749
9463
|
|
|
8750
9464
|
// src/commands/init.tsx
|
|
8751
|
-
import
|
|
9465
|
+
import path6 from "path";
|
|
8752
9466
|
import { Network as Network10 } from "@aptos-labs/ts-sdk";
|
|
8753
|
-
import
|
|
9467
|
+
import fs7 from "fs-extra";
|
|
8754
9468
|
import { render as render3 } from "ink";
|
|
8755
9469
|
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
8756
9470
|
function initCommand(program) {
|
|
@@ -8771,10 +9485,10 @@ function initCommand(program) {
|
|
|
8771
9485
|
);
|
|
8772
9486
|
process.exit(1);
|
|
8773
9487
|
}
|
|
8774
|
-
const configPath =
|
|
9488
|
+
const configPath = getPathForNewConfig();
|
|
8775
9489
|
const resolvedPath = resolveConfigPath(configPath);
|
|
8776
9490
|
const accountName = program.opts().account;
|
|
8777
|
-
const hasExistingConfig =
|
|
9491
|
+
const hasExistingConfig = fs7.existsSync(resolvedPath);
|
|
8778
9492
|
let existingConfigValid = false;
|
|
8779
9493
|
if (hasExistingConfig) {
|
|
8780
9494
|
try {
|
|
@@ -8791,7 +9505,7 @@ function initCommand(program) {
|
|
|
8791
9505
|
}
|
|
8792
9506
|
}
|
|
8793
9507
|
if (options.setupDefault) {
|
|
8794
|
-
if (
|
|
9508
|
+
if (fs7.existsSync(resolvedPath)) {
|
|
8795
9509
|
console.error(
|
|
8796
9510
|
`\u274C Refusing to overwrite existing config at ${resolvedPath}. Remove it first or run 'shelby init' interactively.`
|
|
8797
9511
|
);
|
|
@@ -8879,12 +9593,12 @@ function cloneContexts(contexts) {
|
|
|
8879
9593
|
return JSON.parse(JSON.stringify(contexts));
|
|
8880
9594
|
}
|
|
8881
9595
|
function ensureConfigDir(resolvedPath) {
|
|
8882
|
-
|
|
9596
|
+
fs7.mkdirpSync(path6.dirname(resolvedPath));
|
|
8883
9597
|
}
|
|
8884
9598
|
|
|
8885
9599
|
// src/commands/upload.tsx
|
|
8886
|
-
import * as
|
|
8887
|
-
import * as
|
|
9600
|
+
import * as fs8 from "fs/promises";
|
|
9601
|
+
import * as path7 from "path";
|
|
8888
9602
|
import { Aptos as Aptos5, AptosConfig as AptosConfig4 } from "@aptos-labs/ts-sdk";
|
|
8889
9603
|
import * as chrono from "chrono-node";
|
|
8890
9604
|
import { glob } from "glob";
|
|
@@ -8892,7 +9606,7 @@ import ignore from "ignore";
|
|
|
8892
9606
|
import { Box as Box7, render as render4, Text as Text7 } from "ink";
|
|
8893
9607
|
import SelectInput4 from "ink-select-input";
|
|
8894
9608
|
import ora2 from "ora";
|
|
8895
|
-
import { z as
|
|
9609
|
+
import { z as z17 } from "zod";
|
|
8896
9610
|
|
|
8897
9611
|
// src/utils/commander-helpers.ts
|
|
8898
9612
|
function createExitOverrideHandler(commandName, requiredArgs, requiredOptions, exampleUsage, warningMessage) {
|
|
@@ -8943,8 +9657,8 @@ function createExitOverrideHandler(commandName, requiredArgs, requiredOptions, e
|
|
|
8943
9657
|
|
|
8944
9658
|
// src/commands/upload.tsx
|
|
8945
9659
|
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
8946
|
-
var normBlobName2 = (i, f, b) => normBlobName(
|
|
8947
|
-
var flexibleDateSchema =
|
|
9660
|
+
var normBlobName2 = (i, f, b) => normBlobName(path7, i, f, b);
|
|
9661
|
+
var flexibleDateSchema = z17.string().transform((val, ctx) => {
|
|
8948
9662
|
const now = /* @__PURE__ */ new Date();
|
|
8949
9663
|
let parsedDate = null;
|
|
8950
9664
|
if (/^\d+$/.test(val)) {
|
|
@@ -8967,7 +9681,7 @@ var flexibleDateSchema = z16.string().transform((val, ctx) => {
|
|
|
8967
9681
|
}
|
|
8968
9682
|
if (!parsedDate || Number.isNaN(parsedDate.getTime())) {
|
|
8969
9683
|
ctx.addIssue({
|
|
8970
|
-
code:
|
|
9684
|
+
code: z17.ZodIssueCode.custom,
|
|
8971
9685
|
message: `
|
|
8972
9686
|
\u274C Upload Failed
|
|
8973
9687
|
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
@@ -8981,11 +9695,11 @@ var flexibleDateSchema = z16.string().transform((val, ctx) => {
|
|
|
8981
9695
|
|
|
8982
9696
|
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`
|
|
8983
9697
|
});
|
|
8984
|
-
return
|
|
9698
|
+
return z17.NEVER;
|
|
8985
9699
|
}
|
|
8986
9700
|
if (parsedDate.getTime() <= now.getTime()) {
|
|
8987
9701
|
ctx.addIssue({
|
|
8988
|
-
code:
|
|
9702
|
+
code: z17.ZodIssueCode.custom,
|
|
8989
9703
|
message: `
|
|
8990
9704
|
\u274C Upload Failed
|
|
8991
9705
|
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
@@ -8997,26 +9711,26 @@ var flexibleDateSchema = z16.string().transform((val, ctx) => {
|
|
|
8997
9711
|
|
|
8998
9712
|
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`
|
|
8999
9713
|
});
|
|
9000
|
-
return
|
|
9714
|
+
return z17.NEVER;
|
|
9001
9715
|
}
|
|
9002
9716
|
return parsedDate;
|
|
9003
9717
|
});
|
|
9004
|
-
var UploadOptionsSchema =
|
|
9005
|
-
source:
|
|
9718
|
+
var UploadOptionsSchema = z17.object({
|
|
9719
|
+
source: z17.string({
|
|
9006
9720
|
required_error: '\n\u274C Missing Required Argument\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\u26A0\uFE0F Missing source file or directory path (first argument)\n\n\u{1F4A1} Usage:\n shelby upload <source-file-or-directory> <destination-blob-name> [options]\n\n\u{1F4DD} Examples:\n shelby upload ./myfile.txt my-blob.txt -e tomorrow\n shelby upload ./my-folder/ my-folder/ -r -e "next week"\n\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500'
|
|
9007
9721
|
}).min(1, "Source file or directory path is required"),
|
|
9008
|
-
destination:
|
|
9722
|
+
destination: z17.string({
|
|
9009
9723
|
required_error: "\n\u274C Missing Required Argument\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\u26A0\uFE0F Missing destination blob name (second argument)\n\n\u{1F4A1} Usage:\n shelby upload <source-file-or-directory> <destination-blob-name> [options]\n\n\u{1F4DD} Example:\n shelby upload ./myfile.txt files/my-blob.txt -e tomorrow\n\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
|
|
9010
9724
|
}).min(1, "Destination blob name is required"),
|
|
9011
9725
|
expiration: flexibleDateSchema,
|
|
9012
|
-
recursive:
|
|
9013
|
-
assumeYes:
|
|
9014
|
-
outputCommitments:
|
|
9726
|
+
recursive: z17.boolean().optional().default(false),
|
|
9727
|
+
assumeYes: z17.boolean().optional().default(false),
|
|
9728
|
+
outputCommitments: z17.string().optional()
|
|
9015
9729
|
}).superRefine(async (data, ctx) => {
|
|
9016
|
-
const stats = await
|
|
9730
|
+
const stats = await fs8.stat(data.source);
|
|
9017
9731
|
if (!stats.isFile() && !stats.isDirectory()) {
|
|
9018
9732
|
ctx.addIssue({
|
|
9019
|
-
code:
|
|
9733
|
+
code: z17.ZodIssueCode.custom,
|
|
9020
9734
|
message: "\n\u274C Upload Failed\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\u26A0\uFE0F Source path must be a file or directory\n\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
9021
9735
|
path: ["source"]
|
|
9022
9736
|
});
|
|
@@ -9025,7 +9739,7 @@ var UploadOptionsSchema = z16.object({
|
|
|
9025
9739
|
if (stats.isDirectory()) {
|
|
9026
9740
|
if (!data.destination.endsWith("/")) {
|
|
9027
9741
|
ctx.addIssue({
|
|
9028
|
-
code:
|
|
9742
|
+
code: z17.ZodIssueCode.custom,
|
|
9029
9743
|
message: `
|
|
9030
9744
|
\u274C Upload Failed
|
|
9031
9745
|
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
@@ -9043,7 +9757,7 @@ var UploadOptionsSchema = z16.object({
|
|
|
9043
9757
|
const blobNameResult = BlobNameSchema.safeParse(data.destination);
|
|
9044
9758
|
if (!blobNameResult.success) {
|
|
9045
9759
|
ctx.addIssue({
|
|
9046
|
-
code:
|
|
9760
|
+
code: z17.ZodIssueCode.custom,
|
|
9047
9761
|
message: `
|
|
9048
9762
|
\u274C Upload Failed
|
|
9049
9763
|
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
@@ -9060,7 +9774,7 @@ var UploadOptionsSchema = z16.object({
|
|
|
9060
9774
|
}
|
|
9061
9775
|
});
|
|
9062
9776
|
async function buildGitignoreMap(root) {
|
|
9063
|
-
const resolvedRoot =
|
|
9777
|
+
const resolvedRoot = path7.resolve(root);
|
|
9064
9778
|
const gitignoreMap = /* @__PURE__ */ new Map();
|
|
9065
9779
|
const ensureMatcher = (dir) => {
|
|
9066
9780
|
const existing = gitignoreMap.get(dir);
|
|
@@ -9080,8 +9794,8 @@ async function buildGitignoreMap(root) {
|
|
|
9080
9794
|
});
|
|
9081
9795
|
for (const gitignorePath of gitignoreFiles) {
|
|
9082
9796
|
try {
|
|
9083
|
-
const contents = await
|
|
9084
|
-
const directory =
|
|
9797
|
+
const contents = await fs8.readFile(gitignorePath, "utf8");
|
|
9798
|
+
const directory = path7.dirname(gitignorePath);
|
|
9085
9799
|
ensureMatcher(directory).add(contents);
|
|
9086
9800
|
} catch (error) {
|
|
9087
9801
|
if (error instanceof Error && Object.hasOwn(error, "code") && // biome-ignore lint/suspicious/noExplicitAny: node fs error type
|
|
@@ -9095,13 +9809,13 @@ async function buildGitignoreMap(root) {
|
|
|
9095
9809
|
}
|
|
9096
9810
|
function collectDirectoriesFromRoot(root, filePath) {
|
|
9097
9811
|
const directories = [];
|
|
9098
|
-
let current =
|
|
9812
|
+
let current = path7.dirname(filePath);
|
|
9099
9813
|
while (true) {
|
|
9100
9814
|
directories.push(current);
|
|
9101
9815
|
if (current === root) {
|
|
9102
9816
|
break;
|
|
9103
9817
|
}
|
|
9104
|
-
const parent =
|
|
9818
|
+
const parent = path7.dirname(current);
|
|
9105
9819
|
if (parent === current) {
|
|
9106
9820
|
break;
|
|
9107
9821
|
}
|
|
@@ -9117,7 +9831,7 @@ function shouldIgnorePath(gitignoreMap, root, filePath) {
|
|
|
9117
9831
|
if (!matcher) {
|
|
9118
9832
|
continue;
|
|
9119
9833
|
}
|
|
9120
|
-
const relative2 =
|
|
9834
|
+
const relative2 = path7.relative(directory, filePath).split(path7.sep).join("/");
|
|
9121
9835
|
const result = matcher.test(relative2);
|
|
9122
9836
|
if (result.ignored) {
|
|
9123
9837
|
ignored = true;
|
|
@@ -9129,7 +9843,7 @@ function shouldIgnorePath(gitignoreMap, root, filePath) {
|
|
|
9129
9843
|
return ignored;
|
|
9130
9844
|
}
|
|
9131
9845
|
async function createFilelist(options) {
|
|
9132
|
-
const stats = await
|
|
9846
|
+
const stats = await fs8.stat(options.source);
|
|
9133
9847
|
if (stats.isFile()) {
|
|
9134
9848
|
const blobname = normBlobName2(
|
|
9135
9849
|
options.source,
|
|
@@ -9149,7 +9863,7 @@ async function createFilelist(options) {
|
|
|
9149
9863
|
`${options.source} is a directory. Use --recursive to upload directories.`
|
|
9150
9864
|
);
|
|
9151
9865
|
}
|
|
9152
|
-
const sourceRoot =
|
|
9866
|
+
const sourceRoot = path7.resolve(options.source);
|
|
9153
9867
|
const gitignoreMap = await buildGitignoreMap(sourceRoot);
|
|
9154
9868
|
const fileList = [];
|
|
9155
9869
|
const result = await glob("**/*", {
|
|
@@ -9162,7 +9876,7 @@ async function createFilelist(options) {
|
|
|
9162
9876
|
if (shouldIgnorePath(gitignoreMap, sourceRoot, file)) {
|
|
9163
9877
|
continue;
|
|
9164
9878
|
}
|
|
9165
|
-
const stats2 = await
|
|
9879
|
+
const stats2 = await fs8.stat(file);
|
|
9166
9880
|
if (!stats2.isFile()) {
|
|
9167
9881
|
continue;
|
|
9168
9882
|
}
|
|
@@ -9185,9 +9899,10 @@ function uploadCommand(program) {
|
|
|
9185
9899
|
const uploadCmd = program.command("upload").description("Upload a file or directory to the shelby RPC in the config.").argument("[source]", "Source file or directory path").argument("[destination]", "Destination blob name").requiredOption(
|
|
9186
9900
|
"-e, --expiration <datetime>",
|
|
9187
9901
|
'Expiration date/time (required). Examples: "tomorrow", "in 2 days", "next Friday", "2025-12-31", UNIX timestamp'
|
|
9188
|
-
).option("-r, --recursive", "If uploading a directory, recurse").option(
|
|
9902
|
+
).option("-r, --recursive", "If uploading a directory, recurse", false).option(
|
|
9189
9903
|
"--assume-yes",
|
|
9190
|
-
"Do not prompt interactively, assume yes for any questions"
|
|
9904
|
+
"Do not prompt interactively, assume yes for any questions",
|
|
9905
|
+
false
|
|
9191
9906
|
).option(
|
|
9192
9907
|
"--output-commitments <filename>",
|
|
9193
9908
|
"Location to store commitments computed as as part of the upload"
|
|
@@ -9205,16 +9920,16 @@ function uploadCommand(program) {
|
|
|
9205
9920
|
)
|
|
9206
9921
|
);
|
|
9207
9922
|
uploadCmd.action(
|
|
9208
|
-
async (source, destination,
|
|
9209
|
-
let
|
|
9923
|
+
async (source, destination, rawOptions) => {
|
|
9924
|
+
let options;
|
|
9210
9925
|
try {
|
|
9211
|
-
|
|
9212
|
-
...
|
|
9926
|
+
options = await UploadOptionsSchema.parseAsync({
|
|
9927
|
+
...rawOptions,
|
|
9213
9928
|
source,
|
|
9214
9929
|
destination
|
|
9215
9930
|
});
|
|
9216
9931
|
} catch (error) {
|
|
9217
|
-
if (error instanceof
|
|
9932
|
+
if (error instanceof z17.ZodError) {
|
|
9218
9933
|
const firstIssue = error.issues[0];
|
|
9219
9934
|
if (firstIssue) {
|
|
9220
9935
|
console.log(firstIssue.message);
|
|
@@ -9227,16 +9942,9 @@ function uploadCommand(program) {
|
|
|
9227
9942
|
}
|
|
9228
9943
|
process.exit(1);
|
|
9229
9944
|
}
|
|
9230
|
-
const
|
|
9231
|
-
let config;
|
|
9232
|
-
try {
|
|
9233
|
-
config = loadConfig(configPath);
|
|
9234
|
-
} catch (error) {
|
|
9235
|
-
console.error(`Error: ${error.message}`);
|
|
9236
|
-
process.exit(1);
|
|
9237
|
-
}
|
|
9945
|
+
const { config } = loadConfigOrExit(program.opts().configFile);
|
|
9238
9946
|
const start = performance.now();
|
|
9239
|
-
const filelist = await createFilelist(
|
|
9947
|
+
const filelist = await createFilelist(options);
|
|
9240
9948
|
const timeToCreateFilelist = ((performance.now() - start) / 1e3).toFixed(
|
|
9241
9949
|
5
|
|
9242
9950
|
);
|
|
@@ -9253,10 +9961,10 @@ function uploadCommand(program) {
|
|
|
9253
9961
|
`\u{1F9EE} Filelist created (${filelist.length} ${filelist.length === 1 ? "entry" : "entries"})`
|
|
9254
9962
|
);
|
|
9255
9963
|
console.log(`\u23F1\uFE0F Took: ${timeToCreateFilelist}s`);
|
|
9256
|
-
if (
|
|
9964
|
+
if (options.assumeYes) {
|
|
9257
9965
|
console.log("\u2699\uFE0F Flag: --assume-yes (auto-confirmed)");
|
|
9258
9966
|
}
|
|
9259
|
-
if (!
|
|
9967
|
+
if (!options.assumeYes) {
|
|
9260
9968
|
const shouldContinue = await new Promise((resolve3) => {
|
|
9261
9969
|
const { unmount } = render4(
|
|
9262
9970
|
/* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
@@ -9297,7 +10005,7 @@ function uploadCommand(program) {
|
|
|
9297
10005
|
};
|
|
9298
10006
|
process.removeAllListeners("SIGINT");
|
|
9299
10007
|
process.on("SIGINT", handleSigint);
|
|
9300
|
-
const expireUsec =
|
|
10008
|
+
const expireUsec = options.expiration.getTime() * 1e3;
|
|
9301
10009
|
const expirationDate = new Date(expireUsec / 1e3);
|
|
9302
10010
|
const formattedExpiration = expirationDate.toLocaleDateString("en-US", {
|
|
9303
10011
|
year: "numeric",
|
|
@@ -9326,11 +10034,11 @@ function uploadCommand(program) {
|
|
|
9326
10034
|
const formatProgressPercent = () => totalSize > 0 ? (100 * (amountUploaded / totalSize)).toFixed(2) : "0.00";
|
|
9327
10035
|
let filesProcessed = 0;
|
|
9328
10036
|
for (const entry of filelist) {
|
|
9329
|
-
const fileName =
|
|
10037
|
+
const fileName = path7.basename(entry.filename);
|
|
9330
10038
|
const fileProgress = isSingleFile ? `(${formatProgressPercent()}%)` : `(${filesProcessed}/${filelist.length} files, ${formatProgressPercent()}%)`;
|
|
9331
10039
|
spinner.text = `\u{1F4D6} Reading ${fileName}... ${fileProgress}`;
|
|
9332
10040
|
try {
|
|
9333
|
-
const blobData = await
|
|
10041
|
+
const blobData = await fs8.readFile(entry.filename);
|
|
9334
10042
|
if (blobData.length !== entry.sizeBytes) {
|
|
9335
10043
|
throw new Error(
|
|
9336
10044
|
`Size of file ${entry.filename} changed after initial scan. Original size was ${entry.sizeBytes} but it is now ${blobData.length}`
|
|
@@ -9350,7 +10058,7 @@ function uploadCommand(program) {
|
|
|
9350
10058
|
spinner.text = `\u{1F517} Generating commitments for ${fileName}... ${fileProgress}`;
|
|
9351
10059
|
const provider = await getErasureCodingProvider();
|
|
9352
10060
|
const blobCommitments = await generateCommitments(provider, blobData);
|
|
9353
|
-
if (
|
|
10061
|
+
if (options.outputCommitments) {
|
|
9354
10062
|
outputCommitments[entry.filename] = blobCommitments;
|
|
9355
10063
|
}
|
|
9356
10064
|
spinner.text = `\u{1F517} Registering ${fileName} on L1... ${fileProgress}`;
|
|
@@ -9359,7 +10067,7 @@ function uploadCommand(program) {
|
|
|
9359
10067
|
blobName: entry.blobname,
|
|
9360
10068
|
blobMerkleRoot: blobCommitments.blob_merkle_root,
|
|
9361
10069
|
size: blobData.length,
|
|
9362
|
-
expirationMicros:
|
|
10070
|
+
expirationMicros: options.expiration.getTime() * 1e3
|
|
9363
10071
|
});
|
|
9364
10072
|
const registerTransactionHash = pendingRegisterBlobTransaction.hash;
|
|
9365
10073
|
if (!firstTransactionHash) {
|
|
@@ -9382,9 +10090,9 @@ function uploadCommand(program) {
|
|
|
9382
10090
|
process.exit(1);
|
|
9383
10091
|
}
|
|
9384
10092
|
}
|
|
9385
|
-
if (
|
|
9386
|
-
await
|
|
9387
|
-
|
|
10093
|
+
if (options.outputCommitments) {
|
|
10094
|
+
await fs8.writeFile(
|
|
10095
|
+
options.outputCommitments,
|
|
9388
10096
|
JSON.stringify(outputCommitments)
|
|
9389
10097
|
);
|
|
9390
10098
|
}
|
|
@@ -9414,37 +10122,772 @@ function uploadCommand(program) {
|
|
|
9414
10122
|
);
|
|
9415
10123
|
}
|
|
9416
10124
|
|
|
9417
|
-
// src/
|
|
9418
|
-
|
|
9419
|
-
|
|
9420
|
-
|
|
10125
|
+
// src/commands/localnet/start.tsx
|
|
10126
|
+
import fs10 from "fs";
|
|
10127
|
+
import path9 from "path";
|
|
10128
|
+
import Dockerode from "dockerode";
|
|
10129
|
+
import { execa } from "execa";
|
|
10130
|
+
import ora3 from "ora";
|
|
10131
|
+
import { parse as parse2, stringify } from "yaml";
|
|
10132
|
+
|
|
10133
|
+
// src/commands/localnet/assets.ts
|
|
10134
|
+
import "fs";
|
|
10135
|
+
import "path";
|
|
10136
|
+
import "url";
|
|
10137
|
+
var hasuraMetadataContent;
|
|
10138
|
+
var nciConfigContent;
|
|
10139
|
+
if (true) {
|
|
10140
|
+
hasuraMetadataContent = (await Promise.resolve().then(() => __toESM(require_hasura_metadata(), 1))).default;
|
|
10141
|
+
nciConfigContent = (await Promise.resolve().then(() => __toESM(require_shelby_internal(), 1))).default;
|
|
10142
|
+
} else {
|
|
10143
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10144
|
+
const __dirname = path8.dirname(__filename);
|
|
10145
|
+
const assetsDir = path8.resolve(__dirname, "../../../assets");
|
|
10146
|
+
hasuraMetadataContent = fs9.readFileSync(
|
|
10147
|
+
path8.join(assetsDir, "hasura_metadata.txt"),
|
|
10148
|
+
"utf-8"
|
|
10149
|
+
);
|
|
10150
|
+
nciConfigContent = fs9.readFileSync(
|
|
10151
|
+
path8.join(assetsDir, "shelby_internal.txt"),
|
|
10152
|
+
"utf-8"
|
|
10153
|
+
);
|
|
10154
|
+
}
|
|
10155
|
+
|
|
10156
|
+
// src/commands/localnet/common.ts
|
|
10157
|
+
var LOCALNET_NAME = "shelby-localnet";
|
|
10158
|
+
var MOUNT_DIR = "/mounted";
|
|
10159
|
+
var debugEnabled = false;
|
|
10160
|
+
function setDebugEnabled(enabled) {
|
|
10161
|
+
debugEnabled = enabled;
|
|
10162
|
+
}
|
|
10163
|
+
function debug(message) {
|
|
10164
|
+
if (debugEnabled) {
|
|
10165
|
+
console.log(`\u{1F50D} ${message}`);
|
|
10166
|
+
}
|
|
10167
|
+
}
|
|
10168
|
+
|
|
10169
|
+
// src/commands/localnet/docker.ts
|
|
10170
|
+
var SHELBY_LOCALNET_NETWORK = "shelby-localnet-network";
|
|
10171
|
+
var restart = "no";
|
|
10172
|
+
var shelbyPostgres = "shelby-postgres";
|
|
10173
|
+
var shelbyAptosLocalnetIndexerApi = "shelby-aptos-localnet-indexer-api";
|
|
10174
|
+
var shelbyAptosLocalnet = "shelby-aptos-localnet";
|
|
10175
|
+
var shelbyNciProcessor = "shelby-nci-processor";
|
|
10176
|
+
var shelbyNciApi = "shelby-nci-api";
|
|
10177
|
+
var shelbyRpc = "shelby-rpc";
|
|
10178
|
+
var corePostgresDatabase = "shelby_aptos_localnet";
|
|
10179
|
+
var nciPostgresDatabase = "postgres";
|
|
10180
|
+
var aptosNodePort = 8080;
|
|
10181
|
+
var mountDirEnvVar = {
|
|
10182
|
+
MOUNT_DIR
|
|
10183
|
+
};
|
|
10184
|
+
function createDockerCompose({
|
|
10185
|
+
hostDataPath,
|
|
10186
|
+
shelbyRepoWithSlash,
|
|
10187
|
+
tags,
|
|
10188
|
+
skipNci,
|
|
10189
|
+
skipRpc,
|
|
10190
|
+
ports,
|
|
10191
|
+
additionalAptosLocalnetArgs
|
|
10192
|
+
}) {
|
|
10193
|
+
const coreHasuraDbString = `postgresql://postgres:postgres@${shelbyPostgres}:${ports.postgres}/${corePostgresDatabase}`;
|
|
10194
|
+
const nciHasuraDbString = `postgresql://postgres:postgres@${shelbyPostgres}:${ports.postgres}/postgres`;
|
|
10195
|
+
const services = {
|
|
10196
|
+
[shelbyPostgres]: {
|
|
10197
|
+
image: "postgres:17",
|
|
10198
|
+
container_name: shelbyPostgres,
|
|
10199
|
+
networks: [SHELBY_LOCALNET_NETWORK],
|
|
10200
|
+
environment: {
|
|
10201
|
+
POSTGRES_HOST_AUTH_METHOD: "trust",
|
|
10202
|
+
PGPORT: ports.postgres.toString(),
|
|
10203
|
+
POSTGRES_DB: corePostgresDatabase
|
|
10204
|
+
},
|
|
10205
|
+
healthcheck: {
|
|
10206
|
+
test: [
|
|
10207
|
+
"CMD",
|
|
10208
|
+
"pg_isready",
|
|
10209
|
+
"-U",
|
|
10210
|
+
"postgres",
|
|
10211
|
+
"-d",
|
|
10212
|
+
corePostgresDatabase
|
|
10213
|
+
],
|
|
10214
|
+
interval: "1s",
|
|
10215
|
+
timeout: "2s",
|
|
10216
|
+
retries: 30,
|
|
10217
|
+
start_period: "30s"
|
|
10218
|
+
},
|
|
10219
|
+
ports: [`${ports.postgres}:${ports.postgres}`],
|
|
10220
|
+
restart,
|
|
10221
|
+
volumes: [`${hostDataPath}/postgres:/var/lib/postgresql/data`]
|
|
10222
|
+
},
|
|
10223
|
+
// Hasura GraphQL API for the core Aptos localnet indexer.
|
|
10224
|
+
[shelbyAptosLocalnetIndexerApi]: createHasuraService(
|
|
10225
|
+
shelbyAptosLocalnetIndexerApi,
|
|
10226
|
+
coreHasuraDbString,
|
|
10227
|
+
ports.coreIndexerApi,
|
|
10228
|
+
{
|
|
10229
|
+
[shelbyPostgres]: {
|
|
10230
|
+
condition: "service_healthy"
|
|
10231
|
+
}
|
|
10232
|
+
},
|
|
10233
|
+
{
|
|
10234
|
+
INDEXER_V2_POSTGRES_URL: coreHasuraDbString
|
|
10235
|
+
},
|
|
10236
|
+
tags.hasura
|
|
10237
|
+
),
|
|
10238
|
+
// Aptos localnet with pre-deployed Shelby contracts.
|
|
10239
|
+
[shelbyAptosLocalnet]: {
|
|
10240
|
+
command: [
|
|
10241
|
+
"--bind-to",
|
|
10242
|
+
"0.0.0.0",
|
|
10243
|
+
// This flag is what causes the CLI to run the processors and apply the Hasura
|
|
10244
|
+
// metadata. It won't run postgres or Hasura itself like normal because of the
|
|
10245
|
+
// --use-host-postgres and --existing-hasura-url flags.
|
|
10246
|
+
"--with-indexer-api",
|
|
10247
|
+
"--use-host-postgres",
|
|
10248
|
+
"--host-postgres-host",
|
|
10249
|
+
// We route via the Docker network, not the host (host.docker.internal).
|
|
10250
|
+
shelbyPostgres,
|
|
10251
|
+
"--host-postgres-port",
|
|
10252
|
+
ports.postgres.toString(),
|
|
10253
|
+
"--postgres-database",
|
|
10254
|
+
corePostgresDatabase,
|
|
10255
|
+
"--existing-hasura-url",
|
|
10256
|
+
`http://${shelbyAptosLocalnetIndexerApi}:${ports.coreIndexerApi}`,
|
|
10257
|
+
"--faucet-port",
|
|
10258
|
+
ports.faucet.toString(),
|
|
10259
|
+
"--txn-stream-port",
|
|
10260
|
+
ports.txnStream.toString(),
|
|
10261
|
+
"--indexer-api-port",
|
|
10262
|
+
ports.coreIndexerApi.toString(),
|
|
10263
|
+
"--ready-server-listen-port",
|
|
10264
|
+
ports.localnetReadiness.toString(),
|
|
10265
|
+
...additionalAptosLocalnetArgs
|
|
10266
|
+
],
|
|
10267
|
+
container_name: shelbyAptosLocalnet,
|
|
10268
|
+
depends_on: {
|
|
10269
|
+
[shelbyAptosLocalnetIndexerApi]: {
|
|
10270
|
+
condition: "service_healthy"
|
|
10271
|
+
},
|
|
10272
|
+
[shelbyPostgres]: {
|
|
10273
|
+
condition: "service_healthy"
|
|
10274
|
+
}
|
|
10275
|
+
},
|
|
10276
|
+
environment: { ...mountDirEnvVar },
|
|
10277
|
+
healthcheck: {
|
|
10278
|
+
test: [
|
|
10279
|
+
"CMD",
|
|
10280
|
+
"curl",
|
|
10281
|
+
"-f",
|
|
10282
|
+
`http://localhost:${ports.localnetReadiness}/`
|
|
10283
|
+
],
|
|
10284
|
+
interval: "1s",
|
|
10285
|
+
timeout: "3s",
|
|
10286
|
+
retries: 60,
|
|
10287
|
+
start_period: "10s"
|
|
10288
|
+
},
|
|
10289
|
+
image: `${shelbyRepoWithSlash}shelby/aptos-localnet:${tags.aptosLocalnet}`,
|
|
10290
|
+
networks: [SHELBY_LOCALNET_NETWORK],
|
|
10291
|
+
ports: [
|
|
10292
|
+
`${aptosNodePort}:${aptosNodePort}`,
|
|
10293
|
+
`${ports.localnetReadiness}:${ports.localnetReadiness}`,
|
|
10294
|
+
`${ports.faucet}:${ports.faucet}`,
|
|
10295
|
+
`${ports.txnStream}:${ports.txnStream}`
|
|
10296
|
+
],
|
|
10297
|
+
restart,
|
|
10298
|
+
volumes: [`${hostDataPath}:${MOUNT_DIR}`]
|
|
10299
|
+
}
|
|
10300
|
+
};
|
|
10301
|
+
if (!skipNci) {
|
|
10302
|
+
services[shelbyNciProcessor] = {
|
|
10303
|
+
command: [
|
|
10304
|
+
"/usr/local/bin/remapping-processor",
|
|
10305
|
+
"--config-path",
|
|
10306
|
+
`${MOUNT_DIR}/nci/shelby_internal.yaml`
|
|
10307
|
+
],
|
|
10308
|
+
container_name: shelbyNciProcessor,
|
|
10309
|
+
depends_on: {
|
|
10310
|
+
[shelbyPostgres]: {
|
|
10311
|
+
condition: "service_healthy"
|
|
10312
|
+
},
|
|
10313
|
+
[shelbyAptosLocalnet]: {
|
|
10314
|
+
condition: "service_healthy"
|
|
10315
|
+
}
|
|
10316
|
+
},
|
|
10317
|
+
environment: { ...mountDirEnvVar },
|
|
10318
|
+
healthcheck: {
|
|
10319
|
+
test: [
|
|
10320
|
+
"CMD-SHELL",
|
|
10321
|
+
`timeout 1 bash -c 'echo > /dev/tcp/localhost/${ports.nciProcessorMetrics}'`
|
|
10322
|
+
],
|
|
10323
|
+
interval: "2s",
|
|
10324
|
+
timeout: "4s",
|
|
10325
|
+
retries: 10,
|
|
10326
|
+
start_period: "10s"
|
|
10327
|
+
},
|
|
10328
|
+
image: `aptoslabs/aptos-nocode-processors:${tags.nciProcessor}`,
|
|
10329
|
+
networks: [SHELBY_LOCALNET_NETWORK],
|
|
10330
|
+
// We don't build the image for arm at the moment, so we force amd64.
|
|
10331
|
+
platform: "linux/amd64",
|
|
10332
|
+
ports: [`${ports.nciProcessorMetrics}:${ports.nciProcessorMetrics}`],
|
|
10333
|
+
restart,
|
|
10334
|
+
volumes: [`${hostDataPath}:${MOUNT_DIR}`]
|
|
10335
|
+
};
|
|
10336
|
+
services[shelbyNciApi] = createHasuraService(
|
|
10337
|
+
shelbyNciApi,
|
|
10338
|
+
nciHasuraDbString,
|
|
10339
|
+
ports.nciIndexerApi,
|
|
10340
|
+
{
|
|
10341
|
+
[shelbyPostgres]: {
|
|
10342
|
+
condition: "service_healthy"
|
|
10343
|
+
},
|
|
10344
|
+
[shelbyAptosLocalnet]: {
|
|
10345
|
+
condition: "service_healthy"
|
|
10346
|
+
},
|
|
10347
|
+
[shelbyNciProcessor]: {
|
|
10348
|
+
condition: "service_healthy"
|
|
10349
|
+
}
|
|
10350
|
+
},
|
|
10351
|
+
{
|
|
10352
|
+
// This corresponds to from_env in the Hasura metadata.
|
|
10353
|
+
PROCESSOR_DATABASE_URL: nciHasuraDbString
|
|
10354
|
+
},
|
|
10355
|
+
tags.hasura
|
|
10356
|
+
);
|
|
10357
|
+
}
|
|
10358
|
+
if (!skipRpc) {
|
|
10359
|
+
services[shelbyRpc] = {
|
|
10360
|
+
container_name: shelbyRpc,
|
|
10361
|
+
depends_on: {
|
|
10362
|
+
// For now this uses its own sqlite database.
|
|
10363
|
+
[shelbyAptosLocalnet]: {
|
|
10364
|
+
condition: "service_healthy"
|
|
10365
|
+
}
|
|
10366
|
+
},
|
|
10367
|
+
environment: {
|
|
10368
|
+
PORT: ports.rpc.toString(),
|
|
10369
|
+
APTOS_LOCAL_NODE_API_URL: `http://${shelbyAptosLocalnet}:${aptosNodePort}/v1`,
|
|
10370
|
+
...mountDirEnvVar
|
|
10371
|
+
},
|
|
10372
|
+
healthcheck: {
|
|
10373
|
+
// TODO: Do a better healthcheck when one is available.
|
|
10374
|
+
test: ["CMD", "curl", "-f", `http://localhost:${ports.rpc}/metrics`],
|
|
10375
|
+
interval: "1s"
|
|
10376
|
+
},
|
|
10377
|
+
image: `${shelbyRepoWithSlash}shelby/rpc:${tags.rpc}`,
|
|
10378
|
+
networks: [SHELBY_LOCALNET_NETWORK],
|
|
10379
|
+
ports: [`${ports.rpc}:${ports.rpc}`],
|
|
10380
|
+
restart,
|
|
10381
|
+
volumes: [`${hostDataPath}/rpc:${MOUNT_DIR}`]
|
|
10382
|
+
};
|
|
10383
|
+
}
|
|
10384
|
+
return {
|
|
10385
|
+
services,
|
|
10386
|
+
networks: {
|
|
10387
|
+
[SHELBY_LOCALNET_NETWORK]: {
|
|
10388
|
+
name: SHELBY_LOCALNET_NETWORK,
|
|
10389
|
+
driver: "bridge"
|
|
10390
|
+
}
|
|
10391
|
+
}
|
|
10392
|
+
};
|
|
10393
|
+
}
|
|
10394
|
+
async function cleanupLocalnet(dockerode) {
|
|
10395
|
+
const labelKey = "com.docker.compose.project";
|
|
10396
|
+
const labelValue = LOCALNET_NAME;
|
|
10397
|
+
const labelFilter = `${labelKey}=${labelValue}`;
|
|
10398
|
+
const filters = JSON.stringify({ label: [labelFilter] });
|
|
10399
|
+
const deletedItems = [];
|
|
10400
|
+
const containers = await dockerode.listContainers({ all: true, filters });
|
|
10401
|
+
for (const info of containers) {
|
|
10402
|
+
debug(`Deleting container ${info.Names.join(",")}...`);
|
|
10403
|
+
const container = await dockerode.getContainer(info.Id);
|
|
10404
|
+
await container.remove({ force: true });
|
|
10405
|
+
debug(`Deleted container ${info.Names.join(",")}`);
|
|
10406
|
+
deletedItems.push(...info.Names);
|
|
10407
|
+
}
|
|
10408
|
+
const networks = await dockerode.listNetworks({ filters });
|
|
10409
|
+
for (const info of networks) {
|
|
10410
|
+
debug(`Deleting network ${info.Name}...`);
|
|
10411
|
+
const network = await dockerode.getNetwork(info.Id);
|
|
10412
|
+
await network.remove();
|
|
10413
|
+
debug(`Deleted network ${info.Name}`);
|
|
10414
|
+
deletedItems.push(info.Name);
|
|
10415
|
+
}
|
|
10416
|
+
return deletedItems;
|
|
10417
|
+
}
|
|
10418
|
+
function createHasuraService(containerName, dbString, port, dependsOn, extraEnvironment, hasuraTag) {
|
|
10419
|
+
return {
|
|
10420
|
+
container_name: containerName,
|
|
10421
|
+
depends_on: dependsOn,
|
|
10422
|
+
environment: {
|
|
10423
|
+
HASURA_GRAPHQL_CONSOLE_ASSETS_DIR: "/srv/console-assets",
|
|
10424
|
+
HASURA_GRAPHQL_DEV_MODE: "true",
|
|
10425
|
+
HASURA_GRAPHQL_ENABLE_CONSOLE: "true",
|
|
10426
|
+
HASURA_GRAPHQL_METADATA_DATABASE_URL: dbString,
|
|
10427
|
+
PG_DATABASE_URL: dbString,
|
|
10428
|
+
HASURA_GRAPHQL_SERVER_PORT: port.toString(),
|
|
10429
|
+
...extraEnvironment
|
|
10430
|
+
},
|
|
10431
|
+
healthcheck: {
|
|
10432
|
+
interval: "1s",
|
|
10433
|
+
retries: 30,
|
|
10434
|
+
start_period: "10s",
|
|
10435
|
+
test: ["CMD", "curl", "-f", `http://localhost:${port}/healthz`],
|
|
10436
|
+
timeout: "3s"
|
|
10437
|
+
},
|
|
10438
|
+
image: `hasura/graphql-engine:${hasuraTag}`,
|
|
10439
|
+
networks: [SHELBY_LOCALNET_NETWORK],
|
|
10440
|
+
ports: [`${port}:${port}`],
|
|
10441
|
+
restart
|
|
10442
|
+
};
|
|
10443
|
+
}
|
|
10444
|
+
|
|
10445
|
+
// src/commands/localnet/hasura.ts
|
|
10446
|
+
async function makeHasuraMetadataRequest(url, type, args) {
|
|
10447
|
+
const metadataUrl = new URL("/v1/metadata", url);
|
|
10448
|
+
const payload = {
|
|
10449
|
+
type,
|
|
10450
|
+
args: args || {}
|
|
10451
|
+
};
|
|
10452
|
+
const response = await fetch(metadataUrl.toString(), {
|
|
10453
|
+
method: "POST",
|
|
10454
|
+
headers: {
|
|
10455
|
+
"Content-Type": "application/json"
|
|
10456
|
+
},
|
|
10457
|
+
body: JSON.stringify(payload)
|
|
10458
|
+
});
|
|
10459
|
+
if (!response.ok) {
|
|
10460
|
+
const responseBody = await response.text();
|
|
10461
|
+
throw new Error(
|
|
10462
|
+
`Hasura metadata request failed: ${response.status} ${response.statusText}
|
|
10463
|
+
Response body: ${responseBody}`
|
|
10464
|
+
);
|
|
10465
|
+
}
|
|
10466
|
+
return await response.json();
|
|
10467
|
+
}
|
|
10468
|
+
async function applyHasuraMetadata(url, metadataContent) {
|
|
10469
|
+
const metadataJson = JSON.parse(metadataContent);
|
|
10470
|
+
const response = await makeHasuraMetadataRequest(
|
|
10471
|
+
url,
|
|
10472
|
+
"replace_metadata",
|
|
10473
|
+
metadataJson
|
|
10474
|
+
);
|
|
10475
|
+
if (response.is_consistent === true) {
|
|
10476
|
+
return;
|
|
10477
|
+
}
|
|
10478
|
+
throw new Error(
|
|
10479
|
+
`Failed to apply Hasura metadata consistently. Response: ${JSON.stringify(response, null, 2)}`
|
|
10480
|
+
);
|
|
10481
|
+
}
|
|
10482
|
+
async function confirmHasuraMetadataApplied(url) {
|
|
10483
|
+
const response = await makeHasuraMetadataRequest(url, "export_metadata");
|
|
10484
|
+
if (response.sources && Array.isArray(response.sources) && response.sources.length > 0) {
|
|
10485
|
+
return;
|
|
10486
|
+
}
|
|
10487
|
+
throw new Error(
|
|
10488
|
+
`Hasura metadata has not been applied yet. Response: ${JSON.stringify(response, null, 2)}`
|
|
10489
|
+
);
|
|
10490
|
+
}
|
|
10491
|
+
async function applyAndConfirmHasuraMetadata(url, metadataContent, maxRetries = 6, retryDelayMs = 2500) {
|
|
10492
|
+
let lastError = null;
|
|
10493
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
9421
10494
|
try {
|
|
9422
|
-
|
|
9423
|
-
|
|
9424
|
-
|
|
10495
|
+
await applyHasuraMetadata(url, metadataContent);
|
|
10496
|
+
await confirmHasuraMetadataApplied(url);
|
|
10497
|
+
return;
|
|
10498
|
+
} catch (error) {
|
|
10499
|
+
lastError = error;
|
|
10500
|
+
if (attempt < maxRetries) {
|
|
10501
|
+
await new Promise((resolve3) => setTimeout(resolve3, retryDelayMs));
|
|
10502
|
+
}
|
|
9425
10503
|
}
|
|
9426
10504
|
}
|
|
9427
|
-
|
|
9428
|
-
|
|
10505
|
+
throw new Error(
|
|
10506
|
+
`Failed to apply Hasura metadata after ${maxRetries} attempts: ${lastError?.message}`
|
|
10507
|
+
);
|
|
10508
|
+
}
|
|
10509
|
+
|
|
10510
|
+
// src/commands/localnet/start.tsx
|
|
10511
|
+
function parsePort(value) {
|
|
10512
|
+
const port = Number.parseInt(value.trim(), 10);
|
|
10513
|
+
if (Number.isNaN(port)) {
|
|
10514
|
+
console.error(`Invalid port: ${value}`);
|
|
10515
|
+
process.exit(1);
|
|
10516
|
+
}
|
|
10517
|
+
if (port === 0) {
|
|
10518
|
+
console.error("We cannot handle port = 0 right now, sorry!");
|
|
10519
|
+
process.exit(1);
|
|
10520
|
+
}
|
|
10521
|
+
return port;
|
|
10522
|
+
}
|
|
10523
|
+
function localnetStartCommand(program) {
|
|
10524
|
+
program.command("start").description("Start a Shelby localnet (without SPs at the moment)").option("-d, --debug", "Enable debug logging", false).option("-f", "Follow logs after starting", false).option(
|
|
10525
|
+
"--additional-aptos-localnet-args <args>",
|
|
10526
|
+
"Additional arguments to pass to Aptos localnet",
|
|
10527
|
+
""
|
|
10528
|
+
).option(
|
|
10529
|
+
"--data-path <path>",
|
|
10530
|
+
"Directory where localnet data will be stored (default: .shelby location based on global config)",
|
|
10531
|
+
path9.join(path9.dirname(findExistingConfigPath()), "localnet")
|
|
10532
|
+
).option("--reset", "Wipe all existing localnet data before starting", false).option(
|
|
10533
|
+
"--docker-repo <registry>",
|
|
10534
|
+
"Docker registry to use for Shelby images",
|
|
10535
|
+
"ghcr.io"
|
|
10536
|
+
).option(
|
|
10537
|
+
"--aptos-localnet-tag <tag>",
|
|
10538
|
+
"Tag to use for Aptos localnet image (e.g., latest, <commit-hash>)",
|
|
10539
|
+
"latest"
|
|
10540
|
+
).option("--rpc-tag <tag>", "Tag to use for RPC image", "latest").option("--sp-tag <tag>", "Tag to use for Storage Provider image", "latest").option(
|
|
10541
|
+
"--nci-processor-tag <tag>",
|
|
10542
|
+
"Tag to use for No-Code Indexer Processor image",
|
|
10543
|
+
"02b51d2cf5a0609eb04771adfc906457ffad95be"
|
|
10544
|
+
).option("--hasura-tag <tag>", "Tag to use for Hasura image", "v2.48.5-ce").option(
|
|
10545
|
+
"--postgres-port <port>",
|
|
10546
|
+
"Port to use for postgres",
|
|
10547
|
+
parsePort,
|
|
10548
|
+
5433
|
|
10549
|
+
).option(
|
|
10550
|
+
"--faucet-port <port>",
|
|
10551
|
+
"Port to use for Aptos faucet",
|
|
10552
|
+
parsePort,
|
|
10553
|
+
8081
|
|
10554
|
+
).option(
|
|
10555
|
+
"--txn-stream-port <port>",
|
|
10556
|
+
"Port to use for Aptos localnet transaction stream",
|
|
10557
|
+
parsePort,
|
|
10558
|
+
50051
|
|
10559
|
+
).option(
|
|
10560
|
+
"--core-indexer-api-port <port>",
|
|
10561
|
+
"Port to use for Aptos indexer API",
|
|
10562
|
+
parsePort,
|
|
10563
|
+
8090
|
|
10564
|
+
).option(
|
|
10565
|
+
"--localnet-readiness-port <port>",
|
|
10566
|
+
"Port to use for Aptos localnet readiness",
|
|
10567
|
+
parsePort,
|
|
10568
|
+
8070
|
|
10569
|
+
).option(
|
|
10570
|
+
"--nci-processor-metrics-port <port>",
|
|
10571
|
+
"Port to use for no-code indexer processor metrics",
|
|
10572
|
+
parsePort,
|
|
10573
|
+
7654
|
|
10574
|
+
).option(
|
|
10575
|
+
"--nci-indexer-api-port <port>",
|
|
10576
|
+
"Port to use for no-code indexer API",
|
|
10577
|
+
parsePort,
|
|
10578
|
+
8091
|
|
10579
|
+
).option(
|
|
10580
|
+
"--rpc-port <port>",
|
|
10581
|
+
"Port to use for the Shelby RPC",
|
|
10582
|
+
parsePort,
|
|
10583
|
+
8093
|
|
10584
|
+
).option(
|
|
10585
|
+
"--skip-nci",
|
|
10586
|
+
"Skip running the no-code indexer processor + API",
|
|
10587
|
+
false
|
|
10588
|
+
).option("--skip-rpc", "Skip running the Shelby RPC", false).action(async (options) => {
|
|
10589
|
+
const dataPath = path9.resolve(options.dataPath);
|
|
10590
|
+
const shelbyRepo = options.dockerRepo || "";
|
|
10591
|
+
const shelbyRepoWithSlash = shelbyRepo ? `${shelbyRepo}/` : "";
|
|
10592
|
+
setDebugEnabled(options.debug);
|
|
10593
|
+
const spinner = ora3();
|
|
10594
|
+
console.log("\u{1F680} Starting Shelby localnet...\n");
|
|
10595
|
+
console.log(`\u{1F5C2}\uFE0F Data path: ${dataPath}`);
|
|
10596
|
+
if (options.reset) {
|
|
10597
|
+
console.log("\u{1F5D1}\uFE0F Reset flag set - wiping data before starting");
|
|
10598
|
+
}
|
|
10599
|
+
if (shelbyRepo) {
|
|
10600
|
+
console.log(
|
|
10601
|
+
`\u{1F433} Using Docker registry for Shelby images: ${shelbyRepo}`
|
|
10602
|
+
);
|
|
10603
|
+
}
|
|
10604
|
+
console.log("");
|
|
10605
|
+
if (options.reset && fs10.existsSync(dataPath)) {
|
|
10606
|
+
const spinner2 = ora3("Removing existing data...").start();
|
|
10607
|
+
fs10.rmSync(dataPath, { recursive: true, force: true });
|
|
10608
|
+
spinner2.succeed("Data path wiped");
|
|
10609
|
+
}
|
|
10610
|
+
debug(`Creating localnet data in ${dataPath}...`);
|
|
10611
|
+
fs10.mkdirSync(dataPath, { recursive: true });
|
|
10612
|
+
fs10.mkdirSync(path9.join(dataPath, "postgres"), { recursive: true });
|
|
10613
|
+
fs10.mkdirSync(path9.join(dataPath, "nci"), { recursive: true });
|
|
10614
|
+
fs10.mkdirSync(path9.join(dataPath, "rpc", "blobs"), { recursive: true });
|
|
10615
|
+
debug("Directory structure created");
|
|
10616
|
+
const nciConfigPath = path9.join(dataPath, "nci", "shelby_internal.yaml");
|
|
10617
|
+
fs10.writeFileSync(nciConfigPath, nciConfigContent);
|
|
10618
|
+
fs10.writeFileSync(
|
|
10619
|
+
path9.join(dataPath, "nci", "hasura_metadata.json"),
|
|
10620
|
+
hasuraMetadataContent
|
|
10621
|
+
);
|
|
10622
|
+
const nciConfig = parse2(nciConfigContent);
|
|
10623
|
+
nciConfig.common_config.transaction_stream_config.indexer_grpc_data_service_address = `http://${shelbyAptosLocalnet}:${options.txnStreamPort}`;
|
|
10624
|
+
nciConfig.common_config.db_config.postgres_connection_string = `postgresql://postgres:postgres@${shelbyPostgres}:${options.postgresPort}/${nciPostgresDatabase}`;
|
|
10625
|
+
nciConfig.common_config.health_check_port = options.nciProcessorMetricsPort;
|
|
10626
|
+
fs10.writeFileSync(nciConfigPath, stringify(nciConfig, { indent: 2 }));
|
|
10627
|
+
debug("Generating docker-compose.yml...");
|
|
10628
|
+
const additionalAptosLocalnetArgs = options.additionalAptosLocalnetArgs ? options.additionalAptosLocalnetArgs.split(" ") : [];
|
|
10629
|
+
const composeConfig = createDockerCompose({
|
|
10630
|
+
shelbyRepoWithSlash,
|
|
10631
|
+
tags: {
|
|
10632
|
+
aptosLocalnet: options.aptosLocalnetTag,
|
|
10633
|
+
nciProcessor: options.nciProcessorTag,
|
|
10634
|
+
hasura: options.hasuraTag,
|
|
10635
|
+
rpc: options.rpcTag
|
|
10636
|
+
},
|
|
10637
|
+
skipNci: options.skipNci,
|
|
10638
|
+
skipRpc: options.skipRpc,
|
|
10639
|
+
ports: {
|
|
10640
|
+
postgres: options.postgresPort,
|
|
10641
|
+
faucet: options.faucetPort,
|
|
10642
|
+
txnStream: options.txnStreamPort,
|
|
10643
|
+
coreIndexerApi: options.coreIndexerApiPort,
|
|
10644
|
+
localnetReadiness: options.localnetReadinessPort,
|
|
10645
|
+
nciProcessorMetrics: options.nciProcessorMetricsPort,
|
|
10646
|
+
nciIndexerApi: options.nciIndexerApiPort,
|
|
10647
|
+
rpc: options.rpcPort
|
|
10648
|
+
},
|
|
10649
|
+
hostDataPath: dataPath,
|
|
10650
|
+
additionalAptosLocalnetArgs
|
|
10651
|
+
});
|
|
10652
|
+
const dockerComposePath = path9.join(dataPath, "docker-compose.yml");
|
|
10653
|
+
fs10.writeFileSync(
|
|
10654
|
+
dockerComposePath,
|
|
10655
|
+
stringify(composeConfig, { indent: 2 })
|
|
10656
|
+
);
|
|
10657
|
+
debug("docker-compose.yml generated");
|
|
10658
|
+
let dockerode;
|
|
10659
|
+
try {
|
|
10660
|
+
dockerode = new Dockerode();
|
|
10661
|
+
} catch (error) {
|
|
10662
|
+
console.error("Failed to connect to Docker, is it running?");
|
|
10663
|
+
throw error;
|
|
10664
|
+
}
|
|
10665
|
+
try {
|
|
10666
|
+
const deletedItems = await cleanupLocalnet(dockerode);
|
|
10667
|
+
if (deletedItems.length > 0) {
|
|
10668
|
+
debug(
|
|
10669
|
+
`Cleaned up leftover Docker resources from previous localnet: ${deletedItems.join(", ")}`
|
|
10670
|
+
);
|
|
10671
|
+
} else {
|
|
10672
|
+
debug("No leftover Docker resources found");
|
|
10673
|
+
}
|
|
10674
|
+
} catch (error) {
|
|
10675
|
+
console.error("Failed to clean up leftover Docker resources");
|
|
10676
|
+
throw error;
|
|
10677
|
+
}
|
|
10678
|
+
console.log("\nStarting services...");
|
|
10679
|
+
let logsProcess = null;
|
|
10680
|
+
let isShuttingDown = false;
|
|
10681
|
+
const shutdownHandler = async (signal) => {
|
|
10682
|
+
if (isShuttingDown) {
|
|
10683
|
+
console.log("\n\u26A0\uFE0F Second interrupt received, forcing exit...");
|
|
10684
|
+
process.exit(1);
|
|
10685
|
+
}
|
|
10686
|
+
isShuttingDown = true;
|
|
10687
|
+
console.log(`
|
|
10688
|
+
|
|
10689
|
+
\u{1F6D1} Received ${signal}, shutting down gracefully...`);
|
|
10690
|
+
console.log(" (Press Ctrl+C again to force exit)\n");
|
|
10691
|
+
try {
|
|
10692
|
+
if (logsProcess && !logsProcess.killed) {
|
|
10693
|
+
logsProcess.kill("SIGTERM");
|
|
10694
|
+
}
|
|
10695
|
+
await execa(
|
|
10696
|
+
"docker",
|
|
10697
|
+
["compose", "-f", dockerComposePath, "-p", LOCALNET_NAME, "down"],
|
|
10698
|
+
{
|
|
10699
|
+
stdio: "inherit"
|
|
10700
|
+
}
|
|
10701
|
+
);
|
|
10702
|
+
console.log("\n\u2705 Localnet shut down gracefully");
|
|
10703
|
+
process.exit(0);
|
|
10704
|
+
} catch (error) {
|
|
10705
|
+
console.error("\n\u274C Error during shutdown:", error);
|
|
10706
|
+
process.exit(1);
|
|
10707
|
+
}
|
|
10708
|
+
};
|
|
10709
|
+
process.on("SIGINT", () => {
|
|
10710
|
+
if (!isShuttingDown) {
|
|
10711
|
+
shutdownHandler("SIGINT");
|
|
10712
|
+
}
|
|
10713
|
+
});
|
|
10714
|
+
try {
|
|
10715
|
+
await execa(
|
|
10716
|
+
"docker",
|
|
10717
|
+
["compose", "-f", dockerComposePath, "-p", LOCALNET_NAME, "up", "-d"],
|
|
10718
|
+
{
|
|
10719
|
+
stdio: "inherit"
|
|
10720
|
+
}
|
|
10721
|
+
);
|
|
10722
|
+
console.log("\u2714 Services spawned");
|
|
10723
|
+
spinner.start("Waiting up to 2 minutes for services to be healthy...");
|
|
10724
|
+
await execa(
|
|
10725
|
+
"docker",
|
|
10726
|
+
[
|
|
10727
|
+
"compose",
|
|
10728
|
+
"-f",
|
|
10729
|
+
dockerComposePath,
|
|
10730
|
+
"-p",
|
|
10731
|
+
LOCALNET_NAME,
|
|
10732
|
+
"up",
|
|
10733
|
+
"--wait",
|
|
10734
|
+
"--wait-timeout",
|
|
10735
|
+
"120"
|
|
10736
|
+
],
|
|
10737
|
+
{
|
|
10738
|
+
stdio: "pipe"
|
|
10739
|
+
}
|
|
10740
|
+
);
|
|
10741
|
+
spinner.succeed("All services are healthy");
|
|
10742
|
+
} catch (error) {
|
|
10743
|
+
spinner.fail(
|
|
10744
|
+
`Failed to start services, try running: docker compose -p ${LOCALNET_NAME} logs -f`
|
|
10745
|
+
);
|
|
10746
|
+
throw error;
|
|
10747
|
+
}
|
|
10748
|
+
console.log();
|
|
10749
|
+
spinner.start("Running post-startup steps...");
|
|
10750
|
+
if (!options.skipNci) {
|
|
10751
|
+
try {
|
|
10752
|
+
await applyAndConfirmHasuraMetadata(
|
|
10753
|
+
`http://127.0.0.1:${options.nciIndexerApiPort}`,
|
|
10754
|
+
hasuraMetadataContent
|
|
10755
|
+
);
|
|
10756
|
+
} catch (error) {
|
|
10757
|
+
spinner.fail(`Failed to apply Hasura metadata: ${error}`);
|
|
10758
|
+
throw error;
|
|
10759
|
+
}
|
|
10760
|
+
}
|
|
10761
|
+
spinner.succeed("Post-startup steps complete");
|
|
10762
|
+
console.log("\n\u2705 Shelby localnet is running!\n");
|
|
10763
|
+
console.log("\u{1F4CD} Service Endpoints:");
|
|
10764
|
+
console.log(` Aptos REST API: http://127.0.0.1:${aptosNodePort}`);
|
|
10765
|
+
console.log(
|
|
10766
|
+
` Aptos Faucet: http://127.0.0.1:${options.faucetPort}`
|
|
10767
|
+
);
|
|
10768
|
+
if (!options.skipRpc) {
|
|
10769
|
+
console.log(
|
|
10770
|
+
` Shelby RPC Server: http://127.0.0.1:${options.rpcPort}`
|
|
10771
|
+
);
|
|
10772
|
+
}
|
|
10773
|
+
console.log(
|
|
10774
|
+
` Transaction Stream: http://127.0.0.1:${options.txnStreamPort}`
|
|
10775
|
+
);
|
|
10776
|
+
console.log(
|
|
10777
|
+
` Core Indexer API: http://127.0.0.1:${options.coreIndexerApiPort}`
|
|
10778
|
+
);
|
|
10779
|
+
if (!options.skipNci) {
|
|
10780
|
+
console.log(
|
|
10781
|
+
` No-Code Indexer API: http://127.0.0.1:${options.nciIndexerApiPort}`
|
|
10782
|
+
);
|
|
10783
|
+
}
|
|
10784
|
+
console.log(
|
|
10785
|
+
` Postgres: postgresql://postgres:postgres@127.0.0.1:${options.postgresPort}/${corePostgresDatabase}`
|
|
10786
|
+
);
|
|
10787
|
+
console.log("");
|
|
10788
|
+
if (options.f) {
|
|
10789
|
+
console.log("\u{1F4DA} Following logs (press Ctrl+C to stop)...");
|
|
10790
|
+
console.log("");
|
|
10791
|
+
try {
|
|
10792
|
+
logsProcess = execa(
|
|
10793
|
+
"docker",
|
|
10794
|
+
[
|
|
10795
|
+
"compose",
|
|
10796
|
+
"-f",
|
|
10797
|
+
dockerComposePath,
|
|
10798
|
+
"-p",
|
|
10799
|
+
LOCALNET_NAME,
|
|
10800
|
+
"logs",
|
|
10801
|
+
"-f"
|
|
10802
|
+
],
|
|
10803
|
+
{
|
|
10804
|
+
stdio: "inherit",
|
|
10805
|
+
reject: false
|
|
10806
|
+
}
|
|
10807
|
+
);
|
|
10808
|
+
await logsProcess;
|
|
10809
|
+
} catch (error) {
|
|
10810
|
+
console.error("Error while following logs:", error);
|
|
10811
|
+
throw error;
|
|
10812
|
+
}
|
|
10813
|
+
} else {
|
|
10814
|
+
console.log(
|
|
10815
|
+
[
|
|
10816
|
+
"\u{1F4DA} To view logs:",
|
|
10817
|
+
` docker compose -p ${LOCALNET_NAME} logs -f`,
|
|
10818
|
+
"",
|
|
10819
|
+
"\u{1F52C} To check the status:",
|
|
10820
|
+
` docker compose -p ${LOCALNET_NAME} ps --format 'table {{.Name}}\\t{{.State}}'`,
|
|
10821
|
+
"",
|
|
10822
|
+
"\u{1F6D1} To stop:",
|
|
10823
|
+
` docker compose -p ${LOCALNET_NAME} down`,
|
|
10824
|
+
""
|
|
10825
|
+
].join("\n")
|
|
10826
|
+
);
|
|
10827
|
+
}
|
|
10828
|
+
});
|
|
10829
|
+
}
|
|
10830
|
+
|
|
10831
|
+
// src/commands/localnet/index.tsx
|
|
10832
|
+
function localnetCommand(program) {
|
|
10833
|
+
const localnetCmd = program.command("localnet").description("Manage Shelby localnet");
|
|
10834
|
+
localnetStartCommand(localnetCmd);
|
|
10835
|
+
}
|
|
10836
|
+
|
|
10837
|
+
// src/cli.tsx
|
|
10838
|
+
var DEFAULT_CONTEXT = "default_context";
|
|
10839
|
+
var DEFAULT_ACCOUNT = "default_account";
|
|
10840
|
+
function getBaseCommand(defaultContext, defaultAccount) {
|
|
10841
|
+
return new Command().name("shelby").description(
|
|
9429
10842
|
"CLI tool for preparing, uploading, and reading video content on Shelby"
|
|
9430
10843
|
).version(version).option("-v, --verbose", "Enable verbose logging", false).option(
|
|
9431
10844
|
"-C, --config-file <path>",
|
|
9432
|
-
"Path to your Shelby CLI config"
|
|
9433
|
-
"~/.shelby/config.yaml"
|
|
10845
|
+
"Path to your Shelby CLI config (defaults to ~/.shelby/config.yaml unless config_location_behavior in global config is set to 'walk')"
|
|
9434
10846
|
).option(
|
|
9435
10847
|
"-c, --context <name>",
|
|
9436
|
-
"Load endpoints from contexts.<name>",
|
|
9437
|
-
|
|
10848
|
+
"Load endpoints from contexts.<name> (defaults to default_context in config)",
|
|
10849
|
+
defaultContext || "default_context"
|
|
9438
10850
|
).option(
|
|
9439
10851
|
"-a, --account <name>",
|
|
9440
|
-
"Load signing credentials from accounts.<name>",
|
|
9441
|
-
|
|
10852
|
+
"Load signing credentials from accounts.<name> (defaults to default_account in config)",
|
|
10853
|
+
defaultAccount || "default_account"
|
|
10854
|
+
);
|
|
10855
|
+
}
|
|
10856
|
+
function parseConfigFileArg() {
|
|
10857
|
+
const args = process.argv;
|
|
10858
|
+
for (let i = 0; i < args.length; i++) {
|
|
10859
|
+
if (args[i] === "--config-file" || args[i] === "-C") {
|
|
10860
|
+
if (i + 1 >= args.length || args[i + 1].startsWith("-")) {
|
|
10861
|
+
console.error(
|
|
10862
|
+
`\u274C Missing required value for ${args[i]} argument. Please provide a config file path after ${args[i]}.`
|
|
10863
|
+
);
|
|
10864
|
+
process.exit(1);
|
|
10865
|
+
}
|
|
10866
|
+
return args[i + 1];
|
|
10867
|
+
}
|
|
10868
|
+
}
|
|
10869
|
+
return void 0;
|
|
10870
|
+
}
|
|
10871
|
+
function createProgram() {
|
|
10872
|
+
const explicitConfigPath = parseConfigFileArg();
|
|
10873
|
+
let config;
|
|
10874
|
+
try {
|
|
10875
|
+
const configPath = explicitConfigPath || findExistingConfigPath();
|
|
10876
|
+
config = loadConfig(configPath);
|
|
10877
|
+
} catch (_err) {
|
|
10878
|
+
config = void 0;
|
|
10879
|
+
}
|
|
10880
|
+
const program = getBaseCommand(
|
|
10881
|
+
config?.default_context,
|
|
10882
|
+
config?.default_account
|
|
9442
10883
|
);
|
|
9443
10884
|
initCommand(program);
|
|
9444
10885
|
accountCommand(program);
|
|
10886
|
+
configCommand(program);
|
|
9445
10887
|
contextCommand(program);
|
|
9446
10888
|
downloadCommand(program);
|
|
9447
10889
|
faucetCommand(program);
|
|
10890
|
+
localnetCommand(program);
|
|
9448
10891
|
uploadCommand(program);
|
|
9449
10892
|
commitmentCommand(program);
|
|
9450
10893
|
return program;
|