@secondlayer/cli 23.0.0 → 23.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +158 -19
- package/dist/cli.js.map +6 -5
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -31507,7 +31507,7 @@ function client() {
|
|
|
31507
31507
|
apiKey: resolveDataPlaneKey()
|
|
31508
31508
|
});
|
|
31509
31509
|
}
|
|
31510
|
-
function
|
|
31510
|
+
function fail2(action, err) {
|
|
31511
31511
|
const message = err instanceof Error ? err.message : String(err);
|
|
31512
31512
|
error(`Failed to ${action}: ${message}`);
|
|
31513
31513
|
if (/\b403\b/.test(message) || /forbidden/i.test(message)) {
|
|
@@ -31598,7 +31598,7 @@ function registerIndexCommand(program) {
|
|
|
31598
31598
|
recipient: o.recipient
|
|
31599
31599
|
}), o.json);
|
|
31600
31600
|
} catch (err) {
|
|
31601
|
-
|
|
31601
|
+
fail2("list ft transfers", err);
|
|
31602
31602
|
}
|
|
31603
31603
|
});
|
|
31604
31604
|
orderFlag(rangeFlags(index.command("nft-transfers"))).description("List decoded SIP-009 non-fungible-token transfers").option("--sender <principal>", "Filter by sender").option("--recipient <principal>", "Filter by recipient").option("--asset-identifier <id>", "Filter by asset identifier").action(async (o) => {
|
|
@@ -31611,7 +31611,7 @@ function registerIndexCommand(program) {
|
|
|
31611
31611
|
assetIdentifier: o.assetIdentifier
|
|
31612
31612
|
}), o.json);
|
|
31613
31613
|
} catch (err) {
|
|
31614
|
-
|
|
31614
|
+
fail2("list nft transfers", err);
|
|
31615
31615
|
}
|
|
31616
31616
|
});
|
|
31617
31617
|
orderFlag(rangeFlags(index.command("events"))).description("List decoded events by type (stx_*, ft/nft mint/burn, print, …)").option("--event-type <type>", `decoded event type (${VALID_INDEX_TYPES.join(", ")})`).option("--types <type>", "alias for --event-type, ONE value (the Streams spelling)").option("--sender <principal>", "Filter by sender").option("--recipient <principal>", "Filter by recipient").option("--asset-identifier <id>", "Filter by asset identifier").action(async (o) => {
|
|
@@ -31625,7 +31625,7 @@ function registerIndexCommand(program) {
|
|
|
31625
31625
|
assetIdentifier: o.assetIdentifier
|
|
31626
31626
|
}), o.json);
|
|
31627
31627
|
} catch (err) {
|
|
31628
|
-
|
|
31628
|
+
fail2("list events", err);
|
|
31629
31629
|
}
|
|
31630
31630
|
});
|
|
31631
31631
|
rangeFlags(index.command("contract-calls")).description("List decoded contract calls (function, args, result)").option("--function-name <name>", "Filter by called function").option("--sender <principal>", "Filter by caller").action(async (o) => {
|
|
@@ -31636,21 +31636,21 @@ function registerIndexCommand(program) {
|
|
|
31636
31636
|
sender: o.sender
|
|
31637
31637
|
}), o.json);
|
|
31638
31638
|
} catch (err) {
|
|
31639
|
-
|
|
31639
|
+
fail2("list contract calls", err);
|
|
31640
31640
|
}
|
|
31641
31641
|
});
|
|
31642
31642
|
heightFlags(index.command("canonical")).description("List the canonical Stacks block sequence (height + hash)").action(async (o) => {
|
|
31643
31643
|
try {
|
|
31644
31644
|
emit(await client().canonical.list(heightParams(o)), o.json);
|
|
31645
31645
|
} catch (err) {
|
|
31646
|
-
|
|
31646
|
+
fail2("list canonical blocks", err);
|
|
31647
31647
|
}
|
|
31648
31648
|
});
|
|
31649
31649
|
const blocks = heightFlags(index.command("blocks")).description("List decoded blocks (run `blocks get <ref>` for one block)").action(async (o) => {
|
|
31650
31650
|
try {
|
|
31651
31651
|
emit(await client().blocks.list(heightParams(o)), o.json);
|
|
31652
31652
|
} catch (err) {
|
|
31653
|
-
|
|
31653
|
+
fail2("list blocks", err);
|
|
31654
31654
|
}
|
|
31655
31655
|
});
|
|
31656
31656
|
blocks.command("get <ref>").description("Get a single block by height or block hash").option("--json", "Print as JSON").action(async (ref, o) => {
|
|
@@ -31658,7 +31658,7 @@ function registerIndexCommand(program) {
|
|
|
31658
31658
|
const block = await client().blocks.get(/^\d+$/.test(ref) ? Number.parseInt(ref, 10) : ref);
|
|
31659
31659
|
emitOne(block, `block ${ref}`, o.json);
|
|
31660
31660
|
} catch (err) {
|
|
31661
|
-
|
|
31661
|
+
fail2("get block", err);
|
|
31662
31662
|
}
|
|
31663
31663
|
});
|
|
31664
31664
|
const transactions = rangeFlags(index.command("transactions")).description("List decoded transactions (run `transactions get <txId>` for one)").option("--type <type>", "Filter by transaction type").option("--sender <principal>", "Filter by sender").action(async (o) => {
|
|
@@ -31669,14 +31669,14 @@ function registerIndexCommand(program) {
|
|
|
31669
31669
|
sender: o.sender
|
|
31670
31670
|
}), o.json);
|
|
31671
31671
|
} catch (err) {
|
|
31672
|
-
|
|
31672
|
+
fail2("list transactions", err);
|
|
31673
31673
|
}
|
|
31674
31674
|
});
|
|
31675
31675
|
transactions.command("get <txId>").description("Get a single transaction by tx_id").option("--json", "Print as JSON").action(async (txId, o) => {
|
|
31676
31676
|
try {
|
|
31677
31677
|
emitOne(await client().transactions.get(txId), `tx ${txId}`, o.json);
|
|
31678
31678
|
} catch (err) {
|
|
31679
|
-
|
|
31679
|
+
fail2("get transaction", err);
|
|
31680
31680
|
}
|
|
31681
31681
|
});
|
|
31682
31682
|
heightFlags(index.command("stacking")).description("List decoded PoX-4 stacking actions").option("--function-name <name>", "Filter by PoX function name").option("--stacker <principal>", "Filter by stacker").option("--caller <principal>", "Filter by caller").action(async (o) => {
|
|
@@ -31688,7 +31688,7 @@ function registerIndexCommand(program) {
|
|
|
31688
31688
|
caller: o.caller
|
|
31689
31689
|
}), o.json);
|
|
31690
31690
|
} catch (err) {
|
|
31691
|
-
|
|
31691
|
+
fail2("list stacking actions", err);
|
|
31692
31692
|
}
|
|
31693
31693
|
});
|
|
31694
31694
|
const mempool = index.command("mempool").description("List pending mempool transactions (run `mempool get <txId>` for one)").option("--contract-id <id>", "Filter to pending calls to a contract").option("--function-name <name>", "Filter to pending calls to a function").option("--sender <principal>", "Filter by sender").option("--type <type>", "Filter by transaction type").option("--cursor <cursor>", "Resume token from a previous next_cursor").option("--limit <n>", "Rows per page").option("--json", "Print the full envelope as JSON").action(async (o) => {
|
|
@@ -31702,14 +31702,14 @@ function registerIndexCommand(program) {
|
|
|
31702
31702
|
limit: o.limit ? Number.parseInt(o.limit, 10) : undefined
|
|
31703
31703
|
}), o.json);
|
|
31704
31704
|
} catch (err) {
|
|
31705
|
-
|
|
31705
|
+
fail2("list mempool", err);
|
|
31706
31706
|
}
|
|
31707
31707
|
});
|
|
31708
31708
|
mempool.command("get <txId>").description("Get a single pending transaction by tx_id (404 once mined)").option("--json", "Print as JSON").action(async (txId, o) => {
|
|
31709
31709
|
try {
|
|
31710
31710
|
emitOne(await client().mempool.get(txId), `pending tx ${txId}`, o.json);
|
|
31711
31711
|
} catch (err) {
|
|
31712
|
-
|
|
31712
|
+
fail2("get mempool tx", err);
|
|
31713
31713
|
}
|
|
31714
31714
|
});
|
|
31715
31715
|
const runes = index.command("runes").description("List etched runes (Bitcoin; run `runes get <rune>` for one)").option("--search <prefix>", "Name prefix, spacers and case ignored").option("--sort <order>", "number (etch order) or mints (busiest first)").option("--cursor <cursor>", "Resume token from a previous next_cursor").option("--limit <n>", "Rows per page").option("--json", "Print the full envelope as JSON").action(async (o) => {
|
|
@@ -31721,7 +31721,7 @@ function registerIndexCommand(program) {
|
|
|
31721
31721
|
limit: o.limit ? Number.parseInt(o.limit, 10) : undefined
|
|
31722
31722
|
}), o.json);
|
|
31723
31723
|
} catch (err) {
|
|
31724
|
-
|
|
31724
|
+
fail2("list runes", err);
|
|
31725
31725
|
}
|
|
31726
31726
|
});
|
|
31727
31727
|
runes.command("get <rune>").description("Get one rune by id (840000:3) or name, any spacing or case").option("--json", "Print as JSON").action(async (rune, _o, cmd) => {
|
|
@@ -31729,7 +31729,7 @@ function registerIndexCommand(program) {
|
|
|
31729
31729
|
try {
|
|
31730
31730
|
emitOne(await client().runes.get(rune), `rune ${rune}`, o.json);
|
|
31731
31731
|
} catch (err) {
|
|
31732
|
-
|
|
31732
|
+
fail2("get rune", err);
|
|
31733
31733
|
}
|
|
31734
31734
|
});
|
|
31735
31735
|
runes.command("balances").description("Current rune balances by address or outpoint (Bitcoin)").option("--address <address>", "Bitcoin address").option("--outpoint <txid:vout>", "Unspent output").option("--rune <ref>", "Narrow to one rune (id or name)").option("--cursor <cursor>", "Resume token from a previous next_cursor").option("--limit <n>", "Rows per page").option("--json", "Print the full envelope as JSON").action(async (_o, cmd) => {
|
|
@@ -31742,7 +31742,7 @@ function registerIndexCommand(program) {
|
|
|
31742
31742
|
limit: o.limit ? Number.parseInt(o.limit, 10) : undefined
|
|
31743
31743
|
}), o.json);
|
|
31744
31744
|
} catch (err) {
|
|
31745
|
-
|
|
31745
|
+
fail2("list rune balances", err);
|
|
31746
31746
|
}
|
|
31747
31747
|
});
|
|
31748
31748
|
runes.command("activity").description("List rune etches, mints, transfers and burns (Bitcoin)").option("--rune <ref>", "Filter by rune (id or name)").option("--address <address>", "Filter by Bitcoin address").option("--kind <kinds>", `Comma list of ${RUNE_KINDS.join(", ")}`).option("--txid <txid>", "Filter by Bitcoin transaction id").option("--from-height <n>", "Start Bitcoin block height (inclusive)").option("--to-height <n>", "End Bitcoin block height (inclusive)").option("--cursor <cursor>", "Resume token from a previous next_cursor").option("--limit <n>", "Rows per page").option("--json", "Print the full envelope as JSON").action(async (_o, cmd) => {
|
|
@@ -31756,7 +31756,7 @@ function registerIndexCommand(program) {
|
|
|
31756
31756
|
txid: o.txid
|
|
31757
31757
|
}), o.json);
|
|
31758
31758
|
} catch (err) {
|
|
31759
|
-
|
|
31759
|
+
fail2("list rune activity", err);
|
|
31760
31760
|
}
|
|
31761
31761
|
});
|
|
31762
31762
|
}
|
|
@@ -31888,7 +31888,7 @@ var {
|
|
|
31888
31888
|
// package.json
|
|
31889
31889
|
var package_default = {
|
|
31890
31890
|
name: "@secondlayer/cli",
|
|
31891
|
-
version: "23.
|
|
31891
|
+
version: "23.1.0",
|
|
31892
31892
|
description: "Run a Stacks index on your own hardware — set it up, restore verified history, and keep it current.",
|
|
31893
31893
|
repository: {
|
|
31894
31894
|
type: "git",
|
|
@@ -34546,6 +34546,144 @@ async function runRefill(opts) {
|
|
|
34546
34546
|
}
|
|
34547
34547
|
});
|
|
34548
34548
|
}
|
|
34549
|
+
// src/commands/keys.ts
|
|
34550
|
+
init_http();
|
|
34551
|
+
init_output();
|
|
34552
|
+
init_session();
|
|
34553
|
+
import { resolveAccountKey as resolveAccountKey4 } from "@secondlayer/sdk";
|
|
34554
|
+
var MIN_ID_REF_LENGTH = 8;
|
|
34555
|
+
function rotatableKeys(keys) {
|
|
34556
|
+
return keys.filter((k) => k.status === "active" && k.product === "account");
|
|
34557
|
+
}
|
|
34558
|
+
function describeKey(key) {
|
|
34559
|
+
return `${key.id.slice(0, 8)} ${key.name ?? "(unnamed)"}`;
|
|
34560
|
+
}
|
|
34561
|
+
function resolveKeyRef(keys, ref) {
|
|
34562
|
+
const candidates = rotatableKeys(keys);
|
|
34563
|
+
const barePrefix = ref.replace(/…$/, "");
|
|
34564
|
+
const kinds = [
|
|
34565
|
+
(k) => k.id === ref || ref.length >= MIN_ID_REF_LENGTH && k.id.startsWith(ref),
|
|
34566
|
+
(k) => k.prefix === barePrefix,
|
|
34567
|
+
(k) => k.name === ref
|
|
34568
|
+
];
|
|
34569
|
+
for (const matches of kinds) {
|
|
34570
|
+
const found = candidates.filter(matches);
|
|
34571
|
+
if (found.length === 1)
|
|
34572
|
+
return found[0];
|
|
34573
|
+
if (found.length > 1) {
|
|
34574
|
+
throw new Error(`"${ref}" matches ${found.length} keys: ${found.map(describeKey).join(", ")}. Use an id.`);
|
|
34575
|
+
}
|
|
34576
|
+
}
|
|
34577
|
+
throw new Error(`No active account key matches "${ref}". Run: secondlayer keys list`);
|
|
34578
|
+
}
|
|
34579
|
+
async function applyRotationToLogin(prefix, newKey, deps = {}) {
|
|
34580
|
+
const apiUrl = deps.apiUrl ?? resolveArchiveOpsUrl();
|
|
34581
|
+
const read = deps.readSession ?? readSession;
|
|
34582
|
+
const write = deps.writeSession ?? writeSession;
|
|
34583
|
+
const envKey = "envKey" in deps ? deps.envKey : resolveAccountKey4();
|
|
34584
|
+
if (!prefix)
|
|
34585
|
+
return { loginUpdated: false, envStale: false };
|
|
34586
|
+
let loginUpdated = false;
|
|
34587
|
+
const session = await read(apiUrl);
|
|
34588
|
+
if (session?.token.startsWith(prefix)) {
|
|
34589
|
+
await write({ ...session, token: newKey }, apiUrl);
|
|
34590
|
+
loginUpdated = true;
|
|
34591
|
+
}
|
|
34592
|
+
return { loginUpdated, envStale: envKey?.startsWith(prefix) ?? false };
|
|
34593
|
+
}
|
|
34594
|
+
async function saveRotatedLogin(prefix, newKey, deps = {}) {
|
|
34595
|
+
try {
|
|
34596
|
+
return await applyRotationToLogin(prefix, newKey, deps);
|
|
34597
|
+
} catch (err) {
|
|
34598
|
+
const envKey = "envKey" in deps ? deps.envKey : resolveAccountKey4();
|
|
34599
|
+
return {
|
|
34600
|
+
loginUpdated: false,
|
|
34601
|
+
envStale: Boolean(prefix) && (envKey?.startsWith(prefix) ?? false),
|
|
34602
|
+
loginError: err instanceof Error ? err.message : String(err)
|
|
34603
|
+
};
|
|
34604
|
+
}
|
|
34605
|
+
}
|
|
34606
|
+
function fail(err) {
|
|
34607
|
+
if (err instanceof Error) {
|
|
34608
|
+
error(err.message);
|
|
34609
|
+
process.exit(1);
|
|
34610
|
+
}
|
|
34611
|
+
throw err;
|
|
34612
|
+
}
|
|
34613
|
+
async function fetchKeys() {
|
|
34614
|
+
const res = await httpArchiveOps("/api/keys");
|
|
34615
|
+
return res.keys;
|
|
34616
|
+
}
|
|
34617
|
+
async function runList(opts) {
|
|
34618
|
+
let keys;
|
|
34619
|
+
try {
|
|
34620
|
+
keys = rotatableKeys(await fetchKeys());
|
|
34621
|
+
} catch (err) {
|
|
34622
|
+
fail(err);
|
|
34623
|
+
}
|
|
34624
|
+
output({
|
|
34625
|
+
json: opts.json,
|
|
34626
|
+
data: {
|
|
34627
|
+
keys: keys.map(({ rowsDaily: _rowsDaily, ...rest }) => rest)
|
|
34628
|
+
},
|
|
34629
|
+
human: () => {
|
|
34630
|
+
if (keys.length === 0) {
|
|
34631
|
+
note("No active account keys. Make one at https://www.secondlayer.tools/account/keys");
|
|
34632
|
+
return;
|
|
34633
|
+
}
|
|
34634
|
+
console.log(formatTable(["ID", "NAME", "KEY", "LAST READ", "ROWS 30D"], keys.map((k) => [
|
|
34635
|
+
k.id.slice(0, 8),
|
|
34636
|
+
k.name ?? "(unnamed)",
|
|
34637
|
+
`${k.prefix}…`,
|
|
34638
|
+
k.lastUsedAt ?? "never",
|
|
34639
|
+
k.rows30d.toLocaleString("en-US")
|
|
34640
|
+
])));
|
|
34641
|
+
}
|
|
34642
|
+
});
|
|
34643
|
+
}
|
|
34644
|
+
async function runRotate(ref, opts) {
|
|
34645
|
+
let target;
|
|
34646
|
+
try {
|
|
34647
|
+
target = resolveKeyRef(await fetchKeys(), ref);
|
|
34648
|
+
} catch (err) {
|
|
34649
|
+
fail(err);
|
|
34650
|
+
}
|
|
34651
|
+
const label = target.name ?? "(unnamed)";
|
|
34652
|
+
const ok = await confirmDestructive({
|
|
34653
|
+
message: `Rotate "${label}" (${target.prefix}…)? Anything using it gets a 401 at once.`,
|
|
34654
|
+
yes: opts.yes
|
|
34655
|
+
});
|
|
34656
|
+
if (!ok) {
|
|
34657
|
+
info("Cancelled");
|
|
34658
|
+
return;
|
|
34659
|
+
}
|
|
34660
|
+
let rotated;
|
|
34661
|
+
try {
|
|
34662
|
+
rotated = await httpArchiveOps(`/api/keys/${target.id}/rotate`, { method: "POST", body: {} });
|
|
34663
|
+
} catch (err) {
|
|
34664
|
+
fail(err);
|
|
34665
|
+
}
|
|
34666
|
+
const { loginUpdated, envStale, loginError } = await saveRotatedLogin(target.prefix, rotated.key);
|
|
34667
|
+
if (opts.json) {
|
|
34668
|
+
writeData(JSON.stringify({ ...rotated, loginUpdated }, null, 2));
|
|
34669
|
+
} else {
|
|
34670
|
+
success(`Rotated ${blue(label)}. The old key has stopped working.`);
|
|
34671
|
+
writeData(rotated.key);
|
|
34672
|
+
note("Shown once. Copy it now.");
|
|
34673
|
+
}
|
|
34674
|
+
if (loginError) {
|
|
34675
|
+
warn(`Couldn't update your CLI login: ${loginError}. Run: secondlayer login --with-token`);
|
|
34676
|
+
}
|
|
34677
|
+
if (loginUpdated)
|
|
34678
|
+
info("Updated your CLI login to the new key.");
|
|
34679
|
+
if (envStale)
|
|
34680
|
+
warn("SECONDLAYER_API_KEY still holds the old key. Update it.");
|
|
34681
|
+
}
|
|
34682
|
+
function registerKeysCommand(program) {
|
|
34683
|
+
const keys = program.command("keys").description("Manage account keys");
|
|
34684
|
+
keys.command("list").alias("ls").description("List your active account keys").option("--json", "Output as JSON").action((opts) => runList(opts));
|
|
34685
|
+
keys.command("rotate <ref>").description("Replace a key's secret; the old one stops working at once").option("-y, --yes", "Skip confirmation").option("--json", "Output as JSON").action((ref, opts) => runRotate(ref, opts));
|
|
34686
|
+
}
|
|
34549
34687
|
// src/commands/codegen.ts
|
|
34550
34688
|
function registerCodegenCommand(program) {
|
|
34551
34689
|
const codegen = program.command("codegen").description("Generate typed code: contracts, subgraphs, Index, clients");
|
|
@@ -37615,6 +37753,7 @@ registerObserverCommand(program);
|
|
|
37615
37753
|
registerLoginCommand(program);
|
|
37616
37754
|
registerLogoutCommand(program);
|
|
37617
37755
|
registerWhoamiCommand(program);
|
|
37756
|
+
registerKeysCommand(program);
|
|
37618
37757
|
program.commandsGroup("Your data:");
|
|
37619
37758
|
registerSubgraphsCommand(program);
|
|
37620
37759
|
registerWebhooksCommand(program);
|
|
@@ -37638,5 +37777,5 @@ registerCreditsCommand(program);
|
|
|
37638
37777
|
registerArchiveCommand(program);
|
|
37639
37778
|
program.parse();
|
|
37640
37779
|
|
|
37641
|
-
//# debugId=
|
|
37780
|
+
//# debugId=0DC9F45DD895F4A264756E2164756E21
|
|
37642
37781
|
//# sourceMappingURL=cli.js.map
|