settld 0.2.4 → 0.2.6
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/Dockerfile +2 -2
- package/docs/CONFIG.md +12 -0
- package/docs/README.md +3 -0
- package/docs/ops/HOSTED_BASELINE_R2.md +4 -2
- package/docs/ops/MINIMUM_PRODUCTION_TOPOLOGY.md +19 -7
- package/docs/ops/PRODUCTION_DEPLOYMENT_CHECKLIST.md +8 -3
- package/package.json +4 -1
- package/packages/api-sdk/README.md +71 -0
- package/packages/api-sdk/src/client.js +1021 -0
- package/packages/api-sdk/src/express-middleware.js +163 -0
- package/packages/api-sdk/src/index.d.ts +1662 -0
- package/packages/api-sdk/src/index.js +10 -0
- package/packages/api-sdk/src/webhook-signature.js +182 -0
- package/packages/api-sdk/src/x402-autopay.js +210 -0
- package/scripts/ci/cli-pack-smoke.mjs +2 -0
- package/scripts/ci/run-public-onboarding-gate.mjs +136 -0
- package/scripts/setup/login.mjs +73 -2
- package/scripts/setup/onboard.mjs +173 -28
- package/scripts/setup/onboarding-failure-taxonomy.mjs +107 -0
- package/scripts/setup/onboarding-state-machine.mjs +102 -0
- package/services/magic-link/README.md +352 -0
- package/services/magic-link/assets/samples/closepack/known-bad/acceptance/acceptance_criteria.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/acceptance/acceptance_evaluation.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/attestation/bundle_head_attestation.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/evidence/evidence_index.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/governance/policy.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/governance/revocations.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/manifest.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/attestation/bundle_head_attestation.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/governance/policy.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/governance/revocations.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/invoice/invoice_claim.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/manifest.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/metering/metering_report.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/attestation/bundle_head_attestation.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/events/events.jsonl +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/events/payload_material.jsonl +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/governance/global/events/events.jsonl +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/governance/global/events/payload_material.jsonl +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/governance/global/snapshot.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/governance/policy.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/governance/revocations.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/events/events.jsonl +0 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/events/payload_material.jsonl +0 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/snapshot.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/job/snapshot.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/keys/public_keys.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/manifest.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/verify/report.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/payload/job_proof_bundle/verify/verification_report.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/pricing/pricing_matrix.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/pricing/pricing_matrix_signatures.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/settld.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/payload/invoice_bundle/verify/verification_report.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/settld.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/sla/sla_definition.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/sla/sla_evaluation.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-bad/verify/verification_report.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/acceptance/acceptance_criteria.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/acceptance/acceptance_evaluation.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/attestation/bundle_head_attestation.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/evidence/evidence_index.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/governance/policy.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/governance/revocations.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/manifest.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/attestation/bundle_head_attestation.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/governance/policy.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/governance/revocations.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/invoice/invoice_claim.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/manifest.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/metering/metering_report.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/attestation/bundle_head_attestation.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/events/events.jsonl +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/events/payload_material.jsonl +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/governance/global/events/events.jsonl +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/governance/global/events/payload_material.jsonl +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/governance/global/snapshot.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/governance/policy.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/governance/revocations.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/events/events.jsonl +0 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/events/payload_material.jsonl +0 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/governance/tenant/snapshot.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/job/snapshot.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/keys/public_keys.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/manifest.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/verify/report.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/payload/job_proof_bundle/verify/verification_report.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/pricing/pricing_matrix.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/pricing/pricing_matrix_signatures.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/settld.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/payload/invoice_bundle/verify/verification_report.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/settld.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/sla/sla_definition.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/sla/sla_evaluation.json +1 -0
- package/services/magic-link/assets/samples/closepack/known-good/verify/verification_report.json +1 -0
- package/services/magic-link/assets/samples/trust.json +11 -0
- package/services/magic-link/src/audit-log.js +24 -0
- package/services/magic-link/src/buyer-auth.js +251 -0
- package/services/magic-link/src/buyer-notifications.js +402 -0
- package/services/magic-link/src/buyer-users.js +129 -0
- package/services/magic-link/src/decision-otp.js +187 -0
- package/services/magic-link/src/decisions.js +92 -0
- package/services/magic-link/src/email-resend.js +89 -0
- package/services/magic-link/src/ingest-keys.js +137 -0
- package/services/magic-link/src/maintenance.js +95 -0
- package/services/magic-link/src/onboarding-email-sequence.js +331 -0
- package/services/magic-link/src/payment-triggers.js +733 -0
- package/services/magic-link/src/pdf.js +149 -0
- package/services/magic-link/src/policy.js +69 -0
- package/services/magic-link/src/redaction.js +6 -0
- package/services/magic-link/src/render-model.js +70 -0
- package/services/magic-link/src/retention-gc.js +158 -0
- package/services/magic-link/src/run-records.js +496 -0
- package/services/magic-link/src/s3.js +171 -0
- package/services/magic-link/src/server.js +15849 -0
- package/services/magic-link/src/settlement-decisions.js +84 -0
- package/services/magic-link/src/smtp.js +217 -0
- package/services/magic-link/src/storage-cli.js +88 -0
- package/services/magic-link/src/storage-format.js +59 -0
- package/services/magic-link/src/tenant-billing.js +115 -0
- package/services/magic-link/src/tenant-onboarding.js +467 -0
- package/services/magic-link/src/tenant-settings.js +1140 -0
- package/services/magic-link/src/usage.js +80 -0
- package/services/magic-link/src/verify-queue.js +179 -0
- package/services/magic-link/src/verify-worker.js +157 -0
- package/services/magic-link/src/webhook-retries.js +542 -0
- package/services/magic-link/src/webhooks.js +218 -0
- package/src/api/app.js +135 -1
package/Dockerfile
CHANGED
|
@@ -30,8 +30,8 @@ COPY --from=deps /app/node_modules ./node_modules
|
|
|
30
30
|
COPY --from=deps /app/package.json ./package.json
|
|
31
31
|
COPY --from=deps /app/SETTLD_VERSION ./SETTLD_VERSION
|
|
32
32
|
|
|
33
|
-
# Runtime-writable locations should be mounted as volumes in k8s;
|
|
34
|
-
COPY --from=prep /data /data
|
|
33
|
+
# Runtime-writable locations should be mounted as volumes in k8s; copy with nonroot ownership for distroless runtime.
|
|
34
|
+
COPY --chown=65532:65532 --from=prep /data /data
|
|
35
35
|
|
|
36
36
|
# Copy application code.
|
|
37
37
|
COPY src ./src
|
package/docs/CONFIG.md
CHANGED
|
@@ -82,6 +82,18 @@ Delivery/worker tuning:
|
|
|
82
82
|
- `PROXY_AUTH_KEY_TOUCH_MIN_SECONDS` (default: `60`)
|
|
83
83
|
Throttle how often `last_used_at` is updated for API keys (reduces DB write amplification).
|
|
84
84
|
|
|
85
|
+
## Public onboarding routing
|
|
86
|
+
|
|
87
|
+
- `PROXY_ONBOARDING_BASE_URL` (optional but required for public onboarding on `settld-api`)
|
|
88
|
+
Absolute `http(s)` URL for the onboarding service (`services/magic-link`). When set, `settld-api` reverse-proxies public onboarding routes:
|
|
89
|
+
- `/v1/public/auth-mode`
|
|
90
|
+
- `/v1/public/signup`
|
|
91
|
+
- `/v1/tenants/:tenantId/buyer/login/otp`
|
|
92
|
+
- `/v1/tenants/:tenantId/buyer/login`
|
|
93
|
+
- `/v1/tenants/:tenantId/onboarding/*`
|
|
94
|
+
|
|
95
|
+
If missing, these routes fail closed with `503` and code `ONBOARDING_PROXY_NOT_CONFIGURED`.
|
|
96
|
+
|
|
85
97
|
## Ingest auth
|
|
86
98
|
|
|
87
99
|
- `PROXY_INGEST_TOKEN` (optional)
|
package/docs/README.md
CHANGED
|
@@ -32,3 +32,6 @@ Reference docs:
|
|
|
32
32
|
|
|
33
33
|
- `docs/QUICKSTART_MCP_HOSTS.md`
|
|
34
34
|
- `docs/QUICKSTART_MCP.md`
|
|
35
|
+
- `planning/trust-os-v1/state-of-the-art-launch-readiness-scorecard.md`
|
|
36
|
+
- `planning/sprints/state-of-the-art-v1-6-week-plan.md`
|
|
37
|
+
- `planning/jira/state-of-the-art-v1-backlog.json`
|
|
@@ -13,14 +13,16 @@ This is the minimum hosted setup for a real product surface.
|
|
|
13
13
|
|
|
14
14
|
## 2) Railway service split
|
|
15
15
|
|
|
16
|
-
Create
|
|
16
|
+
Create three Railway services from this repo per environment:
|
|
17
17
|
|
|
18
18
|
- `settld-api`:
|
|
19
19
|
- start command: `npm run start:prod`
|
|
20
|
+
- `settld-magic-link`:
|
|
21
|
+
- start command: `npm run start:magic-link`
|
|
20
22
|
- `settld-worker`:
|
|
21
23
|
- start command: `npm run start:maintenance`
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
All services must point at the same environment DB and secret set for that environment.
|
|
24
26
|
|
|
25
27
|
## 3) Required runtime controls
|
|
26
28
|
|
|
@@ -7,12 +7,13 @@ This is the smallest topology that supports real paid agent tool calls with audi
|
|
|
7
7
|
| Component | Purpose | Start command |
|
|
8
8
|
|---|---|---|
|
|
9
9
|
| `settld-api` | control plane + kernel APIs + receipts + ops endpoints | `npm run start:prod` |
|
|
10
|
+
| `settld-magic-link` | public onboarding/auth/wallet bootstrap service | `npm run start:magic-link` |
|
|
10
11
|
| `settld-maintenance` | reconciliation/cleanup/maintenance ticks | `npm run start:maintenance` |
|
|
11
12
|
| `postgres` | system of record for tenants, gates, receipts, ops state | managed Postgres |
|
|
12
13
|
| `x402-gateway` | payment challenge/authorize/verify wrapper for paid tool calls | `npm run start:x402-gateway` |
|
|
13
14
|
| paid upstream tool API(s) | actual provider tools (`/exa`, `/weather`, etc.) | provider-specific |
|
|
14
15
|
|
|
15
|
-
Without all
|
|
16
|
+
Without all six, public onboarding + paid tool path is incomplete.
|
|
16
17
|
|
|
17
18
|
## 2) Recommended production shape
|
|
18
19
|
|
|
@@ -35,9 +36,19 @@ Reference baseline: `docs/ops/HOSTED_BASELINE_R2.md`.
|
|
|
35
36
|
- `PROXY_OPS_TOKENS` (scoped ops tokens)
|
|
36
37
|
- `PROXY_FINANCE_RECONCILE_ENABLED=1`
|
|
37
38
|
- `PROXY_MONEY_RAIL_RECONCILE_ENABLED=1`
|
|
39
|
+
- `PROXY_ONBOARDING_BASE_URL=https://<magic-link-host>`
|
|
38
40
|
|
|
39
41
|
Primary config source: `docs/CONFIG.md`.
|
|
40
42
|
|
|
43
|
+
### `settld-magic-link`
|
|
44
|
+
|
|
45
|
+
- `NODE_ENV=production`
|
|
46
|
+
- `MAGIC_LINK_API_KEY` (admin key)
|
|
47
|
+
- `MAGIC_LINK_PUBLIC_SIGNUP_ENABLED=1` (for self-serve public onboarding)
|
|
48
|
+
- `MAGIC_LINK_BUYER_OTP_DELIVERY_MODE=smtp` + SMTP env
|
|
49
|
+
- `MAGIC_LINK_SETTLD_API_BASE_URL=https://<settld-api-host>`
|
|
50
|
+
- `MAGIC_LINK_SETTLD_OPS_TOKEN=<scoped ops token>`
|
|
51
|
+
|
|
41
52
|
### `settld-maintenance`
|
|
42
53
|
|
|
43
54
|
- Same DB/env set as `settld-api`
|
|
@@ -67,22 +78,23 @@ Reference flow: `docs/QUICKSTART_X402_GATEWAY.md`.
|
|
|
67
78
|
Must host for real customer traffic:
|
|
68
79
|
|
|
69
80
|
1. `settld-api`
|
|
70
|
-
2. `settld-
|
|
71
|
-
3.
|
|
72
|
-
4.
|
|
73
|
-
5.
|
|
81
|
+
2. `settld-magic-link`
|
|
82
|
+
3. `settld-maintenance`
|
|
83
|
+
4. Postgres
|
|
84
|
+
5. `x402-gateway`
|
|
85
|
+
6. At least one paid upstream provider API
|
|
74
86
|
|
|
75
87
|
Optional at first:
|
|
76
88
|
|
|
77
89
|
1. Receiver service (`npm run start:receiver`)
|
|
78
90
|
2. Finance sink (`npm run start:finance-sink`)
|
|
79
|
-
3.
|
|
91
|
+
3. Additional onboarding UI shells
|
|
80
92
|
|
|
81
93
|
## 6) Definition of "usable in production"
|
|
82
94
|
|
|
83
95
|
A deployment is considered usable when all are true:
|
|
84
96
|
|
|
85
|
-
1. `GET /healthz` is green on API and gateway.
|
|
97
|
+
1. `GET /healthz` is green on API and gateway; `GET /v1/public/auth-mode` is reachable on API host.
|
|
86
98
|
2. Hosted baseline evidence command passes for the environment.
|
|
87
99
|
3. One paid MCP tool call succeeds end-to-end with artifact output.
|
|
88
100
|
4. Receipt verification succeeds and is replay-auditable.
|
|
@@ -14,7 +14,7 @@ Use this checklist to launch and verify a real hosted Settld environment.
|
|
|
14
14
|
2. Confirm release workflow is blocked unless NOO-50 and the kernel/cutover gates are green for the release commit.
|
|
15
15
|
3. Confirm release workflow runs NOO-65 promotion guard and blocks publish lanes if `release-promotion-guard.json` verdict is not pass/override-pass.
|
|
16
16
|
4. Confirm staging and production have separate domains, databases, secrets, and signer keys.
|
|
17
|
-
5. Confirm required services are deployable: `npm run start:prod`, `npm run start:maintenance`, `npm run start:x402-gateway`.
|
|
17
|
+
5. Confirm required services are deployable: `npm run start:prod`, `npm run start:magic-link`, `npm run start:maintenance`, `npm run start:x402-gateway`.
|
|
18
18
|
6. Configure GitHub Environment `production_cutover_gate` with:
|
|
19
19
|
- `PROD_BASE_URL`
|
|
20
20
|
- `PROD_TENANT_ID`
|
|
@@ -29,17 +29,22 @@ Use this checklist to launch and verify a real hosted Settld environment.
|
|
|
29
29
|
3. Set scoped `PROXY_OPS_TOKENS`.
|
|
30
30
|
4. Configure rate limits and quotas from `docs/CONFIG.md`.
|
|
31
31
|
5. Configure gateway secrets: `SETTLD_API_URL`, `SETTLD_API_KEY`, `UPSTREAM_URL`.
|
|
32
|
+
6. Configure onboarding routing:
|
|
33
|
+
- `PROXY_ONBOARDING_BASE_URL=https://<magic-link-host>` on `settld-api`
|
|
34
|
+
- `MAGIC_LINK_PUBLIC_SIGNUP_ENABLED=1` and OTP delivery (`smtp`) on `settld-magic-link`
|
|
32
35
|
|
|
33
36
|
## Phase 2: Deploy services
|
|
34
37
|
|
|
35
38
|
1. Deploy `settld-api`.
|
|
36
|
-
2. Deploy `settld-
|
|
37
|
-
3. Deploy `
|
|
39
|
+
2. Deploy `settld-magic-link`.
|
|
40
|
+
3. Deploy `settld-maintenance`.
|
|
41
|
+
4. Deploy `x402-gateway`.
|
|
38
42
|
4. Verify service health:
|
|
39
43
|
|
|
40
44
|
```bash
|
|
41
45
|
curl -fsS https://api.settld.work/healthz
|
|
42
46
|
curl -fsS https://gateway.settld.work/healthz
|
|
47
|
+
npm run test:ops:public-onboarding-gate -- --base-url https://api.settld.work --tenant-id tenant_default
|
|
43
48
|
```
|
|
44
49
|
|
|
45
50
|
## Phase 3: Baseline ops verification
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "settld",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "Settld kernel CLI and local control-plane tooling",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -21,10 +21,12 @@
|
|
|
21
21
|
"docker-compose.yml",
|
|
22
22
|
"bin",
|
|
23
23
|
"conformance",
|
|
24
|
+
"packages/api-sdk/src",
|
|
24
25
|
"packages/artifact-verify/src",
|
|
25
26
|
"scripts",
|
|
26
27
|
"docs",
|
|
27
28
|
"src",
|
|
29
|
+
"services/magic-link",
|
|
28
30
|
"services/finance-sink",
|
|
29
31
|
"services/x402-gateway",
|
|
30
32
|
"services/receiver"
|
|
@@ -110,6 +112,7 @@
|
|
|
110
112
|
"test:ops:onboarding-host-success-gate": "node scripts/ci/run-onboarding-host-success-gate.mjs",
|
|
111
113
|
"test:ops:self-serve-benchmark": "node scripts/ci/build-self-serve-benchmark-report.mjs",
|
|
112
114
|
"test:ops:launch-cutover-packet": "node scripts/ci/build-launch-cutover-packet.mjs",
|
|
115
|
+
"test:ops:public-onboarding-gate": "node scripts/ci/run-public-onboarding-gate.mjs",
|
|
113
116
|
"test:ops:production-cutover-gate": "node scripts/ci/run-production-cutover-gate.mjs",
|
|
114
117
|
"test:ops:release-promotion-guard": "node scripts/ci/run-release-promotion-guard.mjs",
|
|
115
118
|
"test:ci:mcp-host-smoke": "node scripts/ci/run-mcp-host-smoke.mjs",
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# settld-api-sdk
|
|
2
|
+
|
|
3
|
+
Node/TypeScript SDK for Settld API + x402 helpers.
|
|
4
|
+
|
|
5
|
+
## Webhook Signature Verification
|
|
6
|
+
|
|
7
|
+
Use `verifySettldWebhookSignature` to verify incoming `x-settld-signature` headers with:
|
|
8
|
+
|
|
9
|
+
- multi-signature support (`v1=...` list, including rotation windows),
|
|
10
|
+
- constant-time comparison (`crypto.timingSafeEqual`),
|
|
11
|
+
- timestamp tolerance checks (replay protection).
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
import express from "express";
|
|
15
|
+
import { verifySettldWebhookSignature } from "settld-api-sdk";
|
|
16
|
+
|
|
17
|
+
const app = express();
|
|
18
|
+
|
|
19
|
+
// IMPORTANT: keep the raw body; do not JSON-parse before verification.
|
|
20
|
+
app.post("/webhooks/settld", express.raw({ type: "application/json" }), (req, res) => {
|
|
21
|
+
const signatureHeader = req.get("x-settld-signature") ?? "";
|
|
22
|
+
const timestamp = req.get("x-settld-timestamp"); // required for current Settld delivery format
|
|
23
|
+
const secret = process.env.SETTLD_WEBHOOK_SECRET;
|
|
24
|
+
|
|
25
|
+
verifySettldWebhookSignature(req.body, signatureHeader, secret, {
|
|
26
|
+
timestamp,
|
|
27
|
+
toleranceSeconds: 300
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const event = JSON.parse(req.body.toString("utf8"));
|
|
31
|
+
// handle event...
|
|
32
|
+
res.status(200).json({ ok: true });
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The verifier also supports signature headers that embed timestamp directly:
|
|
37
|
+
|
|
38
|
+
`x-settld-signature: t=1708380000,v1=<sig-new>,v1=<sig-old>`
|
|
39
|
+
|
|
40
|
+
## Express Middleware Helper
|
|
41
|
+
|
|
42
|
+
Use `verifySettldWebhook` to verify signatures in an Express-style middleware.
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
import express from "express";
|
|
46
|
+
import { verifySettldWebhook } from "settld-api-sdk";
|
|
47
|
+
|
|
48
|
+
const app = express();
|
|
49
|
+
const secret = process.env.SETTLD_WEBHOOK_SECRET;
|
|
50
|
+
|
|
51
|
+
// IMPORTANT: preserve raw body bytes before JSON parsing mutates payload shape.
|
|
52
|
+
app.use(
|
|
53
|
+
express.json({
|
|
54
|
+
verify(req, _res, buf) {
|
|
55
|
+
req.rawBody = buf;
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
app.post(
|
|
61
|
+
"/webhooks/settld",
|
|
62
|
+
verifySettldWebhook(secret, { toleranceSeconds: 300 }),
|
|
63
|
+
(req, res) => {
|
|
64
|
+
const event = req.body;
|
|
65
|
+
// handle event...
|
|
66
|
+
res.status(200).json({ ok: true });
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
If `req.rawBody` is missing (or `req.body` is already parsed into a plain object), the middleware returns `400` with a raw-body guidance message.
|