settld 0.2.1 → 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 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
@@ -86,6 +96,28 @@ npm install -g settld
86
96
  settld setup
87
97
  ```
88
98
 
99
+ Check wallet wiring and funding path:
100
+
101
+ ```sh
102
+ settld login
103
+ settld wallet status
104
+ settld wallet fund --open
105
+ settld wallet fund --method transfer
106
+ settld wallet balance --watch --min-usdc 1
107
+ ```
108
+
109
+ Hosted top-up (recommended): configure Coinbase Hosted Onramp on the backend so `settld wallet fund --open` launches funding directly:
110
+
111
+ ```sh
112
+ export MAGIC_LINK_WALLET_FUND_PROVIDER='coinbase'
113
+ export MAGIC_LINK_COINBASE_API_KEY_VALUE='organizations/<org_id>/apiKeys/<key_id>'
114
+ export MAGIC_LINK_COINBASE_API_SECRET_KEY='-----BEGIN EC PRIVATE KEY-----\n...\n-----END EC PRIVATE KEY-----'
115
+ export MAGIC_LINK_COINBASE_PROJECT_ID='<project_id>'
116
+ export MAGIC_LINK_COINBASE_DESTINATION_NETWORK='base'
117
+ export MAGIC_LINK_COINBASE_ASSET='USDC'
118
+ export MAGIC_LINK_COINBASE_FIAT_CURRENCY='USD'
119
+ ```
120
+
89
121
  Legacy setup wizard (advanced / old flags):
90
122
 
91
123
  ```sh
package/bin/settld.js CHANGED
@@ -22,6 +22,15 @@ function usage() {
22
22
  console.error(" settld closepack export --agreement-hash <sha256> --out <path.zip> [--ops-token tok_ops] [--base-url http://127.0.0.1:3000] [--tenant-id tenant_default] [--protocol 1.0]");
23
23
  console.error(" settld closepack verify <path.zip> [--json-out <path.json>]");
24
24
  console.error(" settld x402 receipt verify <receipt.json|-> [--strict] [--format json|text] [--json-out <path>]");
25
+ console.error(
26
+ " settld wallet status [--base-url <url>] [--tenant-id <id>] [--session-file <path>] [--cookie <cookie>] [--magic-link-api-key <key>] [--format text|json] [--json-out <path>]"
27
+ );
28
+ console.error(
29
+ " settld wallet fund [--method card|bank|transfer|faucet] [--open] [--hosted-url <url>] [--non-interactive] [--base-url <url>] [--tenant-id <id>] [--session-file <path>] [--cookie <cookie>] [--magic-link-api-key <key>] [--format text|json] [--json-out <path>]"
30
+ );
31
+ console.error(
32
+ " settld wallet balance [--watch] [--min-usdc <amount>] [--interval-seconds <n>] [--timeout-seconds <n>] [--base-url <url>] [--tenant-id <id>] [--session-file <path>] [--cookie <cookie>] [--magic-link-api-key <key>] [--format text|json] [--json-out <path>]"
33
+ );
25
34
  console.error(" settld profile list [--format json|text] [--json-out <path>]");
26
35
  console.error(" settld profile init <profile-id> [--out <path>] [--force] [--format json|text] [--json-out <path>]");
27
36
  console.error(
@@ -271,6 +280,10 @@ function main() {
271
280
  process.exit(1);
272
281
  }
273
282
 
283
+ if (cmd === "wallet") {
284
+ return runNodeScript("scripts/wallet/cli.mjs", argv.slice(1));
285
+ }
286
+
274
287
  if (cmd === "profile") {
275
288
  return runNodeScript("scripts/profile/cli.mjs", argv.slice(1));
276
289
  }
@@ -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
- Required inputs:
16
+ Public default path (recommended):
17
17
 
18
- - `SETTLD_BASE_URL` (local or hosted API URL)
19
- - `SETTLD_TENANT_ID`
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` (onboarding bootstrap key that mints `SETTLD_API_KEY` during setup)
23
- - Node.js 20+
28
+ - `SETTLD_BOOTSTRAP_API_KEY` (bootstrap key that mints runtime key)
29
+
30
+ Recommended interactive pattern:
24
31
 
25
- Recommended non-interactive pattern:
32
+ ```bash
33
+ settld setup
34
+ ```
35
+
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 for you:
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
- The wizard handles:
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
@@ -169,7 +184,66 @@ Then activate host-side:
169
184
  - `cursor`: restart Cursor.
170
185
  - `openclaw`: run `openclaw doctor`, ensure OpenClaw onboarding is complete (`openclaw onboard --install-daemon`), then run `openclaw tui`.
171
186
 
172
- ## 5) How the agent uses Settld after activation
187
+ ## 5) Fund and verify wallet state
188
+
189
+ Check wallet assignment after setup:
190
+
191
+ ```bash
192
+ settld wallet status
193
+ ```
194
+
195
+ If wallet commands return auth errors, run:
196
+
197
+ ```bash
198
+ settld login
199
+ ```
200
+
201
+ Funding paths:
202
+
203
+ ```bash
204
+ # Guided selector (recommended)
205
+ settld wallet fund --open
206
+
207
+ # Hosted flow (card/bank) - provider-hosted URL, add --open to launch browser
208
+ settld wallet fund --method card --open
209
+ settld wallet fund --method bank --open
210
+
211
+ # Direct transfer path (prints chain + destination address)
212
+ settld wallet fund --method transfer
213
+
214
+ # Sandbox only: request faucet top-up
215
+ settld wallet fund --method faucet
216
+ ```
217
+
218
+ Provider-hosted card/bank links are configured on the control-plane backend.
219
+
220
+ Option A (recommended): Coinbase Hosted Onramp:
221
+
222
+ ```bash
223
+ export MAGIC_LINK_WALLET_FUND_PROVIDER='coinbase'
224
+ export MAGIC_LINK_COINBASE_API_KEY_VALUE='organizations/<org_id>/apiKeys/<key_id>'
225
+ export MAGIC_LINK_COINBASE_API_SECRET_KEY='-----BEGIN EC PRIVATE KEY-----\n...\n-----END EC PRIVATE KEY-----'
226
+ export MAGIC_LINK_COINBASE_PROJECT_ID='<project_id>'
227
+ export MAGIC_LINK_COINBASE_DESTINATION_NETWORK='base'
228
+ export MAGIC_LINK_COINBASE_ASSET='USDC'
229
+ export MAGIC_LINK_COINBASE_FIAT_CURRENCY='USD'
230
+ ```
231
+
232
+ Option B: explicit card/bank URLs:
233
+
234
+ ```bash
235
+ # backend env (magic-link service)
236
+ export MAGIC_LINK_WALLET_FUND_CARD_URL='https://pay.example.com/topup?tenant={tenantId}&method=card&address={walletAddress}'
237
+ export MAGIC_LINK_WALLET_FUND_BANK_URL='https://pay.example.com/topup?tenant={tenantId}&method=bank&address={walletAddress}'
238
+ ```
239
+
240
+ After funding, wait until spend wallet has balance:
241
+
242
+ ```bash
243
+ settld wallet balance --watch --min-usdc 1
244
+ ```
245
+
246
+ ## 6) How the agent uses Settld after activation
173
247
 
174
248
  After host activation, the agent interacts with Settld through MCP `settld.*` tools.
175
249
 
@@ -200,7 +274,7 @@ Verify first receipt from artifacts:
200
274
  settld x402 receipt verify <artifactDir>/x402-receipt.json --json-out /tmp/settld-first-receipt.json
201
275
  ```
202
276
 
203
- ## 6) Host config helper customization
277
+ ## 7) Host config helper customization
204
278
 
205
279
  Default host configuration logic is in:
206
280
 
@@ -214,10 +288,15 @@ settld setup --host-config ./path/to/custom-host-config.mjs
214
288
 
215
289
  Your helper should provide resolver/setup exports compatible with `scripts/setup/wizard.mjs`.
216
290
 
217
- ## 7) Troubleshooting
291
+ ## 8) Troubleshooting
218
292
 
219
293
  - `BYO wallet mode missing required env keys`
220
294
  - Provide all required Circle keys in section 3.
295
+ - `auth required: pass --cookie/--magic-link-api-key or run settld login first`
296
+ - Run `settld login`, then retry `settld wallet status` / `settld wallet fund`.
297
+ - `no hosted funding URL configured for card/bank`
298
+ - set backend Coinbase env (`MAGIC_LINK_WALLET_FUND_PROVIDER=coinbase`, `MAGIC_LINK_COINBASE_API_KEY_VALUE`, `MAGIC_LINK_COINBASE_API_SECRET_KEY`) or set explicit `MAGIC_LINK_WALLET_FUND_CARD_URL` / `MAGIC_LINK_WALLET_FUND_BANK_URL`.
299
+ - pass `--hosted-url` for an ad-hoc override.
221
300
  - `host config helper missing`
222
301
  - Add `scripts/setup/host-config.mjs` or pass `--host-config`.
223
302
  - `SETTLD_API_KEY must be a non-empty string`
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`) with your host, tenant, and API key.
21
- 2. Activate your host and run `npm run mcp:probe`.
22
- 3. Run `npm run demo:mcp-paid-exa`.
23
- 4. Verify the first receipt:
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
@@ -19,9 +19,13 @@ Settld gives you a canonical economic loop:
19
19
  ## One-command onboarding
20
20
 
21
21
  ```bash
22
- settld setup --non-interactive --host codex --base-url http://127.0.0.1:3000 --tenant-id tenant_default --settld-api-key sk_live_xxx.yyy --wallet-mode managed --wallet-bootstrap remote --profile-id engineering-spend --smoke
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
- - Settld API URL
9
- - Tenant ID
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
- The guided setup uses arrow-key menus for host/wallet/policy decisions, then asks only the next required fields.
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
 
@@ -51,7 +57,46 @@ source ./.tmp/settld.env
51
57
 
52
58
  Then restart your host app (Codex/Claude/Cursor/OpenClaw) so it reloads MCP config.
53
59
 
54
- ## 2) Verify MCP connectivity
60
+ ## 2) Check wallet and fund it
61
+
62
+ ```bash
63
+ settld login
64
+ settld wallet status
65
+ settld wallet fund --method transfer
66
+ settld wallet balance --watch --min-usdc 1
67
+ ```
68
+
69
+ Optional methods:
70
+
71
+ ```bash
72
+ settld wallet fund --open
73
+ settld wallet fund --method card --open
74
+ settld wallet fund --method bank --open
75
+ settld wallet fund --method faucet
76
+ ```
77
+
78
+ For card/bank, configure one hosted provider URL strategy on the control-plane backend.
79
+
80
+ Option A (recommended): Coinbase Hosted Onramp:
81
+
82
+ ```bash
83
+ export MAGIC_LINK_WALLET_FUND_PROVIDER='coinbase'
84
+ export MAGIC_LINK_COINBASE_API_KEY_VALUE='organizations/<org_id>/apiKeys/<key_id>'
85
+ export MAGIC_LINK_COINBASE_API_SECRET_KEY='-----BEGIN EC PRIVATE KEY-----\n...\n-----END EC PRIVATE KEY-----'
86
+ export MAGIC_LINK_COINBASE_PROJECT_ID='<project_id>'
87
+ export MAGIC_LINK_COINBASE_DESTINATION_NETWORK='base'
88
+ export MAGIC_LINK_COINBASE_ASSET='USDC'
89
+ export MAGIC_LINK_COINBASE_FIAT_CURRENCY='USD'
90
+ ```
91
+
92
+ Option B: explicit card/bank hosted templates:
93
+
94
+ ```bash
95
+ export MAGIC_LINK_WALLET_FUND_CARD_URL='https://pay.example.com/topup?tenant={tenantId}&method=card&address={walletAddress}'
96
+ export MAGIC_LINK_WALLET_FUND_BANK_URL='https://pay.example.com/topup?tenant={tenantId}&method=bank&address={walletAddress}'
97
+ ```
98
+
99
+ ## 3) Verify MCP connectivity
55
100
 
56
101
  ```bash
57
102
  npm run mcp:probe -- --call settld.about '{}'
@@ -62,7 +107,7 @@ Expected outcome:
62
107
  - `settld.about` succeeds
63
108
  - host can discover `settld.*` tools
64
109
 
65
- ## 3) Run first paid call
110
+ ## 4) Run first paid call
66
111
 
67
112
  ```bash
68
113
  npm run demo:mcp-paid-exa
@@ -75,7 +120,7 @@ Expected output includes:
75
120
  - `decisionId=...`
76
121
  - `settlementReceiptId=...`
77
122
 
78
- ## 4) Verify first receipt (proof packet)
123
+ ## 5) Verify first receipt (proof packet)
79
124
 
80
125
  ```bash
81
126
  jq -c 'first' <artifactDir>/x402-receipts.export.jsonl > /tmp/settld-first-receipt.json
@@ -84,7 +129,7 @@ settld x402 receipt verify /tmp/settld-first-receipt.json --format json --json-o
84
129
 
85
130
  `/tmp/settld-first-receipt.verify.json` is your deterministic verification artifact for audit/compliance.
86
131
 
87
- ## 5) Optional: policy profile workflows
132
+ ## 6) Optional: policy profile workflows
88
133
 
89
134
  ```bash
90
135
  settld profile list
@@ -99,5 +144,10 @@ settld profile simulate ./profiles/engineering-spend.profile.json --format json
99
144
  - ensure key is present in setup flags or shell env.
100
145
  - `BYO wallet mode missing required env keys`
101
146
  - provide all required Circle keys in `docs/QUICKSTART_MCP_HOSTS.md`.
147
+ - `auth required: pass --cookie/--magic-link-api-key or run settld login first`
148
+ - run `settld login`, then retry wallet commands.
149
+ - `no hosted funding URL configured for card/bank`
150
+ - set backend Coinbase env (`MAGIC_LINK_WALLET_FUND_PROVIDER=coinbase`, `MAGIC_LINK_COINBASE_API_KEY_VALUE`, `MAGIC_LINK_COINBASE_API_SECRET_KEY`) or set explicit `MAGIC_LINK_WALLET_FUND_CARD_URL` / `MAGIC_LINK_WALLET_FUND_BANK_URL`.
151
+ - pass `--hosted-url` for an ad-hoc override.
102
152
  - Host cannot find MCP tools
103
153
  - rerun setup, restart host, then rerun `npm run mcp:probe`.
@@ -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. wallet mode (`managed` recommended first)
37
- 3. wallet bootstrap (`remote` recommended for first setup)
38
- 4. keep preflight + smoke enabled
39
- 5. apply a starter profile (`engineering-spend`)
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
- If you do not have a tenant `sk_*` yet, let setup mint one:
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 API key (`SETTLD_API_KEY`)
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": "http://127.0.0.1:3000",
7
- "SETTLD_TENANT_ID": "tenant_default",
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "settld",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Settld kernel CLI and local control-plane tooling",
5
5
  "private": false,
6
6
  "type": "module",
@@ -136,6 +136,7 @@
136
136
  },
137
137
  "dependencies": {
138
138
  "@circle-fin/developer-controlled-wallets": "^10.1.0",
139
+ "@coinbase/cdp-sdk": "^1.44.1",
139
140
  "pg": "^8.11.5",
140
141
  "snarkjs": "^0.7.6"
141
142
  },
@@ -11,6 +11,10 @@ function randomId(prefix) {
11
11
  return `${prefix}_${crypto.randomBytes(6).toString("hex")}`;
12
12
  }
13
13
 
14
+ function buildScopedOpsToken(token) {
15
+ return `${String(token ?? "").trim()}:ops_read,ops_write,finance_read,finance_write,audit_read`;
16
+ }
17
+
14
18
  function pickPort() {
15
19
  return new Promise((resolve, reject) => {
16
20
  const server = net.createServer();
@@ -243,6 +247,7 @@ function stopServer(server) {
243
247
  async function main() {
244
248
  const reportPath = path.resolve(process.cwd(), process.env.MCP_HOST_SMOKE_REPORT_PATH || "artifacts/ops/mcp-host-smoke.json");
245
249
  const opsToken = randomId("ops");
250
+ const scopedOpsToken = buildScopedOpsToken(opsToken);
246
251
  const magicLinkApiKey = randomId("ml_admin");
247
252
  const tenantId = randomId("tenant");
248
253
 
@@ -259,6 +264,7 @@ async function main() {
259
264
  env: {
260
265
  PORT: String(apiPort),
261
266
  PROXY_BIND_HOST: "127.0.0.1",
267
+ PROXY_OPS_TOKENS: scopedOpsToken,
262
268
  PROXY_OPS_TOKEN: opsToken,
263
269
  PROXY_AUTOTICK_INTERVAL_MS: "200"
264
270
  }
@@ -141,6 +141,10 @@ function randomId(prefix) {
141
141
  return `${prefix}_${crypto.randomBytes(6).toString("hex")}`;
142
142
  }
143
143
 
144
+ function buildScopedOpsToken(token) {
145
+ return `${String(token ?? "").trim()}:ops_read,ops_write,finance_read,finance_write,audit_read`;
146
+ }
147
+
144
148
  function pickPort() {
145
149
  return new Promise((resolve, reject) => {
146
150
  const server = net.createServer();
@@ -239,6 +243,7 @@ function startNodeProc({ name, scriptPath, env }) {
239
243
  async function startEphemeralApi(env = process.env) {
240
244
  const port = await pickPort();
241
245
  const opsToken = randomId("ops");
246
+ const scopedOpsToken = buildScopedOpsToken(opsToken);
242
247
  const baseUrl = `http://127.0.0.1:${port}`;
243
248
  const api = startNodeProc({
244
249
  name: "cutover-api",
@@ -247,6 +252,7 @@ async function startEphemeralApi(env = process.env) {
247
252
  ...env,
248
253
  PORT: String(port),
249
254
  PROXY_BIND_HOST: "127.0.0.1",
255
+ PROXY_OPS_TOKENS: scopedOpsToken,
250
256
  PROXY_OPS_TOKEN: opsToken,
251
257
  PROXY_AUTOTICK_INTERVAL_MS: "200"
252
258
  }
@@ -192,6 +192,18 @@ function readEnvString(name, fallback = null) {
192
192
  return String(raw).trim();
193
193
  }
194
194
 
195
+ function readFirstOpsTokenFromScopedList(raw) {
196
+ const text = String(raw ?? "").trim();
197
+ if (!text) return null;
198
+ const firstEntry = text
199
+ .split(";")
200
+ .map((entry) => String(entry ?? "").trim())
201
+ .find(Boolean);
202
+ if (!firstEntry) return null;
203
+ const token = firstEntry.split(":")[0]?.trim() ?? "";
204
+ return token || null;
205
+ }
206
+
195
207
  function assertCircleModeInputs({ mode }) {
196
208
  if (mode === "stub") return;
197
209
  const required = ["CIRCLE_API_KEY", "CIRCLE_WALLET_ID_SPEND", "CIRCLE_WALLET_ID_ESCROW", "CIRCLE_TOKEN_ID_USDC"];
@@ -646,7 +658,10 @@ async function main() {
646
658
  const workload = normalizeWorkload(cli.workload ?? readEnvString("SETTLD_DEMO_WORKLOAD", "exa"));
647
659
  const externalReserveRequired = circleMode !== "stub";
648
660
  assertCircleModeInputs({ mode: circleMode });
649
- const opsToken = String(process.env.SETTLD_DEMO_OPS_TOKEN ?? "tok_ops").trim() || "tok_ops";
661
+ const inheritedOpsTokenList = readEnvString("PROXY_OPS_TOKENS", null);
662
+ const derivedOpsToken = readFirstOpsTokenFromScopedList(inheritedOpsTokenList);
663
+ const opsToken = String(process.env.SETTLD_DEMO_OPS_TOKEN ?? derivedOpsToken ?? "tok_ops").trim() || "tok_ops";
664
+ const scopedOpsToken = `${opsToken}:ops_read,ops_write,finance_read,finance_write,audit_read`;
650
665
  const tenantId = String(process.env.SETTLD_TENANT_ID ?? "tenant_default").trim() || "tenant_default";
651
666
 
652
667
  const workloadConfig = (() => {
@@ -733,6 +748,8 @@ async function main() {
733
748
  cmd: "node",
734
749
  args: ["src/api/server.js"],
735
750
  env: {
751
+ // Pin ops auth for this demo process so inherited deployment env can't cause token mismatch.
752
+ PROXY_OPS_TOKENS: scopedOpsToken,
736
753
  PROXY_OPS_TOKEN: opsToken,
737
754
  BIND_HOST: "127.0.0.1",
738
755
  PORT: String(apiPort),
@@ -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 for new signup)", { defaultValue: state.tenantId, required: false });
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, "Company name", { defaultValue: state.company });
200
+ state.company = await promptLine(rl, "What should your tenant/company name be?", { defaultValue: state.company });
198
201
  }
199
202
  }
200
203