@secondlayer/cli 23.0.0 → 23.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/cli.js +173 -31
- package/dist/cli.js.map +9 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ secondlayer --version
|
|
|
12
12
|
|
|
13
13
|
## Auth
|
|
14
14
|
|
|
15
|
-
Default API is `http://127.0.0.1:3800
|
|
15
|
+
Default API is `http://127.0.0.1:3800`, or the hosted API when only `SECONDLAYER_API_KEY` is set. Override with `SECONDLAYER_API_URL`.
|
|
16
16
|
|
|
17
17
|
Writes against a published bind use `INSTANCE_TOKEN` from `secondlayer init`.
|
|
18
18
|
Loopback reads need no token. Your hosted account (credits, archive fetches)
|
|
@@ -191,7 +191,7 @@ or poll the subgraph API: see
|
|
|
191
191
|
|---|---|
|
|
192
192
|
| `INSTANCE_TOKEN` | From `secondlayer init` for writes. Loopback reads need no token |
|
|
193
193
|
| `SECONDLAYER_API_KEY` | Hosted account key (`sk-sl_*`) |
|
|
194
|
-
| `SECONDLAYER_API_URL` |
|
|
194
|
+
| `SECONDLAYER_API_URL` | API URL. Default `http://127.0.0.1:3800`, or hosted with only `SECONDLAYER_API_KEY` set |
|
|
195
195
|
| `STACKS_NETWORK` | Default network (also via `--network <mainnet\|testnet\|devnet>`) |
|
|
196
196
|
| `DATABASE_URL` | Postgres that `bootstrap`, `verify`, `repair`, and `backup` connect to. Point it at the compose Postgres (`postgres://secondlayer:<POSTGRES_PASSWORD>@127.0.0.1:5432/secondlayer`); unset, the shared dev URL `postgres://postgres:postgres@localhost:5432/secondlayer_dev` is used |
|
|
197
197
|
| `HIRO_API_KEY` | Used by `secondlayer codegen contracts` for remote contract fetches |
|
package/dist/cli.js
CHANGED
|
@@ -2129,9 +2129,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2129
2129
|
});
|
|
2130
2130
|
|
|
2131
2131
|
// src/lib/api-url.ts
|
|
2132
|
-
import { isHostedApiUrl } from "@secondlayer/sdk";
|
|
2132
|
+
import { isHostedApiUrl, resolveBaseUrl } from "@secondlayer/sdk";
|
|
2133
2133
|
function resolveApiUrl() {
|
|
2134
|
-
return (
|
|
2134
|
+
return resolveBaseUrl();
|
|
2135
2135
|
}
|
|
2136
2136
|
function resolveArchiveOpsUrl() {
|
|
2137
2137
|
return (process.env.SL_CREDITS_API_URL ?? ARCHIVE_OPS_API_URL).replace(/\/+$/, "");
|
|
@@ -2142,8 +2142,9 @@ function isMerchantUrl(url = resolveApiUrl()) {
|
|
|
2142
2142
|
function assertInstanceUrl(url = resolveApiUrl()) {
|
|
2143
2143
|
if (!isMerchantUrl(url))
|
|
2144
2144
|
return;
|
|
2145
|
+
const fix = process.env.SECONDLAYER_API_URL ? "unset SECONDLAYER_API_URL" : "set INSTANCE_TOKEN";
|
|
2145
2146
|
throw new Error(`this command runs on your instance, not api.secondlayer.tools.
|
|
2146
|
-
|
|
2147
|
+
${fix}, or pass --api-url http://127.0.0.1:3800`);
|
|
2147
2148
|
}
|
|
2148
2149
|
var LOCAL_API_URL = "http://127.0.0.1:3800", ARCHIVE_OPS_API_URL = "https://api.secondlayer.tools";
|
|
2149
2150
|
var init_api_url = () => {};
|
|
@@ -2539,9 +2540,11 @@ var init_output = __esm(() => {
|
|
|
2539
2540
|
|
|
2540
2541
|
// src/lib/api-client.ts
|
|
2541
2542
|
import { ApiError, SecondLayer } from "@secondlayer/sdk";
|
|
2542
|
-
function nextStepHint(status, detail) {
|
|
2543
|
+
function nextStepHint(status, detail, code) {
|
|
2543
2544
|
if (status === undefined)
|
|
2544
2545
|
return;
|
|
2546
|
+
if (code === "STACK_ASLEEP")
|
|
2547
|
+
return "Any write starts it, such as creating or updating a webhook.";
|
|
2545
2548
|
if (status === 402)
|
|
2546
2549
|
return detail === "spend_cap_reached" ? `You reached your monthly spend cap. Raise it: ${CREDITS_URL}` : `Add credits to create webhooks and deploy subgraphs: ${CREDITS_URL}`;
|
|
2547
2550
|
if (status === 403)
|
|
@@ -2581,7 +2584,7 @@ function handleApiError(err, action) {
|
|
|
2581
2584
|
}
|
|
2582
2585
|
const detail = err instanceof Error ? err.message : String(err);
|
|
2583
2586
|
printError(`Failed to ${action}: ${detail}`, {
|
|
2584
|
-
hint: nextStepHint(status, detail)
|
|
2587
|
+
hint: nextStepHint(status, detail, code)
|
|
2585
2588
|
});
|
|
2586
2589
|
process.exit(1);
|
|
2587
2590
|
}
|
|
@@ -29542,7 +29545,7 @@ export default defineSubgraph({
|
|
|
29542
29545
|
import { createHash as createHash4 } from "node:crypto";
|
|
29543
29546
|
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
29544
29547
|
import { dirname as dirname4, resolve as resolve3 } from "node:path";
|
|
29545
|
-
import { Index, resolveApiKey as resolveApiKey3, resolveBaseUrl } from "@secondlayer/sdk";
|
|
29548
|
+
import { Index, resolveApiKey as resolveApiKey3, resolveBaseUrl as resolveBaseUrl2 } from "@secondlayer/sdk";
|
|
29546
29549
|
import {
|
|
29547
29550
|
DECODED_EVENT_TYPES,
|
|
29548
29551
|
VM_EVENT_TYPES
|
|
@@ -29591,7 +29594,7 @@ function eventTypeFor(filter) {
|
|
|
29591
29594
|
return null;
|
|
29592
29595
|
}
|
|
29593
29596
|
function indexApiUrl() {
|
|
29594
|
-
return
|
|
29597
|
+
return resolveBaseUrl2();
|
|
29595
29598
|
}
|
|
29596
29599
|
function indexReadFailure(err, ctx) {
|
|
29597
29600
|
const e = err;
|
|
@@ -29808,7 +29811,7 @@ import { existsSync as existsSync3 } from "node:fs";
|
|
|
29808
29811
|
import { resolve as resolve4 } from "node:path";
|
|
29809
29812
|
import {
|
|
29810
29813
|
Index as Index2,
|
|
29811
|
-
resolveBaseUrl as
|
|
29814
|
+
resolveBaseUrl as resolveBaseUrl3
|
|
29812
29815
|
} from "@secondlayer/sdk";
|
|
29813
29816
|
import {
|
|
29814
29817
|
DECODED_EVENT_TYPES as DECODED_EVENT_TYPES2
|
|
@@ -29903,7 +29906,7 @@ async function runSubgraphPreview(file, options) {
|
|
|
29903
29906
|
source: name,
|
|
29904
29907
|
fromHeight,
|
|
29905
29908
|
toHeight,
|
|
29906
|
-
apiUrl:
|
|
29909
|
+
apiUrl: resolveBaseUrl3(),
|
|
29907
29910
|
file
|
|
29908
29911
|
});
|
|
29909
29912
|
printError(failure.message, { hint: failure.hint });
|
|
@@ -29934,7 +29937,7 @@ async function runSubgraphPreview(file, options) {
|
|
|
29934
29937
|
source: name,
|
|
29935
29938
|
fromHeight,
|
|
29936
29939
|
toHeight,
|
|
29937
|
-
apiUrl:
|
|
29940
|
+
apiUrl: resolveBaseUrl3(),
|
|
29938
29941
|
file
|
|
29939
29942
|
});
|
|
29940
29943
|
printError(failure.message, { hint: failure.hint });
|
|
@@ -31507,7 +31510,7 @@ function client() {
|
|
|
31507
31510
|
apiKey: resolveDataPlaneKey()
|
|
31508
31511
|
});
|
|
31509
31512
|
}
|
|
31510
|
-
function
|
|
31513
|
+
function fail2(action, err) {
|
|
31511
31514
|
const message = err instanceof Error ? err.message : String(err);
|
|
31512
31515
|
error(`Failed to ${action}: ${message}`);
|
|
31513
31516
|
if (/\b403\b/.test(message) || /forbidden/i.test(message)) {
|
|
@@ -31598,7 +31601,7 @@ function registerIndexCommand(program) {
|
|
|
31598
31601
|
recipient: o.recipient
|
|
31599
31602
|
}), o.json);
|
|
31600
31603
|
} catch (err) {
|
|
31601
|
-
|
|
31604
|
+
fail2("list ft transfers", err);
|
|
31602
31605
|
}
|
|
31603
31606
|
});
|
|
31604
31607
|
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 +31614,7 @@ function registerIndexCommand(program) {
|
|
|
31611
31614
|
assetIdentifier: o.assetIdentifier
|
|
31612
31615
|
}), o.json);
|
|
31613
31616
|
} catch (err) {
|
|
31614
|
-
|
|
31617
|
+
fail2("list nft transfers", err);
|
|
31615
31618
|
}
|
|
31616
31619
|
});
|
|
31617
31620
|
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 +31628,7 @@ function registerIndexCommand(program) {
|
|
|
31625
31628
|
assetIdentifier: o.assetIdentifier
|
|
31626
31629
|
}), o.json);
|
|
31627
31630
|
} catch (err) {
|
|
31628
|
-
|
|
31631
|
+
fail2("list events", err);
|
|
31629
31632
|
}
|
|
31630
31633
|
});
|
|
31631
31634
|
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 +31639,21 @@ function registerIndexCommand(program) {
|
|
|
31636
31639
|
sender: o.sender
|
|
31637
31640
|
}), o.json);
|
|
31638
31641
|
} catch (err) {
|
|
31639
|
-
|
|
31642
|
+
fail2("list contract calls", err);
|
|
31640
31643
|
}
|
|
31641
31644
|
});
|
|
31642
31645
|
heightFlags(index.command("canonical")).description("List the canonical Stacks block sequence (height + hash)").action(async (o) => {
|
|
31643
31646
|
try {
|
|
31644
31647
|
emit(await client().canonical.list(heightParams(o)), o.json);
|
|
31645
31648
|
} catch (err) {
|
|
31646
|
-
|
|
31649
|
+
fail2("list canonical blocks", err);
|
|
31647
31650
|
}
|
|
31648
31651
|
});
|
|
31649
31652
|
const blocks = heightFlags(index.command("blocks")).description("List decoded blocks (run `blocks get <ref>` for one block)").action(async (o) => {
|
|
31650
31653
|
try {
|
|
31651
31654
|
emit(await client().blocks.list(heightParams(o)), o.json);
|
|
31652
31655
|
} catch (err) {
|
|
31653
|
-
|
|
31656
|
+
fail2("list blocks", err);
|
|
31654
31657
|
}
|
|
31655
31658
|
});
|
|
31656
31659
|
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 +31661,7 @@ function registerIndexCommand(program) {
|
|
|
31658
31661
|
const block = await client().blocks.get(/^\d+$/.test(ref) ? Number.parseInt(ref, 10) : ref);
|
|
31659
31662
|
emitOne(block, `block ${ref}`, o.json);
|
|
31660
31663
|
} catch (err) {
|
|
31661
|
-
|
|
31664
|
+
fail2("get block", err);
|
|
31662
31665
|
}
|
|
31663
31666
|
});
|
|
31664
31667
|
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 +31672,14 @@ function registerIndexCommand(program) {
|
|
|
31669
31672
|
sender: o.sender
|
|
31670
31673
|
}), o.json);
|
|
31671
31674
|
} catch (err) {
|
|
31672
|
-
|
|
31675
|
+
fail2("list transactions", err);
|
|
31673
31676
|
}
|
|
31674
31677
|
});
|
|
31675
31678
|
transactions.command("get <txId>").description("Get a single transaction by tx_id").option("--json", "Print as JSON").action(async (txId, o) => {
|
|
31676
31679
|
try {
|
|
31677
31680
|
emitOne(await client().transactions.get(txId), `tx ${txId}`, o.json);
|
|
31678
31681
|
} catch (err) {
|
|
31679
|
-
|
|
31682
|
+
fail2("get transaction", err);
|
|
31680
31683
|
}
|
|
31681
31684
|
});
|
|
31682
31685
|
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 +31691,7 @@ function registerIndexCommand(program) {
|
|
|
31688
31691
|
caller: o.caller
|
|
31689
31692
|
}), o.json);
|
|
31690
31693
|
} catch (err) {
|
|
31691
|
-
|
|
31694
|
+
fail2("list stacking actions", err);
|
|
31692
31695
|
}
|
|
31693
31696
|
});
|
|
31694
31697
|
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 +31705,14 @@ function registerIndexCommand(program) {
|
|
|
31702
31705
|
limit: o.limit ? Number.parseInt(o.limit, 10) : undefined
|
|
31703
31706
|
}), o.json);
|
|
31704
31707
|
} catch (err) {
|
|
31705
|
-
|
|
31708
|
+
fail2("list mempool", err);
|
|
31706
31709
|
}
|
|
31707
31710
|
});
|
|
31708
31711
|
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
31712
|
try {
|
|
31710
31713
|
emitOne(await client().mempool.get(txId), `pending tx ${txId}`, o.json);
|
|
31711
31714
|
} catch (err) {
|
|
31712
|
-
|
|
31715
|
+
fail2("get mempool tx", err);
|
|
31713
31716
|
}
|
|
31714
31717
|
});
|
|
31715
31718
|
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 +31724,7 @@ function registerIndexCommand(program) {
|
|
|
31721
31724
|
limit: o.limit ? Number.parseInt(o.limit, 10) : undefined
|
|
31722
31725
|
}), o.json);
|
|
31723
31726
|
} catch (err) {
|
|
31724
|
-
|
|
31727
|
+
fail2("list runes", err);
|
|
31725
31728
|
}
|
|
31726
31729
|
});
|
|
31727
31730
|
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 +31732,7 @@ function registerIndexCommand(program) {
|
|
|
31729
31732
|
try {
|
|
31730
31733
|
emitOne(await client().runes.get(rune), `rune ${rune}`, o.json);
|
|
31731
31734
|
} catch (err) {
|
|
31732
|
-
|
|
31735
|
+
fail2("get rune", err);
|
|
31733
31736
|
}
|
|
31734
31737
|
});
|
|
31735
31738
|
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 +31745,7 @@ function registerIndexCommand(program) {
|
|
|
31742
31745
|
limit: o.limit ? Number.parseInt(o.limit, 10) : undefined
|
|
31743
31746
|
}), o.json);
|
|
31744
31747
|
} catch (err) {
|
|
31745
|
-
|
|
31748
|
+
fail2("list rune balances", err);
|
|
31746
31749
|
}
|
|
31747
31750
|
});
|
|
31748
31751
|
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 +31759,7 @@ function registerIndexCommand(program) {
|
|
|
31756
31759
|
txid: o.txid
|
|
31757
31760
|
}), o.json);
|
|
31758
31761
|
} catch (err) {
|
|
31759
|
-
|
|
31762
|
+
fail2("list rune activity", err);
|
|
31760
31763
|
}
|
|
31761
31764
|
});
|
|
31762
31765
|
}
|
|
@@ -31888,7 +31891,7 @@ var {
|
|
|
31888
31891
|
// package.json
|
|
31889
31892
|
var package_default = {
|
|
31890
31893
|
name: "@secondlayer/cli",
|
|
31891
|
-
version: "23.
|
|
31894
|
+
version: "23.2.0",
|
|
31892
31895
|
description: "Run a Stacks index on your own hardware — set it up, restore verified history, and keep it current.",
|
|
31893
31896
|
repository: {
|
|
31894
31897
|
type: "git",
|
|
@@ -31937,7 +31940,7 @@ var package_default = {
|
|
|
31937
31940
|
"@inquirer/prompts": "^8.2.0",
|
|
31938
31941
|
"@secondlayer/bundler": "^0.7.3",
|
|
31939
31942
|
"@secondlayer/scaffold": "^1.6.3",
|
|
31940
|
-
"@secondlayer/sdk": "^16.
|
|
31943
|
+
"@secondlayer/sdk": "^16.2.0",
|
|
31941
31944
|
"@secondlayer/shared": "^15.0.0",
|
|
31942
31945
|
"@secondlayer/stacks": "^6.5.3",
|
|
31943
31946
|
"@secondlayer/subgraphs": "^8.0.1",
|
|
@@ -34546,6 +34549,144 @@ async function runRefill(opts) {
|
|
|
34546
34549
|
}
|
|
34547
34550
|
});
|
|
34548
34551
|
}
|
|
34552
|
+
// src/commands/keys.ts
|
|
34553
|
+
init_http();
|
|
34554
|
+
init_output();
|
|
34555
|
+
init_session();
|
|
34556
|
+
import { resolveAccountKey as resolveAccountKey4 } from "@secondlayer/sdk";
|
|
34557
|
+
var MIN_ID_REF_LENGTH = 8;
|
|
34558
|
+
function rotatableKeys(keys) {
|
|
34559
|
+
return keys.filter((k) => k.status === "active" && k.product === "account");
|
|
34560
|
+
}
|
|
34561
|
+
function describeKey(key) {
|
|
34562
|
+
return `${key.id.slice(0, 8)} ${key.name ?? "(unnamed)"}`;
|
|
34563
|
+
}
|
|
34564
|
+
function resolveKeyRef(keys, ref) {
|
|
34565
|
+
const candidates = rotatableKeys(keys);
|
|
34566
|
+
const barePrefix = ref.replace(/…$/, "");
|
|
34567
|
+
const kinds = [
|
|
34568
|
+
(k) => k.id === ref || ref.length >= MIN_ID_REF_LENGTH && k.id.startsWith(ref),
|
|
34569
|
+
(k) => k.prefix === barePrefix,
|
|
34570
|
+
(k) => k.name === ref
|
|
34571
|
+
];
|
|
34572
|
+
for (const matches of kinds) {
|
|
34573
|
+
const found = candidates.filter(matches);
|
|
34574
|
+
if (found.length === 1)
|
|
34575
|
+
return found[0];
|
|
34576
|
+
if (found.length > 1) {
|
|
34577
|
+
throw new Error(`"${ref}" matches ${found.length} keys: ${found.map(describeKey).join(", ")}. Use an id.`);
|
|
34578
|
+
}
|
|
34579
|
+
}
|
|
34580
|
+
throw new Error(`No active account key matches "${ref}". Run: secondlayer keys list`);
|
|
34581
|
+
}
|
|
34582
|
+
async function applyRotationToLogin(prefix, newKey, deps = {}) {
|
|
34583
|
+
const apiUrl = deps.apiUrl ?? resolveArchiveOpsUrl();
|
|
34584
|
+
const read = deps.readSession ?? readSession;
|
|
34585
|
+
const write = deps.writeSession ?? writeSession;
|
|
34586
|
+
const envKey = "envKey" in deps ? deps.envKey : resolveAccountKey4();
|
|
34587
|
+
if (!prefix)
|
|
34588
|
+
return { loginUpdated: false, envStale: false };
|
|
34589
|
+
let loginUpdated = false;
|
|
34590
|
+
const session = await read(apiUrl);
|
|
34591
|
+
if (session?.token.startsWith(prefix)) {
|
|
34592
|
+
await write({ ...session, token: newKey }, apiUrl);
|
|
34593
|
+
loginUpdated = true;
|
|
34594
|
+
}
|
|
34595
|
+
return { loginUpdated, envStale: envKey?.startsWith(prefix) ?? false };
|
|
34596
|
+
}
|
|
34597
|
+
async function saveRotatedLogin(prefix, newKey, deps = {}) {
|
|
34598
|
+
try {
|
|
34599
|
+
return await applyRotationToLogin(prefix, newKey, deps);
|
|
34600
|
+
} catch (err) {
|
|
34601
|
+
const envKey = "envKey" in deps ? deps.envKey : resolveAccountKey4();
|
|
34602
|
+
return {
|
|
34603
|
+
loginUpdated: false,
|
|
34604
|
+
envStale: Boolean(prefix) && (envKey?.startsWith(prefix) ?? false),
|
|
34605
|
+
loginError: err instanceof Error ? err.message : String(err)
|
|
34606
|
+
};
|
|
34607
|
+
}
|
|
34608
|
+
}
|
|
34609
|
+
function fail(err) {
|
|
34610
|
+
if (err instanceof Error) {
|
|
34611
|
+
error(err.message);
|
|
34612
|
+
process.exit(1);
|
|
34613
|
+
}
|
|
34614
|
+
throw err;
|
|
34615
|
+
}
|
|
34616
|
+
async function fetchKeys() {
|
|
34617
|
+
const res = await httpArchiveOps("/api/keys");
|
|
34618
|
+
return res.keys;
|
|
34619
|
+
}
|
|
34620
|
+
async function runList(opts) {
|
|
34621
|
+
let keys;
|
|
34622
|
+
try {
|
|
34623
|
+
keys = rotatableKeys(await fetchKeys());
|
|
34624
|
+
} catch (err) {
|
|
34625
|
+
fail(err);
|
|
34626
|
+
}
|
|
34627
|
+
output({
|
|
34628
|
+
json: opts.json,
|
|
34629
|
+
data: {
|
|
34630
|
+
keys: keys.map(({ rowsDaily: _rowsDaily, ...rest }) => rest)
|
|
34631
|
+
},
|
|
34632
|
+
human: () => {
|
|
34633
|
+
if (keys.length === 0) {
|
|
34634
|
+
note("No active account keys. Make one at https://www.secondlayer.tools/account/keys");
|
|
34635
|
+
return;
|
|
34636
|
+
}
|
|
34637
|
+
console.log(formatTable(["ID", "NAME", "KEY", "LAST READ", "ROWS 30D"], keys.map((k) => [
|
|
34638
|
+
k.id.slice(0, 8),
|
|
34639
|
+
k.name ?? "(unnamed)",
|
|
34640
|
+
`${k.prefix}…`,
|
|
34641
|
+
k.lastUsedAt ?? "never",
|
|
34642
|
+
k.rows30d.toLocaleString("en-US")
|
|
34643
|
+
])));
|
|
34644
|
+
}
|
|
34645
|
+
});
|
|
34646
|
+
}
|
|
34647
|
+
async function runRotate(ref, opts) {
|
|
34648
|
+
let target;
|
|
34649
|
+
try {
|
|
34650
|
+
target = resolveKeyRef(await fetchKeys(), ref);
|
|
34651
|
+
} catch (err) {
|
|
34652
|
+
fail(err);
|
|
34653
|
+
}
|
|
34654
|
+
const label = target.name ?? "(unnamed)";
|
|
34655
|
+
const ok = await confirmDestructive({
|
|
34656
|
+
message: `Rotate "${label}" (${target.prefix}…)? Anything using it gets a 401 at once.`,
|
|
34657
|
+
yes: opts.yes
|
|
34658
|
+
});
|
|
34659
|
+
if (!ok) {
|
|
34660
|
+
info("Cancelled");
|
|
34661
|
+
return;
|
|
34662
|
+
}
|
|
34663
|
+
let rotated;
|
|
34664
|
+
try {
|
|
34665
|
+
rotated = await httpArchiveOps(`/api/keys/${target.id}/rotate`, { method: "POST", body: {} });
|
|
34666
|
+
} catch (err) {
|
|
34667
|
+
fail(err);
|
|
34668
|
+
}
|
|
34669
|
+
const { loginUpdated, envStale, loginError } = await saveRotatedLogin(target.prefix, rotated.key);
|
|
34670
|
+
if (opts.json) {
|
|
34671
|
+
writeData(JSON.stringify({ ...rotated, loginUpdated }, null, 2));
|
|
34672
|
+
} else {
|
|
34673
|
+
success(`Rotated ${blue(label)}. The old key has stopped working.`);
|
|
34674
|
+
writeData(rotated.key);
|
|
34675
|
+
note("Shown once. Copy it now.");
|
|
34676
|
+
}
|
|
34677
|
+
if (loginError) {
|
|
34678
|
+
warn(`Couldn't update your CLI login: ${loginError}. Run: secondlayer login --with-token`);
|
|
34679
|
+
}
|
|
34680
|
+
if (loginUpdated)
|
|
34681
|
+
info("Updated your CLI login to the new key.");
|
|
34682
|
+
if (envStale)
|
|
34683
|
+
warn("SECONDLAYER_API_KEY still holds the old key. Update it.");
|
|
34684
|
+
}
|
|
34685
|
+
function registerKeysCommand(program) {
|
|
34686
|
+
const keys = program.command("keys").description("Manage account keys");
|
|
34687
|
+
keys.command("list").alias("ls").description("List your active account keys").option("--json", "Output as JSON").action((opts) => runList(opts));
|
|
34688
|
+
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));
|
|
34689
|
+
}
|
|
34549
34690
|
// src/commands/codegen.ts
|
|
34550
34691
|
function registerCodegenCommand(program) {
|
|
34551
34692
|
const codegen = program.command("codegen").description("Generate typed code: contracts, subgraphs, Index, clients");
|
|
@@ -35822,7 +35963,7 @@ function dockerCompose(composePath, args) {
|
|
|
35822
35963
|
});
|
|
35823
35964
|
return res.status ?? 1;
|
|
35824
35965
|
}
|
|
35825
|
-
var API_URL =
|
|
35966
|
+
var API_URL = (process.env.SECONDLAYER_API_URL || LOCAL_API_URL).replace(/\/+$/, "");
|
|
35826
35967
|
var INDEXER_URL = process.env.INDEXER_URL ?? "http://localhost:3700";
|
|
35827
35968
|
var SERVICES = [
|
|
35828
35969
|
"indexer",
|
|
@@ -37615,6 +37756,7 @@ registerObserverCommand(program);
|
|
|
37615
37756
|
registerLoginCommand(program);
|
|
37616
37757
|
registerLogoutCommand(program);
|
|
37617
37758
|
registerWhoamiCommand(program);
|
|
37759
|
+
registerKeysCommand(program);
|
|
37618
37760
|
program.commandsGroup("Your data:");
|
|
37619
37761
|
registerSubgraphsCommand(program);
|
|
37620
37762
|
registerWebhooksCommand(program);
|
|
@@ -37638,5 +37780,5 @@ registerCreditsCommand(program);
|
|
|
37638
37780
|
registerArchiveCommand(program);
|
|
37639
37781
|
program.parse();
|
|
37640
37782
|
|
|
37641
|
-
//# debugId=
|
|
37783
|
+
//# debugId=E3E81976D75D13F864756E2164756E21
|
|
37642
37784
|
//# sourceMappingURL=cli.js.map
|