xytara 3.1.13 → 3.1.15

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.
Files changed (68) hide show
  1. package/.env.example +38 -4
  2. package/BSV_TERANODE_PLATFORM_DISCONTINUITY_RUNBOOK.md +126 -126
  3. package/REAL_PAYMENT_SETUP.md +14 -7
  4. package/RELEASE_NOTES.md +9 -4
  5. package/fixtures/catalog.js +22 -0
  6. package/lib/a2a_rpc.js +287 -280
  7. package/lib/account_auth.js +585 -585
  8. package/lib/agent_identity.js +162 -162
  9. package/lib/asyncapi_contract.js +3 -3
  10. package/lib/bolt_adapter.js +187 -187
  11. package/lib/bolt_payment_front.js +224 -224
  12. package/lib/buyer_event_log.js +215 -0
  13. package/lib/buyer_safety_policy.js +132 -0
  14. package/lib/checkout_processor_adapter.js +217 -217
  15. package/lib/command_flow.js +911 -722
  16. package/lib/commerce_artifacts.js +591 -591
  17. package/lib/commerce_bridge.js +274 -274
  18. package/lib/commerce_cases.js +399 -399
  19. package/lib/commerce_client.js +7694 -7694
  20. package/lib/commerce_quotes.js +29 -0
  21. package/lib/commerce_runtime.js +322 -322
  22. package/lib/execution_dedupe.js +86 -86
  23. package/lib/external_credit_bridge.js +142 -142
  24. package/lib/http_transport.js +99 -81
  25. package/lib/l402_adapter.js +241 -241
  26. package/lib/l402_payment_front.js +265 -265
  27. package/lib/mpp_adapter.js +237 -237
  28. package/lib/openapi_contract.js +4 -0
  29. package/lib/payment_config.js +257 -253
  30. package/lib/payment_verification.js +357 -357
  31. package/lib/provider_payout_execution.js +155 -155
  32. package/lib/provider_registry.js +852 -842
  33. package/lib/rate_limiter.js +81 -81
  34. package/lib/runtime_state_store.js +495 -369
  35. package/lib/settlement_bsv_live.js +600 -600
  36. package/lib/settlement_bsv_teranode.js +117 -117
  37. package/lib/stripe_mpp_payment_front.js +258 -258
  38. package/lib/x402_facilitator.js +198 -191
  39. package/lib/x402_lane_contract.js +5 -3
  40. package/lib/x402_settlement_recovery.js +175 -0
  41. package/package.json +9 -3
  42. package/scripts/buyer_events_daily_report.js +79 -0
  43. package/scripts/state_backup_offsite.js +196 -0
  44. package/scripts/verify_a2a_rpc.js +131 -105
  45. package/scripts/verify_agent_identity.js +153 -153
  46. package/scripts/verify_all.js +1 -1
  47. package/scripts/verify_bolt_adapter.js +128 -128
  48. package/scripts/verify_buyer_event_log.js +123 -0
  49. package/scripts/verify_buyer_safety.js +141 -0
  50. package/scripts/verify_cdp_facilitator.js +110 -110
  51. package/scripts/verify_checkout_processor.js +109 -109
  52. package/scripts/verify_commerce_bridge.js +177 -177
  53. package/scripts/verify_execution_dedupe.js +189 -189
  54. package/scripts/verify_execution_surfacing.js +76 -76
  55. package/scripts/verify_final_activation.js +191 -191
  56. package/scripts/verify_l402_adapter.js +86 -86
  57. package/scripts/verify_lifecycle_spend_binding.js +88 -0
  58. package/scripts/verify_mpp_adapter.js +128 -128
  59. package/scripts/verify_production_readiness.js +268 -268
  60. package/scripts/verify_rate_limiter.js +52 -52
  61. package/scripts/verify_refund_credit.js +106 -106
  62. package/scripts/verify_release_candidate.js +81 -81
  63. package/scripts/verify_runtime_state_guard.js +117 -0
  64. package/scripts/verify_service.js +15421 -15421
  65. package/scripts/verify_verify_execute_settle.js +209 -208
  66. package/scripts/verify_x402_facilitator.js +307 -286
  67. package/scripts/verify_x402_settlement_recovery.js +153 -0
  68. package/server.js +12242 -11974
package/.env.example CHANGED
@@ -10,9 +10,36 @@ XYTARA_X402_FACILITATOR_URL=https://x402.org/facilitator
10
10
  XYTARA_X402_FACILITATOR_HEADERS_JSON={}
11
11
  XYTARA_X402_FACILITATOR_TIMEOUT_MS=15000
12
12
  XYTARA_X402_SETTLE=true
13
- # credit units a single self-serve /x402/credits/topup grants (default 1000);
14
- # an accepts entry may override per-payment via its extra.credits
15
- XYTARA_X402_TOPUP_UNITS=1000
13
+ # self-serve /x402/credits/topup: priced at this multiple of the per-call accepts amount
14
+ # (default 100: $0.01 -> $1.00); credits = amount paid / XYTARA_CREDIT_UNIT_PRICE_ATOMIC
15
+ # (USDC base units per credit; default 2500 = $0.0025). An accepts entry's extra.credits may
16
+ # lower the grant, never raise it. Testnet networks cannot buy credits unless this is 1:
17
+ XYTARA_X402_TOPUP_AMOUNT_MULTIPLIER=100
18
+ XYTARA_CREDIT_UNIT_PRICE_ATOMIC=2500
19
+ XYTARA_X402_TESTNET_TOPUP=0
20
+ # floor for the advertised maxTimeoutSeconds (buyers sign validBefore = now + this)
21
+ XYTARA_X402_MIN_TIMEOUT_SECONDS=300
22
+ # money-safety policies: "strict" by default on a hosted deploy (RENDER set), "permissive" locally.
23
+ # paid execution: only tasks with a real execution target can be quoted/charged
24
+ # credit spend: spending credits needs the account's spend credential (xytara_spend_...)
25
+ # ledger reads: ledger/quote-list/receipts/operations/revenue GETs are operator-only
26
+ XYTARA_PAID_EXECUTION_POLICY=
27
+ XYTARA_CREDIT_SPEND_POLICY=
28
+ XYTARA_LEDGER_READ_POLICY=
29
+ # provider calls: per-attempt timeout floor for registered providers (default 25000 on Render)
30
+ XYTARA_PROVIDER_MIN_TIMEOUT_MS=
31
+ # chain RPC used to check whether an x402 authorization settled after a facilitator timeout
32
+ XYTARA_RPC_URL_EIP155_8453=https://mainnet.base.org
33
+ XYTARA_RPC_URL_EIP155_84532=https://sepolia.base.org
34
+ # buyer event log: ring size, payer-hash salt, and the token the MCP executor uses to forward
35
+ # its events to POST /v1/operator/buyer-events/ingest
36
+ XYTARA_BUYER_EVENT_LOG_MAX=500
37
+ XYTARA_BUYER_EVENT_SALT=
38
+ XYTARA_EVENT_INGEST_TOKEN=
39
+ # Supabase request timeout (ms) for state restore/flush
40
+ XYTARA_SUPABASE_TIMEOUT_MS=10000
41
+ # public base URL advertised in OpenAPI/AsyncAPI
42
+ XYTARA_PUBLIC_BASE_URL=https://xytara.onrender.com
16
43
  # Coinbase CDP auth for the CDP-hosted facilitator (Base mainnet); Ed25519 Secret API Key.
17
44
  # The runtime mints a fresh CDP Bearer JWT per request when both are set.
18
45
  CDP_API_KEY_ID=
@@ -132,7 +159,14 @@ XYTARA_EXTERNAL_EXECUTION_IP_FAMILY=auto
132
159
  XYTARA_CALLBACK_IP_FAMILY=auto
133
160
  XYTARA_SETTLEMENT_IP_FAMILY=auto
134
161
  XYTARA_STATE_FILE=./var/xytara/runtime-state.json
135
- XYTARA_STATE_SNAPSHOT_INTERVAL_MS=5000
162
+ # How often the durable snapshot is checked for changes; an unchanged snapshot is never rewritten.
163
+ XYTARA_STATE_SNAPSHOT_INTERVAL_MS=15000
164
+ # Supabase mode: also keep rolling history copies of the snapshot in the same table
165
+ # (rows "<state key>::history::<n>"), one per interval, rotating over N slots. 0 disables.
166
+ XYTARA_STATE_HISTORY_INTERVAL_MS=3600000
167
+ XYTARA_STATE_HISTORY_SLOTS=24
168
+ # Expired, never-paid quotes are dropped from durable state after this long (default 7 days).
169
+ XYTARA_QUOTE_RETENTION_MS=604800000
136
170
  XYTARA_SUPABASE_URL=
137
171
  XYTARA_SUPABASE_SERVICE_ROLE_KEY=
138
172
  XYTARA_SUPABASE_STATE_TABLE=xytara_runtime_state
@@ -1,126 +1,126 @@
1
- # BSV Teranode Platform Discontinuity Runbook
2
-
3
- Date: `2026-05-06`
4
-
5
- ## Purpose
6
-
7
- This runbook explains how to keep `xytara` production-safe through the announced shutdown of the legacy Teranode web platform on `2026-05-15`.
8
-
9
- The important distinction is:
10
-
11
- - the dashboard/control-plane website is being discontinued
12
- - your runtime settlement contract in `xytara` should continue to depend on live ARC submission and live observation endpoints, not on the retiring dashboard
13
-
14
- ## What The Notice Means Operationally
15
-
16
- Treat the notice as saying:
17
-
18
- - do not depend on `https://platform.teranode.group/` remaining available for operator workflows after `2026-05-15`
19
- - existing API keys may continue working, but you should not treat that as your only launch-safe posture
20
- - if you want a replacement ARC key after the shutdown, request it proactively before launch
21
- - WhatsOnChain support and contact ownership are separate from the retiring dashboard
22
-
23
- ## Immediate Pre-3.0.0 Actions
24
-
25
- 1. Back up the operator information you still need from the legacy platform now.
26
- - current API key labels
27
- - network association
28
- - any usage or billing screenshots you care about
29
- - any endpoint, auth, or support notes you may need later
30
-
31
- 2. Do not expose or rotate secrets casually.
32
- - keep the current live ARC key in place until a tested replacement exists
33
- - treat screenshots or copied values as sensitive
34
-
35
- 3. Acquire a replacement or second ARC key before cutover if possible.
36
- - that gives us a tested rollback-safe key path instead of a launch-week scramble
37
-
38
- 4. Keep the observer path independent.
39
- - `xytara` already defaults to WhatsOnChain for observation unless overridden
40
- - if you want a different observer, set it explicitly
41
-
42
- 5. Keep the runtime provider-neutral.
43
- - prefer the neutral `XYTARA_BSV_*` aliases going forward
44
- - legacy `XYTARA_BSV_TERANODE_*` envs remain supported for compatibility
45
-
46
- ## Preferred Environment Shape Going Forward
47
-
48
- Use these neutral envs where practical:
49
-
50
- ```env
51
- XYTARA_BSV_NETWORK=mainnet
52
- XYTARA_BSV_SETTLEMENT_RUNTIME_MODE=arc
53
- XYTARA_BSV_MERCHANT_ADDRESS=<real-bsv-address-or-paymail>
54
- XYTARA_BSV_ARC_RPC_URL=<live-arc-submit-endpoint>
55
- XYTARA_BSV_ARC_RPC_API_KEY=<live-arc-api-key>
56
- XYTARA_BSV_ARC_RPC_AUTH_HEADER=authorization
57
- XYTARA_BSV_ARC_RPC_AUTH_SCHEME=
58
- XYTARA_BSV_OBSERVER_URL=https://api.whatsonchain.com/v1/bsv/main
59
- ```
60
-
61
- Legacy compatibility envs are still accepted:
62
-
63
- - `XYTARA_BSV_TERANODE_NETWORK`
64
- - `XYTARA_BSV_TERANODE_SETTLEMENT_RUNTIME_MODE`
65
- - `XYTARA_BSV_TERANODE_MERCHANT_ADDRESS`
66
- - `XYTARA_BSV_TERANODE_MERCHANT_PAYMAIL`
67
- - `XYTARA_BSV_ARC_RPC_URL`
68
- - `XYTARA_BSV_ARC_RPC_API_KEY`
69
- - `XYTARA_BSV_ARC_RPC_AUTH_HEADER`
70
- - `XYTARA_BSV_ARC_RPC_AUTH_SCHEME`
71
- - legacy `XYTARA_BSV_TERANODE_RPC_*` aliases remain accepted
72
- - `XYTARA_BSV_TERANODE_OBSERVER_URL`
73
-
74
- ## Cutover Validation Sequence
75
-
76
- After you have either confirmed the current key still works or obtained a replacement ARC key:
77
-
78
- 1. update the live Render envs for `xytara`
79
- 2. redeploy `xytara`
80
- 3. check:
81
-
82
- ```text
83
- GET /v1/settlement/bsv-teranode/readiness
84
- GET /v1/settlement/bsv-teranode
85
- GET /v1/payment-rail-truth/summary
86
- GET /v1/autonomous-entry/summary
87
- ```
88
-
89
- 4. run one real settlement path validation
90
- - one quote
91
- - one payment acceptance path
92
- - one settlement record
93
- - one submit/refresh loop
94
-
95
- 5. confirm:
96
- - live submission still works in `arc` mode
97
- - live observation still works
98
- - the runtime does not depend on the retiring dashboard
99
-
100
- ## What To Change If The Provider Changes Endpoint Or Auth Style
101
-
102
- If the ARC provider gives you:
103
-
104
- - a new submit URL
105
- - a new auth header
106
- - a new auth scheme
107
- - a replacement API key
108
-
109
- you should only need to update env values, not the public `bsv_teranode` product contract.
110
-
111
- That is exactly why the runtime should remain:
112
-
113
- - provider-neutral in config
114
- - stable in public naming
115
- - explicit in readiness checks
116
-
117
- ## Launch Rule
118
-
119
- Do not let the old dashboard shutdown weaken the `3.0.0` product truth unnecessarily.
120
-
121
- The right finish-line standard is:
122
-
123
- - `bsv_teranode` remains the native public settlement name
124
- - `xytara` remains provider-neutral behind that name
125
- - live ARC submission and live observation remain validated at operator level
126
- - the public product keeps working even if the original dashboard disappears
1
+ # BSV Teranode Platform Discontinuity Runbook
2
+
3
+ Date: `2026-05-06`
4
+
5
+ ## Purpose
6
+
7
+ This runbook explains how to keep `xytara` production-safe through the announced shutdown of the legacy Teranode web platform on `2026-05-15`.
8
+
9
+ The important distinction is:
10
+
11
+ - the dashboard/control-plane website is being discontinued
12
+ - your runtime settlement contract in `xytara` should continue to depend on live ARC submission and live observation endpoints, not on the retiring dashboard
13
+
14
+ ## What The Notice Means Operationally
15
+
16
+ Treat the notice as saying:
17
+
18
+ - do not depend on `https://platform.teranode.group/` remaining available for operator workflows after `2026-05-15`
19
+ - existing API keys may continue working, but you should not treat that as your only launch-safe posture
20
+ - if you want a replacement ARC key after the shutdown, request it proactively before launch
21
+ - WhatsOnChain support and contact ownership are separate from the retiring dashboard
22
+
23
+ ## Immediate Pre-3.0.0 Actions
24
+
25
+ 1. Back up the operator information you still need from the legacy platform now.
26
+ - current API key labels
27
+ - network association
28
+ - any usage or billing screenshots you care about
29
+ - any endpoint, auth, or support notes you may need later
30
+
31
+ 2. Do not expose or rotate secrets casually.
32
+ - keep the current live ARC key in place until a tested replacement exists
33
+ - treat screenshots or copied values as sensitive
34
+
35
+ 3. Acquire a replacement or second ARC key before cutover if possible.
36
+ - that gives us a tested rollback-safe key path instead of a launch-week scramble
37
+
38
+ 4. Keep the observer path independent.
39
+ - `xytara` already defaults to WhatsOnChain for observation unless overridden
40
+ - if you want a different observer, set it explicitly
41
+
42
+ 5. Keep the runtime provider-neutral.
43
+ - prefer the neutral `XYTARA_BSV_*` aliases going forward
44
+ - legacy `XYTARA_BSV_TERANODE_*` envs remain supported for compatibility
45
+
46
+ ## Preferred Environment Shape Going Forward
47
+
48
+ Use these neutral envs where practical:
49
+
50
+ ```env
51
+ XYTARA_BSV_NETWORK=mainnet
52
+ XYTARA_BSV_SETTLEMENT_RUNTIME_MODE=arc
53
+ XYTARA_BSV_MERCHANT_ADDRESS=<real-bsv-address-or-paymail>
54
+ XYTARA_BSV_ARC_RPC_URL=<live-arc-submit-endpoint>
55
+ XYTARA_BSV_ARC_RPC_API_KEY=<live-arc-api-key>
56
+ XYTARA_BSV_ARC_RPC_AUTH_HEADER=authorization
57
+ XYTARA_BSV_ARC_RPC_AUTH_SCHEME=
58
+ XYTARA_BSV_OBSERVER_URL=https://api.whatsonchain.com/v1/bsv/main
59
+ ```
60
+
61
+ Legacy compatibility envs are still accepted:
62
+
63
+ - `XYTARA_BSV_TERANODE_NETWORK`
64
+ - `XYTARA_BSV_TERANODE_SETTLEMENT_RUNTIME_MODE`
65
+ - `XYTARA_BSV_TERANODE_MERCHANT_ADDRESS`
66
+ - `XYTARA_BSV_TERANODE_MERCHANT_PAYMAIL`
67
+ - `XYTARA_BSV_ARC_RPC_URL`
68
+ - `XYTARA_BSV_ARC_RPC_API_KEY`
69
+ - `XYTARA_BSV_ARC_RPC_AUTH_HEADER`
70
+ - `XYTARA_BSV_ARC_RPC_AUTH_SCHEME`
71
+ - legacy `XYTARA_BSV_TERANODE_RPC_*` aliases remain accepted
72
+ - `XYTARA_BSV_TERANODE_OBSERVER_URL`
73
+
74
+ ## Cutover Validation Sequence
75
+
76
+ After you have either confirmed the current key still works or obtained a replacement ARC key:
77
+
78
+ 1. update the live Render envs for `xytara`
79
+ 2. redeploy `xytara`
80
+ 3. check:
81
+
82
+ ```text
83
+ GET /v1/settlement/bsv-teranode/readiness
84
+ GET /v1/settlement/bsv-teranode
85
+ GET /v1/payment-rail-truth/summary
86
+ GET /v1/autonomous-entry/summary
87
+ ```
88
+
89
+ 4. run one real settlement path validation
90
+ - one quote
91
+ - one payment acceptance path
92
+ - one settlement record
93
+ - one submit/refresh loop
94
+
95
+ 5. confirm:
96
+ - live submission still works in `arc` mode
97
+ - live observation still works
98
+ - the runtime does not depend on the retiring dashboard
99
+
100
+ ## What To Change If The Provider Changes Endpoint Or Auth Style
101
+
102
+ If the ARC provider gives you:
103
+
104
+ - a new submit URL
105
+ - a new auth header
106
+ - a new auth scheme
107
+ - a replacement API key
108
+
109
+ you should only need to update env values, not the public `bsv_teranode` product contract.
110
+
111
+ That is exactly why the runtime should remain:
112
+
113
+ - provider-neutral in config
114
+ - stable in public naming
115
+ - explicit in readiness checks
116
+
117
+ ## Launch Rule
118
+
119
+ Do not let the old dashboard shutdown weaken the `3.0.0` product truth unnecessarily.
120
+
121
+ The right finish-line standard is:
122
+
123
+ - `bsv_teranode` remains the native public settlement name
124
+ - `xytara` remains provider-neutral behind that name
125
+ - live ARC submission and live observation remain validated at operator level
126
+ - the public product keeps working even if the original dashboard disappears
@@ -50,17 +50,24 @@ runtime takes a command-execute body rather than an MCP JSON-RPC call.
50
50
  Beyond paying per call, a buyer can convert a single x402 payment into spendable
51
51
  runtime credits with no operator grant, via `POST /x402/credits/topup`:
52
52
 
53
- - without a `PAYMENT-SIGNATURE`, it returns `402` advertising the same `accepts` plus
54
- `credits_per_topup` (how many credit units one payment buys)
53
+ - without a `PAYMENT-SIGNATURE`, it returns `402` advertising the top-up `accepts` (each
54
+ per-call amount x `XYTARA_X402_TOPUP_AMOUNT_MULTIPLIER`, default 100: $0.01 -> $1.00),
55
+ `credits_per_topup` and a `topup_options` list (network, amount, credits)
55
56
  - with a valid payment, the facilitator settles it on-chain and the runtime mints the
56
- credits to the account, returning the grant, the new balance, and a `PAYMENT-RESPONSE`
57
- settlement receipt
58
- - credits land on `account_id` from the body, falling back to the paying wallet address
57
+ credits to the account, returning the grant, the new balance, a `PAYMENT-RESPONSE`
58
+ settlement receipt and — when the credits went to the paying address — a
59
+ `spend_credential` (`Bearer xytara_spend_...`, shown once) for spending them
60
+ - credits land on the paying wallet address by default; credits sent to another `account_id`
61
+ are a gift and carry no spend credential
59
62
  - replays are idempotent: the payment nonce keys the grant, so re-sending the same settled
60
63
  payment never mints twice
61
64
 
62
- Each top-up grants `XYTARA_X402_TOPUP_UNITS` credit units (default `1000`), unless the matched
63
- `accepts` entry sets its own `extra.credits`. The route is live only in `x402_facilitator`
65
+ Credits are derived from what was paid: amount / `XYTARA_CREDIT_UNIT_PRICE_ATOMIC` (default
66
+ 2500 base units = $0.0025 per credit, so $1.00 buys 400 credits; a task costs 1–8 credits by
67
+ tier). A matched `accepts` entry's `extra.credits` may lower that, never raise it. Testnet
68
+ networks (Base Sepolia) cannot buy credits unless `XYTARA_X402_TESTNET_TOPUP=1`. Spend them with
69
+ `payment_preference: "credits_first"` and the spend credential as the bearer — on a hosted
70
+ deploy a bare `account_id` is never authority. The route is live only in `x402_facilitator`
64
71
  mode with `XYTARA_X402_ACCEPTS_JSON` set, and credits persist only when runtime state
65
72
  persistence (`XYTARA_SUPABASE_*` or `XYTARA_STATE_FILE`) is configured. A runnable buyer is in
66
73
  `services/mcp-execution-target/buyer-demo/x402-credits-topup-demo.js`.
package/RELEASE_NOTES.md CHANGED
@@ -1,5 +1,10 @@
1
- `xytara` 3.1.13 adds signed delivery receipts and makes the direct MCP path charge only on success.
1
+ `xytara` 3.1.15 makes the buyer path safe end to end: a buyer is never charged for a result that was not produced, every failed attempt is visible to the operator, and standard x402 MCP clients can pay the MCP server directly.
2
2
 
3
- - **Signed delivery receipts** (`naxytra-delivery-receipt/1`) on every paid call, from the runtime and from the MCP executor. A receipt binds the payment leg (for x402: network, asset, amount, payer, pay_to, settlement transaction), the provider that delivered, and the SHA-256 of the canonical request and of the delivered output. It is signed over its JCS (RFC 8785) canonical form with Ed25519, plus ML-DSA-65 (FIPS-204) where the issuer has a post-quantum key; the signed suite is inside the signed bytes, so stripping a signature fails verification. Public keys: `GET /.well-known/delivery-receipt-keys`; runtime receipts are retrievable at `GET /v1/delivery-receipts/:id`; free check at `POST /v1/delivery-receipts/verify`. Key ids use the xoonya key-ref format, so xoonya's verifier checks them too. Without a configured key a receipt is still issued and marked unsigned — never a fake signature. Boundary: a receipt proves who delivered what for which paid call, unaltered — not whether the output was correct.
4
- - **Real x402 settlement records** — for an x402-paid call the runtime's settlement, treasury, and default-path records now carry the x402 rail, network, amount, payer, pay_to, and settlement transaction, instead of the quote's unsubmitted default rail.
5
- - **MCP executor charges only on success** — `tools/call` now verifies the payment, runs the tool, and settles only if the call succeeded. A tool error, unknown tool, or bad params is never charged; if settlement fails after the work, the output is withheld and the buyer is not charged. A concurrent replay of the same signed authorization is refused (`409 payment_authorization_in_use`).
3
+ - **Pay only for real work** — on a hosted deploy a task is quoted and charged only when it resolves to a real execution target (an operator-pinned target or an active open-network provider). Anything else is refused up front with `501 capability_not_executable` and the list of executable tasks; no payment is requested. The catalog marks every task with `purchase.executable_now` and its per-call price. Post-quantum proof verification (`adapter.xoonya.invoke`) is now a catalog task.
4
+ - **Verify, execute, then settle — everywhere** — paid A2A calls now settle only after the skill succeeds, like the HTTP routes. If the facilitator times out at settlement, the runtime checks the EIP-3009 `authorizationState` on-chain: a used authorization is a settled payment and the result is delivered; otherwise the finished result is held and returned when the buyer resends the same payment (bound to the original request). A resent settled payment returns its stored result instead of failing. The execution deadline stays inside the signed authorization's `validBefore`, and the advertised `maxTimeoutSeconds` has a floor of 300.
5
+ - **Credits are safe and priced from what was paid** — spending credits requires the account's spend credential; a bare `account_id` is never authority. A self-serve top-up is priced at 100x the per-call amount, is mainnet-only by default, grants credits derived from the amount paid (default $0.0025 per credit), and returns a spend credential to the paying address. Provider revenue on credit spends accrues on the credits' purchase value, never on the catalog quote. Credit routes answer `503` with `Retry-After` while durable state is still being restored.
6
+ - **Buyer event log** — every failed buyer attempt is recorded with its stage, reason, fault (ours, upstream, buyer) and a request id the buyer also receives (`X-Request-Id`), with per-day counters for challenges issued and paid calls served. No signatures, request bodies, tokens or full addresses are stored. Operator-only `GET /v1/operator/buyer-events` and `/summary`; the MCP server forwards its events to `POST /v1/operator/buyer-events/ingest`; a daily report job flags money that moved without a delivered result.
7
+ - **MCP server** — speaks the x402 MCP transport natively (payment-required tool result; payment in `_meta["x402/payment"]`, `PAYMENT-SIGNATURE` or `X-PAYMENT`; settlement in `_meta["x402/payment-response"]`), with `/mcp/http402` for fetch-wrapper clients. Bad arguments and unknown tools are rejected before any payment, `GET /mcp` is no longer a paid route, and CORS is enabled. Every paid tool was corrected so that an empty, invalid or unverifiable answer is an error and never charged; `json.validate` validates against a JSON Schema subset, `x402.verify-receipt` confirms only a matching USDC transfer, ABI tools are strict, and hostile inputs are bounded.
8
+ - **Request-bound agent signatures** — the credit lifecycle routes (reserve, release, reverse) honour the agent's signed binding to the exact account, amount and task.
9
+ - **Robustness and privacy** — malformed JSON is a `400` (oversize `413`), internal errors are logged under the request id without leaking details, state-store calls time out, registered providers get a cold-start timeout floor and are woken when a buyer is quoted, and ledger, quote-list, receipt, operations and revenue reads are operator-only on a hosted deploy. x402 challenges show the price actually charged; OpenAPI and AsyncAPI point at the hosted runtime.
10
+ - Published through npm trusted publishing (GitHub OIDC) — no npm token involved.
@@ -779,6 +779,28 @@ const tasks = [
779
779
  capabilities: ["adapter.mcp.invoke"],
780
780
  adapters: ["mcp"]
781
781
  }),
782
+ makeTask({
783
+ task_ref: "internal.adapter.xoonya.invoke",
784
+ public_task_ref: "adapter.xoonya.invoke",
785
+ public_category: "adapter",
786
+ public_title: "Post-quantum proof verification (xoonya)",
787
+ execution_mode: "direct_http",
788
+ pricing_band: "decision_support",
789
+ public_launch_price: { amount_minor: 1, currency: "USD_CENTS" },
790
+ latency_class: "near_real_time",
791
+ failure_posture: "retry_bounded",
792
+ input_schema: {
793
+ type: "object",
794
+ required: ["tool_name"],
795
+ properties: {
796
+ tool_name: { type: "string", enum: ["proof.verify-signature", "proof.verify-bundle"] },
797
+ arguments: { type: "object" }
798
+ },
799
+ additionalProperties: false
800
+ },
801
+ capabilities: ["adapter.xoonya.invoke"],
802
+ adapters: ["xoonya"]
803
+ }),
782
804
  makeTask({
783
805
  task_ref: "internal.adapter.mcp.catalog",
784
806
  public_task_ref: "adapter.mcp.catalog",