@truealter/sdk 0.5.0 → 0.5.3
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 +161 -80
- package/dist/bin/alter-identity.js +532 -45
- package/dist/bin/mcp-bridge.js +56 -5
- package/dist/index.cjs +667 -60
- package/dist/index.d.cts +533 -144
- package/dist/index.d.ts +533 -144
- package/dist/index.js +645 -62
- package/package.json +6 -3
package/dist/bin/mcp-bridge.js
CHANGED
|
@@ -215,17 +215,27 @@ var AlterInvalidResponse = class extends AlterError {
|
|
|
215
215
|
}
|
|
216
216
|
};
|
|
217
217
|
|
|
218
|
-
// src/
|
|
218
|
+
// src/meta.ts
|
|
219
|
+
var SDK_NAME = "@truealter/sdk";
|
|
220
|
+
var SDK_VERSION = "0.5.3" ;
|
|
219
221
|
var X402Client = class {
|
|
220
222
|
signer;
|
|
221
223
|
maxPerQuery;
|
|
222
224
|
networks;
|
|
223
225
|
assets;
|
|
226
|
+
// undefined = allowlist check disabled (backward-compatible default).
|
|
227
|
+
// Non-null = active allowlist; reject any recipient not in the set.
|
|
228
|
+
recipientAllowlist;
|
|
224
229
|
constructor(opts = {}) {
|
|
225
230
|
this.signer = opts.signer;
|
|
226
231
|
this.maxPerQuery = opts.maxPerQuery !== void 0 ? Number(opts.maxPerQuery) : void 0;
|
|
227
232
|
this.networks = new Set(opts.networks ?? ["base", "base-sepolia"]);
|
|
228
233
|
this.assets = new Set(opts.assets ?? ["USDC"]);
|
|
234
|
+
if (opts.recipientAllowlist !== void 0) {
|
|
235
|
+
this.recipientAllowlist = opts.recipientAllowlist.length === 0 ? void 0 : new Set(opts.recipientAllowlist.map((a) => a.toLowerCase()));
|
|
236
|
+
} else {
|
|
237
|
+
this.recipientAllowlist = void 0;
|
|
238
|
+
}
|
|
229
239
|
}
|
|
230
240
|
/**
|
|
231
241
|
* Validate the envelope against this client's policy and, if a signer
|
|
@@ -251,6 +261,15 @@ var X402Client = class {
|
|
|
251
261
|
);
|
|
252
262
|
}
|
|
253
263
|
}
|
|
264
|
+
if (this.recipientAllowlist !== void 0) {
|
|
265
|
+
const recipientNorm = (envelope.recipient ?? "").toLowerCase();
|
|
266
|
+
if (!recipientNorm || !this.recipientAllowlist.has(recipientNorm)) {
|
|
267
|
+
throw new AlterError(
|
|
268
|
+
"PAYMENT_REQUIRED",
|
|
269
|
+
`recipient "${envelope.recipient}" is not on the known-recipient allowlist`
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
254
273
|
if (!this.signer) {
|
|
255
274
|
throw new AlterPaymentRequired(envelope.resource ?? "unknown", envelope);
|
|
256
275
|
}
|
|
@@ -309,6 +328,9 @@ var MCPClient = class {
|
|
|
309
328
|
x402;
|
|
310
329
|
signing;
|
|
311
330
|
extraHeaders;
|
|
331
|
+
preflightHook;
|
|
332
|
+
preflightPromise = null;
|
|
333
|
+
preflightDone = false;
|
|
312
334
|
requestCounter = 0;
|
|
313
335
|
initialised = false;
|
|
314
336
|
constructor(opts = {}) {
|
|
@@ -317,17 +339,43 @@ var MCPClient = class {
|
|
|
317
339
|
this.fetchImpl = opts.fetch ?? fetch;
|
|
318
340
|
this.timeoutMs = opts.timeoutMs ?? 3e4;
|
|
319
341
|
this.maxRetries = opts.maxRetries ?? 2;
|
|
320
|
-
this.clientInfo = opts.clientInfo ?? { name:
|
|
342
|
+
this.clientInfo = opts.clientInfo ?? { name: SDK_NAME, version: SDK_VERSION };
|
|
321
343
|
this.x402 = opts.x402;
|
|
322
344
|
this.signing = opts.signing;
|
|
323
345
|
this.extraHeaders = opts.extraHeaders;
|
|
346
|
+
this.preflightHook = opts.preflightHook;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Run the lazy preflight hook (D-MIN-VERSION-FLOOR-1) exactly once.
|
|
350
|
+
* Idempotent and serialised: concurrent callers share the same
|
|
351
|
+
* promise. Throws from the hook propagate to every concurrent caller.
|
|
352
|
+
*/
|
|
353
|
+
async runPreflight() {
|
|
354
|
+
if (this.preflightDone) return;
|
|
355
|
+
if (!this.preflightHook) {
|
|
356
|
+
this.preflightDone = true;
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if (!this.preflightPromise) {
|
|
360
|
+
this.preflightPromise = this.preflightHook().then(
|
|
361
|
+
() => {
|
|
362
|
+
this.preflightDone = true;
|
|
363
|
+
},
|
|
364
|
+
(err) => {
|
|
365
|
+
this.preflightPromise = null;
|
|
366
|
+
throw err;
|
|
367
|
+
}
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
await this.preflightPromise;
|
|
324
371
|
}
|
|
325
372
|
/**
|
|
326
373
|
* Send the MCP `initialize` handshake and capture the resulting session
|
|
327
|
-
* id. Idempotent
|
|
374
|
+
* id. Idempotent: safe to call multiple times.
|
|
328
375
|
*/
|
|
329
376
|
async initialize() {
|
|
330
377
|
if (this.initialised) return null;
|
|
378
|
+
await this.runPreflight();
|
|
331
379
|
const result = await this.rpc("initialize", {
|
|
332
380
|
protocolVersion: MCP_PROTOCOL_VERSION,
|
|
333
381
|
capabilities: {},
|
|
@@ -487,7 +535,10 @@ var MCPClient = class {
|
|
|
487
535
|
...this.extraHeaders ?? {},
|
|
488
536
|
"Content-Type": "application/json",
|
|
489
537
|
Accept: "application/json",
|
|
490
|
-
"User-Agent": `${this.clientInfo.name}/${this.clientInfo.version}
|
|
538
|
+
"User-Agent": `${this.clientInfo.name}/${this.clientInfo.version}`,
|
|
539
|
+
"X-Alter-Client-Id": "alter-identity",
|
|
540
|
+
"X-Alter-Client-Version": SDK_VERSION,
|
|
541
|
+
"X-Alter-Client-Channel": "npm"
|
|
491
542
|
};
|
|
492
543
|
if (this.apiKey) headers["X-ALTER-API-Key"] = this.apiKey;
|
|
493
544
|
if (this.sessionId) headers["Mcp-Session-Id"] = this.sessionId;
|
|
@@ -574,7 +625,7 @@ function buildExtraHeaders() {
|
|
|
574
625
|
}
|
|
575
626
|
var EXTRA_HEADERS = buildExtraHeaders();
|
|
576
627
|
console.warn(
|
|
577
|
-
"This bridge is a dev/demo surface. Authenticated MCP tools require
|
|
628
|
+
"This bridge is a dev/demo surface. Authenticated MCP tools require ES256 per-invocation signing; for production, import `@truealter/sdk` directly. Bridge signing is planned for a future release."
|
|
578
629
|
);
|
|
579
630
|
var client = new MCPClient({
|
|
580
631
|
endpoint: ENDPOINT,
|