agentic-wallet-mcp 0.4.2 → 0.5.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/README.md +10 -1
- package/dist/server-bundle.cjs +613 -47
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ VC issuance → identity proof → pay-per-use).
|
|
|
23
23
|
| `wallet_status` | Report holder DID/address/network + held VCs (client-supplied, or the local cache) | `{ heldCredentials? }` | `{ holderDid, zetrixAddress, network, credentials }` |
|
|
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? }` |
|
|
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
28
|
|
|
29
29
|
> **VCs are cached locally**, keyed by `templateId`, under `~/.agentic-wallet-mcp/vc-cache/`
|
|
@@ -38,6 +38,15 @@ VC issuance → identity proof → pay-per-use).
|
|
|
38
38
|
> back to the `expirationDate` requested at issuance; a VC with neither is cached indefinitely.
|
|
39
39
|
> All Ed25519 signing still goes through Wallet BE HSM; no plaintext private keys.
|
|
40
40
|
|
|
41
|
+
> `subscribe_and_issue` also returns `schema: { required, optional }` — the template's full
|
|
42
|
+
> declared attribute list, read from chain — on every outcome (issued, dry-run quote, or a
|
|
43
|
+
> missing-attribute error), so you always see the complete field list rather than only what went
|
|
44
|
+
> wrong. Attributes the wallet auto-fills for you (e.g. `agentDid`, or a template-declared derived
|
|
45
|
+
> key like the `AI Birthcert` template's `id` ← `agentUsername`) are omitted from `schema` since
|
|
46
|
+
> you never need to supply them. Some templates also declare format validators for optional
|
|
47
|
+
> attributes (e.g. `AI Birthcert`'s `dob` must be `YYYY-MM-DD`, `countryOfOrigin` must be a valid
|
|
48
|
+
> ISO 3166 code or name) — an invalid value is rejected locally before any payment or MBI call.
|
|
49
|
+
|
|
41
50
|
> `create_holder_account` mints a **brand-new** keypair — Wallet BE's `/account/create` has no
|
|
42
51
|
> way to provision a pre-chosen address. It always checks first whether an account is already
|
|
43
52
|
> active for this session; if so, it returns `{ alreadyExists: true, existing }` and creates
|
package/dist/server-bundle.cjs
CHANGED
|
@@ -2233,8 +2233,8 @@ var require_resolve = __commonJS({
|
|
|
2233
2233
|
}
|
|
2234
2234
|
return count;
|
|
2235
2235
|
}
|
|
2236
|
-
function getFullPath(resolver, id = "",
|
|
2237
|
-
if (
|
|
2236
|
+
function getFullPath(resolver, id = "", normalize3) {
|
|
2237
|
+
if (normalize3 !== false)
|
|
2238
2238
|
id = normalizeId(id);
|
|
2239
2239
|
const p = resolver.parse(id);
|
|
2240
2240
|
return _getFullPath(resolver, p);
|
|
@@ -3630,7 +3630,7 @@ var require_fast_uri = __commonJS({
|
|
|
3630
3630
|
"use strict";
|
|
3631
3631
|
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
3632
3632
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
3633
|
-
function
|
|
3633
|
+
function normalize3(uri, options) {
|
|
3634
3634
|
if (typeof uri === "string") {
|
|
3635
3635
|
uri = /** @type {T} */
|
|
3636
3636
|
normalizeString(uri, options);
|
|
@@ -3897,7 +3897,7 @@ var require_fast_uri = __commonJS({
|
|
|
3897
3897
|
}
|
|
3898
3898
|
var fastUri = {
|
|
3899
3899
|
SCHEMES,
|
|
3900
|
-
normalize:
|
|
3900
|
+
normalize: normalize3,
|
|
3901
3901
|
resolve,
|
|
3902
3902
|
resolveComponent,
|
|
3903
3903
|
equal,
|
|
@@ -8541,13 +8541,13 @@ var require_path = __commonJS({
|
|
|
8541
8541
|
return /^(?:\/|\w+:)/.test(path2);
|
|
8542
8542
|
}
|
|
8543
8543
|
);
|
|
8544
|
-
var
|
|
8544
|
+
var normalize3 = (
|
|
8545
8545
|
/**
|
|
8546
8546
|
* Normalizes the specified path.
|
|
8547
8547
|
* @param {string} path Path to normalize
|
|
8548
8548
|
* @returns {string} Normalized path
|
|
8549
8549
|
*/
|
|
8550
|
-
path.normalize = function
|
|
8550
|
+
path.normalize = function normalize4(path2) {
|
|
8551
8551
|
path2 = path2.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
|
|
8552
8552
|
var parts = path2.split("/"), absolute = isAbsolute(path2), prefix = "";
|
|
8553
8553
|
if (absolute)
|
|
@@ -8570,12 +8570,12 @@ var require_path = __commonJS({
|
|
|
8570
8570
|
);
|
|
8571
8571
|
path.resolve = function resolve(originPath, includePath, alreadyNormalized) {
|
|
8572
8572
|
if (!alreadyNormalized)
|
|
8573
|
-
includePath =
|
|
8573
|
+
includePath = normalize3(includePath);
|
|
8574
8574
|
if (isAbsolute(includePath))
|
|
8575
8575
|
return includePath;
|
|
8576
8576
|
if (!alreadyNormalized)
|
|
8577
|
-
originPath =
|
|
8578
|
-
return (originPath = originPath.replace(/(?:\/|^)[^/]+$/, "")).length ?
|
|
8577
|
+
originPath = normalize3(originPath);
|
|
8578
|
+
return (originPath = originPath.replace(/(?:\/|^)[^/]+$/, "")).length ? normalize3(originPath + "/" + includePath) : includePath;
|
|
8579
8579
|
};
|
|
8580
8580
|
}
|
|
8581
8581
|
});
|
|
@@ -12192,7 +12192,7 @@ var require_payment_engine = __commonJS({
|
|
|
12192
12192
|
var blob_decoder_1 = require_blob_decoder();
|
|
12193
12193
|
var prepare_client_1 = require_prepare_client();
|
|
12194
12194
|
var _sdkCtor = require("zetrix-sdk-nodejs");
|
|
12195
|
-
var
|
|
12195
|
+
var InsufficientBalanceError2 = class _InsufficientBalanceError extends Error {
|
|
12196
12196
|
constructor(message, required2, available, asset) {
|
|
12197
12197
|
super(message);
|
|
12198
12198
|
this.required = required2;
|
|
@@ -12202,7 +12202,7 @@ var require_payment_engine = __commonJS({
|
|
|
12202
12202
|
Object.setPrototypeOf(this, _InsufficientBalanceError.prototype);
|
|
12203
12203
|
}
|
|
12204
12204
|
};
|
|
12205
|
-
exports2.InsufficientBalanceError =
|
|
12205
|
+
exports2.InsufficientBalanceError = InsufficientBalanceError2;
|
|
12206
12206
|
exports2.PaymentEngine = {
|
|
12207
12207
|
/**
|
|
12208
12208
|
* Create a Zetrix SDK instance for the given node config.
|
|
@@ -12295,20 +12295,20 @@ var require_payment_engine = __commonJS({
|
|
|
12295
12295
|
const { balance } = await exports2.PaymentEngine.fetchAccountInfo(wallet.address, node);
|
|
12296
12296
|
const required2 = amount + fee;
|
|
12297
12297
|
if (BigInt(balance) < required2) {
|
|
12298
|
-
throw new
|
|
12298
|
+
throw new InsufficientBalanceError2(`Insufficient ZTX: required ${required2}, available ${balance}`, String(required2), balance, "ZTX");
|
|
12299
12299
|
}
|
|
12300
12300
|
return;
|
|
12301
12301
|
}
|
|
12302
12302
|
if (!opts.skipTokenCheck) {
|
|
12303
12303
|
const { balance: tokenBal } = await exports2.PaymentEngine.fetchZTP20Balance(req.asset, wallet.address, node);
|
|
12304
12304
|
if (BigInt(tokenBal) < amount) {
|
|
12305
|
-
throw new
|
|
12305
|
+
throw new InsufficientBalanceError2(`Insufficient ${req.asset}: required ${req.maxAmountRequired}, available ${tokenBal}`, req.maxAmountRequired, tokenBal, req.asset);
|
|
12306
12306
|
}
|
|
12307
12307
|
}
|
|
12308
12308
|
if (fee > 0n) {
|
|
12309
12309
|
const { balance: ztxBal } = await exports2.PaymentEngine.fetchAccountInfo(wallet.address, node);
|
|
12310
12310
|
if (BigInt(ztxBal) < fee) {
|
|
12311
|
-
throw new
|
|
12311
|
+
throw new InsufficientBalanceError2(`Insufficient ZTX for gas: required ${feeLimit}, available ${ztxBal}`, feeLimit, ztxBal, "ZTX");
|
|
12312
12312
|
}
|
|
12313
12313
|
}
|
|
12314
12314
|
},
|
|
@@ -12547,7 +12547,7 @@ var import_node_path3 = require("node:path");
|
|
|
12547
12547
|
// package.json
|
|
12548
12548
|
var package_default = {
|
|
12549
12549
|
name: "agentic-wallet-mcp",
|
|
12550
|
-
version: "0.
|
|
12550
|
+
version: "0.5.0",
|
|
12551
12551
|
description: "Agent-facing MCP wallet for Zetrix \u2014 orchestrates x401 identity proof, x402 payment, and MBI VC issuance",
|
|
12552
12552
|
keywords: ["mcp", "model-context-protocol", "zetrix", "wallet", "x401", "x402", "blockchain"],
|
|
12553
12553
|
license: "MIT",
|
|
@@ -21159,7 +21159,7 @@ var StdioServerTransport = class {
|
|
|
21159
21159
|
};
|
|
21160
21160
|
|
|
21161
21161
|
// src/index.ts
|
|
21162
|
-
var
|
|
21162
|
+
var import_x402_zetrix_client2 = __toESM(require_dist2(), 1);
|
|
21163
21163
|
|
|
21164
21164
|
// node_modules/x401-zetrix-client/dist/config.js
|
|
21165
21165
|
var ZETRIX_OID4VP_URLS = {
|
|
@@ -21547,6 +21547,14 @@ function deriveMbiBaseUrl(network) {
|
|
|
21547
21547
|
function deriveTemplateRegistryAddress(network) {
|
|
21548
21548
|
return network.includes("testnet") ? "ZTX3JszqPgRUx743SAp7q7zURfjvkWuH2FMEz" : "ZTX3GqJM1U6ifMPonwD4fGvrgoTKJua7b2cKX";
|
|
21549
21549
|
}
|
|
21550
|
+
var TOKEN_REGISTRY = {
|
|
21551
|
+
JMYR: { testnet: "ZTX3WeinXtt28YMyr4vUZ14ddTgEMGeuc1e6b", mainnet: "ZTX3NCkXBqbyJWjZZxciQez945Lu6tGAcjNJr" }
|
|
21552
|
+
};
|
|
21553
|
+
function resolveTokenAddress(symbol, network) {
|
|
21554
|
+
const entry = TOKEN_REGISTRY[symbol.toUpperCase()];
|
|
21555
|
+
if (!entry) return void 0;
|
|
21556
|
+
return network.includes("testnet") ? entry.testnet : entry.mainnet;
|
|
21557
|
+
}
|
|
21550
21558
|
function loadConfig(env) {
|
|
21551
21559
|
const req = (key, hint) => {
|
|
21552
21560
|
const v = env[key];
|
|
@@ -21609,6 +21617,32 @@ async function resolveAssetSymbol(asset, query) {
|
|
|
21609
21617
|
return info?.symbol ?? asset;
|
|
21610
21618
|
}
|
|
21611
21619
|
|
|
21620
|
+
// src/clients/contract-query-client.ts
|
|
21621
|
+
async function queryContract(input, query) {
|
|
21622
|
+
let response;
|
|
21623
|
+
try {
|
|
21624
|
+
response = await query({
|
|
21625
|
+
contractAddress: input.contractAddress,
|
|
21626
|
+
input: JSON.stringify({ method: input.method, params: input.params ?? {} }),
|
|
21627
|
+
optType: 2
|
|
21628
|
+
});
|
|
21629
|
+
} catch (e) {
|
|
21630
|
+
return { ok: false, error: `query_contract: RPC call failed \u2014 ${e.message}` };
|
|
21631
|
+
}
|
|
21632
|
+
if (response.errorCode !== 0) {
|
|
21633
|
+
return { ok: false, error: `query_contract: contract call failed with errorCode ${response.errorCode}` };
|
|
21634
|
+
}
|
|
21635
|
+
const raw = response.result?.query_rets?.[0]?.result?.value;
|
|
21636
|
+
if (raw === void 0) {
|
|
21637
|
+
return { ok: false, error: "query_contract: no result value returned" };
|
|
21638
|
+
}
|
|
21639
|
+
try {
|
|
21640
|
+
return { ok: true, result: JSON.parse(raw) };
|
|
21641
|
+
} catch {
|
|
21642
|
+
return { ok: true, result: raw };
|
|
21643
|
+
}
|
|
21644
|
+
}
|
|
21645
|
+
|
|
21612
21646
|
// src/clients/template-info-client.ts
|
|
21613
21647
|
async function fetchTemplateFields(templateId, registryAddress, nodeBaseUrl, query) {
|
|
21614
21648
|
const key = `template__${templateId}`;
|
|
@@ -21667,6 +21701,10 @@ var WalletBeClient = class {
|
|
|
21667
21701
|
createAccount(password, label, purpose) {
|
|
21668
21702
|
return this.post("/wallet/hsm/account/create", { password, label, purpose });
|
|
21669
21703
|
}
|
|
21704
|
+
/** GET /wallet/hsm/account/activate/status — ground-truth on-chain activation check (no local state). */
|
|
21705
|
+
checkActivationStatus(address) {
|
|
21706
|
+
return this.get("/wallet/hsm/account/activate/status", { address });
|
|
21707
|
+
}
|
|
21670
21708
|
async post(path, body) {
|
|
21671
21709
|
const url = `${this.baseUrl}${path}`;
|
|
21672
21710
|
let res;
|
|
@@ -21694,6 +21732,25 @@ var WalletBeClient = class {
|
|
|
21694
21732
|
}
|
|
21695
21733
|
return env.data;
|
|
21696
21734
|
}
|
|
21735
|
+
async get(path, query) {
|
|
21736
|
+
const url = `${this.baseUrl}${path}?${new URLSearchParams(query).toString()}`;
|
|
21737
|
+
let res;
|
|
21738
|
+
try {
|
|
21739
|
+
res = await fetch(url, { headers: { Accept: "application/json" } });
|
|
21740
|
+
} catch (e) {
|
|
21741
|
+
throw new WalletBeError(`Wallet BE ${path} request failed`, void 0, e);
|
|
21742
|
+
}
|
|
21743
|
+
if (!res.ok) {
|
|
21744
|
+
const text = await res.text().catch(() => "");
|
|
21745
|
+
throw new WalletBeError(`Wallet BE ${path} HTTP ${res.status}: ${text}`);
|
|
21746
|
+
}
|
|
21747
|
+
const env = await res.json();
|
|
21748
|
+
if (env.errorCode !== 0) {
|
|
21749
|
+
const detail = env.data?.errorList?.length ? ` \u2014 ${env.data.errorList.join("; ")}` : "";
|
|
21750
|
+
throw new WalletBeError(`Wallet BE ${path} errorCode ${env.errorCode}: ${env.message ?? "error"}${detail}`, env.errorCode);
|
|
21751
|
+
}
|
|
21752
|
+
return env.data;
|
|
21753
|
+
}
|
|
21697
21754
|
};
|
|
21698
21755
|
|
|
21699
21756
|
// src/signer.ts
|
|
@@ -22035,6 +22092,36 @@ function extractValidUntil(vc, fallback) {
|
|
|
22035
22092
|
return fallback;
|
|
22036
22093
|
}
|
|
22037
22094
|
|
|
22095
|
+
// src/payment-readiness.ts
|
|
22096
|
+
var import_x402_zetrix_client = __toESM(require_dist2(), 1);
|
|
22097
|
+
var PaymentReadinessError = class extends Error {
|
|
22098
|
+
shortfall;
|
|
22099
|
+
constructor(message, shortfall) {
|
|
22100
|
+
super(message);
|
|
22101
|
+
this.name = "PaymentReadinessError";
|
|
22102
|
+
this.shortfall = shortfall;
|
|
22103
|
+
}
|
|
22104
|
+
};
|
|
22105
|
+
function toPaymentReadinessError(err, requestedAsset) {
|
|
22106
|
+
if (!(err instanceof import_x402_zetrix_client.InsufficientBalanceError)) return null;
|
|
22107
|
+
const reason = err.asset === "ZTX" && requestedAsset !== "ZTX" ? "gas" : "resource_payment";
|
|
22108
|
+
return new PaymentReadinessError(err.message, {
|
|
22109
|
+
asset: err.asset,
|
|
22110
|
+
required: err.required,
|
|
22111
|
+
available: err.available,
|
|
22112
|
+
reason
|
|
22113
|
+
});
|
|
22114
|
+
}
|
|
22115
|
+
async function payWithReadinessCheck(requestedAsset, rawPay) {
|
|
22116
|
+
try {
|
|
22117
|
+
return await rawPay();
|
|
22118
|
+
} catch (err) {
|
|
22119
|
+
const readinessError = toPaymentReadinessError(err, requestedAsset);
|
|
22120
|
+
if (readinessError) throw readinessError;
|
|
22121
|
+
throw err;
|
|
22122
|
+
}
|
|
22123
|
+
}
|
|
22124
|
+
|
|
22038
22125
|
// src/orchestrator/subscribe.ts
|
|
22039
22126
|
async function subscribeAndIssue(deps, opts) {
|
|
22040
22127
|
if (!/^did:zid:/.test(opts.templateId)) {
|
|
@@ -22058,13 +22145,15 @@ async function subscribeAndIssue(deps, opts) {
|
|
|
22058
22145
|
const { agentDid, ...rest } = opts.attributes ?? {};
|
|
22059
22146
|
const shouldAutoFillAgentDid = !agentDid && fields !== null && fields.allKeys.includes("agentDid");
|
|
22060
22147
|
const attributes = shouldAutoFillAgentDid ? { agentDid: deps.holderDid, ...rest } : opts.attributes ?? {};
|
|
22061
|
-
|
|
22148
|
+
const schema = fields ? { required: fields.required, optional: fields.allKeys.filter((k) => !fields.required.includes(k)) } : void 0;
|
|
22149
|
+
if (fields) {
|
|
22062
22150
|
const attrs = attributes;
|
|
22063
22151
|
const missing = fields.required.filter((k) => attrs[k] === void 0 || attrs[k] === null || attrs[k] === "");
|
|
22064
22152
|
if (missing.length > 0) {
|
|
22065
22153
|
return {
|
|
22066
22154
|
issued: false,
|
|
22067
|
-
reason: `template requires attribute(s) not supplied: ${missing.join(", ")} \u2014 no payment made
|
|
22155
|
+
reason: `template requires attribute(s) not supplied: ${missing.join(", ")} \u2014 no payment made`,
|
|
22156
|
+
...schema ? { schema } : {}
|
|
22068
22157
|
};
|
|
22069
22158
|
}
|
|
22070
22159
|
}
|
|
@@ -22073,7 +22162,15 @@ async function subscribeAndIssue(deps, opts) {
|
|
|
22073
22162
|
const { signBlob: signData, publicKey } = await deps.sign(blob);
|
|
22074
22163
|
const body = { data, signData, publicKey };
|
|
22075
22164
|
if (opts.expirationDate) body.expirationDate = opts.expirationDate;
|
|
22076
|
-
|
|
22165
|
+
let challenge;
|
|
22166
|
+
try {
|
|
22167
|
+
challenge = await deps.mbi.applyChallenge(body);
|
|
22168
|
+
} catch (err) {
|
|
22169
|
+
if (err instanceof MbiError) {
|
|
22170
|
+
return { issued: false, reason: err.message, httpStatus: err.httpStatus, ...schema ? { schema } : {} };
|
|
22171
|
+
}
|
|
22172
|
+
throw err;
|
|
22173
|
+
}
|
|
22077
22174
|
if (challenge.issued) {
|
|
22078
22175
|
const issued2 = challenge.issued;
|
|
22079
22176
|
if (deps.cache) {
|
|
@@ -22095,11 +22192,12 @@ async function subscribeAndIssue(deps, opts) {
|
|
|
22095
22192
|
txHash: issued2.txHash,
|
|
22096
22193
|
paidAsset: "none",
|
|
22097
22194
|
amountPaid: "0",
|
|
22195
|
+
...schema ? { schema } : {},
|
|
22098
22196
|
...opts.dryRun ? { reason: "this template requires no payment \u2014 MBI issues synchronously at phase 1, so dryRun could not prevent this issuance" } : {}
|
|
22099
22197
|
};
|
|
22100
22198
|
}
|
|
22101
22199
|
const accept = challenge.accepts[0];
|
|
22102
|
-
if (!accept) return { issued: false, reason: "MBI 402 returned no payment options" };
|
|
22200
|
+
if (!accept) return { issued: false, reason: "MBI 402 returned no payment options", ...schema ? { schema } : {} };
|
|
22103
22201
|
if (opts.dryRun) {
|
|
22104
22202
|
const quotedRaw = String(accept.asset ?? "");
|
|
22105
22203
|
const quotedAsset = deps.resolveSymbol ? await deps.resolveSymbol(quotedRaw) : quotedRaw;
|
|
@@ -22109,13 +22207,29 @@ async function subscribeAndIssue(deps, opts) {
|
|
|
22109
22207
|
quote: {
|
|
22110
22208
|
asset: quotedAsset,
|
|
22111
22209
|
maxAmountRequired: accept.maxAmountRequired,
|
|
22112
|
-
payTo: accept.payTo
|
|
22113
|
-
|
|
22114
|
-
}
|
|
22210
|
+
payTo: accept.payTo
|
|
22211
|
+
},
|
|
22212
|
+
...schema ? { schema } : {}
|
|
22115
22213
|
};
|
|
22116
22214
|
}
|
|
22117
|
-
|
|
22118
|
-
|
|
22215
|
+
let xPayment;
|
|
22216
|
+
try {
|
|
22217
|
+
xPayment = await deps.pay(accept);
|
|
22218
|
+
} catch (err) {
|
|
22219
|
+
if (err instanceof PaymentReadinessError) {
|
|
22220
|
+
return { issued: false, reason: `insufficient funds: ${err.message}`, insufficientFunds: err.shortfall };
|
|
22221
|
+
}
|
|
22222
|
+
throw err;
|
|
22223
|
+
}
|
|
22224
|
+
let issued;
|
|
22225
|
+
try {
|
|
22226
|
+
issued = await deps.mbi.applySettle({ ...body, paymentId: challenge.paymentId }, xPayment);
|
|
22227
|
+
} catch (err) {
|
|
22228
|
+
if (err instanceof MbiError) {
|
|
22229
|
+
return { issued: false, reason: err.message, httpStatus: err.httpStatus, ...schema ? { schema } : {} };
|
|
22230
|
+
}
|
|
22231
|
+
throw err;
|
|
22232
|
+
}
|
|
22119
22233
|
const rawAsset = String(accept.asset ?? "");
|
|
22120
22234
|
const paidAsset = deps.resolveSymbol ? await deps.resolveSymbol(rawAsset) : rawAsset;
|
|
22121
22235
|
const amountPaid = String(accept.maxAmountRequired ?? "");
|
|
@@ -22137,10 +22251,23 @@ async function subscribeAndIssue(deps, opts) {
|
|
|
22137
22251
|
vc: issued.verifiableCredential,
|
|
22138
22252
|
txHash: issued.txHash,
|
|
22139
22253
|
paidAsset,
|
|
22140
|
-
amountPaid
|
|
22254
|
+
amountPaid,
|
|
22255
|
+
...schema ? { schema } : {}
|
|
22141
22256
|
};
|
|
22142
22257
|
}
|
|
22143
22258
|
|
|
22259
|
+
// src/orchestrator/wait-for-activation.ts
|
|
22260
|
+
async function waitForActivation(check, address, sleep, opts = {}) {
|
|
22261
|
+
const attempts = opts.attempts ?? 3;
|
|
22262
|
+
const delayMs = opts.delayMs ?? 3e3;
|
|
22263
|
+
for (let i = 0; i < attempts; i++) {
|
|
22264
|
+
await sleep(delayMs);
|
|
22265
|
+
const { activated } = await check(address);
|
|
22266
|
+
if (activated) return true;
|
|
22267
|
+
}
|
|
22268
|
+
return false;
|
|
22269
|
+
}
|
|
22270
|
+
|
|
22144
22271
|
// src/orchestrator/onboard.ts
|
|
22145
22272
|
function deriveHolderDid(publicKeyHex) {
|
|
22146
22273
|
const hex = publicKeyHex.trim();
|
|
@@ -22158,31 +22285,383 @@ async function createHolderAccount(deps, input) {
|
|
|
22158
22285
|
message: `An account already exists for this wallet (zetrixAddress=${existing.zetrixAddress}, holderDid=${existing.holderDid}). Ask the user whether to keep using it or create a brand-new one \u2014 call create_holder_account again with confirmNew:true to mint a new account.`
|
|
22159
22286
|
};
|
|
22160
22287
|
}
|
|
22161
|
-
const { zetrixAddress, publicKeyHex } = await deps.create(input.password, input.label, input.purpose);
|
|
22288
|
+
const { zetrixAddress, publicKeyHex, activated } = await deps.create(input.password, input.label, input.purpose);
|
|
22162
22289
|
const holderDid = deriveHolderDid(publicKeyHex);
|
|
22163
22290
|
await deps.saveAccount({ zetrixAddress, holderDid, hsmPassword: input.password, label: input.label, purpose: input.purpose });
|
|
22164
|
-
const
|
|
22165
|
-
|
|
22291
|
+
const finalActivated = activated || await waitForActivation(deps.checkActivationStatus, zetrixAddress, deps.sleep);
|
|
22292
|
+
const message = `New holder HSM account created \u2014 address, DID, and password saved to the wallet's local account store. Both will be used automatically on the next server restart; no manual config edit needed. If your MCP config also sets ZETRIX_ADDRESS/HSM_PASSWORD via environment variables, update or remove those too: an explicit env ZETRIX_ADDRESS/HSM_PASSWORD always takes precedence over the saved account. ZETRIX_ADDRESS=${zetrixAddress} (HOLDER_DID=${holderDid} is optional \u2014 it re-derives automatically).` + (finalActivated ? "" : ` Note: on-chain activation has not completed yet \u2014 balance/on-chain calls for this address may fail until it does; check again later.`);
|
|
22293
|
+
return { created: true, alreadyExists: Boolean(existing), zetrixAddress, holderDid, publicKeyHex, activated: finalActivated, message };
|
|
22294
|
+
}
|
|
22295
|
+
|
|
22296
|
+
// src/iso3166.ts
|
|
22297
|
+
var COUNTRIES = [
|
|
22298
|
+
{ alpha2: "AD", alpha3: "AND", name: "Andorra" },
|
|
22299
|
+
{ alpha2: "AE", alpha3: "ARE", name: "United Arab Emirates" },
|
|
22300
|
+
{ alpha2: "AF", alpha3: "AFG", name: "Afghanistan" },
|
|
22301
|
+
{ alpha2: "AG", alpha3: "ATG", name: "Antigua and Barbuda" },
|
|
22302
|
+
{ alpha2: "AI", alpha3: "AIA", name: "Anguilla" },
|
|
22303
|
+
{ alpha2: "AL", alpha3: "ALB", name: "Albania" },
|
|
22304
|
+
{ alpha2: "AM", alpha3: "ARM", name: "Armenia" },
|
|
22305
|
+
{ alpha2: "AO", alpha3: "AGO", name: "Angola" },
|
|
22306
|
+
{ alpha2: "AQ", alpha3: "ATA", name: "Antarctica" },
|
|
22307
|
+
{ alpha2: "AR", alpha3: "ARG", name: "Argentina" },
|
|
22308
|
+
{ alpha2: "AS", alpha3: "ASM", name: "American Samoa" },
|
|
22309
|
+
{ alpha2: "AT", alpha3: "AUT", name: "Austria" },
|
|
22310
|
+
{ alpha2: "AU", alpha3: "AUS", name: "Australia" },
|
|
22311
|
+
{ alpha2: "AW", alpha3: "ABW", name: "Aruba" },
|
|
22312
|
+
{ alpha2: "AX", alpha3: "ALA", name: "\xC5land Islands" },
|
|
22313
|
+
{ alpha2: "AZ", alpha3: "AZE", name: "Azerbaijan" },
|
|
22314
|
+
{ alpha2: "BA", alpha3: "BIH", name: "Bosnia and Herzegovina" },
|
|
22315
|
+
{ alpha2: "BB", alpha3: "BRB", name: "Barbados" },
|
|
22316
|
+
{ alpha2: "BD", alpha3: "BGD", name: "Bangladesh" },
|
|
22317
|
+
{ alpha2: "BE", alpha3: "BEL", name: "Belgium" },
|
|
22318
|
+
{ alpha2: "BF", alpha3: "BFA", name: "Burkina Faso" },
|
|
22319
|
+
{ alpha2: "BG", alpha3: "BGR", name: "Bulgaria" },
|
|
22320
|
+
{ alpha2: "BH", alpha3: "BHR", name: "Bahrain" },
|
|
22321
|
+
{ alpha2: "BI", alpha3: "BDI", name: "Burundi" },
|
|
22322
|
+
{ alpha2: "BJ", alpha3: "BEN", name: "Benin" },
|
|
22323
|
+
{ alpha2: "BL", alpha3: "BLM", name: "Saint Barth\xE9lemy" },
|
|
22324
|
+
{ alpha2: "BM", alpha3: "BMU", name: "Bermuda" },
|
|
22325
|
+
{ alpha2: "BN", alpha3: "BRN", name: "Brunei Darussalam" },
|
|
22326
|
+
{ alpha2: "BO", alpha3: "BOL", name: "Bolivia (Plurinational State of)" },
|
|
22327
|
+
{ alpha2: "BQ", alpha3: "BES", name: "Bonaire, Sint Eustatius and Saba" },
|
|
22328
|
+
{ alpha2: "BR", alpha3: "BRA", name: "Brazil" },
|
|
22329
|
+
{ alpha2: "BS", alpha3: "BHS", name: "Bahamas" },
|
|
22330
|
+
{ alpha2: "BT", alpha3: "BTN", name: "Bhutan" },
|
|
22331
|
+
{ alpha2: "BV", alpha3: "BVT", name: "Bouvet Island" },
|
|
22332
|
+
{ alpha2: "BW", alpha3: "BWA", name: "Botswana" },
|
|
22333
|
+
{ alpha2: "BY", alpha3: "BLR", name: "Belarus" },
|
|
22334
|
+
{ alpha2: "BZ", alpha3: "BLZ", name: "Belize" },
|
|
22335
|
+
{ alpha2: "CA", alpha3: "CAN", name: "Canada" },
|
|
22336
|
+
{ alpha2: "CC", alpha3: "CCK", name: "Cocos (Keeling) Islands" },
|
|
22337
|
+
{ alpha2: "CD", alpha3: "COD", name: "Congo, Democratic Republic of the" },
|
|
22338
|
+
{ alpha2: "CF", alpha3: "CAF", name: "Central African Republic" },
|
|
22339
|
+
{ alpha2: "CG", alpha3: "COG", name: "Congo" },
|
|
22340
|
+
{ alpha2: "CH", alpha3: "CHE", name: "Switzerland" },
|
|
22341
|
+
{ alpha2: "CI", alpha3: "CIV", name: "C\xF4te d'Ivoire" },
|
|
22342
|
+
{ alpha2: "CK", alpha3: "COK", name: "Cook Islands" },
|
|
22343
|
+
{ alpha2: "CL", alpha3: "CHL", name: "Chile" },
|
|
22344
|
+
{ alpha2: "CM", alpha3: "CMR", name: "Cameroon" },
|
|
22345
|
+
{ alpha2: "CN", alpha3: "CHN", name: "China" },
|
|
22346
|
+
{ alpha2: "CO", alpha3: "COL", name: "Colombia" },
|
|
22347
|
+
{ alpha2: "CR", alpha3: "CRI", name: "Costa Rica" },
|
|
22348
|
+
{ alpha2: "CU", alpha3: "CUB", name: "Cuba" },
|
|
22349
|
+
{ alpha2: "CV", alpha3: "CPV", name: "Cabo Verde" },
|
|
22350
|
+
{ alpha2: "CW", alpha3: "CUW", name: "Cura\xE7ao" },
|
|
22351
|
+
{ alpha2: "CX", alpha3: "CXR", name: "Christmas Island" },
|
|
22352
|
+
{ alpha2: "CY", alpha3: "CYP", name: "Cyprus" },
|
|
22353
|
+
{ alpha2: "CZ", alpha3: "CZE", name: "Czechia" },
|
|
22354
|
+
{ alpha2: "DE", alpha3: "DEU", name: "Germany" },
|
|
22355
|
+
{ alpha2: "DJ", alpha3: "DJI", name: "Djibouti" },
|
|
22356
|
+
{ alpha2: "DK", alpha3: "DNK", name: "Denmark" },
|
|
22357
|
+
{ alpha2: "DM", alpha3: "DMA", name: "Dominica" },
|
|
22358
|
+
{ alpha2: "DO", alpha3: "DOM", name: "Dominican Republic" },
|
|
22359
|
+
{ alpha2: "DZ", alpha3: "DZA", name: "Algeria" },
|
|
22360
|
+
{ alpha2: "EC", alpha3: "ECU", name: "Ecuador" },
|
|
22361
|
+
{ alpha2: "EE", alpha3: "EST", name: "Estonia" },
|
|
22362
|
+
{ alpha2: "EG", alpha3: "EGY", name: "Egypt" },
|
|
22363
|
+
{ alpha2: "EH", alpha3: "ESH", name: "Western Sahara" },
|
|
22364
|
+
{ alpha2: "ER", alpha3: "ERI", name: "Eritrea" },
|
|
22365
|
+
{ alpha2: "ES", alpha3: "ESP", name: "Spain" },
|
|
22366
|
+
{ alpha2: "ET", alpha3: "ETH", name: "Ethiopia" },
|
|
22367
|
+
{ alpha2: "FI", alpha3: "FIN", name: "Finland" },
|
|
22368
|
+
{ alpha2: "FJ", alpha3: "FJI", name: "Fiji" },
|
|
22369
|
+
{ alpha2: "FK", alpha3: "FLK", name: "Falkland Islands (Malvinas)" },
|
|
22370
|
+
{ alpha2: "FM", alpha3: "FSM", name: "Micronesia (Federated States of)" },
|
|
22371
|
+
{ alpha2: "FO", alpha3: "FRO", name: "Faroe Islands" },
|
|
22372
|
+
{ alpha2: "FR", alpha3: "FRA", name: "France" },
|
|
22373
|
+
{ alpha2: "GA", alpha3: "GAB", name: "Gabon" },
|
|
22374
|
+
{ alpha2: "GB", alpha3: "GBR", name: "United Kingdom of Great Britain and Northern Ireland" },
|
|
22375
|
+
{ alpha2: "GD", alpha3: "GRD", name: "Grenada" },
|
|
22376
|
+
{ alpha2: "GE", alpha3: "GEO", name: "Georgia" },
|
|
22377
|
+
{ alpha2: "GF", alpha3: "GUF", name: "French Guiana" },
|
|
22378
|
+
{ alpha2: "GG", alpha3: "GGY", name: "Guernsey" },
|
|
22379
|
+
{ alpha2: "GH", alpha3: "GHA", name: "Ghana" },
|
|
22380
|
+
{ alpha2: "GI", alpha3: "GIB", name: "Gibraltar" },
|
|
22381
|
+
{ alpha2: "GL", alpha3: "GRL", name: "Greenland" },
|
|
22382
|
+
{ alpha2: "GM", alpha3: "GMB", name: "Gambia" },
|
|
22383
|
+
{ alpha2: "GN", alpha3: "GIN", name: "Guinea" },
|
|
22384
|
+
{ alpha2: "GP", alpha3: "GLP", name: "Guadeloupe" },
|
|
22385
|
+
{ alpha2: "GQ", alpha3: "GNQ", name: "Equatorial Guinea" },
|
|
22386
|
+
{ alpha2: "GR", alpha3: "GRC", name: "Greece" },
|
|
22387
|
+
{ alpha2: "GS", alpha3: "SGS", name: "South Georgia and the South Sandwich Islands" },
|
|
22388
|
+
{ alpha2: "GT", alpha3: "GTM", name: "Guatemala" },
|
|
22389
|
+
{ alpha2: "GU", alpha3: "GUM", name: "Guam" },
|
|
22390
|
+
{ alpha2: "GW", alpha3: "GNB", name: "Guinea-Bissau" },
|
|
22391
|
+
{ alpha2: "GY", alpha3: "GUY", name: "Guyana" },
|
|
22392
|
+
{ alpha2: "HK", alpha3: "HKG", name: "Hong Kong" },
|
|
22393
|
+
{ alpha2: "HM", alpha3: "HMD", name: "Heard Island and McDonald Islands" },
|
|
22394
|
+
{ alpha2: "HN", alpha3: "HND", name: "Honduras" },
|
|
22395
|
+
{ alpha2: "HR", alpha3: "HRV", name: "Croatia" },
|
|
22396
|
+
{ alpha2: "HT", alpha3: "HTI", name: "Haiti" },
|
|
22397
|
+
{ alpha2: "HU", alpha3: "HUN", name: "Hungary" },
|
|
22398
|
+
{ alpha2: "ID", alpha3: "IDN", name: "Indonesia" },
|
|
22399
|
+
{ alpha2: "IE", alpha3: "IRL", name: "Ireland" },
|
|
22400
|
+
{ alpha2: "IL", alpha3: "ISR", name: "Israel" },
|
|
22401
|
+
{ alpha2: "IM", alpha3: "IMN", name: "Isle of Man" },
|
|
22402
|
+
{ alpha2: "IN", alpha3: "IND", name: "India" },
|
|
22403
|
+
{ alpha2: "IO", alpha3: "IOT", name: "British Indian Ocean Territory" },
|
|
22404
|
+
{ alpha2: "IQ", alpha3: "IRQ", name: "Iraq" },
|
|
22405
|
+
{ alpha2: "IR", alpha3: "IRN", name: "Iran (Islamic Republic of)" },
|
|
22406
|
+
{ alpha2: "IS", alpha3: "ISL", name: "Iceland" },
|
|
22407
|
+
{ alpha2: "IT", alpha3: "ITA", name: "Italy" },
|
|
22408
|
+
{ alpha2: "JE", alpha3: "JEY", name: "Jersey" },
|
|
22409
|
+
{ alpha2: "JM", alpha3: "JAM", name: "Jamaica" },
|
|
22410
|
+
{ alpha2: "JO", alpha3: "JOR", name: "Jordan" },
|
|
22411
|
+
{ alpha2: "JP", alpha3: "JPN", name: "Japan" },
|
|
22412
|
+
{ alpha2: "KE", alpha3: "KEN", name: "Kenya" },
|
|
22413
|
+
{ alpha2: "KG", alpha3: "KGZ", name: "Kyrgyzstan" },
|
|
22414
|
+
{ alpha2: "KH", alpha3: "KHM", name: "Cambodia" },
|
|
22415
|
+
{ alpha2: "KI", alpha3: "KIR", name: "Kiribati" },
|
|
22416
|
+
{ alpha2: "KM", alpha3: "COM", name: "Comoros" },
|
|
22417
|
+
{ alpha2: "KN", alpha3: "KNA", name: "Saint Kitts and Nevis" },
|
|
22418
|
+
{ alpha2: "KP", alpha3: "PRK", name: "Korea (Democratic People's Republic of)" },
|
|
22419
|
+
{ alpha2: "KR", alpha3: "KOR", name: "Korea, Republic of" },
|
|
22420
|
+
{ alpha2: "KW", alpha3: "KWT", name: "Kuwait" },
|
|
22421
|
+
{ alpha2: "KY", alpha3: "CYM", name: "Cayman Islands" },
|
|
22422
|
+
{ alpha2: "KZ", alpha3: "KAZ", name: "Kazakhstan" },
|
|
22423
|
+
{ alpha2: "LA", alpha3: "LAO", name: "Lao People's Democratic Republic" },
|
|
22424
|
+
{ alpha2: "LB", alpha3: "LBN", name: "Lebanon" },
|
|
22425
|
+
{ alpha2: "LC", alpha3: "LCA", name: "Saint Lucia" },
|
|
22426
|
+
{ alpha2: "LI", alpha3: "LIE", name: "Liechtenstein" },
|
|
22427
|
+
{ alpha2: "LK", alpha3: "LKA", name: "Sri Lanka" },
|
|
22428
|
+
{ alpha2: "LR", alpha3: "LBR", name: "Liberia" },
|
|
22429
|
+
{ alpha2: "LS", alpha3: "LSO", name: "Lesotho" },
|
|
22430
|
+
{ alpha2: "LT", alpha3: "LTU", name: "Lithuania" },
|
|
22431
|
+
{ alpha2: "LU", alpha3: "LUX", name: "Luxembourg" },
|
|
22432
|
+
{ alpha2: "LV", alpha3: "LVA", name: "Latvia" },
|
|
22433
|
+
{ alpha2: "LY", alpha3: "LBY", name: "Libya" },
|
|
22434
|
+
{ alpha2: "MA", alpha3: "MAR", name: "Morocco" },
|
|
22435
|
+
{ alpha2: "MC", alpha3: "MCO", name: "Monaco" },
|
|
22436
|
+
{ alpha2: "MD", alpha3: "MDA", name: "Moldova, Republic of" },
|
|
22437
|
+
{ alpha2: "ME", alpha3: "MNE", name: "Montenegro" },
|
|
22438
|
+
{ alpha2: "MF", alpha3: "MAF", name: "Saint Martin (French part)" },
|
|
22439
|
+
{ alpha2: "MG", alpha3: "MDG", name: "Madagascar" },
|
|
22440
|
+
{ alpha2: "MH", alpha3: "MHL", name: "Marshall Islands" },
|
|
22441
|
+
{ alpha2: "MK", alpha3: "MKD", name: "North Macedonia" },
|
|
22442
|
+
{ alpha2: "ML", alpha3: "MLI", name: "Mali" },
|
|
22443
|
+
{ alpha2: "MM", alpha3: "MMR", name: "Myanmar" },
|
|
22444
|
+
{ alpha2: "MN", alpha3: "MNG", name: "Mongolia" },
|
|
22445
|
+
{ alpha2: "MO", alpha3: "MAC", name: "Macao" },
|
|
22446
|
+
{ alpha2: "MP", alpha3: "MNP", name: "Northern Mariana Islands" },
|
|
22447
|
+
{ alpha2: "MQ", alpha3: "MTQ", name: "Martinique" },
|
|
22448
|
+
{ alpha2: "MR", alpha3: "MRT", name: "Mauritania" },
|
|
22449
|
+
{ alpha2: "MS", alpha3: "MSR", name: "Montserrat" },
|
|
22450
|
+
{ alpha2: "MT", alpha3: "MLT", name: "Malta" },
|
|
22451
|
+
{ alpha2: "MU", alpha3: "MUS", name: "Mauritius" },
|
|
22452
|
+
{ alpha2: "MV", alpha3: "MDV", name: "Maldives" },
|
|
22453
|
+
{ alpha2: "MW", alpha3: "MWI", name: "Malawi" },
|
|
22454
|
+
{ alpha2: "MX", alpha3: "MEX", name: "Mexico" },
|
|
22455
|
+
{ alpha2: "MY", alpha3: "MYS", name: "Malaysia" },
|
|
22456
|
+
{ alpha2: "MZ", alpha3: "MOZ", name: "Mozambique" },
|
|
22457
|
+
{ alpha2: "NA", alpha3: "NAM", name: "Namibia" },
|
|
22458
|
+
{ alpha2: "NC", alpha3: "NCL", name: "New Caledonia" },
|
|
22459
|
+
{ alpha2: "NE", alpha3: "NER", name: "Niger" },
|
|
22460
|
+
{ alpha2: "NF", alpha3: "NFK", name: "Norfolk Island" },
|
|
22461
|
+
{ alpha2: "NG", alpha3: "NGA", name: "Nigeria" },
|
|
22462
|
+
{ alpha2: "NI", alpha3: "NIC", name: "Nicaragua" },
|
|
22463
|
+
{ alpha2: "NL", alpha3: "NLD", name: "Netherlands" },
|
|
22464
|
+
{ alpha2: "NO", alpha3: "NOR", name: "Norway" },
|
|
22465
|
+
{ alpha2: "NP", alpha3: "NPL", name: "Nepal" },
|
|
22466
|
+
{ alpha2: "NR", alpha3: "NRU", name: "Nauru" },
|
|
22467
|
+
{ alpha2: "NU", alpha3: "NIU", name: "Niue" },
|
|
22468
|
+
{ alpha2: "NZ", alpha3: "NZL", name: "New Zealand" },
|
|
22469
|
+
{ alpha2: "OM", alpha3: "OMN", name: "Oman" },
|
|
22470
|
+
{ alpha2: "PA", alpha3: "PAN", name: "Panama" },
|
|
22471
|
+
{ alpha2: "PE", alpha3: "PER", name: "Peru" },
|
|
22472
|
+
{ alpha2: "PF", alpha3: "PYF", name: "French Polynesia" },
|
|
22473
|
+
{ alpha2: "PG", alpha3: "PNG", name: "Papua New Guinea" },
|
|
22474
|
+
{ alpha2: "PH", alpha3: "PHL", name: "Philippines" },
|
|
22475
|
+
{ alpha2: "PK", alpha3: "PAK", name: "Pakistan" },
|
|
22476
|
+
{ alpha2: "PL", alpha3: "POL", name: "Poland" },
|
|
22477
|
+
{ alpha2: "PM", alpha3: "SPM", name: "Saint Pierre and Miquelon" },
|
|
22478
|
+
{ alpha2: "PN", alpha3: "PCN", name: "Pitcairn" },
|
|
22479
|
+
{ alpha2: "PR", alpha3: "PRI", name: "Puerto Rico" },
|
|
22480
|
+
{ alpha2: "PS", alpha3: "PSE", name: "Palestine, State of" },
|
|
22481
|
+
{ alpha2: "PT", alpha3: "PRT", name: "Portugal" },
|
|
22482
|
+
{ alpha2: "PW", alpha3: "PLW", name: "Palau" },
|
|
22483
|
+
{ alpha2: "PY", alpha3: "PRY", name: "Paraguay" },
|
|
22484
|
+
{ alpha2: "QA", alpha3: "QAT", name: "Qatar" },
|
|
22485
|
+
{ alpha2: "RE", alpha3: "REU", name: "R\xE9union" },
|
|
22486
|
+
{ alpha2: "RO", alpha3: "ROU", name: "Romania" },
|
|
22487
|
+
{ alpha2: "RS", alpha3: "SRB", name: "Serbia" },
|
|
22488
|
+
{ alpha2: "RU", alpha3: "RUS", name: "Russian Federation" },
|
|
22489
|
+
{ alpha2: "RW", alpha3: "RWA", name: "Rwanda" },
|
|
22490
|
+
{ alpha2: "SA", alpha3: "SAU", name: "Saudi Arabia" },
|
|
22491
|
+
{ alpha2: "SB", alpha3: "SLB", name: "Solomon Islands" },
|
|
22492
|
+
{ alpha2: "SC", alpha3: "SYC", name: "Seychelles" },
|
|
22493
|
+
{ alpha2: "SD", alpha3: "SDN", name: "Sudan" },
|
|
22494
|
+
{ alpha2: "SE", alpha3: "SWE", name: "Sweden" },
|
|
22495
|
+
{ alpha2: "SG", alpha3: "SGP", name: "Singapore" },
|
|
22496
|
+
{ alpha2: "SH", alpha3: "SHN", name: "Saint Helena, Ascension and Tristan da Cunha" },
|
|
22497
|
+
{ alpha2: "SI", alpha3: "SVN", name: "Slovenia" },
|
|
22498
|
+
{ alpha2: "SJ", alpha3: "SJM", name: "Svalbard and Jan Mayen" },
|
|
22499
|
+
{ alpha2: "SK", alpha3: "SVK", name: "Slovakia" },
|
|
22500
|
+
{ alpha2: "SL", alpha3: "SLE", name: "Sierra Leone" },
|
|
22501
|
+
{ alpha2: "SM", alpha3: "SMR", name: "San Marino" },
|
|
22502
|
+
{ alpha2: "SN", alpha3: "SEN", name: "Senegal" },
|
|
22503
|
+
{ alpha2: "SO", alpha3: "SOM", name: "Somalia" },
|
|
22504
|
+
{ alpha2: "SR", alpha3: "SUR", name: "Suriname" },
|
|
22505
|
+
{ alpha2: "SS", alpha3: "SSD", name: "South Sudan" },
|
|
22506
|
+
{ alpha2: "ST", alpha3: "STP", name: "Sao Tome and Principe" },
|
|
22507
|
+
{ alpha2: "SV", alpha3: "SLV", name: "El Salvador" },
|
|
22508
|
+
{ alpha2: "SX", alpha3: "SXM", name: "Sint Maarten (Dutch part)" },
|
|
22509
|
+
{ alpha2: "SY", alpha3: "SYR", name: "Syrian Arab Republic" },
|
|
22510
|
+
{ alpha2: "SZ", alpha3: "SWZ", name: "Eswatini" },
|
|
22511
|
+
{ alpha2: "TC", alpha3: "TCA", name: "Turks and Caicos Islands" },
|
|
22512
|
+
{ alpha2: "TD", alpha3: "TCD", name: "Chad" },
|
|
22513
|
+
{ alpha2: "TF", alpha3: "ATF", name: "French Southern Territories" },
|
|
22514
|
+
{ alpha2: "TG", alpha3: "TGO", name: "Togo" },
|
|
22515
|
+
{ alpha2: "TH", alpha3: "THA", name: "Thailand" },
|
|
22516
|
+
{ alpha2: "TJ", alpha3: "TJK", name: "Tajikistan" },
|
|
22517
|
+
{ alpha2: "TK", alpha3: "TKL", name: "Tokelau" },
|
|
22518
|
+
{ alpha2: "TL", alpha3: "TLS", name: "Timor-Leste" },
|
|
22519
|
+
{ alpha2: "TM", alpha3: "TKM", name: "Turkmenistan" },
|
|
22520
|
+
{ alpha2: "TN", alpha3: "TUN", name: "Tunisia" },
|
|
22521
|
+
{ alpha2: "TO", alpha3: "TON", name: "Tonga" },
|
|
22522
|
+
{ alpha2: "TR", alpha3: "TUR", name: "T\xFCrkiye" },
|
|
22523
|
+
{ alpha2: "TT", alpha3: "TTO", name: "Trinidad and Tobago" },
|
|
22524
|
+
{ alpha2: "TV", alpha3: "TUV", name: "Tuvalu" },
|
|
22525
|
+
{ alpha2: "TW", alpha3: "TWN", name: "Taiwan, Province of China" },
|
|
22526
|
+
{ alpha2: "TZ", alpha3: "TZA", name: "Tanzania, United Republic of" },
|
|
22527
|
+
{ alpha2: "UA", alpha3: "UKR", name: "Ukraine" },
|
|
22528
|
+
{ alpha2: "UG", alpha3: "UGA", name: "Uganda" },
|
|
22529
|
+
{ alpha2: "UM", alpha3: "UMI", name: "United States Minor Outlying Islands" },
|
|
22530
|
+
{ alpha2: "US", alpha3: "USA", name: "United States of America" },
|
|
22531
|
+
{ alpha2: "UY", alpha3: "URY", name: "Uruguay" },
|
|
22532
|
+
{ alpha2: "UZ", alpha3: "UZB", name: "Uzbekistan" },
|
|
22533
|
+
{ alpha2: "VA", alpha3: "VAT", name: "Holy See" },
|
|
22534
|
+
{ alpha2: "VC", alpha3: "VCT", name: "Saint Vincent and the Grenadines" },
|
|
22535
|
+
{ alpha2: "VE", alpha3: "VEN", name: "Venezuela (Bolivarian Republic of)" },
|
|
22536
|
+
{ alpha2: "VG", alpha3: "VGB", name: "Virgin Islands (British)" },
|
|
22537
|
+
{ alpha2: "VI", alpha3: "VIR", name: "Virgin Islands (U.S.)" },
|
|
22538
|
+
{ alpha2: "VN", alpha3: "VNM", name: "Viet Nam" },
|
|
22539
|
+
{ alpha2: "VU", alpha3: "VUT", name: "Vanuatu" },
|
|
22540
|
+
{ alpha2: "WF", alpha3: "WLF", name: "Wallis and Futuna" },
|
|
22541
|
+
{ alpha2: "WS", alpha3: "WSM", name: "Samoa" },
|
|
22542
|
+
{ alpha2: "YE", alpha3: "YEM", name: "Yemen" },
|
|
22543
|
+
{ alpha2: "YT", alpha3: "MYT", name: "Mayotte" },
|
|
22544
|
+
{ alpha2: "ZA", alpha3: "ZAF", name: "South Africa" },
|
|
22545
|
+
{ alpha2: "ZM", alpha3: "ZMB", name: "Zambia" },
|
|
22546
|
+
{ alpha2: "ZW", alpha3: "ZWE", name: "Zimbabwe" }
|
|
22547
|
+
];
|
|
22548
|
+
var COMMON_ALIASES = {
|
|
22549
|
+
usa: "US",
|
|
22550
|
+
america: "US",
|
|
22551
|
+
unitedstates: "US",
|
|
22552
|
+
uk: "GB",
|
|
22553
|
+
unitedkingdom: "GB",
|
|
22554
|
+
britain: "GB",
|
|
22555
|
+
greatbritain: "GB",
|
|
22556
|
+
southkorea: "KR",
|
|
22557
|
+
northkorea: "KP",
|
|
22558
|
+
russia: "RU",
|
|
22559
|
+
vietnam: "VN",
|
|
22560
|
+
laos: "LA",
|
|
22561
|
+
syria: "SY",
|
|
22562
|
+
iran: "IR",
|
|
22563
|
+
ivorycoast: "CI",
|
|
22564
|
+
czechrepublic: "CZ",
|
|
22565
|
+
swaziland: "SZ",
|
|
22566
|
+
burma: "MM",
|
|
22567
|
+
capeverde: "CV",
|
|
22568
|
+
easttimor: "TL",
|
|
22569
|
+
taiwan: "TW",
|
|
22570
|
+
macedonia: "MK",
|
|
22571
|
+
vatican: "VA",
|
|
22572
|
+
vaticancity: "VA",
|
|
22573
|
+
holland: "NL",
|
|
22574
|
+
moldova: "MD",
|
|
22575
|
+
bolivia: "BO",
|
|
22576
|
+
tanzania: "TZ",
|
|
22577
|
+
venezuela: "VE",
|
|
22578
|
+
palestine: "PS",
|
|
22579
|
+
brunei: "BN"
|
|
22580
|
+
};
|
|
22581
|
+
function normalize(s) {
|
|
22582
|
+
return s.toLowerCase().trim().replace(/[^a-z0-9]/g, "");
|
|
22583
|
+
}
|
|
22584
|
+
function isValidCountry(input) {
|
|
22585
|
+
const trimmed = input.trim();
|
|
22586
|
+
if (/^[A-Za-z]{2}$/.test(trimmed)) {
|
|
22587
|
+
return COUNTRIES.some((c) => c.alpha2 === trimmed.toUpperCase());
|
|
22588
|
+
}
|
|
22589
|
+
if (/^[A-Za-z]{3}$/.test(trimmed)) {
|
|
22590
|
+
return COUNTRIES.some((c) => c.alpha3 === trimmed.toUpperCase());
|
|
22591
|
+
}
|
|
22592
|
+
const normalized = normalize(trimmed);
|
|
22593
|
+
if (COMMON_ALIASES[normalized]) return true;
|
|
22594
|
+
return COUNTRIES.some((c) => normalize(c.name) === normalized);
|
|
22166
22595
|
}
|
|
22167
22596
|
|
|
22168
22597
|
// src/template-aliases.ts
|
|
22598
|
+
function validateDob(value) {
|
|
22599
|
+
if (typeof value !== "string") return "dob must be a string in YYYY-MM-DD format";
|
|
22600
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) return `dob must match the format YYYY-MM-DD, got "${value}"`;
|
|
22601
|
+
const [year, month, day] = value.split("-").map(Number);
|
|
22602
|
+
const date3 = new Date(Date.UTC(year, month - 1, day));
|
|
22603
|
+
const isRealCalendarDate = date3.getUTCFullYear() === year && date3.getUTCMonth() === month - 1 && date3.getUTCDate() === day;
|
|
22604
|
+
if (!isRealCalendarDate) return `dob is not a valid calendar date: "${value}"`;
|
|
22605
|
+
return void 0;
|
|
22606
|
+
}
|
|
22607
|
+
function validateCountryOfOrigin(value) {
|
|
22608
|
+
if (typeof value !== "string" || !value.trim()) return "countryOfOrigin must be a non-empty string";
|
|
22609
|
+
if (!isValidCountry(value)) return `countryOfOrigin must be an ISO 3166 country code or name, got "${value}"`;
|
|
22610
|
+
return void 0;
|
|
22611
|
+
}
|
|
22169
22612
|
var TEMPLATE_ALIASES = [
|
|
22170
22613
|
{
|
|
22171
22614
|
match: "birthcert",
|
|
22172
|
-
testnet: "did:zid:
|
|
22173
|
-
mainnet: "did:zid:
|
|
22615
|
+
testnet: "did:zid:3c0fb79adff08e14e06dcd6e3243205010dd65f533434a3d96c55575d1d3d959",
|
|
22616
|
+
mainnet: "did:zid:19091d19049abb8869b4b8e2f4a887bd1d1d86e5f5ebd0c8297000255f67765b",
|
|
22617
|
+
deriveAttributes: { id: "agentUsername" },
|
|
22618
|
+
validateAttributes: { dob: validateDob, countryOfOrigin: validateCountryOfOrigin }
|
|
22174
22619
|
}
|
|
22175
22620
|
];
|
|
22176
|
-
function
|
|
22621
|
+
function normalize2(s) {
|
|
22177
22622
|
return s.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
22178
22623
|
}
|
|
22624
|
+
function findEntry(templateId, network) {
|
|
22625
|
+
if (/^did:zid:/.test(templateId)) {
|
|
22626
|
+
const key = network.includes("testnet") ? "testnet" : "mainnet";
|
|
22627
|
+
return TEMPLATE_ALIASES.find((e) => e[key] === templateId);
|
|
22628
|
+
}
|
|
22629
|
+
const normalized = normalize2(templateId);
|
|
22630
|
+
return TEMPLATE_ALIASES.find((e) => normalized.includes(e.match));
|
|
22631
|
+
}
|
|
22179
22632
|
function resolveTemplateAlias(input, network) {
|
|
22180
22633
|
if (/^did:zid:/.test(input)) return void 0;
|
|
22181
|
-
const
|
|
22182
|
-
const entry = TEMPLATE_ALIASES.find((e) => normalized.includes(e.match));
|
|
22634
|
+
const entry = findEntry(input, network);
|
|
22183
22635
|
if (!entry) return void 0;
|
|
22184
22636
|
return network.includes("testnet") ? entry.testnet : entry.mainnet;
|
|
22185
22637
|
}
|
|
22638
|
+
function deriveTemplateAttributes(templateId, network, attributes) {
|
|
22639
|
+
const entry = findEntry(templateId, network);
|
|
22640
|
+
if (!entry?.deriveAttributes) return attributes;
|
|
22641
|
+
const result = { ...attributes };
|
|
22642
|
+
for (const [target, source] of Object.entries(entry.deriveAttributes)) {
|
|
22643
|
+
if ((result[target] === void 0 || result[target] === null || result[target] === "") && result[source] !== void 0) {
|
|
22644
|
+
result[target] = result[source];
|
|
22645
|
+
}
|
|
22646
|
+
}
|
|
22647
|
+
return result;
|
|
22648
|
+
}
|
|
22649
|
+
function derivedAttributeKeys(templateId, network) {
|
|
22650
|
+
const entry = findEntry(templateId, network);
|
|
22651
|
+
return entry?.deriveAttributes ? Object.keys(entry.deriveAttributes) : [];
|
|
22652
|
+
}
|
|
22653
|
+
function validateTemplateAttributes(templateId, network, attributes) {
|
|
22654
|
+
const entry = findEntry(templateId, network);
|
|
22655
|
+
if (!entry?.validateAttributes) return [];
|
|
22656
|
+
const errors = [];
|
|
22657
|
+
for (const [key, validate] of Object.entries(entry.validateAttributes)) {
|
|
22658
|
+
const value = attributes[key];
|
|
22659
|
+
if (value === void 0 || value === null || value === "") continue;
|
|
22660
|
+
const error2 = validate(value);
|
|
22661
|
+
if (error2) errors.push(error2);
|
|
22662
|
+
}
|
|
22663
|
+
return errors;
|
|
22664
|
+
}
|
|
22186
22665
|
|
|
22187
22666
|
// src/mcp-tools.ts
|
|
22188
22667
|
async function loadValidCachedCredentials(cache) {
|
|
@@ -22194,13 +22673,15 @@ function createTools(deps) {
|
|
|
22194
22673
|
return {
|
|
22195
22674
|
async wallet_status(input = {}) {
|
|
22196
22675
|
const balances = deps.getBalances ? await deps.getBalances() : void 0;
|
|
22676
|
+
const tokenBalance = input.token && deps.queryTokenBalance ? await deps.queryTokenBalance(input.token) : void 0;
|
|
22197
22677
|
const credentials = input.heldCredentials ?? (await loadValidCachedCredentials(deps.cache)).map((entry) => entry.vc);
|
|
22198
22678
|
return {
|
|
22199
22679
|
holderDid: deps.config.holderDid,
|
|
22200
22680
|
zetrixAddress: deps.config.zetrixAddress,
|
|
22201
22681
|
network: deps.config.network,
|
|
22202
22682
|
credentials,
|
|
22203
|
-
...balances !== void 0 ? { balances } : {}
|
|
22683
|
+
...balances !== void 0 ? { balances } : {},
|
|
22684
|
+
...tokenBalance !== void 0 ? { tokenBalance } : {}
|
|
22204
22685
|
};
|
|
22205
22686
|
},
|
|
22206
22687
|
async prove_identity(input) {
|
|
@@ -22226,16 +22707,36 @@ function createTools(deps) {
|
|
|
22226
22707
|
pay_and_fetch(input) {
|
|
22227
22708
|
return payAndFetch(deps.payer, input);
|
|
22228
22709
|
},
|
|
22229
|
-
subscribe_and_issue(input) {
|
|
22710
|
+
async subscribe_and_issue(input) {
|
|
22230
22711
|
const resolved = resolveTemplateAlias(input.templateId, deps.config.network);
|
|
22231
|
-
|
|
22712
|
+
const templateId = resolved ?? input.templateId;
|
|
22713
|
+
const attributes = deriveTemplateAttributes(templateId, deps.config.network, input.attributes ?? {});
|
|
22714
|
+
const errors = validateTemplateAttributes(templateId, deps.config.network, attributes);
|
|
22715
|
+
if (errors.length > 0) {
|
|
22716
|
+
return { issued: false, reason: errors.join("; ") };
|
|
22717
|
+
}
|
|
22718
|
+
const result = await subscribeAndIssue(deps.subscribeDeps, { ...input, templateId, attributes });
|
|
22719
|
+
if (!result.schema) return result;
|
|
22720
|
+
const hidden = /* @__PURE__ */ new Set(["agentDid", ...derivedAttributeKeys(templateId, deps.config.network)]);
|
|
22721
|
+
return {
|
|
22722
|
+
...result,
|
|
22723
|
+
schema: {
|
|
22724
|
+
required: result.schema.required.filter((k) => !hidden.has(k)),
|
|
22725
|
+
optional: result.schema.optional.filter((k) => !hidden.has(k))
|
|
22726
|
+
}
|
|
22727
|
+
};
|
|
22728
|
+
},
|
|
22729
|
+
query_contract(input) {
|
|
22730
|
+
return deps.queryContract(input);
|
|
22232
22731
|
},
|
|
22233
22732
|
create_holder_account(input) {
|
|
22234
22733
|
return createHolderAccount(
|
|
22235
22734
|
{
|
|
22236
22735
|
create: deps.createAccount,
|
|
22237
22736
|
getExistingAccount: () => Promise.resolve(deps.config.zetrixAddress ? { zetrixAddress: deps.config.zetrixAddress, holderDid: deps.config.holderDid } : null),
|
|
22238
|
-
saveAccount: deps.saveAccount
|
|
22737
|
+
saveAccount: deps.saveAccount,
|
|
22738
|
+
checkActivationStatus: deps.checkActivationStatus,
|
|
22739
|
+
sleep: deps.sleep
|
|
22239
22740
|
},
|
|
22240
22741
|
input
|
|
22241
22742
|
);
|
|
@@ -22246,8 +22747,16 @@ function createTools(deps) {
|
|
|
22246
22747
|
// src/orchestrator/resolve-holder.ts
|
|
22247
22748
|
async function resolveHolder(deps, input) {
|
|
22248
22749
|
if (!input.zetrixAddress) {
|
|
22249
|
-
const { zetrixAddress, publicKeyHex } = await deps.createAccount(input.hsmPassword);
|
|
22250
|
-
|
|
22750
|
+
const { zetrixAddress, publicKeyHex, activated } = await deps.createAccount(input.hsmPassword);
|
|
22751
|
+
let finalActivated = activated;
|
|
22752
|
+
if (!finalActivated) {
|
|
22753
|
+
try {
|
|
22754
|
+
finalActivated = await waitForActivation(deps.checkActivationStatus, zetrixAddress, deps.sleep);
|
|
22755
|
+
} catch {
|
|
22756
|
+
finalActivated = false;
|
|
22757
|
+
}
|
|
22758
|
+
}
|
|
22759
|
+
return { zetrixAddress, holderDid: deriveHolderDid(publicKeyHex), created: true, didMismatch: false, activated: finalActivated };
|
|
22251
22760
|
}
|
|
22252
22761
|
const { publicKey } = await deps.signMessage(input.zetrixAddress, input.zetrixAddress, input.hsmPassword);
|
|
22253
22762
|
const derivedDid = deriveHolderDid(publicKey);
|
|
@@ -22289,7 +22798,8 @@ function buildToolList() {
|
|
|
22289
22798
|
inputSchema: {
|
|
22290
22799
|
type: "object",
|
|
22291
22800
|
properties: {
|
|
22292
|
-
heldCredentials: { type: "array", items: { type: "object" }, description: "VCs the client holds. Omit to report whatever the wallet has cached locally from prior subscribe_and_issue calls instead." }
|
|
22801
|
+
heldCredentials: { type: "array", items: { type: "object" }, description: "VCs the client holds. Omit to report whatever the wallet has cached locally from prior subscribe_and_issue calls instead." },
|
|
22802
|
+
token: { type: "string", description: 'Optional token symbol (e.g. "ZTX", "JMYR") to check its balance for the active network, alongside the usual status fields.' }
|
|
22293
22803
|
}
|
|
22294
22804
|
}
|
|
22295
22805
|
},
|
|
@@ -22328,9 +22838,22 @@ function buildToolList() {
|
|
|
22328
22838
|
required: ["url"]
|
|
22329
22839
|
}
|
|
22330
22840
|
},
|
|
22841
|
+
{
|
|
22842
|
+
name: "query_contract",
|
|
22843
|
+
description: 'Read-only query against a Zetrix contract or account \u2014 call an arbitrary contract method (e.g. "balanceOf", "contractInfo") and return its raw result. No signing, no state change.',
|
|
22844
|
+
inputSchema: {
|
|
22845
|
+
type: "object",
|
|
22846
|
+
properties: {
|
|
22847
|
+
contractAddress: { type: "string", description: "Zetrix contract address to query." },
|
|
22848
|
+
method: { type: "string", description: 'Contract method name, e.g. "balanceOf", "contractInfo".' },
|
|
22849
|
+
params: { type: "object", description: 'Method parameters, e.g. { "address": "ZTX..." } for balanceOf.' }
|
|
22850
|
+
},
|
|
22851
|
+
required: ["contractAddress", "method"]
|
|
22852
|
+
}
|
|
22853
|
+
},
|
|
22331
22854
|
{
|
|
22332
22855
|
name: "subscribe_and_issue",
|
|
22333
|
-
description: "Obtain a VC from MBI: build the signed payload, pay x402, and return the issued credential. If a still-valid credential for this templateId is already cached locally, it is returned directly with no payment (fromCache: true) \u2014 pass forceReissue:true to pay and issue fresh regardless. Payment is asset-agnostic \u2014 MBI's 402 challenge may quote the native ZETRIX token or a ZTP20 token (e.g. JMYR); pass dryRun:true first to see the quoted asset/amount for free before committing to pay.",
|
|
22856
|
+
description: "Obtain a VC from MBI: build the signed payload, pay x402, and return the issued credential. If a still-valid credential for this templateId is already cached locally, it is returned directly with no payment (fromCache: true) \u2014 pass forceReissue:true to pay and issue fresh regardless. Payment is asset-agnostic \u2014 MBI's 402 challenge may quote the native ZETRIX token or a ZTP20 token (e.g. JMYR); pass dryRun:true first to see the quoted asset/amount for free before committing to pay. Every response (success, dry-run, or a missing-attribute error) also includes { schema: { required, optional } } \u2014 the template's full declared attribute schema read from chain \u2014 so you always see the complete field list, not just what went wrong.",
|
|
22334
22857
|
inputSchema: {
|
|
22335
22858
|
type: "object",
|
|
22336
22859
|
properties: {
|
|
@@ -22345,7 +22868,7 @@ function buildToolList() {
|
|
|
22345
22868
|
expirationDate: { type: "string" },
|
|
22346
22869
|
dryRun: {
|
|
22347
22870
|
type: "boolean",
|
|
22348
|
-
description: "Stop after MBI's free phase-1 quote and return { quote: { asset, maxAmountRequired, payTo,
|
|
22871
|
+
description: "Stop after MBI's free phase-1 quote and return { quote: { asset, maxAmountRequired, payTo }, schema: { required, optional } } without paying or issuing \u2014 use this to check the payment requirement AND the template's full attribute schema (read from chain) before spending funds. Still validates required attributes locally first \u2014 a missing one blocks before any MBI call."
|
|
22349
22872
|
},
|
|
22350
22873
|
forceReissue: {
|
|
22351
22874
|
type: "boolean",
|
|
@@ -22388,10 +22911,13 @@ async function main() {
|
|
|
22388
22911
|
const config2 = loadConfig(env);
|
|
22389
22912
|
const hsmPassword = config2.hsmPassword;
|
|
22390
22913
|
const be = new WalletBeClient(config2.walletBeUrl);
|
|
22391
|
-
const
|
|
22914
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
22915
|
+
const { zetrixAddress, holderDid, created, didMismatch, activated } = await resolveHolder(
|
|
22392
22916
|
{
|
|
22393
22917
|
createAccount: (password) => be.createAccount(password),
|
|
22394
|
-
signMessage: (message, address, password) => be.signMessage(message, address, password)
|
|
22918
|
+
signMessage: (message, address, password) => be.signMessage(message, address, password),
|
|
22919
|
+
checkActivationStatus: (address) => be.checkActivationStatus(address),
|
|
22920
|
+
sleep
|
|
22395
22921
|
},
|
|
22396
22922
|
{ zetrixAddress: config2.zetrixAddress, holderDid: config2.holderDid, hsmPassword }
|
|
22397
22923
|
);
|
|
@@ -22410,6 +22936,12 @@ async function main() {
|
|
|
22410
22936
|
if (didMismatch) {
|
|
22411
22937
|
process.stderr.write(
|
|
22412
22938
|
`agentic-wallet-mcp: configured HOLDER_DID=${config2.holderDid} does not match the account's actual public key \u2014 using the derived HOLDER_DID=${holderDid} instead. Update your MCP config.
|
|
22939
|
+
`
|
|
22940
|
+
);
|
|
22941
|
+
}
|
|
22942
|
+
if (created && !activated) {
|
|
22943
|
+
process.stderr.write(
|
|
22944
|
+
`agentic-wallet-mcp: the newly created HSM account (ZETRIX_ADDRESS=${zetrixAddress}) has not completed on-chain activation yet \u2014 balance/on-chain calls for this address may fail until it does.
|
|
22413
22945
|
`
|
|
22414
22946
|
);
|
|
22415
22947
|
}
|
|
@@ -22420,6 +22952,25 @@ async function main() {
|
|
|
22420
22952
|
const sdk = new import_zetrix_sdk_nodejs.default({ host: config2.nodeHost, port: config2.nodePort });
|
|
22421
22953
|
const contractQuery = (a) => sdk.contract.call(a);
|
|
22422
22954
|
const resolveSymbol = (asset) => resolveAssetSymbol(asset, contractQuery);
|
|
22955
|
+
const queryTokenBalance = async (token) => {
|
|
22956
|
+
const symbol = token.toUpperCase();
|
|
22957
|
+
if (symbol === "ZTX") {
|
|
22958
|
+
try {
|
|
22959
|
+
const { balance } = await import_x402_zetrix_client2.PaymentEngine.fetchAccountInfo(zetrixAddress, node);
|
|
22960
|
+
return { token: symbol, balance };
|
|
22961
|
+
} catch {
|
|
22962
|
+
return { token: symbol, error: "query_failed" };
|
|
22963
|
+
}
|
|
22964
|
+
}
|
|
22965
|
+
const contractAddress = resolveTokenAddress(symbol, config2.network);
|
|
22966
|
+
if (!contractAddress) return { token: symbol, error: "unknown_token" };
|
|
22967
|
+
try {
|
|
22968
|
+
const { balance } = await import_x402_zetrix_client2.PaymentEngine.fetchZTP20Balance(contractAddress, zetrixAddress, node);
|
|
22969
|
+
return { token: symbol, balance };
|
|
22970
|
+
} catch {
|
|
22971
|
+
return { token: symbol, error: "query_failed" };
|
|
22972
|
+
}
|
|
22973
|
+
};
|
|
22423
22974
|
const nodeBaseUrl = `https://${config2.nodeHost}${config2.nodePort ? `:${config2.nodePort}` : ""}`;
|
|
22424
22975
|
const nodeMetaQuery = (url) => fetch(url, { headers: { Accept: "application/json" } }).then((r) => r.json());
|
|
22425
22976
|
const resolveTemplateFields = (templateId) => fetchTemplateFields(templateId, config2.templateRegistryAddress, nodeBaseUrl, nodeMetaQuery);
|
|
@@ -22427,7 +22978,10 @@ async function main() {
|
|
|
22427
22978
|
const vcCache = createFsVcCache((0, import_node_path3.join)((0, import_node_os.homedir)(), ".agentic-wallet-mcp", "vc-cache", cacheScope));
|
|
22428
22979
|
const pay = (accept) => {
|
|
22429
22980
|
assertWithinPaymentCap(accept, config2.maxPaymentAmount);
|
|
22430
|
-
return
|
|
22981
|
+
return payWithReadinessCheck(
|
|
22982
|
+
String(accept.asset ?? ""),
|
|
22983
|
+
() => import_x402_zetrix_client2.PaymentEngine.pay(asPayRequest(accept), walletCfg, node, {}, walletBeSignerFn)
|
|
22984
|
+
);
|
|
22431
22985
|
};
|
|
22432
22986
|
const payer = async (req) => {
|
|
22433
22987
|
const init = { method: req.method ?? "GET", headers: req.headers, body: req.body };
|
|
@@ -22438,7 +22992,15 @@ async function main() {
|
|
|
22438
22992
|
const parsed = await res.json();
|
|
22439
22993
|
const accept = parsed.accepts?.[0];
|
|
22440
22994
|
if (!accept) throw new Error("pay_and_fetch: 402 had no accepts[]");
|
|
22441
|
-
|
|
22995
|
+
let xPayment;
|
|
22996
|
+
try {
|
|
22997
|
+
xPayment = await pay(accept);
|
|
22998
|
+
} catch (err) {
|
|
22999
|
+
if (err instanceof PaymentReadinessError) {
|
|
23000
|
+
return { status: 402, body: "", paymentMade: false, amountPaid: "", amountPaidHuman: "", asset: "", insufficientFunds: err.shortfall };
|
|
23001
|
+
}
|
|
23002
|
+
throw err;
|
|
23003
|
+
}
|
|
22442
23004
|
const retry = await fetch(req.url, { ...init, headers: { ...req.headers ?? {}, "x-payment": xPayment } });
|
|
22443
23005
|
const asset = await resolveSymbol(String(accept.asset ?? ""));
|
|
22444
23006
|
return {
|
|
@@ -22468,8 +23030,12 @@ async function main() {
|
|
|
22468
23030
|
makeWallet,
|
|
22469
23031
|
payer,
|
|
22470
23032
|
subscribeDeps: { mbi, sign: subscribeSign, pay, resolveSymbol, holderDid, resolveTemplateFields, cache: vcCache },
|
|
23033
|
+
queryContract: (input) => queryContract(input, contractQuery),
|
|
23034
|
+
queryTokenBalance,
|
|
22471
23035
|
createAccount: (password, label, purpose) => be.createAccount(password, label, purpose),
|
|
22472
23036
|
saveAccount: (account) => accountStore.set({ ...account, createdAt: (/* @__PURE__ */ new Date()).toISOString() }),
|
|
23037
|
+
checkActivationStatus: (address) => be.checkActivationStatus(address),
|
|
23038
|
+
sleep,
|
|
22473
23039
|
cache: vcCache
|
|
22474
23040
|
};
|
|
22475
23041
|
const tools = createTools(deps);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentic-wallet-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Agent-facing MCP wallet for Zetrix — orchestrates x401 identity proof, x402 payment, and MBI VC issuance",
|
|
5
5
|
"keywords": ["mcp", "model-context-protocol", "zetrix", "wallet", "x401", "x402", "blockchain"],
|
|
6
6
|
"license": "MIT",
|