agentic-wallet-mcp 0.4.2 → 0.6.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/CHANGELOG.md +138 -0
- package/README.md +88 -6
- package/dist/server-bundle.cjs +789 -56
- package/package.json +11 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `agentic-wallet-mcp` are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
> Entries for 0.5.0 and earlier were reconstructed from commit history when this file was
|
|
9
|
+
> introduced in 0.6.0, so they summarise each release rather than being exhaustive.
|
|
10
|
+
|
|
11
|
+
## [0.6.0] — 2026-07-28
|
|
12
|
+
|
|
13
|
+
This release is about the wallet never misstating what a call cost. Four reporting defects were
|
|
14
|
+
found during live use, in each case the wallet told the caller something untrue about money.
|
|
15
|
+
|
|
16
|
+
### Changed — BREAKING
|
|
17
|
+
|
|
18
|
+
- **`amountPaid` is now `undefined` on a cache hit.** Previously a cache hit replayed the original
|
|
19
|
+
issuance's `txHash`/`paidAsset`/`amountPaid` at the top level, so a **free** call was
|
|
20
|
+
indistinguishable from a fresh charge and anything summing `amountPaid` across calls
|
|
21
|
+
double-counted. Those values now appear under `originalPayment: { txHash, asset, amount }`
|
|
22
|
+
instead, and are omitted entirely when the cached credential was issued free. Any consumer
|
|
23
|
+
reading top-level `amountPaid` to track spend needs updating.
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- **`get_template_schema` tool** — a free read of a credential template's declared attribute
|
|
28
|
+
schema (`{ required, optional }`), taking a `did:zid:...` id or a known template name. No
|
|
29
|
+
payment, no signing, no issuer call. Previously the only way to ask what a template required was
|
|
30
|
+
`subscribe_and_issue` with `dryRun` — a tool whose name reads as "this charges money" — so an
|
|
31
|
+
agent had no obvious reason to reach for it and would discover a newly-required attribute by
|
|
32
|
+
failing an issuance first. A template that cannot be read returns `{ error }` rather than an
|
|
33
|
+
empty schema, so "needs nothing" is never confused with "could not look it up".
|
|
34
|
+
- **`staleAttributes` on a cache hit** — `{ missing, dropped }` when a held credential no longer
|
|
35
|
+
matches the template it came from. Validity checks only ever asked whether a credential had
|
|
36
|
+
expired, never whether its fields still fit the template, so an issuer changing a template left
|
|
37
|
+
holders with a credential that looked valid and wasn't. The cached credential is still returned;
|
|
38
|
+
this reports, it does not re-issue or charge.
|
|
39
|
+
- **`decimals` on `wallet_status({ token })`** — the raw base-unit balance stays canonical (it is
|
|
40
|
+
the unit x402 quotes `maxAmountRequired` in, so cap checks and comparisons remain integer-only),
|
|
41
|
+
but callers no longer need a second contract call to know whether `"473999900"` means 474 or
|
|
42
|
+
474 million.
|
|
43
|
+
- **`paymentAttempted: { asset, amount, paymentId }`** on any failure occurring after the x402
|
|
44
|
+
payment has settled on chain. The issuer's error body carries neither the amount nor a
|
|
45
|
+
transaction reference, so such a debit was previously invisible in the response and discoverable
|
|
46
|
+
only by comparing `balanceOf` before and after. `paymentId` is the handle the issuer's idempotent
|
|
47
|
+
recovery endpoint takes.
|
|
48
|
+
- **Indeterminate-settlement recovery.** The issuer distinguishes a definitive facilitator
|
|
49
|
+
rejection from an outcome that is *unknown* — where the payment may well have landed and the
|
|
50
|
+
record is deliberately left recoverable. On the indeterminate code the wallet now polls the
|
|
51
|
+
issuer's status endpoint (bounded) and reports `recovery: { status, txHash?, vcId?, polls }`,
|
|
52
|
+
rather than discarding a credential already paid for. `status: "ISSUED"` means it exists after
|
|
53
|
+
all; note the status endpoint returns only its id, not the credential body.
|
|
54
|
+
- **`MbiError.mbiStatus`** — the issuer's own numeric status code, parsed from the error body.
|
|
55
|
+
Previously only the HTTP status and an opaque message string were available, so the two
|
|
56
|
+
post-payment failures could be told apart only by substring-matching or by trusting an HTTP 502
|
|
57
|
+
that any gateway can emit.
|
|
58
|
+
- **Explicit HTTP deadline** on the issuer client (90s, overridable), above the issuer's own 60s
|
|
59
|
+
facilitator timeout. Previously the runtime default applied, which happened to be longer but was
|
|
60
|
+
not a deliberate choice — a deadline at or below the issuer's would abort a settlement still
|
|
61
|
+
legitimately in progress.
|
|
62
|
+
|
|
63
|
+
### Fixed
|
|
64
|
+
|
|
65
|
+
- **Failed balance lookups no longer report a fabricated zero.** Any failure — non-zero
|
|
66
|
+
`errorCode`, missing field, malformed payload — previously collapsed to `{ balance: '0' }`,
|
|
67
|
+
making an unreachable node indistinguishable from an empty wallet. Worse, because the
|
|
68
|
+
underlying helpers returned *normally*, a caller's `try`/`catch` never fired. Now surfaced as
|
|
69
|
+
`{ error: 'query_failed' }`. Both the ZTP20 and the native ZTX path had the same defect; both
|
|
70
|
+
are fixed.
|
|
71
|
+
- `originalPayment` is omitted for a cached credential that was issued free, rather than reported
|
|
72
|
+
as `{ asset: 'none', amount: '0' }` — matching the documented behaviour.
|
|
73
|
+
|
|
74
|
+
### Documentation
|
|
75
|
+
|
|
76
|
+
- `query_contract` documented for the first time. It shipped in 0.5.0 but was never added to the
|
|
77
|
+
tool list. The documentation now also states plainly that it is a pass-through with no ABI or
|
|
78
|
+
method list — the contract decides what it understands, and an unknown method returns the same
|
|
79
|
+
shape as a typo.
|
|
80
|
+
- The `subscribe_and_issue` description previously claimed `schema` is returned on *every*
|
|
81
|
+
response; the cache path returns before the chain lookup, so it never did. Corrected, and the
|
|
82
|
+
cache path now performs the lookup so the claim holds.
|
|
83
|
+
|
|
84
|
+
## [0.5.0] — 2026-07-27
|
|
85
|
+
|
|
86
|
+
### Added
|
|
87
|
+
|
|
88
|
+
- Wallet BE account-activation checking: `activated`/`activationTxHash` fields,
|
|
89
|
+
`checkActivationStatus`, a bounded `waitForActivation` polling helper, and polling wired into
|
|
90
|
+
both first-run account creation and `create_holder_account`.
|
|
91
|
+
- x402 payment readiness — `pay_and_fetch` and `subscribe_and_issue` surface an insufficient-funds
|
|
92
|
+
shortfall as a structured result instead of throwing.
|
|
93
|
+
- Per-network JMYR token registry (`resolveTokenAddress`) and token-balance lookup on
|
|
94
|
+
`wallet_status`.
|
|
95
|
+
- `query_contract` — general-purpose read-only contract/account query, exposed as an agent tool.
|
|
96
|
+
- Template attribute validation and derivation, with the full declared schema surfaced.
|
|
97
|
+
|
|
98
|
+
### Fixed
|
|
99
|
+
|
|
100
|
+
- A `resolveHolder` polling failure degrades instead of crashing startup.
|
|
101
|
+
- The `hsmPassword` is persisted alongside address/DID on account override, not dropped.
|
|
102
|
+
|
|
103
|
+
## [0.4.0] — 2026-07-24
|
|
104
|
+
|
|
105
|
+
### Added
|
|
106
|
+
|
|
107
|
+
- Local cache of issued credentials, keyed by template, so `subscribe_and_issue` does not pay and
|
|
108
|
+
re-issue for a credential already held.
|
|
109
|
+
- Named-template alias resolution (e.g. `"AI Birthcert"`), and an `agentDid` auto-fill gated on the
|
|
110
|
+
template's declared schema.
|
|
111
|
+
|
|
112
|
+
### Fixed
|
|
113
|
+
|
|
114
|
+
- `revealAttributes` ordering to match the credential's signed field order, which was breaking BBS+
|
|
115
|
+
presentation verification.
|
|
116
|
+
- Free-template synchronous issuance handled in the issuer's phase 1.
|
|
117
|
+
|
|
118
|
+
## [0.3.0] — 0.3.1
|
|
119
|
+
|
|
120
|
+
### Added
|
|
121
|
+
|
|
122
|
+
- Live x401 proof integration: OID4VP submit authentication, DCQL reveal mapping, and an issuer-key
|
|
123
|
+
override for when the resolver is unreachable.
|
|
124
|
+
- Integration guide, presentation-submission fix, and the switch to the published
|
|
125
|
+
`x401-zetrix-client` package.
|
|
126
|
+
|
|
127
|
+
## [0.2.0]
|
|
128
|
+
|
|
129
|
+
### Added
|
|
130
|
+
|
|
131
|
+
- Optional `ZETRIX_ADDRESS`/`HOLDER_DID` onboarding, with `HSM_PASSWORD` guaranteed present.
|
|
132
|
+
- x402 asset symbol resolved from a ZTP20 contract's `contractInfo`.
|
|
133
|
+
|
|
134
|
+
## [0.1.0]
|
|
135
|
+
|
|
136
|
+
Initial release — the five agent-facing tools (`wallet_status`, `prove_identity`, `pay_and_fetch`,
|
|
137
|
+
`subscribe_and_issue`, `create_holder_account`) over x401, x402, and issuer-side credential
|
|
138
|
+
issuance, with all signing through Wallet BE's HSM.
|
package/README.md
CHANGED
|
@@ -13,18 +13,20 @@ through Wallet BE's HSM.
|
|
|
13
13
|
- **holder key custody + signing** → Wallet BE softHSM (`/wallet/hsm/*`)
|
|
14
14
|
- **VC issuance** → MBI RS (`/v1/vc/pay/*`)
|
|
15
15
|
|
|
16
|
-
[`docs/USAGE_FLOW.md`](docs/USAGE_FLOW.md) has a full end-to-end prompt script (onboarding →
|
|
16
|
+
[`docs/USAGE_FLOW.md`](https://github.com/Zetrix-Chain/zetrix-agentic-wallet/blob/main/docs/USAGE_FLOW.md) has a full end-to-end prompt script (onboarding →
|
|
17
17
|
VC issuance → identity proof → pay-per-use).
|
|
18
18
|
|
|
19
19
|
## Tools
|
|
20
20
|
|
|
21
21
|
| Tool | Does | Input | Output (shape) |
|
|
22
22
|
|---|---|---|---|
|
|
23
|
-
| `wallet_status` | Report holder DID/address/network + held VCs (client-supplied, or the local cache) | `{ heldCredentials? }` | `{ holderDid, zetrixAddress, network, credentials }` |
|
|
23
|
+
| `wallet_status` | Report holder DID/address/network + held VCs (client-supplied, or the local cache); optionally a token balance | `{ heldCredentials?, token? }` | `{ holderDid, zetrixAddress, network, credentials, tokenBalance? }` |
|
|
24
24
|
| `prove_identity` | Answer an x401 `PROOF-REQUEST` → return the `PROOF-RESPONSE` header to replay | `{ proofRequest, vc?, revealAttribute?, issuerKeys? }` | `{ proofResponseHeader, verified, presentationId }` |
|
|
25
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` | Reuse a cached VC if still valid, else pay x402 → MBI issues → return the VC | `{ templateId, attributes, expirationDate?, dryRun?, forceReissue? }` | `{ issued, vcId, vc, txHash, fromCache? }` |
|
|
26
|
+
| `subscribe_and_issue` | Reuse a cached VC if still valid, else pay x402 → MBI issues → return the VC | `{ templateId, attributes, expirationDate?, dryRun?, forceReissue? }` | `{ issued, vcId, vc, txHash, fromCache?, schema?, originalPayment?, paymentAttempted?, recovery? }` |
|
|
27
27
|
| `create_holder_account` | Onboarding: mint an HSM account (the MCP already auto-creates one at startup if `ZETRIX_ADDRESS` is omitted — see Environment below). Always checks for an existing account first — if one is active for this session, returns `{ alreadyExists: true, existing }` without creating anything; pass `confirmNew: true` (after asking the user) to mint a new one anyway | `{ password, label?, purpose?, confirmNew? }` | `{ created, alreadyExists, existing?, zetrixAddress?, holderDid?, publicKeyHex?, message }` |
|
|
28
|
+
| `get_template_schema` | **Free** read of a VC template's declared attribute schema. Call before `subscribe_and_issue` to learn which attributes it requires | `{ templateId }` | `{ templateId, schema: { required, optional } }` or `{ templateId, error }` |
|
|
29
|
+
| `query_contract` | Read-only query against any Zetrix contract — call an arbitrary method and return its raw result. No signing, no state change | `{ contractAddress, method, params? }` | `{ ok: true, result }` or `{ ok: false, error }` |
|
|
28
30
|
|
|
29
31
|
> **VCs are cached locally**, keyed by `templateId`, under `~/.agentic-wallet-mcp/vc-cache/`
|
|
30
32
|
> (scoped per network + holder — different identities or networks never share a cache).
|
|
@@ -38,6 +40,40 @@ VC issuance → identity proof → pay-per-use).
|
|
|
38
40
|
> back to the `expirationDate` requested at issuance; a VC with neither is cached indefinitely.
|
|
39
41
|
> All Ed25519 signing still goes through Wallet BE HSM; no plaintext private keys.
|
|
40
42
|
|
|
43
|
+
> `subscribe_and_issue` also returns `schema: { required, optional }` — the template's full
|
|
44
|
+
> declared attribute list, read from chain — on every outcome that reaches the chain (issued,
|
|
45
|
+
> dry-run quote, or a missing-attribute error), so you always see the complete field list rather
|
|
46
|
+
> than only what went wrong — **including on a cache hit**, so a caller holding a credential can
|
|
47
|
+
> still see what the template currently asks for.
|
|
48
|
+
> Attributes the wallet auto-fills for you (e.g. `agentDid`, or a template-declared derived
|
|
49
|
+
> key like the `AI Birthcert` template's `id` ← `agentUsername`) are omitted from `schema` since
|
|
50
|
+
> you never need to supply them. Some templates also declare format validators for optional
|
|
51
|
+
> attributes (e.g. `AI Birthcert`'s `dob` must be `YYYY-MM-DD`, `countryOfOrigin` must be a valid
|
|
52
|
+
> ISO 3166 code or name) — an invalid value is rejected locally before any payment or MBI call.
|
|
53
|
+
|
|
54
|
+
> **A held credential can go stale without expiring.** `isVcValid` only asks whether a VC is past
|
|
55
|
+
> its `validUntil` — a VC whose *fields* no longer match the template it came from still reads as
|
|
56
|
+
> valid. When an issuer changes a template (adds a required attribute, drops one), a cache hit now
|
|
57
|
+
> reports the delta:
|
|
58
|
+
>
|
|
59
|
+
> ```jsonc
|
|
60
|
+
> { "fromCache": true, "staleAttributes": { "missing": ["agentUsername"], "dropped": ["agentName"] } }
|
|
61
|
+
> ```
|
|
62
|
+
>
|
|
63
|
+
> `missing` is what a reissue would need you to supply; `dropped` is what the held VC carries that
|
|
64
|
+
> the template no longer declares. Absent when the held VC still satisfies the template. **The
|
|
65
|
+
> cached VC is still returned** — this reports, it does not re-issue or charge. Reported from live
|
|
66
|
+
> testing: without it, an agent reusing the attributes from a previously-issued credential only
|
|
67
|
+
> discovered a newly-required field by attempting an issuance and being rejected.
|
|
68
|
+
|
|
69
|
+
> **`get_template_schema` is the free way to ask what a template needs**, and is what an agent
|
|
70
|
+
> should reach for before building an issuance request. It takes a `did:zid:...` id *or* a known
|
|
71
|
+
> template name (e.g. `"AI Birthcert"`), performs no payment/signing/MBI call, and hides the
|
|
72
|
+
> attributes the wallet fills in itself. A template it cannot read returns `{ error }` rather than
|
|
73
|
+
> an empty schema, so *"needs nothing"* is never confused with *"couldn't look it up"*.
|
|
74
|
+
> (`subscribe_and_issue` with `dryRun: true` also returns the schema, alongside the price — use
|
|
75
|
+
> that when you want both.)
|
|
76
|
+
|
|
41
77
|
> `create_holder_account` mints a **brand-new** keypair — Wallet BE's `/account/create` has no
|
|
42
78
|
> way to provision a pre-chosen address. It always checks first whether an account is already
|
|
43
79
|
> active for this session; if so, it returns `{ alreadyExists: true, existing }` and creates
|
|
@@ -49,6 +85,49 @@ VC issuance → identity proof → pay-per-use).
|
|
|
49
85
|
> in your MCP config always overrides the saved account (see Environment below); the tool never
|
|
50
86
|
> writes the MCP host's own config file or restarts the server for you.
|
|
51
87
|
|
|
88
|
+
> **What a call cost is reported precisely.** `paidAsset`/`amountPaid` are set **only when this
|
|
89
|
+
> call paid**. A cache hit reports the earlier charge under `originalPayment: { txHash, asset,
|
|
90
|
+
> amount }` — never as `amountPaid` — so summing spend across calls cannot double-count a free
|
|
91
|
+
> hit (omitted entirely when the cached VC was issued free). If issuance fails **after** the x402
|
|
92
|
+
> payment has already settled on chain (MBI phase 2), the response carries
|
|
93
|
+
> `paymentAttempted: { asset, amount, paymentId }`. MBI's own error body reports none of these, so
|
|
94
|
+
> this is the only in-band signal that you were charged — and `paymentId` is the handle MBI's
|
|
95
|
+
> recovery endpoint takes. It is never set for a phase-1 failure, which happens before anything is
|
|
96
|
+
> paid. **Never retry a post-payment failure: the funds may already be gone, and each attempt costs
|
|
97
|
+
> the full amount again — look the `paymentId` up instead.**
|
|
98
|
+
|
|
99
|
+
> **Two post-payment failures exist and they mean different things:**
|
|
100
|
+
> `4006` is a *definitive* facilitator rejection, while `4012` (HTTP 502) means the settle outcome
|
|
101
|
+
> is **indeterminate** — MBI stopped listening but the payment may well have landed, so it
|
|
102
|
+
> deliberately leaves the record recoverable rather than marking it failed. On `4012` the wallet
|
|
103
|
+
> polls `GET /v1/vc/pay/status/{paymentId}` for you and reports
|
|
104
|
+
> `recovery: { status, txHash?, vcId?, polls }`:
|
|
105
|
+
>
|
|
106
|
+
> | `recovery.status` | Means |
|
|
107
|
+
> |---|---|
|
|
108
|
+
> | `ISSUED` | The payment landed and the credential exists after all. `/status` returns only its `vcId`, **not** the VC body — so `vc` stays unset and you fetch it separately. |
|
|
109
|
+
> | `FAILED` | MBI's terminal verdict on the payment. |
|
|
110
|
+
> | `REQUIRED` / `SETTLED` | Still unresolved when the poll budget ran out — check again later with the `paymentId`. |
|
|
111
|
+
> | `UNKNOWN` | `/status` itself was unreachable. The charge still stands; retry the lookup, not the payment. |
|
|
112
|
+
|
|
113
|
+
> `wallet_status({ token })` returns `tokenBalance: { token, balance, decimals }` for `ZTX` or any
|
|
114
|
+
> registered ZTP20 symbol (e.g. `JMYR`). `balance` is in the asset's **raw base units** — the same
|
|
115
|
+
> unit x402 quotes `maxAmountRequired` in, so cap checks and quote comparisons stay integer-only.
|
|
116
|
+
> Divide by `10^decimals` to display it: `"473999900"` with `decimals: 6` is `473.9999 JMYR`.
|
|
117
|
+
> `decimals` is `null` if the token's `contractInfo` can't be read (the balance is still returned).
|
|
118
|
+
> A failed lookup reports `{ token, error: "query_failed" }` and an unregistered symbol
|
|
119
|
+
> `{ token, error: "unknown_token" }` — **never a zero balance**, so "0" always means you really
|
|
120
|
+
> hold nothing rather than that the node was unreachable.
|
|
121
|
+
|
|
122
|
+
> `query_contract` is a **pass-through**: whatever you put in `method` is sent to the contract
|
|
123
|
+
> as-is. It performs no validation and holds no ABI or method list — the contract decides what it
|
|
124
|
+
> understands, and an unknown method comes back as `{ ok: false, error: "query_contract: no result
|
|
125
|
+
> value returned" }`, the same shape as a typo. To discover what a token supports, start with
|
|
126
|
+
> `contractInfo` (returns `symbol`, `decimals`, `protocol`, `supply`, …); a `protocol: "ztp20"`
|
|
127
|
+
> contract implements at least `balanceOf({ address })`, `totalSupply()` and
|
|
128
|
+
> `allowance({ owner, spender })`. Read-only only (`optType: 2`) — state-changing methods like
|
|
129
|
+
> `transfer`/`approve` need signing and are not reachable through this tool.
|
|
130
|
+
|
|
52
131
|
> `revealAttribute` on `prove_identity` is optional and usually should stay that way. Omitted,
|
|
53
132
|
> it's derived automatically from the challenge's DCQL `credential_requirements` — each claim path
|
|
54
133
|
> is resolved against the presented VC's `credentialSubject` (e.g. a DCQL leaf name `agentName`
|
|
@@ -196,16 +275,19 @@ the `<...>` placeholders (don't commit a filled copy; `mcp.local.json` is gitign
|
|
|
196
275
|
## Example prompts
|
|
197
276
|
|
|
198
277
|
- *"Check my wallet status."* → `wallet_status`
|
|
278
|
+
- *"What's my JMYR balance?"* → `wallet_status({ token: "JMYR" })` (divide `balance` by `10^decimals` to display it)
|
|
199
279
|
- *"I got a 401 with this PROOF-REQUEST header — prove my identity and give me the PROOF-RESPONSE to replay."* → `prove_identity`
|
|
200
280
|
- *"Fetch `https://api.example/data` and pay automatically if it asks."* → `pay_and_fetch`
|
|
281
|
+
- *"What fields does the AI Birthcert template need?"* → `get_template_schema` (free — do this before issuing)
|
|
201
282
|
- *"Apply for the agent-identity credential with these attributes and pay for it."* → `subscribe_and_issue`
|
|
202
283
|
- *"My wallet_status call is failing — I don't have a holder account yet. Set one up."* → `create_holder_account` (asks you for a password; if an account already exists it reports that instead of creating — confirm with the user, then re-call with `confirmNew: true` to replace it)
|
|
284
|
+
- *"What's the total supply of this token contract?"* → `query_contract({ contractAddress, method: "totalSupply" })`
|
|
203
285
|
|
|
204
|
-
For the full ordered script (onboarding → check → issue → prove → pay), see [`docs/USAGE_FLOW.md`](docs/USAGE_FLOW.md).
|
|
286
|
+
For the full ordered script (onboarding → check → issue → prove → pay), see [`docs/USAGE_FLOW.md`](https://github.com/Zetrix-Chain/zetrix-agentic-wallet/blob/main/docs/USAGE_FLOW.md).
|
|
205
287
|
|
|
206
288
|
## End-to-end usage flow
|
|
207
289
|
|
|
208
|
-
Full narrative version with example prompts: [`docs/USAGE_FLOW.md`](docs/USAGE_FLOW.md).
|
|
290
|
+
Full narrative version with example prompts: [`docs/USAGE_FLOW.md`](https://github.com/Zetrix-Chain/zetrix-agentic-wallet/blob/main/docs/USAGE_FLOW.md).
|
|
209
291
|
|
|
210
292
|
**Step 0 — onboarding (once).** Only if `ZETRIX_ADDRESS` isn't set yet: the MCP creates an HSM
|
|
211
293
|
account automatically at startup from `HSM_PASSWORD` alone (see "Onboarding" under Environment
|
|
@@ -232,7 +314,7 @@ via MBI (`/vp/ext/create` + `/vp/ext/submit`, `includeVp: true`) → resolve the
|
|
|
232
314
|
verification keys via the ZID resolver → submit to the verifier with wallet-auth headers →
|
|
233
315
|
package the signed result as a `PROOF-RESPONSE`. Replaying that header back to the original
|
|
234
316
|
resource server happens outside this MCP, in whatever drove the conversation. See "The
|
|
235
|
-
`PROOF-REQUEST` header" section in [`docs/USAGE_FLOW.md`](docs/USAGE_FLOW.md) for the exact wire
|
|
317
|
+
`PROOF-REQUEST` header" section in [`docs/USAGE_FLOW.md`](https://github.com/Zetrix-Chain/zetrix-agentic-wallet/blob/main/docs/USAGE_FLOW.md) for the exact wire
|
|
236
318
|
structure and field semantics.
|
|
237
319
|
|
|
238
320
|
**Phase 4 — `pay_and_fetch` — pay-per-use.**
|