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.
- package/LICENSE +21 -0
- package/README.md +147 -67
- 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`
|
|
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
|
-
|
|
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:
|
|
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 `
|
|
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.
|
|
49
|
-
>
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
60
|
-
|
|
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
|
-
| `
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
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
|
|
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>" }
|
|
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
|
|
88
|
-
just pick `zetrix:testnet` or `zetrix:mainnet` for
|
|
89
|
-
it wires up) uses the built-in default for that
|
|
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
|
|
97
|
-
|
|
98
|
-
|
|
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
|
|
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": "
|
|
120
|
-
"args": ["
|
|
152
|
+
"command": "npx",
|
|
153
|
+
"args": ["-y", "agentic-wallet-mcp"],
|
|
121
154
|
"env": {
|
|
122
155
|
"ZETRIX_NETWORK": "zetrix:testnet",
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
"
|
|
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`
|
|
135
|
-
> own instance of that service — otherwise leave them out and the MCP
|
|
136
|
-
> default for whichever `ZETRIX_NETWORK` you picked (see the table
|
|
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
|
-
##
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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.
|
|
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",
|