agentic-wallet-mcp 0.1.0 → 0.2.0
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/LICENSE +21 -0
- package/README.md +142 -59
- package/dist/server-bundle.cjs +22101 -0
- package/package.json +15 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MyEG Services Berhad
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
An agent-facing **MCP server** that gives an AI agent a Zetrix wallet: it **proves identity**
|
|
4
4
|
(x401), **pays** (x402), and **obtains verifiable credentials** (via the MBI issuer) — by
|
|
5
5
|
orchestrating existing SDKs/MCPs. It is a thin composer: all heavy crypto and payment logic
|
|
6
|
-
lives in the imported libraries.
|
|
6
|
+
lives in the imported libraries. No private key ever exists in this process — everything signs
|
|
7
|
+
through Wallet BE's HSM.
|
|
7
8
|
|
|
8
9
|
- **x401** proof → [`x401-zetrix-client`](https://www.npmjs.com/package/x401-zetrix-client) (npm)
|
|
9
10
|
- **x402** payment → [`x402-zetrix-client`](https://www.npmjs.com/package/x402-zetrix-client) (npm)
|
|
@@ -12,8 +13,6 @@ lives in the imported libraries.
|
|
|
12
13
|
- **holder key custody + signing** → Wallet BE softHSM (`/wallet/hsm/*`)
|
|
13
14
|
- **VC issuance** → MBI RS (`/v1/vc/pay/*`)
|
|
14
15
|
|
|
15
|
-
See [`docs/INTEGRATION_GUIDE.md`](docs/INTEGRATION_GUIDE.md) for the full config reference, tool
|
|
16
|
-
contracts, a live-verified usage flow, and a troubleshooting table for real-infra errors.
|
|
17
16
|
[`docs/CONTRACT_RECONCILIATION.md`](docs/CONTRACT_RECONCILIATION.md) has the authoritative
|
|
18
17
|
endpoint/contract map, [`docs/DEVELOPMENT_CHECKLIST.md`](docs/DEVELOPMENT_CHECKLIST.md) has status,
|
|
19
18
|
and [`docs/USAGE_FLOW.md`](docs/USAGE_FLOW.md) has a full end-to-end prompt script (onboarding →
|
|
@@ -21,13 +20,13 @@ VC issuance → identity proof → pay-per-use).
|
|
|
21
20
|
|
|
22
21
|
## Tools
|
|
23
22
|
|
|
24
|
-
| Tool | Does | Input |
|
|
25
|
-
|
|
26
|
-
| `wallet_status` | Report holder DID/address/network + client-supplied held VCs | `{ heldCredentials? }` |
|
|
27
|
-
| `prove_identity` | Answer an x401 `PROOF-REQUEST` → return the `PROOF-RESPONSE` header to replay | `{ proofRequest, vc, revealAttribute?, issuerKeys? }` |
|
|
28
|
-
| `pay_and_fetch` | Fetch a URL, auto-pay with x402 (self-pay via Wallet BE) on `402` | `{ url, method?, headers?, body? }` |
|
|
29
|
-
| `subscribe_and_issue` | Build the signed payload → pay x402 → MBI issues → return the VC | `{ templateId, attributes, expirationDate? }` |
|
|
30
|
-
| `create_holder_account` | Onboarding:
|
|
23
|
+
| Tool | Does | Input | Output (shape) |
|
|
24
|
+
|---|---|---|---|
|
|
25
|
+
| `wallet_status` | Report holder DID/address/network + client-supplied held VCs | `{ heldCredentials? }` | `{ holderDid, zetrixAddress, network, credentials }` |
|
|
26
|
+
| `prove_identity` | Answer an x401 `PROOF-REQUEST` → return the `PROOF-RESPONSE` header to replay | `{ proofRequest, vc, revealAttribute?, issuerKeys? }` | `{ proofResponseHeader, verified, presentationId }` |
|
|
27
|
+
| `pay_and_fetch` | Fetch a URL, auto-pay with x402 (self-pay via Wallet BE) on `402` | `{ url, method?, headers?, body? }` | `{ status, body, paymentMade, amountPaid, amountPaidHuman, asset }` |
|
|
28
|
+
| `subscribe_and_issue` | Build the signed payload → pay x402 → MBI issues → return the VC | `{ templateId, attributes, expirationDate? }` | `{ issued, vcId, vc, txHash }` |
|
|
29
|
+
| `create_holder_account` | Onboarding: manually mint an additional/replacement HSM account (the MCP already auto-creates one at startup if `ZETRIX_ADDRESS` is omitted — see Environment below) | `{ password, label?, purpose? }` | `{ zetrixAddress, holderDid, publicKeyHex, message }` |
|
|
31
30
|
|
|
32
31
|
> The wallet **never persists VCs** — the client holds them and passes them in (e.g. `vc` on
|
|
33
32
|
> `prove_identity`, `heldCredentials` on `wallet_status`). All Ed25519 signing goes through
|
|
@@ -35,8 +34,14 @@ VC issuance → identity proof → pay-per-use).
|
|
|
35
34
|
|
|
36
35
|
> `create_holder_account` mints a **brand-new** keypair — Wallet BE's `/account/create` has no
|
|
37
36
|
> way to provision a pre-chosen address. It returns the new `zetrixAddress`/`holderDid` for you
|
|
38
|
-
> to paste into `
|
|
39
|
-
> MCP config or restarts the server for you.
|
|
37
|
+
> to paste into `ZETRIX_ADDRESS`/`HSM_PASSWORD` yourself (`HOLDER_DID` is optional — see
|
|
38
|
+
> Environment below); the tool never writes your MCP config or restarts the server for you.
|
|
39
|
+
|
|
40
|
+
> `revealAttribute` on `prove_identity` is optional and usually should stay that way. Omitted,
|
|
41
|
+
> it's derived automatically from the challenge's DCQL `credential_requirements` — each claim path
|
|
42
|
+
> is resolved against the presented VC's `credentialSubject` (e.g. a DCQL leaf name `agentName`
|
|
43
|
+
> resolves to the VC's actual nested path `agentIdentityCredential.agentName`). Only pass it
|
|
44
|
+
> explicitly to reveal a narrower or different set of claims than the challenge asked for.
|
|
40
45
|
|
|
41
46
|
> `prove_identity` no longer takes a `bbsPublicKey` input at all. The OID4VP verifier
|
|
42
47
|
> (`openid4vp-verifier-be`) checks each VC's own issuer-signed proof(s) against the
|
|
@@ -45,28 +50,35 @@ VC issuance → identity proof → pay-per-use).
|
|
|
45
50
|
> resolves them itself: it reads the VC's `issuer` DID and each `proof[].verificationMethod`,
|
|
46
51
|
> resolves the issuer's DID document via the Zetrix ZID resolver, and matches the BBS+
|
|
47
52
|
> (`publicKeyMultibase`) and Ed25519 (`publicKeyHex`) verification methods referenced by the VC's
|
|
48
|
-
> own proofs.
|
|
53
|
+
> own proofs. `issuerKeys` is still accepted as a manual escape hatch if the resolver is ever
|
|
54
|
+
> unreachable. See `docs/CONTRACT_RECONCILIATION.md §8` for the full trace through the verifier's
|
|
49
55
|
> source that led to this.
|
|
50
56
|
|
|
51
|
-
## Install
|
|
57
|
+
## Install
|
|
58
|
+
|
|
59
|
+
Run it directly via `npx` — no install step needed (see "Configuring in Claude Desktop / Claude
|
|
60
|
+
Code" below for wiring it into an MCP client):
|
|
52
61
|
|
|
53
62
|
```bash
|
|
54
|
-
|
|
55
|
-
npm test # 85 tests
|
|
56
|
-
npm run build # tsc + esbuild → dist/server-bundle.cjs (the bin)
|
|
63
|
+
npx agentic-wallet-mcp
|
|
57
64
|
```
|
|
58
65
|
|
|
59
|
-
|
|
60
|
-
|
|
66
|
+
Or install [`agentic-wallet-mcp`](https://www.npmjs.com/package/agentic-wallet-mcp) directly:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm i agentic-wallet-mcp
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Node ≥ 18 required (built-in `fetch`).
|
|
61
73
|
|
|
62
74
|
## Environment
|
|
63
75
|
|
|
64
76
|
| Variable | Required | Description |
|
|
65
77
|
|---|---|---|
|
|
66
|
-
| `ZETRIX_NETWORK` | yes | `zetrix:testnet` or `zetrix:mainnet` — also selects the default `WALLET_BE_URL`/`MBI_BASE_URL`/`OID4VP_BASE_URL` below |
|
|
67
|
-
| `
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
78
|
+
| `ZETRIX_NETWORK` | yes | `zetrix:testnet` or `zetrix:mainnet` — also selects the default `WALLET_BE_URL`/`MBI_BASE_URL`/`OID4VP_BASE_URL`/`ZID_RESOLVER_BASE_URL` below |
|
|
79
|
+
| `HSM_PASSWORD` | yes* | HSM password |
|
|
80
|
+
| `ZETRIX_ADDRESS` | no | Holder Zetrix address (the HSM account). Omit on first run — see "Onboarding" below |
|
|
81
|
+
| `HOLDER_DID` | no | Holder DID. Omit and the MCP derives it automatically — see "Onboarding" below |
|
|
70
82
|
| `WALLET_BE_URL` | no | Wallet BE base URL override (HSM `/wallet/hsm/sign-blob`) — auto-derived from `ZETRIX_NETWORK` when not set |
|
|
71
83
|
| `MBI_BASE_URL` | no | MBI RS base URL override (`/v1/vc/pay/apply`) — auto-derived from `ZETRIX_NETWORK` when not set |
|
|
72
84
|
| `OID4VP_BASE_URL` | no | OID4VP verifier base URL override — auto-derived from `ZETRIX_NETWORK` by the x401 SDK when not set (BT-2368) |
|
|
@@ -76,6 +88,27 @@ Node ≥ 18 (built-in `fetch`). `x401-zetrix-client` is consumed as a normal npm
|
|
|
76
88
|
|
|
77
89
|
\* sensitive — never logged.
|
|
78
90
|
|
|
91
|
+
### Onboarding: two ways to set up your holder identity
|
|
92
|
+
|
|
93
|
+
`ZETRIX_ADDRESS` and `HOLDER_DID` are both optional — the MCP resolves your holder identity at
|
|
94
|
+
startup, in one of two ways:
|
|
95
|
+
|
|
96
|
+
1. **First-time user — only `HSM_PASSWORD` set.** The MCP creates a brand-new HSM account on
|
|
97
|
+
Wallet BE (`POST /wallet/hsm/account/create`) and derives the DID from the returned public
|
|
98
|
+
key. It logs the new `ZETRIX_ADDRESS` (and `HOLDER_DID`) to stderr on startup — copy it into
|
|
99
|
+
your MCP config for next time, since nothing is persisted to disk between runs (env vars only
|
|
100
|
+
load once, at process start).
|
|
101
|
+
2. **Existing user — `ZETRIX_ADDRESS` + `HSM_PASSWORD` set, `HOLDER_DID` optional.** The MCP
|
|
102
|
+
always self-signs the address via the existing `POST /wallet/hsm/sign-message` call and
|
|
103
|
+
derives the DID from the `publicKey` the response carries — no separate lookup endpoint
|
|
104
|
+
needed. A supplied `HOLDER_DID` is never trusted blindly: it's compared against this derived
|
|
105
|
+
value, and if they don't match, the derived (correct) one wins — the mismatch is logged to
|
|
106
|
+
stderr so you know to fix your config. Omit `HOLDER_DID` entirely and the derived value is
|
|
107
|
+
just used directly.
|
|
108
|
+
|
|
109
|
+
Either way, `wallet_status` always reports the resolved `zetrixAddress`/`holderDid` for the
|
|
110
|
+
running session, so you can confirm what the MCP resolved to at any time.
|
|
111
|
+
|
|
79
112
|
\*\* **strongly recommended before pointing this wallet at mainnet/real funds.** `pay_and_fetch`
|
|
80
113
|
and `subscribe_and_issue` auto-pay whatever `maxAmountRequired` a remote server's 402 challenge
|
|
81
114
|
demands, with no built-in ceiling — a prompt-injected or misled agent calling either tool against
|
|
@@ -84,18 +117,20 @@ balance. `MAX_PAYMENT_AMOUNT` is a hard, code-enforced cap that holds regardless
|
|
|
84
117
|
calling agent decides. Once set, it becomes an allowlist: an asset with no entry and no `"*"`
|
|
85
118
|
fallback is **denied**, not passed through uncapped.
|
|
86
119
|
|
|
87
|
-
You don't need to look up or fill in `WALLET_BE_URL`/`MBI_BASE_URL`/`OID4VP_BASE_URL
|
|
88
|
-
just pick `zetrix:testnet` or `zetrix:mainnet` for
|
|
89
|
-
it wires up) uses the built-in default for that
|
|
120
|
+
You don't need to look up or fill in `WALLET_BE_URL`/`MBI_BASE_URL`/`OID4VP_BASE_URL`/
|
|
121
|
+
`ZID_RESOLVER_BASE_URL` yourself — just pick `zetrix:testnet` or `zetrix:mainnet` for
|
|
122
|
+
`ZETRIX_NETWORK` and the MCP (and the x401 SDK it wires up) uses the built-in default for that
|
|
123
|
+
network:
|
|
90
124
|
|
|
91
|
-
| Network | `WALLET_BE_URL` default | `MBI_BASE_URL` default | `OID4VP_BASE_URL` default |
|
|
92
|
-
|
|
93
|
-
| `zetrix:testnet` | `https://wallet-api.myegdev.com/server` | `https://mbi-vc.myegdev.com` | `https://zid-oid4vp-sandbox.zetrix.com/api` |
|
|
94
|
-
| `zetrix:mainnet` | `https://wallet-api.zetrix.com/server` | `https://mbi-vc.zetrix.com` | `https://zid-oid4vp.zetrix.com/api` |
|
|
125
|
+
| Network | `WALLET_BE_URL` default | `MBI_BASE_URL` default | `OID4VP_BASE_URL` default | `ZID_RESOLVER_BASE_URL` default |
|
|
126
|
+
|---|---|---|---|---|
|
|
127
|
+
| `zetrix:testnet` | `https://wallet-api.myegdev.com/server` | `https://mbi-vc.myegdev.com` | `https://zid-oid4vp-sandbox.zetrix.com/api` | `https://zid-resolver-sandbox.zetrix.com` |
|
|
128
|
+
| `zetrix:mainnet` | `https://wallet-api.zetrix.com/server` | `https://mbi-vc.zetrix.com` | `https://zid-oid4vp.zetrix.com/api` | `https://zid-resolver.zetrix.com` |
|
|
95
129
|
|
|
96
|
-
Only set
|
|
97
|
-
|
|
98
|
-
|
|
130
|
+
Only set any of the four explicitly if you run your own instance of that service instead of the
|
|
131
|
+
default one — an explicit value always wins over the network default. The `*.myegdev.com`
|
|
132
|
+
(testnet) hosts are internal — unreachable without VPN; see "Network reachability &
|
|
133
|
+
troubleshooting" below if any of them time out.
|
|
99
134
|
|
|
100
135
|
That's the complete list — no VC-MCP subprocess, no BaaS gateway key, no manually-configured
|
|
101
136
|
BBS+ key to set up (BT-2357 replaced that whole path — see `docs/CONTRACT_RECONCILIATION.md §8`).
|
|
@@ -116,24 +151,32 @@ the `<...>` placeholders (don't commit a filled copy; `mcp.local.json` is gitign
|
|
|
116
151
|
{
|
|
117
152
|
"mcpServers": {
|
|
118
153
|
"agentic-wallet": {
|
|
119
|
-
"command": "
|
|
120
|
-
"args": ["
|
|
154
|
+
"command": "npx",
|
|
155
|
+
"args": ["-y", "agentic-wallet-mcp"],
|
|
121
156
|
"env": {
|
|
122
157
|
"ZETRIX_NETWORK": "zetrix:testnet",
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
"
|
|
158
|
+
"HSM_PASSWORD": "your-hsm-password",
|
|
159
|
+
"ZETRIX_ADDRESS": "ZTX3...",
|
|
160
|
+
"HOLDER_DID": "did:zid:..."
|
|
126
161
|
}
|
|
127
162
|
}
|
|
128
163
|
}
|
|
129
164
|
}
|
|
130
165
|
```
|
|
131
166
|
|
|
167
|
+
> First run, no account yet? Omit `ZETRIX_ADDRESS` (and `HOLDER_DID`) entirely — the MCP creates
|
|
168
|
+
> one for you at startup and logs it to stderr; copy it back into `env` for next time. See
|
|
169
|
+
> "Onboarding" under Environment above.
|
|
170
|
+
|
|
171
|
+
> Working on this repo locally instead of the published package? Point `command`/`args` at the
|
|
172
|
+
> local build directly: `"command": "node"`, `"args": ["/absolute/path/to/zetrix-agentic-wallet/dist/server-bundle.cjs"]`.
|
|
173
|
+
|
|
132
174
|
> Prefer environment/secret managers over inline secrets for `HSM_PASSWORD` in production.
|
|
133
175
|
>
|
|
134
|
-
> Only add `WALLET_BE_URL` / `MBI_BASE_URL` / `OID4VP_BASE_URL`
|
|
135
|
-
> own instance of that service — otherwise leave them out and the MCP
|
|
136
|
-
> default for whichever `ZETRIX_NETWORK` you picked (see the table
|
|
176
|
+
> Only add `WALLET_BE_URL` / `MBI_BASE_URL` / `OID4VP_BASE_URL` / `ZID_RESOLVER_BASE_URL` to the
|
|
177
|
+
> `env` block if you run your own instance of that service — otherwise leave them out and the MCP
|
|
178
|
+
> (and the x401 SDK) use the default for whichever `ZETRIX_NETWORK` you picked (see the table
|
|
179
|
+
> above).
|
|
137
180
|
|
|
138
181
|
## Example prompts
|
|
139
182
|
|
|
@@ -145,21 +188,61 @@ the `<...>` placeholders (don't commit a filled copy; `mcp.local.json` is gitign
|
|
|
145
188
|
|
|
146
189
|
For the full ordered script (onboarding → check → issue → prove → pay), see [`docs/USAGE_FLOW.md`](docs/USAGE_FLOW.md).
|
|
147
190
|
|
|
148
|
-
##
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
191
|
+
## End-to-end usage flow
|
|
192
|
+
|
|
193
|
+
Full narrative version with example prompts: [`docs/USAGE_FLOW.md`](docs/USAGE_FLOW.md).
|
|
194
|
+
|
|
195
|
+
**Step 0 — onboarding (once).** Only if `ZETRIX_ADDRESS` isn't set yet: the MCP creates an HSM
|
|
196
|
+
account automatically at startup from `HSM_PASSWORD` alone (see "Onboarding" under Environment
|
|
197
|
+
above) — copy the logged `zetrixAddress` into your MCP config for next time. Alternatively, call
|
|
198
|
+
`create_holder_account { password }` manually and paste the returned `zetrixAddress` in yourself;
|
|
199
|
+
either way, restart the server afterward (env vars load once, at process start).
|
|
200
|
+
|
|
201
|
+
**Phase 1 — `wallet_status` — pre-check.** Pass any VCs the caller already holds via
|
|
202
|
+
`heldCredentials`; the response tells you whether the agent-identity credential you need is
|
|
203
|
+
already there. Skip to Phase 3 if so.
|
|
204
|
+
|
|
205
|
+
**Phase 2 — `subscribe_and_issue` — VC issuance (✅ live-verified).**
|
|
206
|
+
`{ templateId, attributes }` → holder-signs the payload via Wallet BE → MBI's x402 `402` →
|
|
207
|
+
self-pay → MBI settles **and** issues the VC in one call. **Hold onto the returned `vc`** — it's
|
|
208
|
+
what you pass into every future `prove_identity` call.
|
|
209
|
+
|
|
210
|
+
**Phase 3 — `prove_identity` — x401 identity proof (✅ live-verified, `VERIFIED`).**
|
|
211
|
+
`{ proofRequest, vc }` (omit `revealAttribute`/`issuerKeys` — both now resolve automatically).
|
|
212
|
+
Internally: fetch the OID4VP presentation definition → derive the BBS+ selective-disclosure VP
|
|
213
|
+
via MBI (`/vp/ext/create` + `/vp/ext/submit`, `includeVp: true`) → resolve the issuer's
|
|
214
|
+
verification keys via the ZID resolver → submit to the verifier with wallet-auth headers →
|
|
215
|
+
package the signed result as a `PROOF-RESPONSE`. Replaying that header back to the original
|
|
216
|
+
resource server happens outside this MCP, in whatever drove the conversation. See "The
|
|
217
|
+
`PROOF-REQUEST` header" section in [`docs/USAGE_FLOW.md`](docs/USAGE_FLOW.md) for the exact wire
|
|
218
|
+
structure and field semantics.
|
|
219
|
+
|
|
220
|
+
**Phase 4 — `pay_and_fetch` — pay-per-use (✅ live-verified).**
|
|
221
|
+
`{ url, method?, headers?, body? }` → fetch → on `402`, self-pay → retry with `X-PAYMENT`.
|
|
222
|
+
Independent of Phases 2/3 — no VC or identity proof involved, just a fresh payment per call.
|
|
223
|
+
|
|
224
|
+
## Network reachability & troubleshooting
|
|
225
|
+
|
|
226
|
+
Several dependencies sit behind a corporate VPN or a CDN edge. When something that worked before
|
|
227
|
+
suddenly times out or 403s, check this table before assuming a code regression — in every case
|
|
228
|
+
observed so far, the code was correct and the network/edge state had changed.
|
|
229
|
+
|
|
230
|
+
| Symptom | Cause | Fix / status |
|
|
231
|
+
|---|---|---|
|
|
232
|
+
| `Wallet BE /wallet/hsm/sign-blob request failed <- fetch failed <- UND_ERR_CONNECT_TIMEOUT` (or same for `mbi-vc.myegdev.com`) | `*.myegdev.com` hosts are internal — unreachable without VPN | Connect/reconnect your VPN, then retry. Verify first: `curl -I https://wallet-api.myegdev.com/server` |
|
|
233
|
+
| `VP derivation failed <- ZID resolver HTTP 403 ... cf-mitigated: challenge` | ZID resolver (`zid-resolver-sandbox.zetrix.com`) was behind a Cloudflare **managed challenge** that blocked plain server-to-server `fetch` | **Fixed 2026-07-17** — DevOps allowlisted server-to-server access; the resolver now returns `200` directly (verified: `curl https://zid-resolver-sandbox.zetrix.com/1.0/identifiers/<did>` → real DID document, keys byte-identical to a browser-fetched copy). If it ever regresses, `prove_identity`'s `issuerKeys` input is the fallback — fetch the DID document via a real browser (it clears the JS challenge) and pass its `verificationMethod` entries' `publicKeyMultibase` (BBS+) / `publicKeyHex` (Ed25519) directly. |
|
|
234
|
+
| `OID4VP backend returned a malformed presentation definition` | Historical SDK bug: the live sandbox's `GET /v1/presentation/{id}` response has no `expires_at` field, but the SDK guard required one | **Fixed** in `x401-zetrix-client` — `expiresAt` is now optional on `PresentationDefinition`. If you see this, you're on a stale cached `npx` install — clear it (`npx clear-npx-cache` or bump the version) to pick up the current published `agentic-wallet-mcp`. |
|
|
235
|
+
| `SUBMIT_FAILED: OID4VP backend returned 401 ... Missing X-Wallet-Public-Key header` | Historical SDK gap: `POST /v1/presentation/submit` requires wallet-auth headers (`X-Wallet-Public-Key` / `X-Wallet-Signed-Data`, holder signs their own address) that the SDK didn't send | **Fixed** — `X401Wallet` now accepts an injected `submitAuth` provider and the wallet wires it automatically; nothing to configure. |
|
|
236
|
+
| `MBI /vp/ext/submit did not return vp` | MBI's `includeVp` opt-in (BT-2357) not deployed on the target instance | Confirmed deployed on the sandbox (`mbi-vc.myegdev.com`). If you see this against a different MBI instance, that instance needs the same rollout. |
|
|
237
|
+
|
|
238
|
+
## Security notes
|
|
239
|
+
|
|
240
|
+
- **No plaintext private key ever exists in this process.** All Ed25519 signing routes through
|
|
241
|
+
Wallet BE's HSM (`/wallet/hsm/*`); `walletCfg.privateKey` is always `''`.
|
|
242
|
+
- **`MAX_PAYMENT_AMOUNT` is the real control against unbounded auto-spend** — see Environment
|
|
243
|
+
above. Without it, `pay_and_fetch`/`subscribe_and_issue` will pay whatever a server's `402`
|
|
244
|
+
challenge demands, up to the HSM account's balance. This was raised in code review (finding
|
|
245
|
+
AWL-M01) specifically because an agent-side "confirm before paying" step is not a real security
|
|
246
|
+
boundary: the same prompt injection or bad instruction that drove the call in the first place
|
|
247
|
+
could just as easily drive the confirmation.
|
|
248
|
+
|