@reclaimprotocol/agent 0.1.36 → 0.1.38
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 +8 -8
- package/lib/authoring/backend.d.ts +12 -1
- package/lib/authoring/backend.js +3 -0
- package/lib/authoring/tools.js +33 -5
- package/lib/authoring/util.d.ts +43 -0
- package/lib/authoring/util.js +54 -0
- package/lib/cdp/chrome-for-testing.d.ts +14 -0
- package/lib/cdp/chrome-for-testing.js +43 -0
- package/lib/cdp/geo.d.ts +3 -0
- package/lib/cdp/geo.js +27 -15
- package/lib/cdp/launcher.d.ts +79 -1
- package/lib/cdp/launcher.js +244 -24
- package/lib/logger.js +3 -1
- package/lib/mcp/instructions.js +3 -3
- package/lib/mcp/start.js +17 -2
- package/lib/mcp/tools/agent/attach.d.ts +6 -0
- package/lib/mcp/tools/agent/attach.js +58 -118
- package/lib/mcp/tools/agent/build.js +8 -0
- package/lib/mcp/tools/agent/capture.js +33 -10
- package/lib/mcp/tools/agent/check-attestor.js +15 -7
- package/lib/mcp/tools/agent/draft-tools.d.ts +3 -0
- package/lib/mcp/tools/agent/draft-tools.js +170 -0
- package/lib/mcp/tools/agent/example-app.d.ts +2 -0
- package/lib/mcp/tools/agent/example-app.js +167 -0
- package/lib/mcp/tools/agent/pod-proof.js +5 -1
- package/lib/mcp/tools/agent/proof.d.ts +28 -0
- package/lib/mcp/tools/agent/proof.js +72 -0
- package/lib/mcp/tools/agent/shared.d.ts +8 -1
- package/lib/mcp/tools/agent/shared.js +98 -19
- package/lib/mcp/tools/agent/start-integration.d.ts +2 -1
- package/lib/mcp/tools/agent/start-integration.js +10 -6
- package/lib/mcp/tools/authenticate/authenticate.d.ts +48 -10
- package/lib/mcp/tools/authenticate/authenticate.js +212 -116
- package/lib/mcp/tools/authenticate/build.d.ts +2 -2
- package/lib/mcp/tools/authenticate/build.js +6 -3
- package/lib/mcp/tools/authenticate/builder-access.js +5 -2
- package/lib/mcp/tools/authenticate/eth-key.d.ts +13 -2
- package/lib/mcp/tools/authenticate/eth-key.js +29 -5
- package/lib/mcp/tools/authenticate/index.d.ts +1 -1
- package/lib/mcp/tools/authenticate/index.js +1 -1
- package/lib/mcp/tools/authenticate/issue-org-keypair.d.ts +10 -0
- package/lib/mcp/tools/authenticate/issue-org-keypair.js +82 -0
- package/lib/mcp/tools/authenticate/oauth-config.d.ts +31 -0
- package/lib/mcp/tools/authenticate/oauth-config.js +67 -0
- package/lib/mcp/tools/authenticate/resolve-owner-key.d.ts +4 -5
- package/lib/mcp/tools/authenticate/resolve-owner-key.js +40 -36
- package/lib/mcp/tools/authenticate/session-cache.d.ts +25 -1
- package/lib/mcp/tools/authenticate/session-cache.js +95 -4
- package/lib/mcp/tools/mode/mode.js +6 -6
- package/lib/old/login-cdp.js +2 -3
- package/lib/proof/attestor.js +2 -3
- package/lib/proof/check-attestor.d.ts +12 -2
- package/lib/proof/check-attestor.js +40 -10
- package/lib/proof/check-matchers.d.ts +36 -0
- package/lib/proof/check-matchers.js +161 -0
- package/lib/proof/zk-files.d.ts +50 -11
- package/lib/proof/zk-files.js +259 -63
- package/lib/provider/draft.d.ts +24 -1
- package/lib/provider/draft.js +135 -0
- package/lib/provider/matcher.js +171 -4
- package/package.json +6 -4
- package/skill/SKILL.builder.md +7 -2
- package/skill/SKILL.common.md +90 -70
- package/skill/SKILL.old.md +3 -3
- package/skill/builder-mode.md +35 -5
- package/skill/old-mode.md +18 -13
- package/skill/start-integration.md +50 -33
- package/skill/verification-client-integration.md +21 -6
- package/src/authoring/backend.ts +12 -1
- package/src/authoring/tools.ts +48 -7
- package/src/authoring/util.ts +64 -0
- package/src/cdp/chrome-for-testing.ts +66 -0
- package/src/cdp/geo.ts +36 -21
- package/src/cdp/launcher.ts +328 -24
- package/src/logger.ts +3 -1
- package/src/mcp/instructions.ts +3 -3
- package/src/mcp/start.ts +20 -1
- package/src/mcp/tools/agent/attach.ts +65 -128
- package/src/mcp/tools/agent/build.ts +9 -0
- package/src/mcp/tools/agent/capture.ts +54 -11
- package/src/mcp/tools/agent/check-attestor.ts +15 -7
- package/src/mcp/tools/agent/draft-tools.ts +234 -0
- package/src/mcp/tools/agent/example-app.ts +227 -0
- package/src/mcp/tools/agent/pod-proof.ts +5 -1
- package/src/mcp/tools/agent/proof.ts +110 -1
- package/src/mcp/tools/agent/shared.ts +130 -19
- package/src/mcp/tools/agent/start-integration.ts +10 -6
- package/src/mcp/tools/authenticate/authenticate.ts +276 -131
- package/src/mcp/tools/authenticate/build.ts +6 -3
- package/src/mcp/tools/authenticate/builder-access.ts +5 -2
- package/src/mcp/tools/authenticate/eth-key.ts +41 -7
- package/src/mcp/tools/authenticate/index.ts +1 -1
- package/src/mcp/tools/authenticate/issue-org-keypair.ts +106 -0
- package/src/mcp/tools/authenticate/oauth-config.ts +85 -0
- package/src/mcp/tools/authenticate/resolve-owner-key.ts +42 -39
- package/src/mcp/tools/authenticate/session-cache.ts +125 -5
- package/src/mcp/tools/mode/mode.ts +6 -6
- package/src/old/login-cdp.ts +2 -3
- package/src/proof/attestor.ts +2 -3
- package/src/proof/check-attestor.ts +55 -12
- package/src/proof/check-matchers.ts +227 -0
- package/src/proof/zk-files.ts +357 -65
- package/src/provider/draft.ts +215 -7
- package/src/provider/matcher.ts +237 -4
package/skill/SKILL.common.md
CHANGED
|
@@ -28,45 +28,37 @@ already names it.
|
|
|
28
28
|
- [Container lifetime and isolation](#how-containers-are-shared-and-when-they-close)
|
|
29
29
|
- [Container startup problems](#when-the-container-will-not-start)
|
|
30
30
|
|
|
31
|
-
**
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
31
|
+
**Default: call `attach_browser()` with no arguments. Don't ask anything
|
|
32
|
+
first.** It opens a visible browser on the developer's own machine with the
|
|
33
|
+
persistent Reclaim profile (`~/.reclaim/chrome-profile`), so a site they sign
|
|
34
|
+
in to stays signed in. It uses installed Chrome, then Chromium, then Edge. If
|
|
35
|
+
none is installed, or the installed one won't start, it downloads Chrome for
|
|
36
|
+
Testing once into `~/.reclaim/browsers` and uses that. When the result says
|
|
37
|
+
Chrome for Testing was used, tell the developer in one line.
|
|
38
|
+
|
|
39
|
+
**Side note on sharing.** Tell the developer once, in passing, that if a
|
|
40
|
+
volunteer is helping them sign in, you can set up a shareable link to the
|
|
41
|
+
browser (`container` mode and `share_browser_view`). Don't ask about it, and
|
|
42
|
+
don't set it up unless they ask.
|
|
43
|
+
|
|
44
|
+
**Other modes are opt-in.** Pass `mode` only when the developer explicitly asks
|
|
45
|
+
for one of these, or when `attach_browser()` fails even with Chrome for
|
|
46
|
+
Testing (for example, no display on Linux). In that case, use `container` if
|
|
47
|
+
Docker is running and say why in one line. Otherwise don't offer them, list
|
|
48
|
+
them, or pick one yourself, and don't reuse a mode from an earlier session.
|
|
49
|
+
|
|
50
|
+
| mode | when the developer asks for | needs |
|
|
44
51
|
| --- | --- | --- |
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
**Someone else has to sign in, or the site only works on a phone** — these two
|
|
51
|
-
are the only modes that produce a link another person can open:
|
|
52
|
-
|
|
53
|
-
| mode | what it is | needs | costs |
|
|
54
|
-
| --- | --- | --- | --- |
|
|
55
|
-
| `container` | The Reclaim runtime in Docker, on their machine. `share_browser_view` turns its viewer into a public link. | Docker running | free — their Docker and bandwidth |
|
|
56
|
-
| `builder` | A browser in Reclaim's cloud. The link comes back immediately, with nothing to install. Also the only way to browse from a **specific country**. | Builder auth, `orgId` | **chargeable** — billed against the org's quota |
|
|
57
|
-
|
|
58
|
-
**Say which one costs money.** They are otherwise interchangeable from the
|
|
59
|
-
developer's point of view, so price and "do you have Docker" are the whole
|
|
60
|
-
decision. Do not quietly pick the billed one.
|
|
61
|
-
|
|
62
|
-
`custom` (any `ws://`/`wss://` CDP endpoint they supply) exists for someone who
|
|
63
|
-
was handed an endpoint and knows why. Don't offer it unprompted; it cannot be
|
|
64
|
-
shared either.
|
|
52
|
+
| `attach` | The Chrome they already have open, with its tabs, extensions, and logins | `port` (default 9222) |
|
|
53
|
+
| `container` | Someone else signs in, or a phone-only site. The Reclaim runtime runs in Docker on their machine; `share_browser_view` turns its viewer into a public link | Docker running |
|
|
54
|
+
| `builder` | A browser hosted by Reclaim, or browsing from a specific country. **Billed** against the org's quota; say so before you call it | Builder auth, `orgId` |
|
|
55
|
+
| `custom` | A `ws://` or `wss://` CDP endpoint they supply | `cdpUrl` |
|
|
65
56
|
|
|
66
57
|
**`attach` gotcha (Chrome 136 and later):** the developer's Chrome must be
|
|
67
58
|
started with BOTH `--remote-debugging-port=9222` AND
|
|
68
59
|
`--user-data-dir=<non-default-path>`. The debug flag is silently ignored on the
|
|
69
|
-
default profile. If `attach` fails, say this verbatim
|
|
60
|
+
default profile. If `attach` fails, say this verbatim. The default call with no
|
|
61
|
+
`mode` always works without it.
|
|
70
62
|
|
|
71
63
|
**`builder` specifics:**
|
|
72
64
|
|
|
@@ -81,9 +73,7 @@ default profile. If `attach` fails, say this verbatim and offer `dedicated`.
|
|
|
81
73
|
the suggested country, a country the site must be seen from, or skipping geo
|
|
82
74
|
entirely (`skipCountry: true`, the deployment's default egress). The country
|
|
83
75
|
is **fixed for the session's lifetime** and can't be changed after allocation.
|
|
84
|
-
|
|
85
|
-
remote browser in that country rather than working around it locally. If the
|
|
86
|
-
deployment has no proxy configured the browser is still allocated, just
|
|
76
|
+
If the deployment has no proxy configured the browser is still allocated, just
|
|
87
77
|
without the requested country.
|
|
88
78
|
- Costs one VERIFICATION-pool use under the org's normal plan restrictions.
|
|
89
79
|
- Return the FULL `liveViewUrl` to the developer **verbatim, on its own line** —
|
|
@@ -129,8 +119,8 @@ If they say yes:
|
|
|
129
119
|
|
|
130
120
|
- **`container` is the only mode this applies to.** `builder` returns a hosted
|
|
131
121
|
`liveViewUrl` from `attach_browser` — relay that instead, full and verbatim.
|
|
132
|
-
`dedicated`, `attach`, and `custom` have no view to share at all
|
|
133
|
-
|
|
122
|
+
`dedicated`, `attach`, and `custom` have no view to share at all. If the
|
|
123
|
+
developer asks to let someone else in, re-attach with `mode: "container"`.
|
|
134
124
|
- **The URL is the ONLY credential.** The hostname Cloudflare hands out is the
|
|
135
125
|
whole secret: there is no token and no login behind it, so whoever learns the
|
|
136
126
|
URL has the browser, as the signed-in user. Give it to one person, say plainly
|
|
@@ -141,8 +131,8 @@ If they say yes:
|
|
|
141
131
|
- **It shows the whole browser, not one tab.** A sign-in that opens a separate
|
|
142
132
|
window is visible too.
|
|
143
133
|
- **Opening it on a phone lays the page out for that phone**, with touch,
|
|
144
|
-
pinch-zoom and the soft keyboard. That is
|
|
145
|
-
|
|
134
|
+
pinch-zoom and the soft keyboard. That is why `container` suits a site that
|
|
135
|
+
only works on mobile, when the developer asks for it.
|
|
146
136
|
- **Stop a cloudflared process you started as soon as they're done.** If they
|
|
147
137
|
started it, tell them to stop it. The browser keeps running. `dispose_browser` and `reset_session` stop the
|
|
148
138
|
container itself, but not your cloudflared process.
|
|
@@ -181,18 +171,30 @@ If they say yes:
|
|
|
181
171
|
- A container left over from a crashed run is **reused if it is still serving**,
|
|
182
172
|
and replaced if it is not — a second attach does not need a different port.
|
|
183
173
|
|
|
184
|
-
**When
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
- **
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
174
|
+
**When the default local launch fails**, the error names the reason. Act on
|
|
175
|
+
it rather than switching modes:
|
|
176
|
+
|
|
177
|
+
- **No display** (Linux, neither `WAYLAND_DISPLAY` nor `DISPLAY` set). The MCP
|
|
178
|
+
server was started outside the desktop session. Ask the developer to add the
|
|
179
|
+
variable to the MCP server's environment (for example `DISPLAY=:0`, or
|
|
180
|
+
`WAYLAND_DISPLAY=wayland-0` with `XDG_RUNTIME_DIR`) and restart the agent.
|
|
181
|
+
- **Exited with code N**, followed by the browser's own stderr. Read the
|
|
182
|
+
stderr: it usually names the cause (a missing library, a sandbox error).
|
|
183
|
+
Chrome for Testing was already tried as a fallback when the error mentions
|
|
184
|
+
it.
|
|
185
|
+
- **Profile in use by a running browser (PID N).** A browser on
|
|
186
|
+
`~/.reclaim/chrome-profile` is open without the debugging port. Ask the
|
|
187
|
+
developer to close that window, then retry. Stale locks left by a crashed
|
|
188
|
+
browser are cleared automatically.
|
|
189
|
+
- **Did not answer CDP within 30000ms.** Retry once; a first start on a slow
|
|
190
|
+
disk can be slow. If it repeats, quote the stderr in the error.
|
|
191
|
+
- **Wrong browser picked.** Set `RECLAIM_AGENT_CHROME_PATH` to the binary — on
|
|
192
|
+
Windows `setx RECLAIM_AGENT_CHROME_PATH "C:\path\to\chrome.exe"` (`setx`, not
|
|
193
|
+
`$env:`, so future shells inherit it); on macOS/Linux `export` it. **Then
|
|
194
|
+
fully restart the agent** — MCP servers snapshot env vars at launch.
|
|
192
195
|
- **Pre-existing `chrome.exe` hijacks the launch (Windows).** A new launch with
|
|
193
196
|
`--remote-debugging-port` gets delegated to the running process group and the
|
|
194
197
|
port silently never opens. `taskkill /F /IM chrome.exe`, then retry.
|
|
195
|
-
- **Chrome 136+ default-profile rule** (above) — `dedicated` is always safe.
|
|
196
198
|
|
|
197
199
|
<!-- section: login-detect -->
|
|
198
200
|
**Check login state, wait if needed.** `eval_in_page(captureId, ...)` with a
|
|
@@ -310,9 +312,18 @@ won't help.
|
|
|
310
312
|
|
|
311
313
|
Permitted edits: narrowing the `contains` template, a more distinctive
|
|
312
314
|
xPath class/id when the synthesizer's pick is too generic, fixing `name`,
|
|
313
|
-
adding/removing secret headers.
|
|
315
|
+
adding/removing secret headers. Make matcher edits with `update_draft`
|
|
316
|
+
(never by importing the agent's internals), then confirm them offline with
|
|
317
|
+
`check_matchers`, which runs the attestor's own redaction and match engine
|
|
318
|
+
on the captured response. Tempted to rewrite from scratch? Call
|
|
314
319
|
`propose_provider` again with different inputs instead.
|
|
315
320
|
|
|
321
|
+
If `propose_provider` says the value has no key name next to it, or that
|
|
322
|
+
the window holds a number or a neighbouring value, the request can't give
|
|
323
|
+
a portable matcher (typical of SvelteKit `__data.json` positional arrays).
|
|
324
|
+
Pick the HTML page or another JSON API where the value sits under its own
|
|
325
|
+
key.
|
|
326
|
+
|
|
316
327
|
<!-- section: secrets -->
|
|
317
328
|
### Protect secret values
|
|
318
329
|
|
|
@@ -393,6 +404,15 @@ supplies are context params.
|
|
|
393
404
|
`check_attestor` after the developer fixes their network. Do not loop
|
|
394
405
|
retries; one `run_proof` per change.
|
|
395
406
|
|
|
407
|
+
**Blocked non-browser clients** (`diagnosis.kind` is
|
|
408
|
+
`blocked-non-browser-client`: HTTP 403/406/429/503 or a challenge page,
|
|
409
|
+
often after `replay_request` succeeded): the site blocks clients that
|
|
410
|
+
aren't a real browser (bot protection or TLS fingerprint). Copying
|
|
411
|
+
headers or cookies won't help, and `run_proof_via_pod` doesn't change the
|
|
412
|
+
TLS fingerprint. Try a different endpoint that returns the value (a JSON
|
|
413
|
+
API the page calls), or stop and report. Run `check_matchers` first so a
|
|
414
|
+
recipe bug isn't mistaken for blocking.
|
|
415
|
+
|
|
396
416
|
**Do not auto-retry with a different `attestorUrl`.** There is one live
|
|
397
417
|
public attestor; backup hostnames (`attestor-2.*`, and so on) **do not
|
|
398
418
|
exist**. `attestorUrl` is only for a developer-supplied private/staging URL.
|
|
@@ -421,30 +441,30 @@ supplies are context params.
|
|
|
421
441
|
match — all stop signs. And never accept "the xPath looks too narrow, let me
|
|
422
442
|
write a regex": the synthesizer already pairs the anchor with a
|
|
423
443
|
structure-anchored named-capture regex. If extraction looks wrong, re-run
|
|
424
|
-
`propose_provider` with a better request/target.
|
|
444
|
+
`propose_provider` with a better request/target. The permitted narrowing
|
|
445
|
+
edits go through `update_draft` and `check_matchers`.
|
|
425
446
|
- Never rename or `%CTX%`-prefix the match-template param (see `params`).
|
|
426
447
|
|
|
427
448
|
<!-- section: credentials -->
|
|
428
449
|
## Signing credential for the proof
|
|
429
450
|
|
|
430
|
-
`run_proof`
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
1.
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
and the existing draftId stays valid.
|
|
451
|
+
`run_proof` signs the claim with the eth proof-owner key. It resolves the key
|
|
452
|
+
itself (`RECLAIM_PRIVATE_KEY` env → a `RECLAIM_PRIVATE_KEY=0x…` line in the
|
|
453
|
+
project `.env` → a file at `RECLAIM_PRIVATE_KEY_FILE`); the private key never
|
|
454
|
+
enters the conversation. Don't pass `ownerAddress` and don't ask the developer
|
|
455
|
+
for a key.
|
|
456
|
+
|
|
457
|
+
1. **No key yet:** `run_proof` (or `resolve_owner_key`) creates a local test
|
|
458
|
+
key in the project `.env` (mode 0600, added to `.gitignore`) and returns
|
|
459
|
+
`source: "generated"` with a `note`. Tell the developer once, after the
|
|
460
|
+
fact, that you created a local test signing key. Don't ask for approval:
|
|
461
|
+
owner identity doesn't matter for test proofs.
|
|
462
|
+
2. **Developer wants their own key:** only when they say so,
|
|
463
|
+
`import_credentials({ keyFile })` (a path to a file holding the key; never
|
|
464
|
+
ask them to paste it).
|
|
465
|
+
3. Fully local — no network, no registration. The key is read live from `.env`
|
|
466
|
+
on every `run_proof`, so **no restart** is needed after importing, and the
|
|
467
|
+
existing draftId stays valid.
|
|
448
468
|
|
|
449
469
|
- **Advanced:** `RECLAIM_PRIVATE_KEY` in the MCP server env works too, but env
|
|
450
470
|
vars are snapshotted at Claude Code startup — that route needs a full restart,
|
package/skill/SKILL.old.md
CHANGED
|
@@ -9,7 +9,7 @@ Copy this checklist and check off each step as you finish it. Read the linked
|
|
|
9
9
|
topic before a step you aren't already fluent in.
|
|
10
10
|
|
|
11
11
|
- [ ] 1. `reclaim_authenticate` once. → topic `auth`
|
|
12
|
-
- [ ] 2. `attach_browser` —
|
|
12
|
+
- [ ] 2. `attach_browser()` with no arguments — opens a visible local browser.
|
|
13
13
|
→ topic `browser`
|
|
14
14
|
- [ ] 3. `list_tabs` → `start_capture(tabId)` ⇒ **`captureId`**, your handle for
|
|
15
15
|
everything below. → topic `capture`
|
|
@@ -24,7 +24,7 @@ topic before a step you aren't already fluent in.
|
|
|
24
24
|
- [ ] 7. Parameterize user-specific URL segments; mark secrets. → topic `params`
|
|
25
25
|
- [ ] 8. `replay_request(captureId, draftId)`, then again with
|
|
26
26
|
`withoutSecrets: true`. → topic `prove`
|
|
27
|
-
- [ ] 9. `run_proof(captureId, draftId
|
|
27
|
+
- [ ] 9. `run_proof(captureId, draftId)`.
|
|
28
28
|
→ topics `prove`, `credentials`
|
|
29
29
|
- [ ] 10. `create_provider_version_from_capture`. → topic `publish`
|
|
30
30
|
|
|
@@ -241,7 +241,7 @@ with no secrets/cookies, as an anonymous visitor.
|
|
|
241
241
|
session and re-check. If the value only ever appears on public responses, tell
|
|
242
242
|
the developer it can't be proven as an identity claim.
|
|
243
243
|
|
|
244
|
-
**3. Prove.** `run_proof(captureId, draftId
|
|
244
|
+
**3. Prove.** `run_proof(captureId, draftId)`. On
|
|
245
245
|
`verified: true` the full claim is written to
|
|
246
246
|
`~/.reclaim/claims/<timestamp>.json` and you get
|
|
247
247
|
`{verified, extractedValue, extractedParameters, identifier, owner, claimPath, claim}`.
|
package/skill/builder-mode.md
CHANGED
|
@@ -17,6 +17,21 @@ Never call a provider a "verification."**
|
|
|
17
17
|
"Choose the provider".
|
|
18
18
|
- **Intent unclear:** ask one short question.
|
|
19
19
|
|
|
20
|
+
### Work order
|
|
21
|
+
|
|
22
|
+
Do the steps that need the developer first: sign in to Builder, attach the
|
|
23
|
+
browser, capture, and prove the provider. They show early whether a proof is
|
|
24
|
+
possible on the site. Write app code after the proof works, or while you wait
|
|
25
|
+
on the developer.
|
|
26
|
+
|
|
27
|
+
### Asking the developer
|
|
28
|
+
|
|
29
|
+
When you need an answer or an action from the developer before you can
|
|
30
|
+
continue, end your turn with the question. Don't ask a blocking question
|
|
31
|
+
through a background or asynchronous question tool: the developer may never
|
|
32
|
+
see it. Put every link they need, such as a sign-in or verification URL, in
|
|
33
|
+
that same message.
|
|
34
|
+
|
|
20
35
|
### Choose the provider
|
|
21
36
|
|
|
22
37
|
Default: build a new provider for the claim the developer described. Use an
|
|
@@ -49,6 +64,9 @@ check and holds results for you to read. No tunnel or public URL is needed.
|
|
|
49
64
|
1. Call `read_callback_events`.
|
|
50
65
|
2. `create_verification_session`, then give the developer `verificationUrl`.
|
|
51
66
|
3. Poll `get_verification_session` until it is terminal.
|
|
67
|
+
`list_verification_events` shows progress. Don't read the hosted
|
|
68
|
+
verification page for progress: it streams the site as an image, so text
|
|
69
|
+
and DOM checks of it come back empty.
|
|
52
70
|
4. Call `read_callback_events({ sessionId })` for the verified result.
|
|
53
71
|
|
|
54
72
|
When you set up a new provider build, call `check_attestor` once. If it fails,
|
|
@@ -67,7 +85,8 @@ tell the developer before they spend time on the build.
|
|
|
67
85
|
|
|
68
86
|
## Integrating into an app
|
|
69
87
|
|
|
70
|
-
Call `start_integration
|
|
88
|
+
Call `start_integration` and follow its order: prove the provider first, then
|
|
89
|
+
write app code. Read `how_it_works({ topic: "integration" })`
|
|
71
90
|
for the HTTP session workflow, the `api=2` boundary, result verification, and
|
|
72
91
|
TEE binding. Edit the app with your file tools. Use the HTTP API
|
|
73
92
|
(`POST /verifications/sessions`, open `verificationUrl`, poll
|
|
@@ -122,13 +141,24 @@ script → `find_requests_containing` → `propose_provider` ⇒ `draftId` →
|
|
|
122
141
|
|
|
123
142
|
- **Data points:** propose only values the claim needs, usually one or two.
|
|
124
143
|
Never add identity or profile fields. Name each for what it proves.
|
|
125
|
-
- **Browser:**
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
144
|
+
- **Browser:** call `attach_browser()` with no arguments. It opens a visible
|
|
145
|
+
local browser with the persistent Reclaim profile, and falls back to Chrome
|
|
146
|
+
for Testing itself when no installed browser can be attached. Don't ask
|
|
147
|
+
which browser or who signs in. Use another `mode` only when that fails too,
|
|
148
|
+
or when the developer explicitly asks for it (topic `browser`). Tell the
|
|
149
|
+
developer once, as a side note, that a shareable link can be set up if a
|
|
150
|
+
volunteer is helping them sign in; don't ask about it or set it up unless
|
|
151
|
+
they ask.
|
|
129
152
|
- **Public endpoints:** after `replay_request` succeeds, re-run it with
|
|
130
153
|
`withoutSecrets: true`. If the value still extracts, the endpoint is public
|
|
131
154
|
and the proof binds to nobody. Find an auth-bound request.
|
|
155
|
+
- **Country:** `run_proof` sends the attestor's request from the developer's
|
|
156
|
+
own IP country, which is what `{{DYNAMIC_GEO}}` becomes when they verify;
|
|
157
|
+
`egress` in the result says which country. If a site that serves one
|
|
158
|
+
country (for example, a US airline) blocks the attestor, retry once with
|
|
159
|
+
`geoLocation: "US"`. If that verifies, pin it with
|
|
160
|
+
`update_draft({ geoLocation: "US" })` so the published version goes out
|
|
161
|
+
from there too.
|
|
132
162
|
- **Drafting limits** (topics `draft`, `params`): never `hash` a value that
|
|
133
163
|
also appears in the request URL. A param named with `SECRET` may appear in a
|
|
134
164
|
URL only within a small character budget (2 under `key-update`, 12 under
|
package/skill/old-mode.md
CHANGED
|
@@ -24,25 +24,30 @@ shorten, or reuse one from memory. When state is missing or ambiguous, inspect
|
|
|
24
24
|
it with the relevant get/list/status tool or call `how_it_works` before
|
|
25
25
|
answering. State uncertainty plainly instead of guessing.
|
|
26
26
|
|
|
27
|
+
**Ask blocking questions by ending your turn.** When you need an answer or an
|
|
28
|
+
action from the developer before you can continue, end your turn with the
|
|
29
|
+
question and every link they need. Don't use a background or asynchronous
|
|
30
|
+
question tool for it: the developer may never see it.
|
|
31
|
+
|
|
27
32
|
**Use the guide as needed.** Call `how_it_works({})` for its topic index, then
|
|
28
33
|
fetch only the topic relevant to the next tool call.
|
|
29
34
|
|
|
30
|
-
**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
**Open the browser without asking.** Call `attach_browser()` with no
|
|
36
|
+
arguments: it opens a visible browser on the developer's machine with the
|
|
37
|
+
persistent Reclaim profile, and falls back to Chrome for Testing itself when
|
|
38
|
+
no installed browser can be attached. Don't ask which browser or who signs in.
|
|
39
|
+
Use another `mode` only when that fails too, or when the developer explicitly
|
|
40
|
+
asks for it (topic `browser`). Tell the developer once, as a side note, that a
|
|
41
|
+
shareable link can be set up if a volunteer is helping them sign in; don't ask
|
|
42
|
+
about it or set it up unless they ask.
|
|
43
|
+
|
|
44
|
+
**The flow:** `reclaim_authenticate` once → `attach_browser()` (no arguments: a
|
|
45
|
+
visible local browser) → `start_capture` ⇒ **`captureId`** →
|
|
41
46
|
drive the page (`navigate`,
|
|
42
47
|
`wait_for_page`, `eval_in_page`) → inspect (`list_requests`, `get_request`,
|
|
43
48
|
`find_requests_containing`) → `propose_provider` ⇒ **`draftId`** →
|
|
44
|
-
`replay_request(captureId, draftId)` → `run_proof(captureId,
|
|
45
|
-
|
|
49
|
+
`replay_request(captureId, draftId)` → `run_proof(captureId,
|
|
50
|
+
draftId)` → `create_provider_version_from_capture`.
|
|
46
51
|
|
|
47
52
|
`reclaim_authenticate` itself always uses a local Chrome over loopback CDP. It
|
|
48
53
|
never uses the container, remote Builder, custom-CDP, or shared authoring
|
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Follow this plan end to end. Mark each step done as you go. Do not ask the developer whether to integrate: integrating into this codebase is the goal.
|
|
4
4
|
|
|
5
|
+
**Order.** Do the steps that need the developer first: sign in to Builder, attach the browser, capture, and prove the provider (step 2). These need the developer at the browser, and they show early whether a proof is possible on this site. Write app code (step 3) after the proof works, or while you wait on the developer. Never spend a long stretch on app code before the developer has signed in and the browser is attached.
|
|
6
|
+
|
|
7
|
+
**Asking the developer.** When you need an answer or an action from the developer before you can continue, end your turn with the question. Don't use background or asynchronous question tools for blocking questions: the developer may never see them. Put every link the developer needs, such as a sign-in or verification URL, in that same message.
|
|
8
|
+
|
|
5
9
|
## 1. Sign in and pick the organization
|
|
6
10
|
|
|
7
|
-
- [ ] Call `reclaim_authenticate` if you are not signed in.
|
|
11
|
+
- [ ] Call `reclaim_authenticate` if you are not signed in. Give the developer the returned `signInUrl` to approve in their browser (end your turn first if `browserOpened` is false), then call `wait_for_sign_in`.
|
|
8
12
|
<!-- if:orgId -->
|
|
9
13
|
- [ ] Use organization `{{orgId}}` for every call below.
|
|
10
14
|
<!-- endif -->
|
|
@@ -12,64 +16,77 @@ Follow this plan end to end. Mark each step done as you go. Do not ask the devel
|
|
|
12
16
|
- [ ] Call `list_orgs`. Use the only organization, or ask the developer which one when there are several.
|
|
13
17
|
<!-- endif -->
|
|
14
18
|
|
|
15
|
-
## 2.
|
|
16
|
-
|
|
17
|
-
Setup does not need the provider, so it runs in parallel with step 3 or before it.
|
|
18
|
-
|
|
19
|
-
**Delegation.** If you can run subagents, hand this step to one subagent and start step 3 now: step 3 needs the developer at the browser, step 2 does not. Give the subagent a self-contained brief:
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
Goal: let this app's users prove "{{goal}}" with Reclaim.
|
|
23
|
-
Repository: <absolute path>. Organization: <org ID>.
|
|
24
|
-
Task: do step 2 of the plan below and report the file paths you changed, the
|
|
25
|
-
callback route URL, and the env variable that holds the provider ID.
|
|
26
|
-
Do not build the provider. Never print or commit the org key.
|
|
27
|
-
<paste the step 2 checklist>
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Without subagents, do step 2 first.
|
|
31
|
-
|
|
32
|
-
- [ ] Detect the app's framework and package manager from the repository, and use them. Read `how_it_works({ topic: "integration" })`.
|
|
33
|
-
- [ ] Call `issue_org_token` with the organization, this project's absolute path, and the server env file. It writes the key to that file and never returns it. Never print or commit the key. Confirm the env file is in `.gitignore`.
|
|
34
|
-
- [ ] Add a backend route that creates a verification session (`POST /verifications/sessions`) and returns `verificationUrl`. Read the provider ID from server config (an env variable such as `RECLAIM_PROVIDER_ID`), so the route works before the provider exists.
|
|
35
|
-
- [ ] Add a callback route that verifies each result with `results.receive` from `@reclaimprotocol/client`, then stores only the requested data points. Store every failure on the verification session record and log it server-side: a failure event (`verification_rejected`, `verification_error`, `verification_cancelled`, `session_expired`), or a thrown `ResultVerificationError` (`error.reason` plus each failing proof's `reason`). Respond `error.retryable ? 503 : 200`. A result that failed verification gets 2xx, because retrying can't fix it. Read the exact pattern in `how_it_works({ topic: "integration" })`.
|
|
36
|
-
- [ ] Add a status route the frontend polls. It returns the stored status, data points, and failure reason. While the app has no result, it also reads `GET /verifications/sessions/{sessionId}`, so a session that ended in Builder never stays pending.
|
|
37
|
-
- [ ] Add a frontend Verify button that opens `verificationUrl`, and render every state in "UI states" in `how_it_works({ topic: "integration" })`: idle, waiting in the other tab, verifying, verified (with the data points), failed (plain-language reason and **Try again**), and expired or cancelled (**Try again**). Never leave a spinner as the only feedback.
|
|
38
|
-
- [ ] Start the app. Call `proxy_callback_events({ port, path })` with the callback route's port and path. It forwards the org's verification events to that route on localhost, with no public URL.
|
|
39
|
-
<!-- ifnot:providerIds -->
|
|
40
|
-
- [ ] Call `check_attestor` once. If it fails, tell the developer before they spend time on the provider build: this machine cannot reach the attestor.
|
|
41
|
-
<!-- endif -->
|
|
42
|
-
|
|
43
|
-
## 3. Get the provider
|
|
19
|
+
## 2. Get the provider and prove it
|
|
44
20
|
|
|
45
21
|
<!-- if:providerIds -->
|
|
46
22
|
- [ ] Use these existing providers: {{providerIds}}. Read each with `get_provider` and keep only the data points "{{goal}}" needs. Show the developer and use only those; ignore the rest.
|
|
47
|
-
- [ ] If a provider needs any change (a missing data point, inputs the developer didn't ask for, a different value), make your own copy as the server instructions describe ("Choose the provider"). Otherwise
|
|
23
|
+
- [ ] If a provider needs any change (a missing data point, inputs the developer didn't ask for, a different value), make your own copy as the server instructions describe ("Choose the provider"). Otherwise go on to step 3.
|
|
48
24
|
<!-- endif -->
|
|
49
25
|
<!-- ifnot:providerIds -->
|
|
50
26
|
Build a new organization-private provider for exactly "{{goal}}". Do not search published providers first.
|
|
51
27
|
|
|
28
|
+
- [ ] Call `check_attestor` once. If it fails, tell the developer before they spend time on the provider build: this machine cannot reach the attestor.
|
|
52
29
|
- [ ] If the site, the account, or the value to prove is unclear, ask one concise question. Otherwise do not ask.
|
|
53
30
|
- [ ] Choose the minimum data points: only the values the claim needs, usually one or two. Add no profile or identity extras.
|
|
54
31
|
- [ ] If the developer names an existing provider, use only the data points they asked for and ignore the rest. If it needs any change, make your own copy: a new version when the organization owns it, otherwise a new organization provider from a copy of its config.
|
|
55
32
|
- [ ] Call `how_it_works` with topics `overview`, `user-script`, `capture`, and `publish` before you start. Do not repeat their detail here.
|
|
56
|
-
- [ ] Call `attach_browser`
|
|
33
|
+
- [ ] Call `attach_browser()` with no arguments. It opens a visible local browser, falling back to Chrome for Testing when no installed browser can be attached; don't ask which browser to use. Use another mode only if that fails too (topic `browser`). Mention once, as a side note, that a shareable link can be set up if a volunteer is helping the developer sign in; don't ask or set it up unless they ask. Use `start_capture` on the tab.
|
|
57
34
|
- [ ] Open the sign-in page with `navigate`. The developer signs in; use `wait_for_login`.
|
|
58
35
|
- [ ] Write the navigation script first. Signed out, it goes to the sign-in page. After sign-in, it visits each data page in order. It must stay correct across reloads.
|
|
59
36
|
- [ ] Test it with `test_user_script` and `keep: true`. The kept script stays installed for every later navigation and is published with the provider version.
|
|
60
37
|
- [ ] While the script drives the browser, find the request that returns each data point (`find_requests_containing`, then `analyze_request_constraints`).
|
|
61
38
|
- [ ] Call `propose_provider` with only the needed data points.
|
|
62
39
|
- [ ] Call `replay_request`, then `replay_request` with `withoutSecrets: true` to confirm the request is auth-bound.
|
|
63
|
-
- [ ] Call `
|
|
40
|
+
- [ ] Call `run_proof`. It creates a local test signing key if none exists; tell the developer once afterwards.
|
|
64
41
|
- [ ] Call `create_provider_version_from_capture`. It publishes the kept script as `jsUserScripts`. Follow its `_notes`, then publish the version.
|
|
65
42
|
- [ ] Call `dispose_browser` after asking the developer.
|
|
66
43
|
<!-- endif -->
|
|
67
44
|
|
|
45
|
+
## 3. Set up the app
|
|
46
|
+
|
|
47
|
+
Setup does not need the provider. Start it after step 2 has a working proof, or while you wait on the developer during step 2 (for example, while they sign in to the site). Don't let it delay a step that needs the developer.
|
|
48
|
+
|
|
49
|
+
**Delegation.** When the workspace already has an app and you can run subagents, hand this step to one subagent as soon as you are signed in, and keep working on step 2: step 2 needs the developer at the browser, step 3 does not. Give the subagent a self-contained brief:
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
Goal: let this app's users prove "{{goal}}" with Reclaim.
|
|
53
|
+
Repository: <absolute path>. Organization: <org ID>.
|
|
54
|
+
Task: do step 3 of the plan below and report the file paths you changed, the
|
|
55
|
+
callback route URL, and the env variable that holds the provider ID.
|
|
56
|
+
Do not build the provider. Never print or commit the org key.
|
|
57
|
+
<paste the step 3 checklist>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Without subagents, do step 2 first, and fill waits for the developer with this step.
|
|
61
|
+
|
|
62
|
+
**No app yet?** If the workspace has no app to add verification to (it is empty, or has no backend or frontend), don't write one. Bootstrap from [builder-example](https://github.com/reclaimprotocol/builder-example), a ready-to-run Fastify backend and Vite frontend that already create sessions, verify callbacks, poll status, and render every UI state:
|
|
63
|
+
|
|
64
|
+
Do this yourself, not in a subagent.
|
|
65
|
+
|
|
66
|
+
- [ ] Call `create_example_app` with the workspace root you were started in as `projectDir`. It writes the example there and sets its backend to the latest `@reclaimprotocol/client`. Don't clone the repository or create a subdirectory: commands you run inside a clone count as running external code, and permission checks may block them.
|
|
67
|
+
- [ ] Call `issue_org_token` with the same `projectDir` and `envFile: "packages/backend/.env"`.
|
|
68
|
+
- [ ] Only when the developer asks for session binding or encrypted results: call `issue_org_keypair` with the same `projectDir` and `envFile` (add `encryptResults: true` for encrypted results). It writes `RECLAIM_ORG_ETH_PRIVATE_KEY` and registers the public key. Then pass `orgEthPrivateKey: process.env.RECLAIM_ORG_ETH_PRIVATE_KEY` to `reclaim.sessions.create` in `packages/backend/src/routes/verifications.ts` (binding) and to `reclaim.results.receive` in `packages/backend/src/routes/callback.ts` (decryption and TEE proof checks), and add an empty `RECLAIM_ORG_ETH_PRIVATE_KEY=` line to `packages/backend/example.env`.
|
|
69
|
+
- [ ] From the workspace root, run `npm install`, then `npm run dev`. The backend listens on port 3000; the app opens at <http://localhost:5173>. If a permission check blocks either command, don't work around it: end your turn, say which command was blocked and that it installs and runs the Reclaim example app, and ask the developer to approve it.
|
|
70
|
+
- [ ] Call `proxy_callback_events({ port: 3000, path: "/reclaim/callback" })`.
|
|
71
|
+
- [ ] Skip the rest of this step. In step 4, the provider goes in `packages/backend/config.json`: replace the example entry with `{ "id": "<provider ID>", "name": "<what it proves>" }`, then restart the backend, because it reads the file at startup.
|
|
72
|
+
|
|
73
|
+
**Existing app.** Add verification to it:
|
|
74
|
+
|
|
75
|
+
- [ ] Detect the app's framework and package manager from the repository, and use them. Read `how_it_works({ topic: "integration" })`.
|
|
76
|
+
- [ ] Call `issue_org_token` with the organization, this project's absolute path, and the server env file. It writes the key to that file and never returns it. Never print or commit the key. Confirm the env file is in `.gitignore`.
|
|
77
|
+
- [ ] Add a backend route that creates a verification session (`POST /verifications/sessions`) and returns `verificationUrl`. Read the provider ID from server config (an env variable such as `RECLAIM_PROVIDER_ID`), so the route works before the provider exists.
|
|
78
|
+
- [ ] Only when the developer asks for session binding or encrypted results: call `issue_org_keypair` with the server env file (`encryptResults: true` for encrypted results), and pass `orgEthPrivateKey` from that env variable to `sessions.create` and `results.receive`.
|
|
79
|
+
- [ ] Add a callback route that verifies each result with `results.receive` from `@reclaimprotocol/client`, then stores only the requested data points. Store every failure on the verification session record and log it server-side: a failure event (`verification_rejected`, `verification_error`, `verification_cancelled`, `session_expired`), or a thrown `ResultVerificationError` (`error.reason` plus each failing proof's `reason`). Respond `error.retryable ? 503 : 200`. A result that failed verification gets 2xx, because retrying can't fix it. Read the exact pattern in `how_it_works({ topic: "integration" })`.
|
|
80
|
+
- [ ] Add a status route the frontend polls. It returns the stored status, data points, and failure reason. While the app has no result, it also reads `GET /verifications/sessions/{sessionId}`, so a session that ended in Builder never stays pending.
|
|
81
|
+
- [ ] Add a frontend Verify button that opens `verificationUrl`, and render every state in "UI states" in `how_it_works({ topic: "integration" })`: idle, waiting in the other tab, verifying, verified (with the data points), failed (plain-language reason and **Try again**), and expired or cancelled (**Try again**). Never leave a spinner as the only feedback.
|
|
82
|
+
- [ ] Start the app. Call `proxy_callback_events({ port, path })` with the callback route's port and path. It forwards the org's verification events to that route on localhost, with no public URL.
|
|
83
|
+
|
|
68
84
|
## 4. Wire the provider and test end to end
|
|
69
85
|
|
|
70
86
|
- [ ] Set the provider ID in the app's server config.
|
|
71
87
|
- [ ] Confirm the callback route is forwarding: `proxy_callback_events` with no `stop` returns its status. If `blocked` is not empty, the app rejected that session's event: read the callback route's response and logs, fix the app, and check again.
|
|
72
88
|
- [ ] Tell the developer exactly how to test: open the app, click Verify, sign in, and see the stored result. Also test one failure, such as cancelling in the verification tab, and confirm the app shows the failed state with **Try again**.
|
|
89
|
+
- [ ] The hosted verification page streams the target site as an image, so text or DOM checks of that page come back empty. Check progress with `list_verification_events` and `get_verification_session`, not by reading the page.
|
|
73
90
|
- [ ] After they click Verify, read the delivered events from `proxy_callback_events` status (`recent`) or `read_callback_events`. If the result did not arrive, or the app shows an unexpected failure, call `list_verification_deliveries` and fix the cause. Repeat until the app shows the stored result.
|
|
74
91
|
- [ ] Ask the developer to set up the production callback. The local listener works only while this coding agent's MCP server runs; once it stops, the deployed app receives no results. Call `create_org_callback_subscription` with the deployed app's public callback route URL for all five session-ending events: `verification_success`, `verification_rejected`, `verification_error`, `verification_cancelled`, and `session_expired`.
|
|
75
92
|
- [ ] If they have no deployed URL yet, tell them: "When you deploy, ask me to run `create_org_callback_subscription` with your public callback URL, or results will not reach the app."
|
|
@@ -7,8 +7,18 @@ plan. Don't ask whether to try, integrate, or create an app. Ask one short
|
|
|
7
7
|
question only when intent is unclear. The steps below are the detail behind
|
|
8
8
|
that plan.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
Prove the provider before you write app code: sign in to Builder, attach the
|
|
11
|
+
browser, capture, and run the proof first. Those steps need the developer, and
|
|
12
|
+
they show whether a proof is possible on the site. Write the app code after the
|
|
13
|
+
proof works, or while you wait on the developer. When you need the developer
|
|
14
|
+
to answer or act, end your turn with the question and every link they need;
|
|
15
|
+
don't ask through a background or asynchronous question tool.
|
|
16
|
+
|
|
17
|
+
When the workspace has no app yet, call `create_example_app` to write
|
|
18
|
+
[builder-example](https://github.com/reclaimprotocol/builder-example) into the
|
|
19
|
+
workspace root, as the `start_integration` plan describes, instead of writing a
|
|
20
|
+
new backend and frontend or cloning the repository. Otherwise, inspect the app's frontend, backend, package manager,
|
|
21
|
+
configuration, and callback conventions. Complete the integration in its codebase and run its
|
|
12
22
|
relevant checks. The MCP tools configure Builder resources; your file tools
|
|
13
23
|
edit the app.
|
|
14
24
|
|
|
@@ -27,10 +37,11 @@ server), or migrate to the session flow below. When migrating, remove
|
|
|
27
37
|
production): register a
|
|
28
38
|
public callback URL with `create_org_callback_subscription`, including
|
|
29
39
|
all five session-ending events. If the
|
|
30
|
-
app needs encrypted results
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
the developer
|
|
40
|
+
app needs encrypted results or session binding, call `issue_org_keypair`
|
|
41
|
+
(`encryptResults: true` for encrypted results). It writes the private key to
|
|
42
|
+
the backend's env file and registers only the public key. It returns 409
|
|
43
|
+
when the org already has a different key: ask the developer for that key
|
|
44
|
+
rather than replacing it.
|
|
34
45
|
3. Org key: reuse the `RECLAIM_ORG_SECRET` the app already has. Otherwise an
|
|
35
46
|
organization owner calls `issue_org_token`. It writes the key to the
|
|
36
47
|
project's env file (default `.env`, variable `RECLAIM_ORG_SECRET`) and
|
|
@@ -69,6 +80,10 @@ server), or migrate to the session flow below. When migrating, remove
|
|
|
69
80
|
from `VerificationClient` in the SDK. Do not send an unregistered URL or
|
|
70
81
|
call a legacy backend for an `api=2` session.
|
|
71
82
|
|
|
83
|
+
The hosted verification page streams the target site as an image, so text
|
|
84
|
+
and DOM checks of that page come back empty. Check a session's progress
|
|
85
|
+
with `list_verification_events` and `get_verification_session` instead.
|
|
86
|
+
|
|
72
87
|
The one-time management calls above use the developer's Builder login. The
|
|
73
88
|
consumer backend uses the separate organization token. The SDK's API-only
|
|
74
89
|
entry point, `@reclaimprotocol/client/api`, is available when an application
|
package/src/authoring/backend.ts
CHANGED
|
@@ -35,6 +35,10 @@ export interface Draft {
|
|
|
35
35
|
/** One entry per extracted value (value + its redaction), so replay can
|
|
36
36
|
* validate each against its own selector. */
|
|
37
37
|
extractions: Extraction[]
|
|
38
|
+
/** Outcome of the latest authenticated in-browser replay, recorded by
|
|
39
|
+
* backends that track it. Lets a failed proof tell "the site blocks
|
|
40
|
+
* non-browser clients" apart from a broken recipe. */
|
|
41
|
+
lastReplay?: { status: number, ok: boolean }
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
/** A navigation script installed for every later page load of the authoring
|
|
@@ -49,10 +53,12 @@ export interface KeptScriptRef {
|
|
|
49
53
|
keptScript?: KeptScript
|
|
50
54
|
}
|
|
51
55
|
|
|
52
|
-
/** Per-session draft store: `propose` puts, `replay`/`run_proof` get by id
|
|
56
|
+
/** Per-session draft store: `propose` puts, `replay`/`run_proof` get by id,
|
|
57
|
+
* `update_draft` replaces one in place (same id). */
|
|
53
58
|
export interface DraftStore {
|
|
54
59
|
put(draft: Draft): string
|
|
55
60
|
get(id: string): Draft | undefined
|
|
61
|
+
set(id: string, draft: Draft): void
|
|
56
62
|
}
|
|
57
63
|
|
|
58
64
|
export function makeDraftStore(): DraftStore {
|
|
@@ -64,6 +70,9 @@ export function makeDraftStore(): DraftStore {
|
|
|
64
70
|
return id
|
|
65
71
|
},
|
|
66
72
|
get: (id) => map.get(id),
|
|
73
|
+
set: (id, draft) => {
|
|
74
|
+
map.set(id, draft)
|
|
75
|
+
},
|
|
67
76
|
}
|
|
68
77
|
}
|
|
69
78
|
|
|
@@ -73,6 +82,8 @@ export function makeDraftStore(): DraftStore {
|
|
|
73
82
|
export interface ProveOptions {
|
|
74
83
|
ownerAddress?: string
|
|
75
84
|
attestorUrl?: string
|
|
85
|
+
/** ISO country the attestor's request goes out from (local proofs). */
|
|
86
|
+
geoLocation?: string
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
/**
|