settld 0.2.2 → 0.2.3
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 +11 -0
- package/docs/QUICKSTART_MCP_HOSTS.md +29 -8
- package/docs/README.md +5 -4
- package/docs/gitbook/README.md +5 -1
- package/docs/gitbook/quickstart.md +11 -4
- package/docs/integrations/README.md +1 -1
- package/docs/integrations/openclaw/CLAWHUB_PUBLISH_CHECKLIST.md +1 -1
- package/docs/integrations/openclaw/PUBLIC_QUICKSTART.md +7 -5
- package/docs/integrations/openclaw/settld-mcp-skill/SKILL.md +19 -4
- package/docs/integrations/openclaw/settld-mcp-skill/mcp-server.example.json +3 -5
- package/docs/integrations/openclaw/settld-mcp-skill/skill.json +11 -0
- package/package.json +1 -1
- package/scripts/setup/login.mjs +5 -2
- package/scripts/setup/onboard.mjs +323 -58
package/README.md
CHANGED
|
@@ -73,6 +73,16 @@ Agent host onboarding (Codex / Claude / Cursor / OpenClaw), with guided wallet +
|
|
|
73
73
|
npx -y settld setup
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
+
Default interactive flow is now login-first:
|
|
77
|
+
|
|
78
|
+
1. pick host + wallet mode
|
|
79
|
+
2. choose `quick` setup (recommended)
|
|
80
|
+
3. login with OTP (creates tenant if needed)
|
|
81
|
+
4. setup mints runtime API key automatically
|
|
82
|
+
5. guided wallet fund + first paid call check runs
|
|
83
|
+
|
|
84
|
+
Advanced mode is still available in setup when you need explicit base URL/bootstrap/API-key control.
|
|
85
|
+
|
|
76
86
|
Preflight-only check (no host config write), with JSON report:
|
|
77
87
|
|
|
78
88
|
```sh
|
|
@@ -89,6 +99,7 @@ settld setup
|
|
|
89
99
|
Check wallet wiring and funding path:
|
|
90
100
|
|
|
91
101
|
```sh
|
|
102
|
+
settld login
|
|
92
103
|
settld wallet status
|
|
93
104
|
settld wallet fund --open
|
|
94
105
|
settld wallet fund --method transfer
|
|
@@ -13,16 +13,27 @@ For deeper tool-level examples, see `docs/QUICKSTART_MCP.md`.
|
|
|
13
13
|
|
|
14
14
|
## 1) Before you run `settld setup`
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Public default path (recommended):
|
|
17
17
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
18
|
+
- Node.js 20+
|
|
19
|
+
- no API keys required up front
|
|
20
|
+
- run `settld setup`, choose `quick`, then login with OTP
|
|
21
|
+
- setup creates tenant (if needed), mints runtime key, and wires MCP
|
|
22
|
+
|
|
23
|
+
Admin/operator path (advanced):
|
|
24
|
+
|
|
25
|
+
- explicit `SETTLD_BASE_URL`, `SETTLD_TENANT_ID`
|
|
20
26
|
- one of:
|
|
21
27
|
- `SETTLD_API_KEY` (`keyId.secret`), or
|
|
22
|
-
- `SETTLD_BOOTSTRAP_API_KEY` (
|
|
23
|
-
|
|
28
|
+
- `SETTLD_BOOTSTRAP_API_KEY` (bootstrap key that mints runtime key)
|
|
29
|
+
|
|
30
|
+
Recommended interactive pattern:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
settld setup
|
|
34
|
+
```
|
|
24
35
|
|
|
25
|
-
Recommended non-interactive pattern:
|
|
36
|
+
Recommended non-interactive pattern (automation/support):
|
|
26
37
|
|
|
27
38
|
```bash
|
|
28
39
|
settld setup --non-interactive \
|
|
@@ -37,7 +48,7 @@ settld setup --non-interactive \
|
|
|
37
48
|
--out-env ./.tmp/settld-openclaw.env
|
|
38
49
|
```
|
|
39
50
|
|
|
40
|
-
If you want setup to generate the tenant API key
|
|
51
|
+
If you want non-interactive setup to generate the tenant API key:
|
|
41
52
|
|
|
42
53
|
```bash
|
|
43
54
|
settld setup --non-interactive \
|
|
@@ -73,14 +84,18 @@ Unified setup command:
|
|
|
73
84
|
settld setup
|
|
74
85
|
```
|
|
75
86
|
|
|
76
|
-
|
|
87
|
+
`quick` mode (default) handles:
|
|
77
88
|
|
|
78
89
|
- host selection (`codex|claude|cursor|openclaw`)
|
|
79
90
|
- wallet mode selection (`managed|byo|none`)
|
|
91
|
+
- login/signup + OTP session flow (no manual key paste)
|
|
80
92
|
- preflight checks (API health, tenant auth, profile baseline, host config path)
|
|
81
93
|
- policy apply + optional smoke
|
|
94
|
+
- guided wallet funding and first paid MCP check
|
|
82
95
|
- interactive menus with arrow keys (Up/Down + Enter) for choice steps
|
|
83
96
|
|
|
97
|
+
`advanced` mode exposes explicit key/bootstrap/base-url prompts and fine-grained setup toggles.
|
|
98
|
+
|
|
84
99
|
Host-specific non-interactive examples:
|
|
85
100
|
|
|
86
101
|
```bash
|
|
@@ -177,6 +192,12 @@ Check wallet assignment after setup:
|
|
|
177
192
|
settld wallet status
|
|
178
193
|
```
|
|
179
194
|
|
|
195
|
+
If wallet commands return auth errors, run:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
settld login
|
|
199
|
+
```
|
|
200
|
+
|
|
180
201
|
Funding paths:
|
|
181
202
|
|
|
182
203
|
```bash
|
package/docs/README.md
CHANGED
|
@@ -17,10 +17,11 @@ For curated public docs, start here:
|
|
|
17
17
|
|
|
18
18
|
## Fastest onboarding path
|
|
19
19
|
|
|
20
|
-
1. Run `settld setup` (or `./bin/settld.js setup`)
|
|
21
|
-
2.
|
|
22
|
-
3.
|
|
23
|
-
4.
|
|
20
|
+
1. Run `settld setup` (or `./bin/settld.js setup`), choose `quick`, and complete OTP login.
|
|
21
|
+
2. Let guided wallet funding complete (or run `settld wallet fund` + `settld wallet balance --watch --min-usdc 1`).
|
|
22
|
+
3. Activate your host and run `npm run mcp:probe`.
|
|
23
|
+
4. Run `npm run demo:mcp-paid-exa`.
|
|
24
|
+
5. Verify the first receipt:
|
|
24
25
|
|
|
25
26
|
```bash
|
|
26
27
|
jq -c 'first' artifacts/mcp-paid-exa/*/x402-receipts.export.jsonl > /tmp/settld-first-receipt.json
|
package/docs/gitbook/README.md
CHANGED
|
@@ -19,9 +19,13 @@ Settld gives you a canonical economic loop:
|
|
|
19
19
|
## One-command onboarding
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
settld setup
|
|
22
|
+
settld setup
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
Recommended path: choose `quick`, complete OTP login, and let setup run guided funding + paid-call checks.
|
|
26
|
+
|
|
27
|
+
Advanced/scripted path is still supported with explicit non-interactive flags.
|
|
28
|
+
|
|
25
29
|
Then:
|
|
26
30
|
|
|
27
31
|
1. `npm run mcp:probe -- --call settld.about '{}'`
|
|
@@ -5,9 +5,8 @@ Get from zero to a verified paid agent action in minutes.
|
|
|
5
5
|
## Prerequisites
|
|
6
6
|
|
|
7
7
|
- Node.js 20+
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
- Tenant API key (`keyId.secret`)
|
|
8
|
+
- Public flow: no API key required up front (`settld setup` handles login/session bootstrap)
|
|
9
|
+
- Advanced flow: optional explicit `--base-url`, `--tenant-id`, and `--settld-api-key`
|
|
11
10
|
|
|
12
11
|
## 0) One-command setup
|
|
13
12
|
|
|
@@ -17,7 +16,14 @@ Run guided setup:
|
|
|
17
16
|
settld setup
|
|
18
17
|
```
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
Recommended interactive choices:
|
|
20
|
+
|
|
21
|
+
1. host
|
|
22
|
+
2. `quick` setup mode
|
|
23
|
+
3. wallet mode
|
|
24
|
+
4. OTP login (creates tenant if needed)
|
|
25
|
+
|
|
26
|
+
`quick` mode auto-runs preflight/smoke/profile apply, then starts guided wallet fund + first paid call checks.
|
|
21
27
|
|
|
22
28
|
Non-interactive example:
|
|
23
29
|
|
|
@@ -54,6 +60,7 @@ Then restart your host app (Codex/Claude/Cursor/OpenClaw) so it reloads MCP conf
|
|
|
54
60
|
## 2) Check wallet and fund it
|
|
55
61
|
|
|
56
62
|
```bash
|
|
63
|
+
settld login
|
|
57
64
|
settld wallet status
|
|
58
65
|
settld wallet fund --method transfer
|
|
59
66
|
settld wallet balance --watch --min-usdc 1
|
|
@@ -5,7 +5,7 @@ Copy/paste adoption templates and guardrails:
|
|
|
5
5
|
- `github-actions.md` — composite action usage and trust anchor wiring.
|
|
6
6
|
- `github-actions-verify.yml` — pasteable workflow template.
|
|
7
7
|
- `openclaw/PUBLIC_QUICKSTART.md` — public npm onboarding flow for OpenClaw (`npx settld@latest setup`).
|
|
8
|
-
- `openclaw/settld-mcp-skill/SKILL.md` — OpenClaw skill payload for Settld MCP.
|
|
8
|
+
- `openclaw/settld-mcp-skill/SKILL.md` + `openclaw/settld-mcp-skill/skill.json` — OpenClaw skill payload + manifest for Settld MCP.
|
|
9
9
|
- `openclaw/CLAWHUB_PUBLISH_CHECKLIST.md` — publish + validation checklist for ClawHub.
|
|
10
10
|
|
|
11
11
|
See also:
|
|
@@ -15,6 +15,7 @@ Confirm required files exist:
|
|
|
15
15
|
|
|
16
16
|
- `docs/integrations/openclaw/settld-mcp-skill/SKILL.md`
|
|
17
17
|
- `docs/integrations/openclaw/settld-mcp-skill/mcp-server.example.json`
|
|
18
|
+
- `docs/integrations/openclaw/settld-mcp-skill/skill.json`
|
|
18
19
|
|
|
19
20
|
## 2) Prepare Skill Metadata
|
|
20
21
|
|
|
@@ -62,4 +63,3 @@ Capture these fields each publish:
|
|
|
62
63
|
- Added/changed tools
|
|
63
64
|
- Known limitations
|
|
64
65
|
- Validation run timestamp
|
|
65
|
-
|
|
@@ -33,10 +33,10 @@ npx -y settld@latest setup
|
|
|
33
33
|
Choose:
|
|
34
34
|
|
|
35
35
|
1. `host`: `openclaw`
|
|
36
|
-
2.
|
|
37
|
-
3. wallet
|
|
38
|
-
4.
|
|
39
|
-
5.
|
|
36
|
+
2. setup mode: `quick`
|
|
37
|
+
3. wallet mode (`managed` recommended first)
|
|
38
|
+
4. login with OTP (new tenant is created if needed)
|
|
39
|
+
5. let setup run guided fund + first paid check
|
|
40
40
|
|
|
41
41
|
Non-interactive path (automation/support):
|
|
42
42
|
|
|
@@ -53,7 +53,7 @@ npx -y settld@latest setup \
|
|
|
53
53
|
--smoke
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
Advanced non-interactive key/bootstrap paths are still supported:
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
59
|
npx -y settld@latest setup \
|
|
@@ -102,7 +102,9 @@ npx -y settld@latest x402 receipt verify ./receipt.json --format json
|
|
|
102
102
|
## Notes for operators
|
|
103
103
|
|
|
104
104
|
- Public users do not need to clone the Settld repo.
|
|
105
|
+
- Public users should not need bootstrap/admin keys in the default setup path.
|
|
105
106
|
- Public path is valid only after publishing a package version that includes the current setup flow.
|
|
106
107
|
- For OpenClaw skill packaging and publish flow, see:
|
|
107
108
|
- `docs/integrations/openclaw/settld-mcp-skill/SKILL.md`
|
|
109
|
+
- `docs/integrations/openclaw/settld-mcp-skill/skill.json`
|
|
108
110
|
- `docs/integrations/openclaw/CLAWHUB_PUBLISH_CHECKLIST.md`
|
|
@@ -9,6 +9,14 @@ author: Settld
|
|
|
9
9
|
|
|
10
10
|
This skill teaches OpenClaw agents to use Settld for paid MCP tool calls.
|
|
11
11
|
|
|
12
|
+
It is designed for the public `quick` onboarding flow:
|
|
13
|
+
|
|
14
|
+
1. `settld setup`
|
|
15
|
+
2. pick `openclaw` + `quick`
|
|
16
|
+
3. login via OTP
|
|
17
|
+
4. fund wallet
|
|
18
|
+
5. run paid tool call with deterministic receipt evidence
|
|
19
|
+
|
|
12
20
|
## What This Skill Enables
|
|
13
21
|
|
|
14
22
|
- Discover Settld MCP tools (`settld.*`)
|
|
@@ -19,9 +27,7 @@ This skill teaches OpenClaw agents to use Settld for paid MCP tool calls.
|
|
|
19
27
|
## Prerequisites
|
|
20
28
|
|
|
21
29
|
- Node.js 20+
|
|
22
|
-
- Settld
|
|
23
|
-
- Settld API base URL (`SETTLD_BASE_URL`)
|
|
24
|
-
- Tenant id (`SETTLD_TENANT_ID`)
|
|
30
|
+
- Settld runtime env from setup (`SETTLD_API_KEY`, `SETTLD_BASE_URL`, `SETTLD_TENANT_ID`)
|
|
25
31
|
- Optional paid tools base URL (`SETTLD_PAID_TOOLS_BASE_URL`)
|
|
26
32
|
|
|
27
33
|
## MCP Server Registration
|
|
@@ -61,9 +67,18 @@ Optional env vars:
|
|
|
61
67
|
- "Call `settld.about` and return the result JSON."
|
|
62
68
|
- "Run `settld.weather_current_paid` for Chicago in fahrenheit and include the `x-settld-*` headers."
|
|
63
69
|
|
|
70
|
+
## Identity + Traceability
|
|
71
|
+
|
|
72
|
+
Every paid call should be explainable and auditable:
|
|
73
|
+
|
|
74
|
+
- tenant identity (who owns the runtime)
|
|
75
|
+
- actor/session identity (who approved/triggered)
|
|
76
|
+
- policy decision identity (`allow|challenge|deny|escalate` + reason codes)
|
|
77
|
+
- settlement identity (`settlementReceiptId`)
|
|
78
|
+
- evidence identity (hash-verifiable receipt/timeline artifacts)
|
|
79
|
+
|
|
64
80
|
## Safety Notes
|
|
65
81
|
|
|
66
82
|
- Treat `SETTLD_API_KEY` as secret input.
|
|
67
83
|
- Do not print full API keys in chat output.
|
|
68
84
|
- Keep paid tools scoped to trusted providers and tenant policy.
|
|
69
|
-
|
|
@@ -3,10 +3,8 @@
|
|
|
3
3
|
"command": "npx",
|
|
4
4
|
"args": ["-y", "settld-mcp"],
|
|
5
5
|
"env": {
|
|
6
|
-
"SETTLD_BASE_URL": "
|
|
7
|
-
"SETTLD_TENANT_ID": "
|
|
8
|
-
"SETTLD_API_KEY": "sk_live_xxx.yyy"
|
|
9
|
-
"SETTLD_PAID_TOOLS_BASE_URL": "http://127.0.0.1:8402"
|
|
6
|
+
"SETTLD_BASE_URL": "https://api.settld.work",
|
|
7
|
+
"SETTLD_TENANT_ID": "tenant_xxx",
|
|
8
|
+
"SETTLD_API_KEY": "sk_live_xxx.yyy"
|
|
10
9
|
}
|
|
11
10
|
}
|
|
12
|
-
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "settld-mcp-payments",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "OpenClaw skill for Settld paid MCP tools with policy decisions and verifiable receipts.",
|
|
5
|
+
"author": "Settld",
|
|
6
|
+
"entry": "SKILL.md",
|
|
7
|
+
"files": [
|
|
8
|
+
"SKILL.md",
|
|
9
|
+
"mcp-server.example.json"
|
|
10
|
+
]
|
|
11
|
+
}
|
package/package.json
CHANGED
package/scripts/setup/login.mjs
CHANGED
|
@@ -191,10 +191,13 @@ export async function runLogin({
|
|
|
191
191
|
try {
|
|
192
192
|
if (interactive) {
|
|
193
193
|
state.baseUrl = await promptLine(rl, "Settld base URL", { defaultValue: state.baseUrl || "https://api.settld.work" });
|
|
194
|
-
state.tenantId = await promptLine(rl, "Tenant ID (optional
|
|
194
|
+
state.tenantId = await promptLine(rl, "Tenant ID (optional, leave blank to create new)", {
|
|
195
|
+
defaultValue: state.tenantId,
|
|
196
|
+
required: false
|
|
197
|
+
});
|
|
195
198
|
state.email = (await promptLine(rl, "Email", { defaultValue: state.email })).toLowerCase();
|
|
196
199
|
if (!state.tenantId) {
|
|
197
|
-
state.company = await promptLine(rl, "
|
|
200
|
+
state.company = await promptLine(rl, "What should your tenant/company name be?", { defaultValue: state.company });
|
|
198
201
|
}
|
|
199
202
|
}
|
|
200
203
|
|
|
@@ -13,10 +13,13 @@ import { bootstrapWalletProvider } from "../../src/core/wallet-provider-bootstra
|
|
|
13
13
|
import { extractBootstrapMcpEnv, loadHostConfigHelper, runWizard } from "./wizard.mjs";
|
|
14
14
|
import { SUPPORTED_HOSTS } from "./host-config.mjs";
|
|
15
15
|
import { defaultSessionPath, readSavedSession } from "./session-store.mjs";
|
|
16
|
+
import { runLogin } from "./login.mjs";
|
|
17
|
+
import { runWalletCli } from "../wallet/cli.mjs";
|
|
16
18
|
|
|
17
19
|
const WALLET_MODES = new Set(["managed", "byo", "none"]);
|
|
18
20
|
const WALLET_PROVIDERS = new Set(["circle"]);
|
|
19
21
|
const WALLET_BOOTSTRAP_MODES = new Set(["auto", "local", "remote"]);
|
|
22
|
+
const SETUP_MODES = new Set(["quick", "advanced"]);
|
|
20
23
|
const FORMAT_OPTIONS = new Set(["text", "json"]);
|
|
21
24
|
const HOST_BINARY_HINTS = Object.freeze({
|
|
22
25
|
codex: "codex",
|
|
@@ -38,6 +41,7 @@ const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
|
38
41
|
const REPO_ROOT = path.resolve(SCRIPT_DIR, "..", "..");
|
|
39
42
|
const SETTLD_BIN = path.join(REPO_ROOT, "bin", "settld.js");
|
|
40
43
|
const PROFILE_FINGERPRINT_REGEX = /^[0-9a-f]{64}$/;
|
|
44
|
+
const DEFAULT_PUBLIC_BASE_URL = "https://api.settld.work";
|
|
41
45
|
const ANSI_RESET = "\u001b[0m";
|
|
42
46
|
const ANSI_BOLD = "\u001b[1m";
|
|
43
47
|
const ANSI_DIM = "\u001b[2m";
|
|
@@ -54,6 +58,10 @@ function usage() {
|
|
|
54
58
|
"",
|
|
55
59
|
"flags:",
|
|
56
60
|
" --non-interactive Disable prompts; require explicit flags",
|
|
61
|
+
" --quick Quick setup mode (default for interactive)",
|
|
62
|
+
" --advanced Advanced setup mode (shows all prompts)",
|
|
63
|
+
" --guided-next Run guided fund + first paid check after setup (default in quick mode)",
|
|
64
|
+
" --skip-guided-next Skip guided post-setup actions",
|
|
57
65
|
` --host <${SUPPORTED_HOSTS.join("|")}> Host target (default: auto-detect, fallback openclaw)`,
|
|
58
66
|
" --base-url <url> Settld API base URL (or SETTLD_BASE_URL)",
|
|
59
67
|
" --tenant-id <id> Settld tenant ID (or SETTLD_TENANT_ID)",
|
|
@@ -109,6 +117,8 @@ function parseWalletEnvAssignment(raw) {
|
|
|
109
117
|
function parseArgs(argv) {
|
|
110
118
|
const out = {
|
|
111
119
|
nonInteractive: false,
|
|
120
|
+
setupMode: null,
|
|
121
|
+
guidedNext: null,
|
|
112
122
|
host: null,
|
|
113
123
|
baseUrl: null,
|
|
114
124
|
tenantId: null,
|
|
@@ -149,6 +159,22 @@ function parseArgs(argv) {
|
|
|
149
159
|
out.nonInteractive = true;
|
|
150
160
|
continue;
|
|
151
161
|
}
|
|
162
|
+
if (arg === "--quick") {
|
|
163
|
+
out.setupMode = "quick";
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (arg === "--advanced") {
|
|
167
|
+
out.setupMode = "advanced";
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (arg === "--guided-next") {
|
|
171
|
+
out.guidedNext = true;
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (arg === "--skip-guided-next") {
|
|
175
|
+
out.guidedNext = false;
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
152
178
|
if (arg === "--skip-profile-apply") {
|
|
153
179
|
out.skipProfileApply = true;
|
|
154
180
|
continue;
|
|
@@ -310,6 +336,9 @@ function parseArgs(argv) {
|
|
|
310
336
|
if (out.host && !SUPPORTED_HOSTS.includes(out.host)) {
|
|
311
337
|
throw new Error(`--host must be one of: ${SUPPORTED_HOSTS.join(", ")}`);
|
|
312
338
|
}
|
|
339
|
+
if (out.setupMode && !SETUP_MODES.has(out.setupMode)) {
|
|
340
|
+
throw new Error("--quick or --advanced are the supported setup modes");
|
|
341
|
+
}
|
|
313
342
|
if (!WALLET_MODES.has(out.walletMode)) throw new Error("--wallet-mode must be managed|byo|none");
|
|
314
343
|
if (!WALLET_PROVIDERS.has(out.walletProvider)) throw new Error(`--wallet-provider must be one of: ${[...WALLET_PROVIDERS].join(", ")}`);
|
|
315
344
|
if (!WALLET_BOOTSTRAP_MODES.has(out.walletBootstrap)) throw new Error("--wallet-bootstrap must be auto|local|remote");
|
|
@@ -865,6 +894,144 @@ function buildHostNextSteps({ host, installedHosts }) {
|
|
|
865
894
|
return steps;
|
|
866
895
|
}
|
|
867
896
|
|
|
897
|
+
function runMcpPaidCallProbe({ env, timeoutMs = 45_000 } = {}) {
|
|
898
|
+
const args = [
|
|
899
|
+
path.join("scripts", "mcp", "probe.mjs"),
|
|
900
|
+
"--call",
|
|
901
|
+
"settld.weather_current_paid",
|
|
902
|
+
JSON.stringify({ city: "Chicago", unit: "f" }),
|
|
903
|
+
"--timeout-ms",
|
|
904
|
+
String(timeoutMs)
|
|
905
|
+
];
|
|
906
|
+
const result = spawnSync(process.execPath, args, {
|
|
907
|
+
cwd: REPO_ROOT,
|
|
908
|
+
env: { ...process.env, ...(env ?? {}) },
|
|
909
|
+
encoding: "utf8",
|
|
910
|
+
timeout: timeoutMs + 5000,
|
|
911
|
+
maxBuffer: 4 * 1024 * 1024,
|
|
912
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
913
|
+
});
|
|
914
|
+
const stdoutText = String(result.stdout ?? "");
|
|
915
|
+
const stderrText = String(result.stderr ?? "");
|
|
916
|
+
const sawToolError = /"isError"\s*:\s*true/.test(stdoutText);
|
|
917
|
+
const sawToolSuccess = /"isError"\s*:\s*false/.test(stdoutText);
|
|
918
|
+
const ok = Number(result.status) === 0 && sawToolSuccess && !sawToolError;
|
|
919
|
+
return {
|
|
920
|
+
ok,
|
|
921
|
+
exitCode: typeof result.status === "number" ? result.status : 1,
|
|
922
|
+
stdout: stdoutText,
|
|
923
|
+
stderr: stderrText
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
async function runGuidedQuickFlow({
|
|
928
|
+
enabled = false,
|
|
929
|
+
walletMode = "none",
|
|
930
|
+
normalizedBaseUrl,
|
|
931
|
+
tenantId,
|
|
932
|
+
sessionFile,
|
|
933
|
+
sessionCookie = "",
|
|
934
|
+
mergedEnv = {},
|
|
935
|
+
runtimeEnv = process.env,
|
|
936
|
+
stdin = process.stdin,
|
|
937
|
+
stdout = process.stdout,
|
|
938
|
+
runWalletCliImpl = runWalletCli
|
|
939
|
+
} = {}) {
|
|
940
|
+
const summary = {
|
|
941
|
+
enabled: Boolean(enabled),
|
|
942
|
+
ran: false,
|
|
943
|
+
walletFund: null,
|
|
944
|
+
walletBalanceWatch: null,
|
|
945
|
+
firstPaidCall: null,
|
|
946
|
+
warnings: []
|
|
947
|
+
};
|
|
948
|
+
if (!summary.enabled) return summary;
|
|
949
|
+
if (!stdin?.isTTY || !stdout?.isTTY) {
|
|
950
|
+
summary.warnings.push("guided quick flow skipped (non-interactive terminal)");
|
|
951
|
+
return summary;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
const actionEnv = {
|
|
955
|
+
...runtimeEnv,
|
|
956
|
+
...mergedEnv,
|
|
957
|
+
SETTLD_BASE_URL: normalizedBaseUrl,
|
|
958
|
+
SETTLD_TENANT_ID: tenantId,
|
|
959
|
+
...(sessionCookie ? { SETTLD_SESSION_COOKIE: sessionCookie } : {})
|
|
960
|
+
};
|
|
961
|
+
summary.ran = true;
|
|
962
|
+
|
|
963
|
+
if (walletMode !== "none") {
|
|
964
|
+
try {
|
|
965
|
+
const fundResult = await runWalletCliImpl({
|
|
966
|
+
argv: ["fund", "--open", "--base-url", normalizedBaseUrl, "--tenant-id", tenantId, "--session-file", sessionFile, "--format", "json"],
|
|
967
|
+
env: actionEnv,
|
|
968
|
+
stdin,
|
|
969
|
+
stdout
|
|
970
|
+
});
|
|
971
|
+
summary.walletFund = {
|
|
972
|
+
ok: true,
|
|
973
|
+
method: String(fundResult?.method ?? "").trim() || null
|
|
974
|
+
};
|
|
975
|
+
} catch (err) {
|
|
976
|
+
summary.walletFund = {
|
|
977
|
+
ok: false,
|
|
978
|
+
error: err?.message ?? String(err ?? "")
|
|
979
|
+
};
|
|
980
|
+
summary.warnings.push("wallet funding did not complete during guided flow");
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
try {
|
|
984
|
+
const watchResult = await runWalletCliImpl({
|
|
985
|
+
argv: [
|
|
986
|
+
"balance",
|
|
987
|
+
"--watch",
|
|
988
|
+
"--min-usdc",
|
|
989
|
+
"1",
|
|
990
|
+
"--timeout-seconds",
|
|
991
|
+
"300",
|
|
992
|
+
"--interval-seconds",
|
|
993
|
+
"5",
|
|
994
|
+
"--base-url",
|
|
995
|
+
normalizedBaseUrl,
|
|
996
|
+
"--tenant-id",
|
|
997
|
+
tenantId,
|
|
998
|
+
"--session-file",
|
|
999
|
+
sessionFile,
|
|
1000
|
+
"--format",
|
|
1001
|
+
"json"
|
|
1002
|
+
],
|
|
1003
|
+
env: actionEnv,
|
|
1004
|
+
stdin,
|
|
1005
|
+
stdout
|
|
1006
|
+
});
|
|
1007
|
+
summary.walletBalanceWatch = {
|
|
1008
|
+
ok: Boolean(watchResult?.ok),
|
|
1009
|
+
satisfied: Boolean(watchResult?.watch?.satisfied)
|
|
1010
|
+
};
|
|
1011
|
+
} catch (err) {
|
|
1012
|
+
summary.walletBalanceWatch = {
|
|
1013
|
+
ok: false,
|
|
1014
|
+
error: err?.message ?? String(err ?? "")
|
|
1015
|
+
};
|
|
1016
|
+
summary.warnings.push("wallet balance watch did not reach target within timeout");
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
const paidProbe = runMcpPaidCallProbe({ env: actionEnv });
|
|
1021
|
+
if (paidProbe.ok) {
|
|
1022
|
+
summary.firstPaidCall = { ok: true };
|
|
1023
|
+
} else {
|
|
1024
|
+
summary.firstPaidCall = {
|
|
1025
|
+
ok: false,
|
|
1026
|
+
exitCode: paidProbe.exitCode,
|
|
1027
|
+
error: paidProbe.stderr || "paid call returned tool error"
|
|
1028
|
+
};
|
|
1029
|
+
summary.warnings.push("first paid call probe failed");
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
return summary;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
868
1035
|
function resolveByoWalletEnv({ walletProvider, walletEnvRows, runtimeEnv }) {
|
|
869
1036
|
const env = {};
|
|
870
1037
|
for (const row of walletEnvRows ?? []) env[row.key] = row.value;
|
|
@@ -1028,16 +1195,21 @@ async function resolveRuntimeConfig({
|
|
|
1028
1195
|
runtimeEnv,
|
|
1029
1196
|
stdin = process.stdin,
|
|
1030
1197
|
stdout = process.stdout,
|
|
1031
|
-
detectInstalledHostsImpl = detectInstalledHosts
|
|
1198
|
+
detectInstalledHostsImpl = detectInstalledHosts,
|
|
1199
|
+
fetchImpl = fetch,
|
|
1200
|
+
runLoginImpl = runLogin,
|
|
1201
|
+
readSavedSessionImpl = readSavedSession
|
|
1032
1202
|
}) {
|
|
1033
1203
|
const sessionFile = String(args.sessionFile ?? runtimeEnv.SETTLD_SESSION_FILE ?? defaultSessionPath()).trim();
|
|
1034
|
-
const savedSession = await
|
|
1204
|
+
const savedSession = await readSavedSessionImpl({ sessionPath: sessionFile });
|
|
1035
1205
|
const installedHosts = detectInstalledHostsImpl();
|
|
1036
1206
|
const defaultHost = selectDefaultHost({
|
|
1037
1207
|
explicitHost: args.host ? String(args.host).toLowerCase() : "",
|
|
1038
1208
|
installedHosts
|
|
1039
1209
|
});
|
|
1040
1210
|
const out = {
|
|
1211
|
+
setupMode: args.setupMode ?? "quick",
|
|
1212
|
+
guidedNext: args.guidedNext,
|
|
1041
1213
|
host: args.host ?? defaultHost,
|
|
1042
1214
|
walletMode: args.walletMode,
|
|
1043
1215
|
baseUrl: String(args.baseUrl ?? runtimeEnv.SETTLD_BASE_URL ?? "").trim(),
|
|
@@ -1071,6 +1243,9 @@ async function resolveRuntimeConfig({
|
|
|
1071
1243
|
}
|
|
1072
1244
|
|
|
1073
1245
|
if (args.nonInteractive) {
|
|
1246
|
+
if (!out.setupMode) out.setupMode = "quick";
|
|
1247
|
+
if (!SETUP_MODES.has(out.setupMode)) throw new Error("--quick or --advanced are the supported setup modes");
|
|
1248
|
+
if (out.guidedNext === null || out.guidedNext === undefined) out.guidedNext = false;
|
|
1074
1249
|
if (!SUPPORTED_HOSTS.includes(out.host)) throw new Error(`--host must be one of: ${SUPPORTED_HOSTS.join(", ")}`);
|
|
1075
1250
|
if (!out.baseUrl) throw new Error("--base-url is required");
|
|
1076
1251
|
if (!out.tenantId) throw new Error("--tenant-id is required");
|
|
@@ -1105,6 +1280,24 @@ async function resolveRuntimeConfig({
|
|
|
1105
1280
|
}
|
|
1106
1281
|
stdout.write("\n");
|
|
1107
1282
|
|
|
1283
|
+
if (!out.setupMode || !SETUP_MODES.has(out.setupMode)) {
|
|
1284
|
+
out.setupMode = "quick";
|
|
1285
|
+
}
|
|
1286
|
+
out.setupMode = await promptSelect(
|
|
1287
|
+
rl,
|
|
1288
|
+
stdin,
|
|
1289
|
+
stdout,
|
|
1290
|
+
"Setup mode",
|
|
1291
|
+
[
|
|
1292
|
+
{ value: "quick", label: "quick", hint: "Recommended: minimal prompts and guided next steps" },
|
|
1293
|
+
{ value: "advanced", label: "advanced", hint: "Full control over all setup options" }
|
|
1294
|
+
],
|
|
1295
|
+
{ defaultValue: out.setupMode, color }
|
|
1296
|
+
);
|
|
1297
|
+
if (out.guidedNext === null || out.guidedNext === undefined) {
|
|
1298
|
+
out.guidedNext = out.setupMode === "quick";
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1108
1301
|
const hostPromptDefault = out.host && SUPPORTED_HOSTS.includes(out.host) ? out.host : defaultHost;
|
|
1109
1302
|
const hostOptions = SUPPORTED_HOSTS.map((host) => ({
|
|
1110
1303
|
value: host,
|
|
@@ -1133,68 +1326,100 @@ async function resolveRuntimeConfig({
|
|
|
1133
1326
|
{ defaultValue: out.walletMode, color }
|
|
1134
1327
|
);
|
|
1135
1328
|
|
|
1136
|
-
if (!out.baseUrl)
|
|
1137
|
-
out.baseUrl = await promptLine(rl, "Settld base URL", { defaultValue: "https://api.settld.work" });
|
|
1138
|
-
}
|
|
1139
|
-
if (!out.tenantId) {
|
|
1140
|
-
out.tenantId = await promptLine(rl, "Tenant ID", { defaultValue: "tenant_default" });
|
|
1141
|
-
}
|
|
1329
|
+
if (!out.baseUrl) out.baseUrl = DEFAULT_PUBLIC_BASE_URL;
|
|
1142
1330
|
if (!out.settldApiKey) {
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
(
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
stdin,
|
|
1163
|
-
stdout,
|
|
1164
|
-
"How should setup get your Settld API key?",
|
|
1165
|
-
keyOptions,
|
|
1166
|
-
{ defaultValue: canUseSavedSession ? "session" : "bootstrap", color }
|
|
1167
|
-
);
|
|
1168
|
-
if (keyMode === "bootstrap") {
|
|
1169
|
-
if (!out.bootstrapApiKey) {
|
|
1170
|
-
out.bootstrapApiKey = await promptSecretLine(rl, mutableOutput, stdout, "Onboarding bootstrap API key");
|
|
1331
|
+
while (!out.settldApiKey) {
|
|
1332
|
+
const canUseSavedSession =
|
|
1333
|
+
Boolean(out.sessionCookie) &&
|
|
1334
|
+
(!savedSession ||
|
|
1335
|
+
(normalizeHttpUrl(out.baseUrl) === normalizeHttpUrl(savedSession?.baseUrl) &&
|
|
1336
|
+
(!out.tenantId || String(out.tenantId ?? "").trim() === String(savedSession?.tenantId ?? "").trim())));
|
|
1337
|
+
const keyOptions = [];
|
|
1338
|
+
if (canUseSavedSession) {
|
|
1339
|
+
keyOptions.push({
|
|
1340
|
+
value: "session",
|
|
1341
|
+
label: "Use saved login session",
|
|
1342
|
+
hint: `Reuse ${out.sessionFile} to mint runtime key`
|
|
1343
|
+
});
|
|
1344
|
+
} else {
|
|
1345
|
+
keyOptions.push({
|
|
1346
|
+
value: "login",
|
|
1347
|
+
label: "Login / create tenant (recommended)",
|
|
1348
|
+
hint: "OTP sign-in; no API key required"
|
|
1349
|
+
});
|
|
1171
1350
|
}
|
|
1172
|
-
|
|
1173
|
-
|
|
1351
|
+
keyOptions.push(
|
|
1352
|
+
{ value: "bootstrap", label: "Generate during setup", hint: "Use onboarding bootstrap API key" },
|
|
1353
|
+
{ value: "manual", label: "Paste existing key", hint: "Use an existing tenant API key" }
|
|
1354
|
+
);
|
|
1355
|
+
const keyMode = await promptSelect(
|
|
1356
|
+
rl,
|
|
1357
|
+
stdin,
|
|
1358
|
+
stdout,
|
|
1359
|
+
"How should setup get your Settld API key?",
|
|
1360
|
+
keyOptions,
|
|
1361
|
+
{ defaultValue: canUseSavedSession ? "session" : "login", color }
|
|
1362
|
+
);
|
|
1363
|
+
if (keyMode === "login") {
|
|
1364
|
+
await runLoginImpl({
|
|
1365
|
+
argv: ["--base-url", out.baseUrl, "--session-file", out.sessionFile],
|
|
1366
|
+
stdin,
|
|
1367
|
+
stdout,
|
|
1368
|
+
fetchImpl
|
|
1369
|
+
});
|
|
1370
|
+
const refreshedSession = await readSavedSessionImpl({ sessionPath: out.sessionFile });
|
|
1371
|
+
if (!refreshedSession) throw new Error("login did not produce a saved session");
|
|
1372
|
+
out.baseUrl = String(refreshedSession.baseUrl ?? out.baseUrl).trim() || out.baseUrl;
|
|
1373
|
+
out.tenantId = String(refreshedSession.tenantId ?? out.tenantId).trim();
|
|
1374
|
+
out.sessionCookie = String(refreshedSession.cookie ?? out.sessionCookie).trim();
|
|
1375
|
+
if (savedSession) {
|
|
1376
|
+
savedSession.baseUrl = refreshedSession.baseUrl;
|
|
1377
|
+
savedSession.tenantId = refreshedSession.tenantId;
|
|
1378
|
+
savedSession.cookie = refreshedSession.cookie;
|
|
1379
|
+
}
|
|
1380
|
+
continue;
|
|
1174
1381
|
}
|
|
1175
|
-
if (
|
|
1176
|
-
out.
|
|
1382
|
+
if (keyMode === "bootstrap") {
|
|
1383
|
+
if (!out.bootstrapApiKey) {
|
|
1384
|
+
out.bootstrapApiKey = await promptSecretLine(rl, mutableOutput, stdout, "Onboarding bootstrap API key");
|
|
1385
|
+
}
|
|
1386
|
+
if (!out.bootstrapKeyId) {
|
|
1387
|
+
out.bootstrapKeyId = await promptLine(rl, "Generated key ID (optional)", { required: false });
|
|
1388
|
+
}
|
|
1389
|
+
if (!out.bootstrapScopes) {
|
|
1390
|
+
out.bootstrapScopes = await promptLine(rl, "Generated key scopes CSV (optional)", { required: false });
|
|
1391
|
+
}
|
|
1392
|
+
break;
|
|
1393
|
+
}
|
|
1394
|
+
if (keyMode === "manual") {
|
|
1395
|
+
out.settldApiKey = await promptSecretLine(rl, mutableOutput, stdout, "Settld API key");
|
|
1396
|
+
break;
|
|
1177
1397
|
}
|
|
1178
|
-
} else if (keyMode === "manual") {
|
|
1179
|
-
out.settldApiKey = await promptSecretLine(rl, mutableOutput, stdout, "Settld API key");
|
|
1180
|
-
} else {
|
|
1181
1398
|
out.bootstrapApiKey = "";
|
|
1399
|
+
break;
|
|
1182
1400
|
}
|
|
1183
1401
|
}
|
|
1402
|
+
if (!out.tenantId) {
|
|
1403
|
+
out.tenantId = await promptLine(rl, "Tenant ID", { defaultValue: "tenant_default" });
|
|
1404
|
+
}
|
|
1184
1405
|
|
|
1185
1406
|
if (out.walletMode === "managed") {
|
|
1186
|
-
out.
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1407
|
+
if (out.setupMode === "quick") {
|
|
1408
|
+
out.walletBootstrap = out.walletBootstrap || "auto";
|
|
1409
|
+
} else {
|
|
1410
|
+
out.walletBootstrap = await promptSelect(
|
|
1411
|
+
rl,
|
|
1412
|
+
stdin,
|
|
1413
|
+
stdout,
|
|
1414
|
+
"Managed wallet bootstrap",
|
|
1415
|
+
[
|
|
1416
|
+
{ value: "auto", label: "auto", hint: "Use local Circle key when present, else remote bootstrap" },
|
|
1417
|
+
{ value: "local", label: "local", hint: "Always use local Circle API key flow" },
|
|
1418
|
+
{ value: "remote", label: "remote", hint: "Always use tenant onboarding endpoint" }
|
|
1419
|
+
],
|
|
1420
|
+
{ defaultValue: out.walletBootstrap || "auto", color }
|
|
1421
|
+
);
|
|
1422
|
+
}
|
|
1198
1423
|
if (out.walletBootstrap === "local" && !out.circleApiKey) {
|
|
1199
1424
|
out.circleApiKey = await promptSecretLine(rl, mutableOutput, stdout, "Circle API key");
|
|
1200
1425
|
}
|
|
@@ -1220,6 +1445,9 @@ async function resolveRuntimeConfig({
|
|
|
1220
1445
|
out.smoke = false;
|
|
1221
1446
|
out.skipProfileApply = true;
|
|
1222
1447
|
out.dryRun = true;
|
|
1448
|
+
out.guidedNext = false;
|
|
1449
|
+
} else if (out.setupMode === "quick") {
|
|
1450
|
+
out.profileId = out.profileId || "engineering-spend";
|
|
1223
1451
|
} else {
|
|
1224
1452
|
out.preflight = await promptBooleanChoice(
|
|
1225
1453
|
rl,
|
|
@@ -1296,7 +1524,10 @@ export async function runOnboard({
|
|
|
1296
1524
|
requestRuntimeBootstrapMcpEnvImpl = requestRuntimeBootstrapMcpEnv,
|
|
1297
1525
|
requestRemoteWalletBootstrapImpl = requestRemoteWalletBootstrap,
|
|
1298
1526
|
runPreflightChecksImpl = runPreflightChecks,
|
|
1299
|
-
detectInstalledHostsImpl = detectInstalledHosts
|
|
1527
|
+
detectInstalledHostsImpl = detectInstalledHosts,
|
|
1528
|
+
runLoginImpl = runLogin,
|
|
1529
|
+
readSavedSessionImpl = readSavedSession,
|
|
1530
|
+
runWalletCliImpl = runWalletCli
|
|
1300
1531
|
} = {}) {
|
|
1301
1532
|
const args = parseArgs(argv);
|
|
1302
1533
|
if (args.help) {
|
|
@@ -1305,7 +1536,7 @@ export async function runOnboard({
|
|
|
1305
1536
|
}
|
|
1306
1537
|
|
|
1307
1538
|
const showSteps = args.format !== "json";
|
|
1308
|
-
const totalSteps = args.preflightOnly ? 4 :
|
|
1539
|
+
const totalSteps = args.preflightOnly ? 4 : 6;
|
|
1309
1540
|
let step = 1;
|
|
1310
1541
|
|
|
1311
1542
|
if (showSteps) printStep(stdout, step, totalSteps, "Resolve setup configuration");
|
|
@@ -1314,7 +1545,10 @@ export async function runOnboard({
|
|
|
1314
1545
|
runtimeEnv,
|
|
1315
1546
|
stdin,
|
|
1316
1547
|
stdout,
|
|
1317
|
-
detectInstalledHostsImpl
|
|
1548
|
+
detectInstalledHostsImpl,
|
|
1549
|
+
fetchImpl,
|
|
1550
|
+
runLoginImpl,
|
|
1551
|
+
readSavedSessionImpl
|
|
1318
1552
|
});
|
|
1319
1553
|
step += 1;
|
|
1320
1554
|
const normalizedBaseUrl = normalizeHttpUrl(mustString(config.baseUrl, "SETTLD_BASE_URL / --base-url"));
|
|
@@ -1512,9 +1746,27 @@ export async function runOnboard({
|
|
|
1512
1746
|
await fs.writeFile(args.outEnv, toEnvFileText(mergedEnv), "utf8");
|
|
1513
1747
|
}
|
|
1514
1748
|
|
|
1749
|
+
if (showSteps) printStep(stdout, step, totalSteps, "Guided next steps");
|
|
1750
|
+
const guided = await runGuidedQuickFlow({
|
|
1751
|
+
enabled: Boolean(config.setupMode === "quick" && config.guidedNext),
|
|
1752
|
+
walletMode: config.walletMode,
|
|
1753
|
+
normalizedBaseUrl,
|
|
1754
|
+
tenantId,
|
|
1755
|
+
sessionFile: config.sessionFile,
|
|
1756
|
+
sessionCookie: config.sessionCookie,
|
|
1757
|
+
mergedEnv,
|
|
1758
|
+
runtimeEnv,
|
|
1759
|
+
stdin,
|
|
1760
|
+
stdout,
|
|
1761
|
+
runWalletCliImpl
|
|
1762
|
+
});
|
|
1763
|
+
step += 1;
|
|
1764
|
+
|
|
1515
1765
|
if (showSteps) printStep(stdout, step, totalSteps, "Finalize output");
|
|
1516
1766
|
const payload = {
|
|
1517
1767
|
ok: true,
|
|
1768
|
+
setupMode: config.setupMode,
|
|
1769
|
+
guided,
|
|
1518
1770
|
host: config.host,
|
|
1519
1771
|
wallet: {
|
|
1520
1772
|
mode: config.walletMode,
|
|
@@ -1546,6 +1798,7 @@ export async function runOnboard({
|
|
|
1546
1798
|
lines.push("Settld onboard complete.");
|
|
1547
1799
|
lines.push(`Host: ${config.host}`);
|
|
1548
1800
|
lines.push(`Settld: ${normalizedBaseUrl} (tenant=${tenantId})`);
|
|
1801
|
+
lines.push(`Setup mode: ${config.setupMode}`);
|
|
1549
1802
|
lines.push(`Preflight: ${config.preflight ? "passed" : "skipped"}`);
|
|
1550
1803
|
lines.push(`Wallet mode: ${config.walletMode}`);
|
|
1551
1804
|
lines.push(`Wallet bootstrap mode: ${walletBootstrapMode}`);
|
|
@@ -1553,6 +1806,18 @@ export async function runOnboard({
|
|
|
1553
1806
|
if (wallet?.wallets?.escrow?.walletId) lines.push(`Escrow wallet: ${wallet.wallets.escrow.walletId}`);
|
|
1554
1807
|
if (wallet?.tokenIdUsdc) lines.push(`USDC token id: ${wallet.tokenIdUsdc}`);
|
|
1555
1808
|
if (args.outEnv) lines.push(`Wrote env file: ${args.outEnv}`);
|
|
1809
|
+
if (guided?.enabled) {
|
|
1810
|
+
lines.push("");
|
|
1811
|
+
lines.push("Guided quick flow:");
|
|
1812
|
+
if (guided.ran) {
|
|
1813
|
+
lines.push(`- wallet fund: ${guided.walletFund?.ok ? "ok" : "not completed"}`);
|
|
1814
|
+
lines.push(`- wallet balance watch: ${guided.walletBalanceWatch?.ok ? "ok" : "not completed"}`);
|
|
1815
|
+
lines.push(`- first paid call: ${guided.firstPaidCall?.ok ? "ok" : "failed"}`);
|
|
1816
|
+
} else {
|
|
1817
|
+
lines.push("- skipped");
|
|
1818
|
+
}
|
|
1819
|
+
for (const warning of guided.warnings ?? []) lines.push(`- warning: ${warning}`);
|
|
1820
|
+
}
|
|
1556
1821
|
lines.push("");
|
|
1557
1822
|
lines.push("Combined exports:");
|
|
1558
1823
|
lines.push(toExportText(mergedEnv));
|