@shelby-protocol/cli 0.0.3 → 0.0.5
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/README.md +2 -15
- package/bin/entry.js +316 -100
- package/package.json +3 -4
package/README.md
CHANGED
|
@@ -33,18 +33,5 @@ shelby <command> [options]
|
|
|
33
33
|
|
|
34
34
|
## Binary Release
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
On homebrew, you can do:
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
brew tap oven-sh/bun
|
|
42
|
-
|
|
43
|
-
brew install bun
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
If you don't have homebrew, see https://bun.sh/get
|
|
47
|
-
|
|
48
|
-
### Run `scripts/bun-release.sh`
|
|
49
|
-
|
|
50
|
-
From `apps/cli` run `bash scripts/bun-release.sh`
|
|
36
|
+
1. Bump version
|
|
37
|
+
2. Run `npm publish`
|
package/bin/entry.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
|
|
6
6
|
// package.json
|
|
7
|
-
var version = "0.0.
|
|
7
|
+
var version = "0.0.5";
|
|
8
8
|
|
|
9
9
|
// src/commands/init.tsx
|
|
10
10
|
import { render } from "ink";
|
|
@@ -444,6 +444,135 @@ var ContextWizard = ({ onComplete }) => {
|
|
|
444
444
|
return null;
|
|
445
445
|
};
|
|
446
446
|
|
|
447
|
+
// src/components/UpdateContextWizard.tsx
|
|
448
|
+
import { Box as Box4, Text as Text4 } from "ink";
|
|
449
|
+
import TextInput4 from "ink-text-input";
|
|
450
|
+
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
451
|
+
|
|
452
|
+
// src/schemas/AptosNetworkSchema.ts
|
|
453
|
+
import { z } from "zod";
|
|
454
|
+
var AptosNetworkSchema = z.enum([
|
|
455
|
+
"mainnet",
|
|
456
|
+
"testnet",
|
|
457
|
+
"devnet",
|
|
458
|
+
"local"
|
|
459
|
+
]);
|
|
460
|
+
|
|
461
|
+
// src/schemas/EndpointSchema.ts
|
|
462
|
+
import { z as z2 } from "zod";
|
|
463
|
+
var EndpointSchema = z2.string().url("Must be a valid URL");
|
|
464
|
+
|
|
465
|
+
// src/components/UpdateContextWizard.tsx
|
|
466
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
467
|
+
var UpdateContextWizard = ({
|
|
468
|
+
contextName,
|
|
469
|
+
currentShelbyRpc,
|
|
470
|
+
currentAptosNetwork,
|
|
471
|
+
onComplete
|
|
472
|
+
}) => {
|
|
473
|
+
const [step, setStep] = useState4("shelbyRpc");
|
|
474
|
+
const [shelbyRpcEndpoint, setShelbyRpcEndpoint] = useState4(currentShelbyRpc);
|
|
475
|
+
const [aptosNetwork, setAptosNetwork] = useState4(currentAptosNetwork);
|
|
476
|
+
const [error, setError] = useState4("");
|
|
477
|
+
useEffect4(() => {
|
|
478
|
+
if (step === "done") {
|
|
479
|
+
const updates = {};
|
|
480
|
+
if (shelbyRpcEndpoint !== currentShelbyRpc) {
|
|
481
|
+
updates.shelbyRpcEndpoint = shelbyRpcEndpoint;
|
|
482
|
+
}
|
|
483
|
+
if (aptosNetwork !== currentAptosNetwork) {
|
|
484
|
+
updates.aptosNetwork = aptosNetwork;
|
|
485
|
+
}
|
|
486
|
+
onComplete(updates);
|
|
487
|
+
}
|
|
488
|
+
}, [
|
|
489
|
+
step,
|
|
490
|
+
shelbyRpcEndpoint,
|
|
491
|
+
aptosNetwork,
|
|
492
|
+
currentShelbyRpc,
|
|
493
|
+
currentAptosNetwork,
|
|
494
|
+
onComplete
|
|
495
|
+
]);
|
|
496
|
+
if (step === "shelbyRpc") {
|
|
497
|
+
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
498
|
+
/* @__PURE__ */ jsxs4(Text4, { children: [
|
|
499
|
+
"Updating context: ",
|
|
500
|
+
contextName
|
|
501
|
+
] }),
|
|
502
|
+
/* @__PURE__ */ jsxs4(Text4, { children: [
|
|
503
|
+
"Shelby RPC endpoint? (current: ",
|
|
504
|
+
currentShelbyRpc,
|
|
505
|
+
")"
|
|
506
|
+
] }),
|
|
507
|
+
error && /* @__PURE__ */ jsxs4(Text4, { color: "red", children: [
|
|
508
|
+
"Error: ",
|
|
509
|
+
error
|
|
510
|
+
] }),
|
|
511
|
+
/* @__PURE__ */ jsx4(
|
|
512
|
+
TextInput4,
|
|
513
|
+
{
|
|
514
|
+
value: shelbyRpcEndpoint,
|
|
515
|
+
placeholder: currentShelbyRpc,
|
|
516
|
+
onChange: (value) => {
|
|
517
|
+
setShelbyRpcEndpoint(value);
|
|
518
|
+
setError("");
|
|
519
|
+
},
|
|
520
|
+
onSubmit: () => {
|
|
521
|
+
if (shelbyRpcEndpoint && shelbyRpcEndpoint !== currentShelbyRpc) {
|
|
522
|
+
const result = EndpointSchema.safeParse(shelbyRpcEndpoint);
|
|
523
|
+
if (!result.success) {
|
|
524
|
+
setError(result.error.errors[0].message);
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
setError("");
|
|
529
|
+
setStep("aptosApi");
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
),
|
|
533
|
+
/* @__PURE__ */ jsx4(Text4, { color: "gray", children: "Press Enter to continue" })
|
|
534
|
+
] });
|
|
535
|
+
}
|
|
536
|
+
if (step === "aptosApi") {
|
|
537
|
+
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
538
|
+
/* @__PURE__ */ jsxs4(Text4, { children: [
|
|
539
|
+
"Aptos network? (current: ",
|
|
540
|
+
currentAptosNetwork,
|
|
541
|
+
")"
|
|
542
|
+
] }),
|
|
543
|
+
error && /* @__PURE__ */ jsxs4(Text4, { color: "red", children: [
|
|
544
|
+
"Error: ",
|
|
545
|
+
error
|
|
546
|
+
] }),
|
|
547
|
+
/* @__PURE__ */ jsx4(
|
|
548
|
+
TextInput4,
|
|
549
|
+
{
|
|
550
|
+
value: aptosNetwork,
|
|
551
|
+
placeholder: currentAptosNetwork,
|
|
552
|
+
onChange: (value) => {
|
|
553
|
+
setAptosNetwork(value);
|
|
554
|
+
setError("");
|
|
555
|
+
},
|
|
556
|
+
onSubmit: () => {
|
|
557
|
+
if (aptosNetwork && aptosNetwork !== currentAptosNetwork) {
|
|
558
|
+
const result = AptosNetworkSchema.safeParse(aptosNetwork);
|
|
559
|
+
if (!result.success) {
|
|
560
|
+
setError("Must be one of: mainnet, testnet, devnet, local");
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
setError("");
|
|
565
|
+
setStep("done");
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
),
|
|
569
|
+
/* @__PURE__ */ jsx4(Text4, { color: "gray", children: "Valid options: mainnet, testnet, devnet, local" }),
|
|
570
|
+
/* @__PURE__ */ jsx4(Text4, { color: "gray", children: "Press Enter to save changes" })
|
|
571
|
+
] });
|
|
572
|
+
}
|
|
573
|
+
return null;
|
|
574
|
+
};
|
|
575
|
+
|
|
447
576
|
// src/utils/config.ts
|
|
448
577
|
import os from "os";
|
|
449
578
|
import path from "path";
|
|
@@ -455,7 +584,7 @@ import {
|
|
|
455
584
|
} from "@aptos-labs/ts-sdk";
|
|
456
585
|
import fs from "fs-extra";
|
|
457
586
|
import YAML from "yaml";
|
|
458
|
-
import { z } from "zod";
|
|
587
|
+
import { z as z3 } from "zod";
|
|
459
588
|
|
|
460
589
|
// tests/utils/mockConfig.ts
|
|
461
590
|
var mockAccountAlice = generateEd25519Account();
|
|
@@ -493,20 +622,20 @@ var mockConfig = {
|
|
|
493
622
|
var DEFAULT_CONFIG_PATH = "~/.shelby/config.yaml";
|
|
494
623
|
|
|
495
624
|
// src/utils/config.ts
|
|
496
|
-
var ContextSchema =
|
|
497
|
-
aptos_network:
|
|
498
|
-
shelby_rpc_endpoint:
|
|
625
|
+
var ContextSchema = z3.object({
|
|
626
|
+
aptos_network: AptosNetworkSchema,
|
|
627
|
+
shelby_rpc_endpoint: EndpointSchema
|
|
499
628
|
});
|
|
500
|
-
var ConfigSchema =
|
|
501
|
-
contexts:
|
|
502
|
-
accounts:
|
|
503
|
-
|
|
504
|
-
address:
|
|
505
|
-
private_key:
|
|
629
|
+
var ConfigSchema = z3.object({
|
|
630
|
+
contexts: z3.record(ContextSchema),
|
|
631
|
+
accounts: z3.record(
|
|
632
|
+
z3.object({
|
|
633
|
+
address: z3.string().optional(),
|
|
634
|
+
private_key: z3.string({ message: "private_key must be provided" })
|
|
506
635
|
})
|
|
507
636
|
),
|
|
508
|
-
default_context:
|
|
509
|
-
default_account:
|
|
637
|
+
default_context: z3.string(),
|
|
638
|
+
default_account: z3.string()
|
|
510
639
|
});
|
|
511
640
|
function resolveConfigPath(configPath) {
|
|
512
641
|
if (configPath.startsWith("~")) {
|
|
@@ -618,7 +747,7 @@ function denormBlobName(pathModule, blobPrefix, blobName, outputPrefix) {
|
|
|
618
747
|
}
|
|
619
748
|
|
|
620
749
|
// src/commands/init.tsx
|
|
621
|
-
import { jsx as
|
|
750
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
622
751
|
function initCommand(program) {
|
|
623
752
|
program.command("init").description(
|
|
624
753
|
"Bootstrap your Shelby config via an interactive wizard or flags"
|
|
@@ -690,7 +819,7 @@ function initCommand(program) {
|
|
|
690
819
|
);
|
|
691
820
|
} else {
|
|
692
821
|
const { unmount } = render(
|
|
693
|
-
/* @__PURE__ */
|
|
822
|
+
/* @__PURE__ */ jsx5(
|
|
694
823
|
InitWizard,
|
|
695
824
|
{
|
|
696
825
|
onComplete: (config) => {
|
|
@@ -753,8 +882,8 @@ function getChunksetSizeBytes() {
|
|
|
753
882
|
|
|
754
883
|
// ../../packages/sdk/dist/chunk-LATCKOZE.mjs
|
|
755
884
|
import { AccountAddress as AccountAddress2 } from "@aptos-labs/ts-sdk";
|
|
756
|
-
import { z as
|
|
757
|
-
var BlobNameSchema =
|
|
885
|
+
import { z as z4 } from "zod";
|
|
886
|
+
var BlobNameSchema = z4.string().min(1, "Blob name path parameter cannot be empty.").max(1024, "Blob name cannot exceed 1024 characters.").refine((name2) => !name2.endsWith("/"), {
|
|
758
887
|
message: "Blob name cannot end with a slash"
|
|
759
888
|
});
|
|
760
889
|
function roundSize(size) {
|
|
@@ -1335,12 +1464,12 @@ var ShelbyBlobClient = class _ShelbyBlobClient {
|
|
|
1335
1464
|
};
|
|
1336
1465
|
|
|
1337
1466
|
// ../../packages/sdk/dist/chunk-OG3JQI44.mjs
|
|
1338
|
-
import { z as
|
|
1339
|
-
var ChunksetCommitmentSchema =
|
|
1467
|
+
import { z as z5 } from "zod";
|
|
1468
|
+
var ChunksetCommitmentSchema = z5.object({
|
|
1340
1469
|
// Chunkset root (vector commitment of child chunks)
|
|
1341
|
-
chunkset_root:
|
|
1470
|
+
chunkset_root: z5.string().nullable(),
|
|
1342
1471
|
// the size is known statically from the current configuration
|
|
1343
|
-
chunk_commitments:
|
|
1472
|
+
chunk_commitments: z5.array(z5.string())
|
|
1344
1473
|
}).refine(
|
|
1345
1474
|
(data) => {
|
|
1346
1475
|
return data.chunk_commitments.length === ERASURE_K + ERASURE_M;
|
|
@@ -1353,13 +1482,13 @@ var ChunksetCommitmentSchema = z3.object({
|
|
|
1353
1482
|
function expectedTotalChunksets(rawSize) {
|
|
1354
1483
|
return roundSize(rawSize) / getChunksetSizeBytes();
|
|
1355
1484
|
}
|
|
1356
|
-
var BlobCommitmentsSchema =
|
|
1357
|
-
schema_version:
|
|
1358
|
-
raw_data_size:
|
|
1485
|
+
var BlobCommitmentsSchema = z5.object({
|
|
1486
|
+
schema_version: z5.string(),
|
|
1487
|
+
raw_data_size: z5.number(),
|
|
1359
1488
|
// FIXME I am not sure about this being here, or if it should be somewhere else
|
|
1360
1489
|
// I deleted the blob_commitment. What's the difference?
|
|
1361
|
-
blob_merkle_root:
|
|
1362
|
-
chunkset_commitments:
|
|
1490
|
+
blob_merkle_root: z5.string(),
|
|
1491
|
+
chunkset_commitments: z5.array(ChunksetCommitmentSchema)
|
|
1363
1492
|
}).refine(
|
|
1364
1493
|
(data) => {
|
|
1365
1494
|
return expectedTotalChunksets(data.raw_data_size) === data.chunkset_commitments.length;
|
|
@@ -1377,20 +1506,20 @@ import { hashValues } from "@aptos-labs/ts-sdk";
|
|
|
1377
1506
|
// src/commands/account.tsx
|
|
1378
1507
|
import Table from "cli-table3";
|
|
1379
1508
|
import { render as render2 } from "ink";
|
|
1380
|
-
import { z as
|
|
1381
|
-
import { jsx as
|
|
1382
|
-
var CreateAccountOptionsSchema =
|
|
1383
|
-
name:
|
|
1384
|
-
privateKey:
|
|
1385
|
-
address:
|
|
1386
|
-
scheme:
|
|
1509
|
+
import { z as z6 } from "zod";
|
|
1510
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1511
|
+
var CreateAccountOptionsSchema = z6.object({
|
|
1512
|
+
name: z6.string().optional(),
|
|
1513
|
+
privateKey: z6.string().optional(),
|
|
1514
|
+
address: z6.string().optional(),
|
|
1515
|
+
scheme: z6.union([z6.literal(ED25519_NAME), z6.literal(SECP256K1_NAME)]).optional()
|
|
1387
1516
|
});
|
|
1388
|
-
var ListAccountOptionsSchema =
|
|
1389
|
-
var UseAccountOptionsSchema =
|
|
1390
|
-
accountName:
|
|
1517
|
+
var ListAccountOptionsSchema = z6.object({});
|
|
1518
|
+
var UseAccountOptionsSchema = z6.object({
|
|
1519
|
+
accountName: z6.string()
|
|
1391
1520
|
});
|
|
1392
|
-
var DeleteAccountOptionsSchema =
|
|
1393
|
-
accountName:
|
|
1521
|
+
var DeleteAccountOptionsSchema = z6.object({
|
|
1522
|
+
accountName: z6.string()
|
|
1394
1523
|
});
|
|
1395
1524
|
function accountCommand(program) {
|
|
1396
1525
|
const account = program.command("account").description("Manage signing accounts (addresses & keys)");
|
|
@@ -1428,7 +1557,7 @@ function accountCommand(program) {
|
|
|
1428
1557
|
} else {
|
|
1429
1558
|
try {
|
|
1430
1559
|
const { unmount } = render2(
|
|
1431
|
-
/* @__PURE__ */
|
|
1560
|
+
/* @__PURE__ */ jsx6(
|
|
1432
1561
|
AccountWizard,
|
|
1433
1562
|
{
|
|
1434
1563
|
onComplete: ({
|
|
@@ -1533,23 +1662,21 @@ function accountCommand(program) {
|
|
|
1533
1662
|
const configPath = program.opts().configFile;
|
|
1534
1663
|
try {
|
|
1535
1664
|
const config = loadConfig(configPath);
|
|
1665
|
+
const accountName = program.opts().account || config.default_account;
|
|
1536
1666
|
const shelbyConfig = getCurrentShelbyConfig(config, {
|
|
1537
1667
|
context: program.opts().context
|
|
1538
1668
|
});
|
|
1539
|
-
const activeAccount = getCurrentAccount(
|
|
1540
|
-
config,
|
|
1541
|
-
program.opts().account
|
|
1542
|
-
).account;
|
|
1669
|
+
const activeAccount = getCurrentAccount(config, accountName).account;
|
|
1543
1670
|
const aptos = new Aptos3(shelbyConfig.aptos.config);
|
|
1544
1671
|
const blobClient = new ShelbyBlobClient({ aptos });
|
|
1545
1672
|
console.log(
|
|
1546
|
-
`\u{1F50D} Retrieving blobs for ${
|
|
1673
|
+
`\u{1F50D} Retrieving blobs for ${accountName} (${activeAccount.accountAddress.toString()})`
|
|
1547
1674
|
);
|
|
1548
1675
|
const blobs = await blobClient.getAccountBlobs({
|
|
1549
1676
|
account: activeAccount.accountAddress
|
|
1550
1677
|
});
|
|
1551
1678
|
console.log(
|
|
1552
|
-
`\u2705 Retrieved ${blobs.length} blobs for ${activeAccount.toString()}`
|
|
1679
|
+
`\u2705 Retrieved ${blobs.length} blobs for ${accountName} (${activeAccount.accountAddress.toString()})`
|
|
1553
1680
|
);
|
|
1554
1681
|
const table = new Table({
|
|
1555
1682
|
head: [
|
|
@@ -1594,13 +1721,18 @@ function accountCommand(program) {
|
|
|
1594
1721
|
// src/commands/context.tsx
|
|
1595
1722
|
import Table2 from "cli-table3";
|
|
1596
1723
|
import { render as render3 } from "ink";
|
|
1597
|
-
import { z as
|
|
1598
|
-
import { jsx as
|
|
1599
|
-
var CreateContextOptionsSchema =
|
|
1600
|
-
name:
|
|
1601
|
-
shelbyRpcEndpoint:
|
|
1602
|
-
aptosNetwork:
|
|
1603
|
-
// TODO
|
|
1724
|
+
import { z as z7 } from "zod";
|
|
1725
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1726
|
+
var CreateContextOptionsSchema = z7.object({
|
|
1727
|
+
name: z7.string().optional(),
|
|
1728
|
+
shelbyRpcEndpoint: EndpointSchema.optional(),
|
|
1729
|
+
aptosNetwork: AptosNetworkSchema.optional()
|
|
1730
|
+
// TODO: Add support for custom endpoints objects
|
|
1731
|
+
});
|
|
1732
|
+
var UpdateContextOptionsSchema = z7.object({
|
|
1733
|
+
shelbyRpcEndpoint: EndpointSchema.optional(),
|
|
1734
|
+
aptosNetwork: AptosNetworkSchema.optional()
|
|
1735
|
+
// TODO: Add support for custom endpoints objects
|
|
1604
1736
|
});
|
|
1605
1737
|
function contextCommand(program) {
|
|
1606
1738
|
const context = program.command("context").description("Manage network contexts (Shelby RPC & Aptos endpoints)");
|
|
@@ -1629,7 +1761,7 @@ function contextCommand(program) {
|
|
|
1629
1761
|
return;
|
|
1630
1762
|
}
|
|
1631
1763
|
const { unmount } = render3(
|
|
1632
|
-
/* @__PURE__ */
|
|
1764
|
+
/* @__PURE__ */ jsx7(
|
|
1633
1765
|
ContextWizard,
|
|
1634
1766
|
{
|
|
1635
1767
|
onComplete: ({
|
|
@@ -1650,6 +1782,59 @@ function contextCommand(program) {
|
|
|
1650
1782
|
)
|
|
1651
1783
|
);
|
|
1652
1784
|
});
|
|
1785
|
+
context.command("update").description("Update an existing context").argument("<context-name>", "Name of the context to update").option("--shelby-rpc-endpoint <url>", "URL of the Shelby RPC service").option("--aptos-network <network>", "Aptos network").action((contextName, options) => {
|
|
1786
|
+
UpdateContextOptionsSchema.parse(options);
|
|
1787
|
+
const { shelbyRpcEndpoint, aptosNetwork } = options;
|
|
1788
|
+
const configPath = program.opts().configFile;
|
|
1789
|
+
let config;
|
|
1790
|
+
try {
|
|
1791
|
+
config = loadConfig(configPath);
|
|
1792
|
+
} catch (error) {
|
|
1793
|
+
console.error(`Error loading config: ${error.message}`);
|
|
1794
|
+
process.exit(1);
|
|
1795
|
+
}
|
|
1796
|
+
if (!config.contexts[contextName]) {
|
|
1797
|
+
console.error(`Error: Context '${contextName}' not found`);
|
|
1798
|
+
process.exit(1);
|
|
1799
|
+
}
|
|
1800
|
+
const currentContext = config.contexts[contextName];
|
|
1801
|
+
if (shelbyRpcEndpoint || aptosNetwork) {
|
|
1802
|
+
if (shelbyRpcEndpoint) {
|
|
1803
|
+
config.contexts[contextName].shelby_rpc_endpoint = shelbyRpcEndpoint;
|
|
1804
|
+
}
|
|
1805
|
+
if (aptosNetwork) {
|
|
1806
|
+
config.contexts[contextName].aptos_network = aptosNetwork;
|
|
1807
|
+
}
|
|
1808
|
+
saveConfig(config, configPath);
|
|
1809
|
+
console.log(`\u2705 Context '${contextName}' updated successfully`);
|
|
1810
|
+
return;
|
|
1811
|
+
}
|
|
1812
|
+
const { unmount } = render3(
|
|
1813
|
+
/* @__PURE__ */ jsx7(
|
|
1814
|
+
UpdateContextWizard,
|
|
1815
|
+
{
|
|
1816
|
+
contextName,
|
|
1817
|
+
currentShelbyRpc: currentContext.shelby_rpc_endpoint,
|
|
1818
|
+
currentAptosNetwork: currentContext.aptos_network,
|
|
1819
|
+
onComplete: ({
|
|
1820
|
+
shelbyRpcEndpoint: shelbyRpcEndpoint2,
|
|
1821
|
+
aptosNetwork: aptosNetwork2
|
|
1822
|
+
}) => {
|
|
1823
|
+
if (shelbyRpcEndpoint2) {
|
|
1824
|
+
config.contexts[contextName].shelby_rpc_endpoint = shelbyRpcEndpoint2;
|
|
1825
|
+
}
|
|
1826
|
+
if (aptosNetwork2) {
|
|
1827
|
+
config.contexts[contextName].aptos_network = aptosNetwork2;
|
|
1828
|
+
}
|
|
1829
|
+
saveConfig(config, configPath);
|
|
1830
|
+
console.log(`\u2705 Context '${contextName}' updated successfully`);
|
|
1831
|
+
unmount();
|
|
1832
|
+
process.exit(0);
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
)
|
|
1836
|
+
);
|
|
1837
|
+
});
|
|
1653
1838
|
context.command("list").description("List all contexts in a table").action(() => {
|
|
1654
1839
|
const configPath = program.opts().configFile;
|
|
1655
1840
|
let config;
|
|
@@ -1729,16 +1914,16 @@ import { Transform as Transform2 } from "stream";
|
|
|
1729
1914
|
import { pipeline } from "stream/promises";
|
|
1730
1915
|
import { Aptos as Aptos4 } from "@aptos-labs/ts-sdk";
|
|
1731
1916
|
import ora from "ora";
|
|
1732
|
-
import { z as
|
|
1917
|
+
import { z as z8 } from "zod";
|
|
1733
1918
|
var denormBlobName2 = (a, b, c) => denormBlobName(path3, a, b, c);
|
|
1734
1919
|
var endsWithDirectorySeparator = (filePath) => {
|
|
1735
1920
|
return filePath.endsWith("/") || filePath.endsWith("\\") || filePath.endsWith(path3.sep);
|
|
1736
1921
|
};
|
|
1737
|
-
var DownloadOptionsSchema =
|
|
1738
|
-
input:
|
|
1739
|
-
output:
|
|
1740
|
-
recursive:
|
|
1741
|
-
force:
|
|
1922
|
+
var DownloadOptionsSchema = z8.object({
|
|
1923
|
+
input: z8.string().min(1, "Input must be a valid blob name or directory prefix").describe("Blob name or directory prefix to download"),
|
|
1924
|
+
output: z8.string().min(1, "Output must be a valid filepath").describe("Local path where to save the downloaded content"),
|
|
1925
|
+
recursive: z8.boolean().default(false).describe("Download assuming canonical directory layout and recurse"),
|
|
1926
|
+
force: z8.boolean().default(false).describe("Overwrite the output if it already exists")
|
|
1742
1927
|
}).refine(
|
|
1743
1928
|
(data) => {
|
|
1744
1929
|
if (data.recursive) {
|
|
@@ -1982,15 +2167,16 @@ function downloadCommand(program) {
|
|
|
1982
2167
|
// src/commands/upload.tsx
|
|
1983
2168
|
import * as fs3 from "fs/promises";
|
|
1984
2169
|
import * as path4 from "path";
|
|
2170
|
+
import { Readable as Readable4 } from "stream";
|
|
1985
2171
|
import { Aptos as Aptos5 } from "@aptos-labs/ts-sdk";
|
|
1986
2172
|
import { glob } from "glob";
|
|
1987
|
-
import { Box as
|
|
2173
|
+
import { Box as Box5, Text as Text5, render as render4 } from "ink";
|
|
1988
2174
|
import SelectInput2 from "ink-select-input";
|
|
1989
2175
|
import ora2 from "ora";
|
|
1990
|
-
import { z as
|
|
1991
|
-
import { jsx as
|
|
2176
|
+
import { z as z9 } from "zod";
|
|
2177
|
+
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1992
2178
|
var normBlobName2 = (i, f, b) => normBlobName(path4, i, f, b);
|
|
1993
|
-
var flexibleDateSchema =
|
|
2179
|
+
var flexibleDateSchema = z9.string().transform((val) => {
|
|
1994
2180
|
if (/^\d+$/.test(val)) {
|
|
1995
2181
|
const timestamp = Number.parseInt(val, 10);
|
|
1996
2182
|
if (timestamp > 0 && timestamp < 4102444800) {
|
|
@@ -2003,18 +2189,18 @@ var flexibleDateSchema = z7.string().transform((val) => {
|
|
|
2003
2189
|
}
|
|
2004
2190
|
return ret;
|
|
2005
2191
|
});
|
|
2006
|
-
var UploadOptionsSchema =
|
|
2007
|
-
input:
|
|
2008
|
-
output:
|
|
2192
|
+
var UploadOptionsSchema = z9.object({
|
|
2193
|
+
input: z9.string().nonempty("`--input` is required"),
|
|
2194
|
+
output: z9.string().nonempty("`output` is required"),
|
|
2009
2195
|
expiration: flexibleDateSchema,
|
|
2010
|
-
recursive:
|
|
2011
|
-
assumeYes:
|
|
2012
|
-
outputCommitments:
|
|
2196
|
+
recursive: z9.boolean().optional().default(false),
|
|
2197
|
+
assumeYes: z9.boolean().optional().default(false),
|
|
2198
|
+
outputCommitments: z9.string().optional()
|
|
2013
2199
|
}).superRefine(async (data, ctx) => {
|
|
2014
2200
|
const stats = await fs3.stat(data.input);
|
|
2015
2201
|
if (!stats.isFile() && !stats.isDirectory()) {
|
|
2016
2202
|
ctx.addIssue({
|
|
2017
|
-
code:
|
|
2203
|
+
code: z9.ZodIssueCode.custom,
|
|
2018
2204
|
message: "`--input` must be a file or a directory",
|
|
2019
2205
|
path: ["input"]
|
|
2020
2206
|
});
|
|
@@ -2023,7 +2209,7 @@ var UploadOptionsSchema = z7.object({
|
|
|
2023
2209
|
if (stats.isDirectory()) {
|
|
2024
2210
|
if (!data.output.endsWith("/")) {
|
|
2025
2211
|
ctx.addIssue({
|
|
2026
|
-
code:
|
|
2212
|
+
code: z9.ZodIssueCode.custom,
|
|
2027
2213
|
message: "When input is a directory, output must end with '/'",
|
|
2028
2214
|
path: ["output"]
|
|
2029
2215
|
});
|
|
@@ -2032,7 +2218,7 @@ var UploadOptionsSchema = z7.object({
|
|
|
2032
2218
|
const blobNameResult = BlobNameSchema.safeParse(data.output);
|
|
2033
2219
|
if (!blobNameResult.success) {
|
|
2034
2220
|
ctx.addIssue({
|
|
2035
|
-
code:
|
|
2221
|
+
code: z9.ZodIssueCode.custom,
|
|
2036
2222
|
message: "When input is a file, output must be a valid blob name (cannot end with '/')",
|
|
2037
2223
|
path: ["output"]
|
|
2038
2224
|
});
|
|
@@ -2081,9 +2267,9 @@ function computeCost(filelist) {
|
|
|
2081
2267
|
return 1e8 * filelist.length;
|
|
2082
2268
|
}
|
|
2083
2269
|
function uploadCommand(program) {
|
|
2084
|
-
program.command("upload <input> <output>").description("Upload a file or directory to the shelby RPC in the config.").
|
|
2270
|
+
program.command("upload <input> <output>").description("Upload a file or directory to the shelby RPC in the config.").requiredOption(
|
|
2085
2271
|
"-e, --expiration <datetime>",
|
|
2086
|
-
"
|
|
2272
|
+
"UNIX Timestamp at which this blob will expire"
|
|
2087
2273
|
).option("-r, --recursive", "If uploading a directory, recurse").option(
|
|
2088
2274
|
"--assume-yes",
|
|
2089
2275
|
"Do not prompt interactively, assume yes for any questions"
|
|
@@ -2117,13 +2303,13 @@ function uploadCommand(program) {
|
|
|
2117
2303
|
if (!validatedOptions.assumeYes) {
|
|
2118
2304
|
const shouldContinue = await new Promise((resolve2) => {
|
|
2119
2305
|
const { unmount } = render4(
|
|
2120
|
-
/* @__PURE__ */
|
|
2121
|
-
/* @__PURE__ */
|
|
2306
|
+
/* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
|
|
2307
|
+
/* @__PURE__ */ jsxs5(Text5, { children: [
|
|
2122
2308
|
"Upload will cost ",
|
|
2123
2309
|
cost,
|
|
2124
2310
|
". Continue?"
|
|
2125
2311
|
] }),
|
|
2126
|
-
/* @__PURE__ */
|
|
2312
|
+
/* @__PURE__ */ jsx8(
|
|
2127
2313
|
SelectInput2,
|
|
2128
2314
|
{
|
|
2129
2315
|
items: [
|
|
@@ -2185,6 +2371,7 @@ function uploadCommand(program) {
|
|
|
2185
2371
|
for (const entry of filelist) {
|
|
2186
2372
|
totalSize += entry.sizeBytes;
|
|
2187
2373
|
}
|
|
2374
|
+
let hasUploadedBlob = false;
|
|
2188
2375
|
for (const entry of filelist) {
|
|
2189
2376
|
spinner.text = `Reading ${entry.filename}.. (Overall: ${formatProgressPercent()}%, ${formatProgressRate()} MiB/s)`;
|
|
2190
2377
|
const blobData = await fs3.readFile(entry.filename);
|
|
@@ -2194,27 +2381,52 @@ function uploadCommand(program) {
|
|
|
2194
2381
|
);
|
|
2195
2382
|
}
|
|
2196
2383
|
spinner.text = `Committing ${entry.filename} to L1.. (Overall: ${formatProgressPercent()}%, ${formatProgressRate()} MiB/s)`;
|
|
2197
|
-
const {
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
} = await shelbyBlobClient.writeBlobCommitments({
|
|
2201
|
-
account: activeAccount,
|
|
2202
|
-
blobName: entry.blobname,
|
|
2203
|
-
lifetime: validatedOptions.expiration.getTime() * 1e3,
|
|
2204
|
-
data: blobData
|
|
2384
|
+
const existingBlobMetadata = await shelbyBlobClient.getBlobMetadata({
|
|
2385
|
+
account: activeAccount.accountAddress,
|
|
2386
|
+
name: entry.blobname
|
|
2205
2387
|
});
|
|
2388
|
+
const blobCommitments = await generateCommitments(
|
|
2389
|
+
Readable4.from(blobData)
|
|
2390
|
+
);
|
|
2391
|
+
if (!existingBlobMetadata) {
|
|
2392
|
+
const { transaction: pendingWriteBlobCommitmentsTransaction } = await shelbyBlobClient.writeBlobCommitments({
|
|
2393
|
+
account: activeAccount,
|
|
2394
|
+
blobName: entry.blobname,
|
|
2395
|
+
lifetime: validatedOptions.expiration.getTime() * 1e3,
|
|
2396
|
+
blobCommitments
|
|
2397
|
+
});
|
|
2398
|
+
await aptos.waitForTransaction({
|
|
2399
|
+
transactionHash: pendingWriteBlobCommitmentsTransaction.hash
|
|
2400
|
+
});
|
|
2401
|
+
} else {
|
|
2402
|
+
spinner.text = `Blob ${entry.blobname} already exists on L1, skipping commitments and uploading to Shelby RPC...`;
|
|
2403
|
+
}
|
|
2206
2404
|
if (validatedOptions.outputCommitments) {
|
|
2207
2405
|
outputCommitments[entry.filename] = blobCommitments;
|
|
2208
2406
|
}
|
|
2209
|
-
await
|
|
2210
|
-
|
|
2407
|
+
const existingBlobChunks = await shelbyBlobClient.getBlobChunks({
|
|
2408
|
+
account: activeAccount.accountAddress,
|
|
2409
|
+
name: entry.blobname
|
|
2211
2410
|
});
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2411
|
+
if (existingBlobChunks.length === 0) {
|
|
2412
|
+
console.error(
|
|
2413
|
+
`Blob ${entry.blobname} does not exist on L1, an error occurred when uploading commitments...`
|
|
2414
|
+
);
|
|
2415
|
+
process.exit(1);
|
|
2416
|
+
}
|
|
2417
|
+
if (!existingBlobChunks.every(
|
|
2418
|
+
(chunk) => chunk.location.variant === "stored"
|
|
2419
|
+
)) {
|
|
2420
|
+
spinner.text = `Uploading ${entry.filename} to Shelby RPC.. (Overall: ${formatProgressPercent()}%, ${formatProgressRate()} MiB/s)`;
|
|
2421
|
+
await shelbyNodeClient.putBlob(
|
|
2422
|
+
activeAccount.accountAddress,
|
|
2423
|
+
entry.blobname,
|
|
2424
|
+
blobData
|
|
2425
|
+
);
|
|
2426
|
+
hasUploadedBlob = true;
|
|
2427
|
+
} else {
|
|
2428
|
+
spinner.text = "All blob chunks have been stored on L1, skipping upload to Shelby RPC...";
|
|
2429
|
+
}
|
|
2218
2430
|
amountUploaded += blobData.length;
|
|
2219
2431
|
}
|
|
2220
2432
|
if (validatedOptions.outputCommitments) {
|
|
@@ -2223,18 +2435,22 @@ function uploadCommand(program) {
|
|
|
2223
2435
|
JSON.stringify(outputCommitments)
|
|
2224
2436
|
);
|
|
2225
2437
|
}
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2438
|
+
if (hasUploadedBlob) {
|
|
2439
|
+
spinner.succeed(
|
|
2440
|
+
`Uploaded complete, ran at ${formatProgressRate()} MiB/s`
|
|
2441
|
+
);
|
|
2442
|
+
} else {
|
|
2443
|
+
spinner.succeed("Skipped upload, blob has already been uploaded.");
|
|
2444
|
+
}
|
|
2229
2445
|
});
|
|
2230
2446
|
}
|
|
2231
2447
|
|
|
2232
2448
|
// src/commands/commitment.ts
|
|
2233
2449
|
import * as fs4 from "fs";
|
|
2234
2450
|
import * as fsP from "fs/promises";
|
|
2235
|
-
import { z as
|
|
2236
|
-
var CommitmentOptionsSchema =
|
|
2237
|
-
input:
|
|
2451
|
+
import { z as z10 } from "zod";
|
|
2452
|
+
var CommitmentOptionsSchema = z10.object({
|
|
2453
|
+
input: z10.string().nonempty("`--input` is required").refine(
|
|
2238
2454
|
async (path5) => {
|
|
2239
2455
|
const stat4 = await fsP.stat(path5);
|
|
2240
2456
|
return stat4.isFile();
|
|
@@ -2243,7 +2459,7 @@ var CommitmentOptionsSchema = z8.object({
|
|
|
2243
2459
|
message: "`--input` must be a file"
|
|
2244
2460
|
}
|
|
2245
2461
|
),
|
|
2246
|
-
output:
|
|
2462
|
+
output: z10.string().nonempty("`--output` is required")
|
|
2247
2463
|
});
|
|
2248
2464
|
function commitmentCommand(program) {
|
|
2249
2465
|
program.command("commitment").description(
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shelby-protocol/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.5",
|
|
5
5
|
"private": false,
|
|
6
6
|
"bin": {
|
|
7
7
|
"shelby": "bin/entry.js"
|
|
@@ -9,9 +9,7 @@
|
|
|
9
9
|
"publishConfig": {
|
|
10
10
|
"access": "public"
|
|
11
11
|
},
|
|
12
|
-
"files": [
|
|
13
|
-
"bin/entry.js"
|
|
14
|
-
],
|
|
12
|
+
"files": ["bin/entry.js"],
|
|
15
13
|
"scripts": {
|
|
16
14
|
"prepublishOnly": "pnpm run build",
|
|
17
15
|
"lint": "biome check .",
|
|
@@ -24,6 +22,7 @@
|
|
|
24
22
|
},
|
|
25
23
|
"dependencies": {
|
|
26
24
|
"@aptos-labs/ts-sdk": "^2.0.1",
|
|
25
|
+
"@ronomon/reed-solomon": "^6.0.0",
|
|
27
26
|
"boxen": "^8.0.1",
|
|
28
27
|
"chalk": "^5.4.1",
|
|
29
28
|
"cli-table3": "^0.6.5",
|