agentic-wallet-mcp 0.1.0 → 0.3.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.
Files changed (3) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +147 -67
  3. package/package.json +17 -5
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,31 +3,28 @@
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)
10
- - **VC presentation** (BBS+ VP derivation) → MBI RS (`/v1/vp/ext/create` + `/v1/vp/ext/submit`, `includeVp: true` — BT-2357)
11
+ - **VC presentation** (BBS+ VP derivation) → MBI RS (`/v1/vp/ext/create` + `/v1/vp/ext/submit`, `includeVp: true`)
11
12
  - **issuer key resolution** (for the OID4VP submit body) → the Zetrix ZID resolver (`https://zid-resolver[-sandbox].zetrix.com`)
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
- [`docs/CONTRACT_RECONCILIATION.md`](docs/CONTRACT_RECONCILIATION.md) has the authoritative
18
- endpoint/contract map, [`docs/DEVELOPMENT_CHECKLIST.md`](docs/DEVELOPMENT_CHECKLIST.md) has status,
19
- and [`docs/USAGE_FLOW.md`](docs/USAGE_FLOW.md) has a full end-to-end prompt script (onboarding →
16
+ [`docs/USAGE_FLOW.md`](docs/USAGE_FLOW.md) has a full end-to-end prompt script (onboarding →
20
17
  VC issuance → identity proof → pay-per-use).
21
18
 
22
19
  ## Tools
23
20
 
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: create a new HSM account if `HOLDER_ADDRESS` isn't provisioned yet | `{ password, label?, purpose? }` |
21
+ | Tool | Does | Input | Output (shape) |
22
+ |---|---|---|---|
23
+ | `wallet_status` | Report holder DID/address/network + client-supplied held VCs | `{ heldCredentials? }` | `{ holderDid, zetrixAddress, network, credentials }` |
24
+ | `prove_identity` | Answer an x401 `PROOF-REQUEST` → return the `PROOF-RESPONSE` header to replay | `{ proofRequest, vc, revealAttribute?, issuerKeys? }` | `{ proofResponseHeader, verified, presentationId }` |
25
+ | `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 }` |
26
+ | `subscribe_and_issue` | Build the signed payload → pay x402 → MBI issues → return the VC | `{ templateId, attributes, expirationDate? }` | `{ issued, vcId, vc, txHash }` |
27
+ | `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
28
 
32
29
  > The wallet **never persists VCs** — the client holds them and passes them in (e.g. `vc` on
33
30
  > `prove_identity`, `heldCredentials` on `wallet_status`). All Ed25519 signing goes through
@@ -35,8 +32,14 @@ VC issuance → identity proof → pay-per-use).
35
32
 
36
33
  > `create_holder_account` mints a **brand-new** keypair — Wallet BE's `/account/create` has no
37
34
  > way to provision a pre-chosen address. It returns the new `zetrixAddress`/`holderDid` for you
38
- > to paste into `HOLDER_ADDRESS`/`HOLDER_DID`/`HSM_PASSWORD` yourself; the tool never writes your
39
- > MCP config or restarts the server for you.
35
+ > to paste into `ZETRIX_ADDRESS`/`HSM_PASSWORD` yourself (`HOLDER_DID` is optional see
36
+ > Environment below); the tool never writes your MCP config or restarts the server for you.
37
+
38
+ > `revealAttribute` on `prove_identity` is optional and usually should stay that way. Omitted,
39
+ > it's derived automatically from the challenge's DCQL `credential_requirements` — each claim path
40
+ > is resolved against the presented VC's `credentialSubject` (e.g. a DCQL leaf name `agentName`
41
+ > resolves to the VC's actual nested path `agentIdentityCredential.agentName`). Only pass it
42
+ > explicitly to reveal a narrower or different set of claims than the challenge asked for.
40
43
 
41
44
  > `prove_identity` no longer takes a `bbsPublicKey` input at all. The OID4VP verifier
42
45
  > (`openid4vp-verifier-be`) checks each VC's own issuer-signed proof(s) against the
@@ -45,37 +48,64 @@ VC issuance → identity proof → pay-per-use).
45
48
  > resolves them itself: it reads the VC's `issuer` DID and each `proof[].verificationMethod`,
46
49
  > resolves the issuer's DID document via the Zetrix ZID resolver, and matches the BBS+
47
50
  > (`publicKeyMultibase`) and Ed25519 (`publicKeyHex`) verification methods referenced by the VC's
48
- > own proofs. See `docs/CONTRACT_RECONCILIATION.md §8` for the full trace through the verifier's
49
- > source that led to this.
51
+ > own proofs. `issuerKeys` is still accepted as a manual escape hatch if the resolver is ever
52
+ > unreachable.
53
+
54
+ ## Install
50
55
 
51
- ## Install & build
56
+ Run it directly via `npx` — no install step needed (see "Configuring in Claude Desktop / Claude
57
+ Code" below for wiring it into an MCP client):
52
58
 
53
59
  ```bash
54
- npm install
55
- npm test # 85 tests
56
- npm run build # tsc + esbuild → dist/server-bundle.cjs (the bin)
60
+ npx agentic-wallet-mcp
57
61
  ```
58
62
 
59
- Node 18 (built-in `fetch`). `x401-zetrix-client` is consumed as a normal npm dependency; the
60
- `bin` runs the **esbuild bundle** (`dist/server-bundle.cjs`), which inlines it.
63
+ Or install [`agentic-wallet-mcp`](https://www.npmjs.com/package/agentic-wallet-mcp) directly:
64
+
65
+ ```bash
66
+ npm i agentic-wallet-mcp
67
+ ```
68
+
69
+ Node ≥ 18 required (built-in `fetch`).
61
70
 
62
71
  ## Environment
63
72
 
64
73
  | Variable | Required | Description |
65
74
  |---|---|---|
66
- | `ZETRIX_NETWORK` | yes | `zetrix:testnet` or `zetrix:mainnet` — also selects the default `WALLET_BE_URL`/`MBI_BASE_URL`/`OID4VP_BASE_URL` below |
67
- | `HOLDER_ADDRESS` | yes | Holder Zetrix address (the HSM account) |
68
- | `HOLDER_DID` | yes | Holder DID |
69
- | `HSM_PASSWORD` | no* | HSM password (may instead be supplied per tool-call) |
75
+ | `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 |
76
+ | `HSM_PASSWORD` | yes* | HSM password |
77
+ | `ZETRIX_ADDRESS` | no | Holder Zetrix address (the HSM account). Omit on first run — see "Onboarding" below |
78
+ | `HOLDER_DID` | no | Holder DID. Omit and the MCP derives it automatically — see "Onboarding" below |
70
79
  | `WALLET_BE_URL` | no | Wallet BE base URL override (HSM `/wallet/hsm/sign-blob`) — auto-derived from `ZETRIX_NETWORK` when not set |
71
80
  | `MBI_BASE_URL` | no | MBI RS base URL override (`/v1/vc/pay/apply`) — auto-derived from `ZETRIX_NETWORK` when not set |
72
- | `OID4VP_BASE_URL` | no | OID4VP verifier base URL override — auto-derived from `ZETRIX_NETWORK` by the x401 SDK when not set (BT-2368) |
81
+ | `OID4VP_BASE_URL` | no | OID4VP verifier base URL override — auto-derived from `ZETRIX_NETWORK` by the x401 SDK when not set |
73
82
  | `ZETRIX_NODE_HOST` / `ZETRIX_NODE_PORT` | no | RPC node override (auto-derived from network) |
74
83
  | `ZID_RESOLVER_BASE_URL` | no | ZID resolver override (auto-derived from network: sandbox for testnet, prod for mainnet) |
75
- | `MAX_PAYMENT_AMOUNT` | no** | Per-asset x402 auto-pay cap — JSON `{ "<asset>": "<maxRawUnits>", "*": "<fallback>" }`, e.g. `{"ZTX":"1000000000","*":"0"}`. Unset = no cap enforced. |
84
+ | `MAX_PAYMENT_AMOUNT` | no** | Per-asset x402 auto-pay cap — JSON `{ "<asset>": "<maxRawUnits>", "*": "<fallback>" }`. `pay_and_fetch`/`subscribe_and_issue` are asset-agnostic: the resource server's 402 challenge may quote the native ZETRIX token (asset code `ZTX`) **or** a ZTP20 token (e.g. `JMYR`) — cap whichever assets you expect, e.g. `{"ZTX":"1000000000","JMYR":"5000000","*":"0"}`. Unset = no cap enforced. |
76
85
 
77
86
  \* sensitive — never logged.
78
87
 
88
+ ### Onboarding: two ways to set up your holder identity
89
+
90
+ `ZETRIX_ADDRESS` and `HOLDER_DID` are both optional — the MCP resolves your holder identity at
91
+ startup, in one of two ways:
92
+
93
+ 1. **First-time user — only `HSM_PASSWORD` set.** The MCP creates a brand-new HSM account on
94
+ Wallet BE (`POST /wallet/hsm/account/create`) and derives the DID from the returned public
95
+ key. It logs the new `ZETRIX_ADDRESS` (and `HOLDER_DID`) to stderr on startup — copy it into
96
+ your MCP config for next time, since nothing is persisted to disk between runs (env vars only
97
+ load once, at process start).
98
+ 2. **Existing user — `ZETRIX_ADDRESS` + `HSM_PASSWORD` set, `HOLDER_DID` optional.** The MCP
99
+ always self-signs the address via the existing `POST /wallet/hsm/sign-message` call and
100
+ derives the DID from the `publicKey` the response carries — no separate lookup endpoint
101
+ needed. A supplied `HOLDER_DID` is never trusted blindly: it's compared against this derived
102
+ value, and if they don't match, the derived (correct) one wins — the mismatch is logged to
103
+ stderr so you know to fix your config. Omit `HOLDER_DID` entirely and the derived value is
104
+ just used directly.
105
+
106
+ Either way, `wallet_status` always reports the resolved `zetrixAddress`/`holderDid` for the
107
+ running session, so you can confirm what the MCP resolved to at any time.
108
+
79
109
  \*\* **strongly recommended before pointing this wallet at mainnet/real funds.** `pay_and_fetch`
80
110
  and `subscribe_and_issue` auto-pay whatever `maxAmountRequired` a remote server's 402 challenge
81
111
  demands, with no built-in ceiling — a prompt-injected or misled agent calling either tool against
@@ -84,21 +114,24 @@ balance. `MAX_PAYMENT_AMOUNT` is a hard, code-enforced cap that holds regardless
84
114
  calling agent decides. Once set, it becomes an allowlist: an asset with no entry and no `"*"`
85
115
  fallback is **denied**, not passed through uncapped.
86
116
 
87
- You don't need to look up or fill in `WALLET_BE_URL`/`MBI_BASE_URL`/`OID4VP_BASE_URL` yourself —
88
- just pick `zetrix:testnet` or `zetrix:mainnet` for `ZETRIX_NETWORK` and the MCP (and the x401 SDK
89
- it wires up) uses the built-in default for that network:
117
+ You don't need to look up or fill in `WALLET_BE_URL`/`MBI_BASE_URL`/`OID4VP_BASE_URL`/
118
+ `ZID_RESOLVER_BASE_URL` yourself — just pick `zetrix:testnet` or `zetrix:mainnet` for
119
+ `ZETRIX_NETWORK` and the MCP (and the x401 SDK it wires up) uses the built-in default for that
120
+ network:
90
121
 
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` |
122
+ | Network | `WALLET_BE_URL` default | `MBI_BASE_URL` default | `OID4VP_BASE_URL` default | `ZID_RESOLVER_BASE_URL` default |
123
+ |---|---|---|---|---|
124
+ | `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` |
125
+ | `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
126
 
96
- Only set `WALLET_BE_URL`/`MBI_BASE_URL`/`OID4VP_BASE_URL` explicitly if you run your own instance
97
- of that service instead of the default one — an explicit value always wins over the network
98
- default.
127
+ Only set any of the four explicitly if you run your own instance of that service instead of the
128
+ default one — an explicit value always wins over the network default. The `*.myegdev.com`
129
+ (testnet) hosts are public endpoints — no VPN needed; if you're on a corporate VPN and one of
130
+ them times out, disconnecting it is more likely to fix that than connecting it. See "Network
131
+ reachability & troubleshooting" below.
99
132
 
100
133
  That's the complete list — no VC-MCP subprocess, no BaaS gateway key, no manually-configured
101
- BBS+ key to set up (BT-2357 replaced that whole path — see `docs/CONTRACT_RECONCILIATION.md §8`).
134
+ BBS+ key to set up.
102
135
 
103
136
  ## Configuring in Claude Desktop / Claude Code
104
137
 
@@ -116,24 +149,32 @@ the `<...>` placeholders (don't commit a filled copy; `mcp.local.json` is gitign
116
149
  {
117
150
  "mcpServers": {
118
151
  "agentic-wallet": {
119
- "command": "node",
120
- "args": ["/absolute/path/to/zetrix-agentic-wallet/dist/server-bundle.cjs"],
152
+ "command": "npx",
153
+ "args": ["-y", "agentic-wallet-mcp"],
121
154
  "env": {
122
155
  "ZETRIX_NETWORK": "zetrix:testnet",
123
- "HOLDER_ADDRESS": "ZTX3...",
124
- "HOLDER_DID": "did:zid:...",
125
- "HSM_PASSWORD": "your-hsm-password"
156
+ "HSM_PASSWORD": "your-hsm-password",
157
+ "ZETRIX_ADDRESS": "ZTX3...",
158
+ "HOLDER_DID": "did:zid:..."
126
159
  }
127
160
  }
128
161
  }
129
162
  }
130
163
  ```
131
164
 
165
+ > First run, no account yet? Omit `ZETRIX_ADDRESS` (and `HOLDER_DID`) entirely — the MCP creates
166
+ > one for you at startup and logs it to stderr; copy it back into `env` for next time. See
167
+ > "Onboarding" under Environment above.
168
+
169
+ > Working on this repo locally instead of the published package? Point `command`/`args` at the
170
+ > local build directly: `"command": "node"`, `"args": ["/absolute/path/to/zetrix-agentic-wallet/dist/server-bundle.cjs"]`.
171
+
132
172
  > Prefer environment/secret managers over inline secrets for `HSM_PASSWORD` in production.
133
173
  >
134
- > Only add `WALLET_BE_URL` / `MBI_BASE_URL` / `OID4VP_BASE_URL` to the `env` block if you run your
135
- > own instance of that service — otherwise leave them out and the MCP (and the x401 SDK) use the
136
- > default for whichever `ZETRIX_NETWORK` you picked (see the table above).
174
+ > Only add `WALLET_BE_URL` / `MBI_BASE_URL` / `OID4VP_BASE_URL` / `ZID_RESOLVER_BASE_URL` to the
175
+ > `env` block if you run your own instance of that service — otherwise leave them out and the MCP
176
+ > (and the x401 SDK) use the default for whichever `ZETRIX_NETWORK` you picked (see the table
177
+ > above).
137
178
 
138
179
  ## Example prompts
139
180
 
@@ -145,21 +186,60 @@ the `<...>` placeholders (don't commit a filled copy; `mcp.local.json` is gitign
145
186
 
146
187
  For the full ordered script (onboarding → check → issue → prove → pay), see [`docs/USAGE_FLOW.md`](docs/USAGE_FLOW.md).
147
188
 
148
- ## Status
149
-
150
- Milestone 2 (WBS 4.1–4.5) is code-complete **and live-verified end-to-end against the real
151
- sandbox** — not just unit-tested. `subscribe_and_issue` issued a real VC and settled a real
152
- payment; `prove_identity` got a real OID4VP verifier to return `VERIFIED`; `pay_and_fetch`
153
- completed a real x402 payment against `ms-zetrix` (via `ms-public-proxy`) and got real chain data
154
- back. This closed out the remaining G-checks from `docs/CONTRACT_RECONCILIATION.md §7`: the
155
- OID4VP `ResponseWrapper`/wallet-auth submit contract (G6), the MBI `data` hex form (G3), and the
156
- DCQL→`revealAttribute` mapping (G4, now VC-aware resolves DCQL claim paths against the
157
- presented VC's actual nested structure). See
158
- [`docs/INTEGRATION_GUIDE.md`](docs/INTEGRATION_GUIDE.md)its "Live verification record" section
159
- has the exact evidence (VC ids, tx hashes, presentation ids), and its "Network reachability &
160
- troubleshooting" section covers every real-infra error hit along the way and its fix.
161
-
162
- One known item remains open, tracked as a follow-up (not a blocker): `verifiedClaims` came back
163
- empty on a `VERIFIED` proof (likely a verifier echo behavior, not a wallet bug). Also unconfirmed:
164
- Wallet BE's `/account/create` `publicKeyHex` format (raw vs Zetrix `b001…`-encoded
165
- `deriveHolderDid` handles both, but only one is real).
189
+ ## End-to-end usage flow
190
+
191
+ Full narrative version with example prompts: [`docs/USAGE_FLOW.md`](docs/USAGE_FLOW.md).
192
+
193
+ **Step 0 — onboarding (once).** Only if `ZETRIX_ADDRESS` isn't set yet: the MCP creates an HSM
194
+ account automatically at startup from `HSM_PASSWORD` alone (see "Onboarding" under Environment
195
+ above) copy the logged `zetrixAddress` into your MCP config for next time. Alternatively, call
196
+ `create_holder_account { password }` manually and paste the returned `zetrixAddress` in yourself;
197
+ either way, restart the server afterward (env vars load once, at process start).
198
+
199
+ **Phase 1 — `wallet_status` — pre-check.** Pass any VCs the caller already holds via
200
+ `heldCredentials`; the response tells you whether the agent-identity credential you need is
201
+ already there. Skip to Phase 3 if so.
202
+
203
+ **Phase 2 `subscribe_and_issue` VC issuance.**
204
+ `{ templateId, attributes }` holder-signs the payload via Wallet BE MBI's x402 `402`
205
+ self-pay MBI settles **and** issues the VC in one call. **Hold onto the returned `vc`** it's
206
+ what you pass into every future `prove_identity` call.
207
+
208
+ **Phase 3 — `prove_identity` — x401 identity proof.**
209
+ `{ proofRequest, vc }` (omit `revealAttribute`/`issuerKeys` — both now resolve automatically).
210
+ Internally: fetch the OID4VP presentation definition → derive the BBS+ selective-disclosure VP
211
+ via MBI (`/vp/ext/create` + `/vp/ext/submit`, `includeVp: true`) → resolve the issuer's
212
+ verification keys via the ZID resolver → submit to the verifier with wallet-auth headers →
213
+ package the signed result as a `PROOF-RESPONSE`. Replaying that header back to the original
214
+ resource server happens outside this MCP, in whatever drove the conversation. See "The
215
+ `PROOF-REQUEST` header" section in [`docs/USAGE_FLOW.md`](docs/USAGE_FLOW.md) for the exact wire
216
+ structure and field semantics.
217
+
218
+ **Phase 4 — `pay_and_fetch` — pay-per-use.**
219
+ `{ url, method?, headers?, body? }` → fetch → on `402`, self-pay → retry with `X-PAYMENT`.
220
+ Independent of Phases 2/3 — no VC or identity proof involved, just a fresh payment per call.
221
+
222
+ ## Network reachability & troubleshooting
223
+
224
+ The `*.myegdev.com` testnet endpoints are public — no VPN needed to reach them. One dependency
225
+ sits behind a CDN edge (see the ZID resolver row below). When something that worked before
226
+ suddenly times out or 403s, check this table before assuming a code regression.
227
+
228
+ | Symptom | Cause | Fix / status |
229
+ |---|---|---|
230
+ | `Wallet BE /wallet/hsm/sign-blob request failed <- fetch failed <- UND_ERR_CONNECT_TIMEOUT` (or same for `mbi-vc.myegdev.com`) | Transient network issue, or (if you're on a corporate VPN) the VPN routing away from the public internet | If you're on a VPN, try disconnecting it and retrying. Verify reachability directly: `curl -I https://wallet-api.myegdev.com/server` |
231
+ | `VP derivation failed <- ZID resolver HTTP 403 ... cf-mitigated: challenge` | ZID resolver (`zid-resolver-sandbox.zetrix.com`) sitting behind a Cloudflare **managed challenge** that blocks plain server-to-server `fetch` | Server-to-server access to the resolver must be allowlisted so it returns `200` directly. If the challenge is active, `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. |
232
+ | `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`. |
233
+ | `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. |
234
+ | `MBI /vp/ext/submit did not return vp` | MBI's `includeVp` opt-in not deployed on the target instance | Deployed on the sandbox (`mbi-vc.myegdev.com`). If you see this against a different MBI instance, that instance needs the same rollout. |
235
+
236
+ ## Security notes
237
+
238
+ - **No plaintext private key ever exists in this process.** All Ed25519 signing routes through
239
+ Wallet BE's HSM (`/wallet/hsm/*`); `walletCfg.privateKey` is always `''`.
240
+ - **`MAX_PAYMENT_AMOUNT` is the real control against unbounded auto-spend** — see Environment
241
+ above. Without it, `pay_and_fetch`/`subscribe_and_issue` will pay whatever a server's `402`
242
+ challenge demands, up to the HSM account's balance. An agent-side "confirm before paying" step
243
+ is not a real security boundary: the same prompt injection or bad instruction that drove the
244
+ call in the first place could just as easily drive the confirmation.
245
+
package/package.json CHANGED
@@ -1,8 +1,18 @@
1
1
  {
2
2
  "name": "agentic-wallet-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Agent-facing MCP wallet for Zetrix — orchestrates x401 identity proof, x402 payment, and MBI VC issuance",
5
+ "keywords": ["mcp", "model-context-protocol", "zetrix", "wallet", "x401", "x402", "blockchain"],
5
6
  "license": "MIT",
7
+ "author": "MyEG Services Berhad",
8
+ "homepage": "https://github.com/Zetrix-Chain/zetrix-agentic-wallet",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/Zetrix-Chain/zetrix-agentic-wallet.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/Zetrix-Chain/zetrix-agentic-wallet/issues"
15
+ },
6
16
  "type": "module",
7
17
  "engines": {
8
18
  "node": ">=18"
@@ -11,11 +21,12 @@
11
21
  "agentic-wallet-mcp": "dist/server-bundle.cjs"
12
22
  },
13
23
  "files": [
14
- "dist",
15
- "README.md"
24
+ "dist/server-bundle.cjs",
25
+ "README.md",
26
+ "LICENSE"
16
27
  ],
17
28
  "scripts": {
18
- "build": "tsc && esbuild src/index.ts --bundle --platform=node --target=node18 --format=cjs --external:zetrix-sdk-nodejs --outfile=dist/server-bundle.cjs",
29
+ "build": "tsc --noEmit && esbuild src/index.ts --bundle --platform=node --target=node18 --format=cjs --external:zetrix-sdk-nodejs --outfile=dist/server-bundle.cjs",
19
30
  "test": "vitest run",
20
31
  "test:watch": "vitest",
21
32
  "typecheck": "tsc --noEmit"
@@ -23,7 +34,8 @@
23
34
  "dependencies": {
24
35
  "@modelcontextprotocol/sdk": "^1.0.0",
25
36
  "x401-zetrix-client": "^0.2.1",
26
- "x402-zetrix-client": "^0.2.2"
37
+ "x402-zetrix-client": "^0.2.2",
38
+ "zetrix-sdk-nodejs": "^1.0.3"
27
39
  },
28
40
  "devDependencies": {
29
41
  "@types/node": "^20.0.0",