@astrasyncai/verification-gateway 5.20.0 → 5.21.1
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 +62 -3
- package/README.md +2 -2
- package/dist/adapters/express.d.mts +1 -1
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/express.js +1 -1
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +1 -1
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +1 -1
- package/dist/adapters/mcp.d.ts +1 -1
- package/dist/adapters/mcp.js +1 -1
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +1 -1
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.d.mts +1 -1
- package/dist/adapters/nextjs.d.ts +1 -1
- package/dist/adapters/nextjs.js +1 -1
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +1 -1
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +8 -31
- package/dist/adapters/sdk.d.ts +8 -31
- package/dist/adapters/sdk.js +8 -22
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +8 -22
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.js +1 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/index.mjs +1 -1
- package/dist/agent/index.mjs.map +1 -1
- package/dist/bin/astrasync-claude-hook.js +2 -2
- package/dist/bin/astrasync-codex-hook.js +2 -2
- package/dist/bin/astrasync-guard.js +2 -2
- package/dist/bin/astrasync.js +15 -2
- package/dist/browser/background.js +2 -2
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +2 -2
- package/dist/browser/background.mjs.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +1 -1
- package/dist/cli/index.mjs.map +1 -1
- package/dist/codex/index.js +2 -2
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +2 -2
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/extension.js +2 -2
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +2 -2
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/edge-config.d.mts +1 -1
- package/dist/edge-config.d.ts +1 -1
- package/dist/edge-config.js +1 -1
- package/dist/edge-config.js.map +1 -1
- package/dist/edge-config.mjs +1 -1
- package/dist/edge-config.mjs.map +1 -1
- package/dist/edge-core/index.d.mts +1 -1
- package/dist/edge-core/index.d.ts +1 -1
- package/dist/edge-core/index.js +1 -1
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +1 -1
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/gateway/gateway.js +2 -2
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +2 -2
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +1 -1
- package/dist/git-trigger/git-hooks.d.ts +1 -1
- package/dist/index.d.mts +156 -34
- package/dist/index.d.ts +156 -34
- package/dist/index.js +327 -40
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +319 -40
- package/dist/index.mjs.map +1 -1
- package/dist/registration/index.js +1 -1
- package/dist/registration/index.js.map +1 -1
- package/dist/registration/index.mjs +1 -1
- package/dist/registration/index.mjs.map +1 -1
- package/dist/transport/index.js +1 -1
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/index.mjs +1 -1
- package/dist/transport/index.mjs.map +1 -1
- package/dist/{types-D37aSQ9c.d.mts → types-B4zhOAlq.d.mts} +5 -0
- package/dist/{types-Dn8tXnei.d.ts → types-CtBXnWuV.d.ts} +5 -0
- package/dist/{types-CxjqmPl-.d.mts → types-DHHyXtuZ.d.mts} +5 -0
- package/dist/{types-CxjqmPl-.d.ts → types-DHHyXtuZ.d.ts} +5 -0
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/verify.d.mts +1 -1
- package/dist/verify.d.ts +1 -1
- package/dist/verify.js +1 -1
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +1 -1
- package/dist/verify.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -44,6 +44,7 @@ __export(src_exports, {
|
|
|
44
44
|
DECLARED_SOURCE_MAX: () => DECLARED_SOURCE_MAX,
|
|
45
45
|
DEFAULT_EDGE_CONFIG: () => DEFAULT_EDGE_CONFIG,
|
|
46
46
|
DEFAULT_IDEMPOTENCY_TTL_MS: () => DEFAULT_IDEMPOTENCY_TTL_MS,
|
|
47
|
+
ISSUER_PROGRAM_HEADER: () => ISSUER_PROGRAM_HEADER,
|
|
47
48
|
KYDRequiredError: () => KYDRequiredError,
|
|
48
49
|
MAX_HEADERS: () => MAX_HEADERS,
|
|
49
50
|
MAX_HEADER_VALUE_BYTES: () => MAX_HEADER_VALUE_BYTES,
|
|
@@ -102,6 +103,7 @@ __export(src_exports, {
|
|
|
102
103
|
closedPaymentMandate: () => closedPaymentMandate,
|
|
103
104
|
contentDigest: () => contentDigest,
|
|
104
105
|
createAcpCheckoutKit: () => createAcpCheckoutKit,
|
|
106
|
+
createAgentCommerce: () => createAgentCommerce,
|
|
105
107
|
createKbHop: () => createKbHop,
|
|
106
108
|
createMcpMiddleware: () => createMcpMiddleware,
|
|
107
109
|
createUcpCheckoutKit: () => createUcpCheckoutKit,
|
|
@@ -123,6 +125,7 @@ __export(src_exports, {
|
|
|
123
125
|
fetchRoutes: () => fetchRoutes,
|
|
124
126
|
fetchUcpProfile: () => fetchUcpProfile,
|
|
125
127
|
finishIdempotent: () => finishIdempotent,
|
|
128
|
+
fromFeed: () => fromFeed,
|
|
126
129
|
getCachedWellKnownUrls: () => getCachedWellKnownUrls,
|
|
127
130
|
getEdgeConfig: () => getEdgeConfig,
|
|
128
131
|
getTrustLevel: () => getTrustLevel,
|
|
@@ -138,6 +141,7 @@ __export(src_exports, {
|
|
|
138
141
|
isVerificationUnavailable: () => isVerificationUnavailable,
|
|
139
142
|
isVerifiedHopValidFor: () => isVerifiedHopValidFor,
|
|
140
143
|
issueDelegateSdJwt: () => issueDelegateSdJwt,
|
|
144
|
+
issuerOfferPrice: () => issuerOfferPrice,
|
|
141
145
|
matchEdgePathRule: () => matchEdgePathRule,
|
|
142
146
|
matchPlatformSignature: () => matchPlatformSignature,
|
|
143
147
|
matchRoutePattern: () => matchRoutePattern,
|
|
@@ -148,6 +152,7 @@ __export(src_exports, {
|
|
|
148
152
|
onVerificationResult: () => onVerificationResult,
|
|
149
153
|
openCheckoutMandate: () => openCheckoutMandate,
|
|
150
154
|
openPaymentMandate: () => openPaymentMandate,
|
|
155
|
+
parseFeed: () => parseFeed,
|
|
151
156
|
parseLocalPolicyYaml: () => parseYaml,
|
|
152
157
|
parseMppCredential: () => parseMppCredential,
|
|
153
158
|
parseUcpAgentHeader: () => parseUcpAgentHeader,
|
|
@@ -156,6 +161,8 @@ __export(src_exports, {
|
|
|
156
161
|
parseX402Payment: () => parseX402Payment,
|
|
157
162
|
pollStepUpStatus: () => pollStepUpStatus,
|
|
158
163
|
prefetchWellKnown: () => prefetchWellKnown,
|
|
164
|
+
priceForAgent: () => priceForAgent,
|
|
165
|
+
pricingContextFrom: () => pricingContextFrom,
|
|
159
166
|
quickVerify: () => quickVerify,
|
|
160
167
|
recordDecision: () => recordDecision2,
|
|
161
168
|
reportAttempt: () => reportAttempt,
|
|
@@ -169,6 +176,7 @@ __export(src_exports, {
|
|
|
169
176
|
sdkFetch: () => sdkFetch,
|
|
170
177
|
sendUcpWebhook: () => sendUcpWebhook,
|
|
171
178
|
serializeVerifiedHop: () => serializeVerifiedHop,
|
|
179
|
+
serveAgentCatalog: () => serveAgentCatalog,
|
|
172
180
|
setMcpMeta: () => setMcpMeta,
|
|
173
181
|
signHttpRequest: () => signHttpRequest,
|
|
174
182
|
signRootMandate: () => signRootMandate,
|
|
@@ -221,7 +229,7 @@ function getTrustLevel(score) {
|
|
|
221
229
|
}
|
|
222
230
|
|
|
223
231
|
// src/version.ts
|
|
224
|
-
var SDK_VERSION = "5.
|
|
232
|
+
var SDK_VERSION = "5.21.1";
|
|
225
233
|
|
|
226
234
|
// src/http.ts
|
|
227
235
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -3992,37 +4000,23 @@ var VerificationGatewayClient = class {
|
|
|
3992
4000
|
}
|
|
3993
4001
|
return json4.data;
|
|
3994
4002
|
}
|
|
3995
|
-
/**
|
|
3996
|
-
* 5.20.0 (round 29.1): change an endpoint's OPERATIONAL URLs with this
|
|
3997
|
-
* client's API key — `PATCH /api/endpoints/:id`. Accepts the key of the
|
|
3998
|
-
* endpoint's owner, or a personal key of an individual with an active seat
|
|
3999
|
-
* in the owning organisation. Policy (rules, trust floor, challenge, edge
|
|
4000
|
-
* config) stays dashboard-only. `null` clears a field. The owner is alerted
|
|
4001
|
-
* when `eventsUrl` changes.
|
|
4002
|
-
*
|
|
4003
|
-
* @param endpointId the ASTRAE id (defaults to the client's `counterpartyId`)
|
|
4004
|
-
* @returns the endpoint as stored, plus `changed` (the fields that changed)
|
|
4005
|
-
* @throws AstraSyncError — 400 `UNKNOWN_FIELDS` / validation, 401/403, 404
|
|
4006
|
-
*/
|
|
4007
|
-
async updateEndpoint(endpointId, patch) {
|
|
4008
|
-
return this.endpointCall("PATCH", endpointId, "", patch);
|
|
4009
|
-
}
|
|
4010
4003
|
/**
|
|
4011
4004
|
* 5.20.0 (round 29.1): ask AstraSync to send ONE signed step-up event to the
|
|
4012
4005
|
* endpoint's Events URL now — `POST /api/endpoints/:id/events/test`.
|
|
4013
4006
|
* Delivered synchronously, outside the event outbox (random `eventId`, no
|
|
4014
4007
|
* retries), signed with the endpoint's webhook secret like a real event.
|
|
4015
|
-
*
|
|
4016
|
-
* ignores it
|
|
4017
|
-
*
|
|
4018
|
-
*
|
|
4019
|
-
*
|
|
4008
|
+
* The payload is synthetic (`approvalId: "test_…"`); a kit acknowledges and
|
|
4009
|
+
* ignores it.
|
|
4010
|
+
*
|
|
4011
|
+
* 5.21.0 (shops' item 48): synthetic only. Sending a real held approval's
|
|
4012
|
+
* payload (which releases or re-drives that checkout) is dashboard-only, so
|
|
4013
|
+
* a leaked API key can't do it.
|
|
4020
4014
|
*
|
|
4021
4015
|
* Resolves even when your endpoint refused the event (`delivered: false`,
|
|
4022
4016
|
* with `responseCode` / `error`).
|
|
4023
4017
|
*/
|
|
4024
4018
|
async sendTestEvent(endpointId, options) {
|
|
4025
|
-
return this.endpointCall("POST", endpointId, "/events/test", options);
|
|
4019
|
+
return this.endpointCall("POST", endpointId, "/events/test", { type: options.type });
|
|
4026
4020
|
}
|
|
4027
4021
|
async endpointCall(method, endpointId, suffix, body) {
|
|
4028
4022
|
const id = endpointId ?? this.config.counterpartyId;
|
|
@@ -9213,13 +9207,13 @@ function requireLoader() {
|
|
|
9213
9207
|
throwError(state, "ill-formed argument of the YAML directive");
|
|
9214
9208
|
}
|
|
9215
9209
|
const major = parseInt(match[1], 10);
|
|
9216
|
-
const
|
|
9210
|
+
const minor2 = parseInt(match[2], 10);
|
|
9217
9211
|
if (major !== 1) {
|
|
9218
9212
|
throwError(state, "unacceptable YAML version of the document");
|
|
9219
9213
|
}
|
|
9220
9214
|
state.version = args[0];
|
|
9221
|
-
state.checkLineBreaks =
|
|
9222
|
-
if (
|
|
9215
|
+
state.checkLineBreaks = minor2 < 2;
|
|
9216
|
+
if (minor2 !== 1 && minor2 !== 2) {
|
|
9223
9217
|
throwWarning(state, "unsupported YAML version of the document");
|
|
9224
9218
|
}
|
|
9225
9219
|
},
|
|
@@ -11715,6 +11709,228 @@ async function sendUcpWebhook(opts) {
|
|
|
11715
11709
|
return { ok: false, status: last, attempts };
|
|
11716
11710
|
}
|
|
11717
11711
|
|
|
11712
|
+
// src/ucp/agent-commerce.ts
|
|
11713
|
+
var ISSUER_PROGRAM_HEADER = "X-Astra-Issuer-Program";
|
|
11714
|
+
function issuerOfferPrice(priceMinor, percentOff) {
|
|
11715
|
+
if (!percentOff) return priceMinor;
|
|
11716
|
+
const pct = Math.min(100, Math.max(0, percentOff));
|
|
11717
|
+
return Math.max(0, Math.round(priceMinor * (1 - pct / 100)));
|
|
11718
|
+
}
|
|
11719
|
+
function priceForAgent(rules, sku, basePriceMinor, ctx) {
|
|
11720
|
+
const rule = rules?.products?.[sku];
|
|
11721
|
+
let price = rule?.priceMinor ?? basePriceMinor;
|
|
11722
|
+
if (ctx.verified && rules?.verifiedPercentOff) {
|
|
11723
|
+
price = issuerOfferPrice(price, rules.verifiedPercentOff);
|
|
11724
|
+
}
|
|
11725
|
+
const offer = ctx.verified && ctx.issuerProgram && rule?.issuerEligible !== false ? rules?.offers?.find((o) => o.program === ctx.issuerProgram) : void 0;
|
|
11726
|
+
if (offer?.pricePercentOff) {
|
|
11727
|
+
return {
|
|
11728
|
+
priceMinor: issuerOfferPrice(price, offer.pricePercentOff),
|
|
11729
|
+
regularMinor: price,
|
|
11730
|
+
issuerProgram: offer.program
|
|
11731
|
+
};
|
|
11732
|
+
}
|
|
11733
|
+
return { priceMinor: price };
|
|
11734
|
+
}
|
|
11735
|
+
function visibleToAgent(rules, sku, ctx) {
|
|
11736
|
+
if (!ctx.verified && rules?.hideFromUnverified) return false;
|
|
11737
|
+
return rules?.products?.[sku]?.visible !== false;
|
|
11738
|
+
}
|
|
11739
|
+
function createAgentCommerce(opts) {
|
|
11740
|
+
const f = opts.fetch ?? sdkFetch;
|
|
11741
|
+
let current = null;
|
|
11742
|
+
let kitReport;
|
|
11743
|
+
const refreshMs = opts.refreshMs ?? 5 * 6e4;
|
|
11744
|
+
async function refresh() {
|
|
11745
|
+
try {
|
|
11746
|
+
const headers = {
|
|
11747
|
+
Accept: "application/json",
|
|
11748
|
+
Authorization: `Bearer ${opts.apiKey}`,
|
|
11749
|
+
"X-AstraSync-SDK-Version": SDK_VERSION
|
|
11750
|
+
};
|
|
11751
|
+
if (kitReport) {
|
|
11752
|
+
headers["X-AstraSync-Kit-Report"] = Buffer.from(JSON.stringify(kitReport)).toString(
|
|
11753
|
+
"base64url"
|
|
11754
|
+
);
|
|
11755
|
+
}
|
|
11756
|
+
const res = await f(
|
|
11757
|
+
`${opts.apiBaseUrl.replace(/\/+$/, "")}/endpoints/${encodeURIComponent(
|
|
11758
|
+
opts.counterpartyId
|
|
11759
|
+
)}/agent-commerce`,
|
|
11760
|
+
{ method: "GET", headers }
|
|
11761
|
+
);
|
|
11762
|
+
if (!res.ok) return;
|
|
11763
|
+
const body = await res.json();
|
|
11764
|
+
if (body.data && typeof body.data.version === "number") current = body.data;
|
|
11765
|
+
} catch {
|
|
11766
|
+
}
|
|
11767
|
+
}
|
|
11768
|
+
const timer = refreshMs > 0 ? setInterval(() => {
|
|
11769
|
+
void refresh();
|
|
11770
|
+
}, refreshMs) : null;
|
|
11771
|
+
timer?.unref?.();
|
|
11772
|
+
void refresh();
|
|
11773
|
+
return {
|
|
11774
|
+
rules: () => current,
|
|
11775
|
+
refresh,
|
|
11776
|
+
price: (sku, base, ctx) => priceForAgent(current, sku, base, ctx),
|
|
11777
|
+
visible: (sku, ctx) => visibleToAgent(current, sku, ctx),
|
|
11778
|
+
report: (r) => {
|
|
11779
|
+
kitReport = { ...kitReport, ...r };
|
|
11780
|
+
},
|
|
11781
|
+
stop: () => {
|
|
11782
|
+
if (timer) clearInterval(timer);
|
|
11783
|
+
}
|
|
11784
|
+
};
|
|
11785
|
+
}
|
|
11786
|
+
function pricingContextFrom(headers) {
|
|
11787
|
+
const astraId = headers.get("x-astra-id");
|
|
11788
|
+
const hop = parseVerifiedHop(headers.get(MCP_VERIFIED_HOP_HEADER.toLowerCase()));
|
|
11789
|
+
const verified = !!astraId && (!hop || hop.astraId === astraId && Date.now() - hop.checkedAt <= MCP_VERIFIED_HOP_MAX_AGE_MS);
|
|
11790
|
+
const program = headers.get(ISSUER_PROGRAM_HEADER.toLowerCase());
|
|
11791
|
+
return {
|
|
11792
|
+
verified,
|
|
11793
|
+
...verified && program && /^[a-z0-9-]{2,40}$/.test(program) && { issuerProgram: program }
|
|
11794
|
+
};
|
|
11795
|
+
}
|
|
11796
|
+
function minor(value) {
|
|
11797
|
+
const n = typeof value === "number" ? value : Number(String(value ?? "").replace(/[^\d.]/g, ""));
|
|
11798
|
+
return Number.isFinite(n) && n >= 0 ? Math.round(n * 100) : null;
|
|
11799
|
+
}
|
|
11800
|
+
function fromFeed(url, options = {}) {
|
|
11801
|
+
const f = options.fetch ?? fetch;
|
|
11802
|
+
let cache4 = null;
|
|
11803
|
+
return async () => {
|
|
11804
|
+
if (cache4 && Date.now() - cache4.at < 6e4) return cache4.products;
|
|
11805
|
+
const res = await f(url, {
|
|
11806
|
+
headers: { Accept: "application/json, application/xml, text/csv" }
|
|
11807
|
+
});
|
|
11808
|
+
if (!res.ok) throw new Error(`Product feed ${url} answered ${res.status}`);
|
|
11809
|
+
const text = await res.text();
|
|
11810
|
+
const products = parseFeed(text, options.currency ?? "AUD");
|
|
11811
|
+
cache4 = { at: Date.now(), products };
|
|
11812
|
+
return products;
|
|
11813
|
+
};
|
|
11814
|
+
}
|
|
11815
|
+
function parseFeed(text, currency) {
|
|
11816
|
+
const trimmed = text.trimStart();
|
|
11817
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
11818
|
+
const json4 = JSON.parse(trimmed);
|
|
11819
|
+
const list = Array.isArray(json4) ? json4 : json4.products ?? json4.items ?? [];
|
|
11820
|
+
return list.flatMap((p) => {
|
|
11821
|
+
const variant = p.variants?.[0];
|
|
11822
|
+
const price = minor(variant?.price ?? p.price);
|
|
11823
|
+
const sku = String(variant?.sku || p.sku || p.id || "");
|
|
11824
|
+
if (!sku || price === null) return [];
|
|
11825
|
+
const images = Array.isArray(p.images) ? p.images.map(
|
|
11826
|
+
(i) => typeof i === "string" ? i : i.src ?? ""
|
|
11827
|
+
) : [p.image_url, p.image].filter((x) => typeof x === "string");
|
|
11828
|
+
return [
|
|
11829
|
+
{
|
|
11830
|
+
sku,
|
|
11831
|
+
name: String(p.title ?? p.name ?? sku),
|
|
11832
|
+
priceMinor: price,
|
|
11833
|
+
currency: String(p.currency ?? currency),
|
|
11834
|
+
...typeof p.description === "string" && { description: p.description },
|
|
11835
|
+
imageUrls: images.filter((u) => /^https:\/\//.test(u)),
|
|
11836
|
+
inStock: variant ? variant.available !== false : p.in_stock !== false
|
|
11837
|
+
}
|
|
11838
|
+
];
|
|
11839
|
+
});
|
|
11840
|
+
}
|
|
11841
|
+
if (trimmed.startsWith("<")) {
|
|
11842
|
+
const items = trimmed.split(/<item[\s>]|<entry[\s>]/).slice(1);
|
|
11843
|
+
return items.flatMap((chunk) => {
|
|
11844
|
+
const tag = (name) => {
|
|
11845
|
+
const m = new RegExp(`<(?:g:)?${name}[^>]*>([\\s\\S]*?)</(?:g:)?${name}>`).exec(chunk);
|
|
11846
|
+
return m ? m[1].replace(/<!\[CDATA\[|\]\]>/g, "").trim() : void 0;
|
|
11847
|
+
};
|
|
11848
|
+
const sku = tag("id");
|
|
11849
|
+
const price = minor(tag("price"));
|
|
11850
|
+
if (!sku || price === null) return [];
|
|
11851
|
+
const extra = [...chunk.matchAll(/<g:additional_image_link>([^<]+)</g)].map(
|
|
11852
|
+
(m) => m[1].trim()
|
|
11853
|
+
);
|
|
11854
|
+
return [
|
|
11855
|
+
{
|
|
11856
|
+
sku,
|
|
11857
|
+
name: tag("title") ?? sku,
|
|
11858
|
+
priceMinor: price,
|
|
11859
|
+
currency: /[A-Z]{3}/.exec(tag("price") ?? "")?.[0] ?? currency,
|
|
11860
|
+
imageUrls: [tag("image_link"), ...extra].filter(
|
|
11861
|
+
(u) => !!u && /^https:\/\//.test(u)
|
|
11862
|
+
),
|
|
11863
|
+
inStock: (tag("availability") ?? "in stock").replace(/_/g, " ") !== "out of stock"
|
|
11864
|
+
}
|
|
11865
|
+
];
|
|
11866
|
+
});
|
|
11867
|
+
}
|
|
11868
|
+
const [head, ...rows] = trimmed.split(/\r?\n/).filter(Boolean);
|
|
11869
|
+
const cols = head.split(",").map((c) => c.trim().toLowerCase());
|
|
11870
|
+
const at = (r, ...names) => {
|
|
11871
|
+
const i = cols.findIndex((c) => names.includes(c));
|
|
11872
|
+
return i >= 0 ? r[i]?.trim() : void 0;
|
|
11873
|
+
};
|
|
11874
|
+
return rows.flatMap((line) => {
|
|
11875
|
+
const r = line.split(",");
|
|
11876
|
+
const sku = at(r, "id", "sku");
|
|
11877
|
+
const price = minor(at(r, "price"));
|
|
11878
|
+
if (!sku || price === null) return [];
|
|
11879
|
+
const image = at(r, "image_link", "image_url", "image");
|
|
11880
|
+
return [
|
|
11881
|
+
{
|
|
11882
|
+
sku,
|
|
11883
|
+
name: at(r, "title", "name") ?? sku,
|
|
11884
|
+
priceMinor: price,
|
|
11885
|
+
currency,
|
|
11886
|
+
imageUrls: image && /^https:\/\//.test(image) ? [image] : [],
|
|
11887
|
+
inStock: (at(r, "availability", "in_stock") ?? "in stock") !== "out of stock"
|
|
11888
|
+
}
|
|
11889
|
+
];
|
|
11890
|
+
});
|
|
11891
|
+
}
|
|
11892
|
+
function serveAgentCatalog(opts) {
|
|
11893
|
+
return async (req, res) => {
|
|
11894
|
+
const ctx = pricingContextFrom({
|
|
11895
|
+
get: (name) => {
|
|
11896
|
+
const v = req.headers[name.toLowerCase()];
|
|
11897
|
+
return Array.isArray(v) ? v[0] ?? null : v ?? null;
|
|
11898
|
+
}
|
|
11899
|
+
});
|
|
11900
|
+
let products;
|
|
11901
|
+
try {
|
|
11902
|
+
products = await opts.products();
|
|
11903
|
+
} catch {
|
|
11904
|
+
res.status(503).json({ error: "catalog_unavailable" });
|
|
11905
|
+
return;
|
|
11906
|
+
}
|
|
11907
|
+
const rules = opts.commerce.rules();
|
|
11908
|
+
res.setHeader?.("Cache-Control", ctx.verified ? "private, no-store" : "public, max-age=60");
|
|
11909
|
+
res.json({
|
|
11910
|
+
products: products.filter((p) => opts.commerce.visible(p.sku, ctx)).map((p) => {
|
|
11911
|
+
const priced = opts.commerce.price(p.sku, p.priceMinor, ctx);
|
|
11912
|
+
const image = rules?.products?.[p.sku]?.imageUrl ?? p.imageUrls?.[0];
|
|
11913
|
+
return {
|
|
11914
|
+
sku: p.sku,
|
|
11915
|
+
name: p.name,
|
|
11916
|
+
...p.description && { description: p.description },
|
|
11917
|
+
price: priced.priceMinor / 100,
|
|
11918
|
+
currency: p.currency,
|
|
11919
|
+
...image && { image_url: image },
|
|
11920
|
+
in_stock: p.inStock !== false,
|
|
11921
|
+
...p.url && { url: p.url },
|
|
11922
|
+
...priced.issuerProgram && {
|
|
11923
|
+
issuer_offer: {
|
|
11924
|
+
program: priced.issuerProgram,
|
|
11925
|
+
regular_price: (priced.regularMinor ?? p.priceMinor) / 100
|
|
11926
|
+
}
|
|
11927
|
+
}
|
|
11928
|
+
};
|
|
11929
|
+
})
|
|
11930
|
+
});
|
|
11931
|
+
};
|
|
11932
|
+
}
|
|
11933
|
+
|
|
11718
11934
|
// src/ucp/checkout-kit.ts
|
|
11719
11935
|
var import_crypto8 = require("crypto");
|
|
11720
11936
|
var import_jose3 = require("jose");
|
|
@@ -12533,6 +12749,7 @@ var clone = (v) => JSON.parse(JSON.stringify(v));
|
|
|
12533
12749
|
var inFlight = (st) => st === "complete_in_progress" || st === "finishing";
|
|
12534
12750
|
function createUcpCheckoutKit(opts) {
|
|
12535
12751
|
const profile = buildUcpProfile(opts.profile);
|
|
12752
|
+
opts.agentCommerce?.report({ checkoutUrl: opts.profile.endpoint, protocols: ["ucp"] });
|
|
12536
12753
|
const store = opts.store ?? new MemoryCheckoutStore();
|
|
12537
12754
|
const idem = {
|
|
12538
12755
|
store: opts.idempotencyStore ?? new MemoryIdempotencyStore(),
|
|
@@ -12706,9 +12923,7 @@ function createUcpCheckoutKit(opts) {
|
|
|
12706
12923
|
delete s._approvalId;
|
|
12707
12924
|
if (settled.status === "failed") {
|
|
12708
12925
|
s.status = "ready_for_complete";
|
|
12709
|
-
s.messages = [
|
|
12710
|
-
ucpError("payment_failed", "The payment did not go through.", "recoverable")
|
|
12711
|
-
];
|
|
12926
|
+
s.messages = [ucpError("payment_failed", "The payment did not go through.", "recoverable")];
|
|
12712
12927
|
await save(s);
|
|
12713
12928
|
return;
|
|
12714
12929
|
}
|
|
@@ -12742,9 +12957,10 @@ function createUcpCheckoutKit(opts) {
|
|
|
12742
12957
|
const b = checkUcpAgentBinding(req.headers.get("ucp-agent"), identities);
|
|
12743
12958
|
return b.ok ? null : b;
|
|
12744
12959
|
}
|
|
12745
|
-
async function priceLines(lines) {
|
|
12960
|
+
async function priceLines(lines, pricing = { verified: false }) {
|
|
12746
12961
|
const out = [];
|
|
12747
12962
|
const messages = [];
|
|
12963
|
+
let issuerProgram;
|
|
12748
12964
|
for (const [i, l] of lines.entries()) {
|
|
12749
12965
|
const q = Math.max(1, Math.floor(l.quantity ?? 1));
|
|
12750
12966
|
const found = l.item?.id ? await opts.catalog(l.item.id, q) : null;
|
|
@@ -12760,6 +12976,22 @@ function createUcpCheckoutKit(opts) {
|
|
|
12760
12976
|
);
|
|
12761
12977
|
continue;
|
|
12762
12978
|
}
|
|
12979
|
+
if (opts.agentCommerce) {
|
|
12980
|
+
if (!opts.agentCommerce.visible(item.id, pricing)) {
|
|
12981
|
+
messages.push(
|
|
12982
|
+
ucpError(
|
|
12983
|
+
"item_unavailable",
|
|
12984
|
+
`Item ${item.id} is unavailable.`,
|
|
12985
|
+
"recoverable",
|
|
12986
|
+
`$.line_items[${i}]`
|
|
12987
|
+
)
|
|
12988
|
+
);
|
|
12989
|
+
continue;
|
|
12990
|
+
}
|
|
12991
|
+
const priced = opts.agentCommerce.price(item.id, item.price, pricing);
|
|
12992
|
+
item.price = priced.priceMinor;
|
|
12993
|
+
if (priced.issuerProgram) issuerProgram = priced.issuerProgram;
|
|
12994
|
+
}
|
|
12763
12995
|
const amount = item.price * q;
|
|
12764
12996
|
out.push({
|
|
12765
12997
|
id: `li_${i + 1}`,
|
|
@@ -12775,6 +13007,7 @@ function createUcpCheckoutKit(opts) {
|
|
|
12775
13007
|
return {
|
|
12776
13008
|
lines: out,
|
|
12777
13009
|
messages,
|
|
13010
|
+
issuerProgram,
|
|
12778
13011
|
totals: [
|
|
12779
13012
|
{ type: "subtotal", amount: sum },
|
|
12780
13013
|
{ type: "total", amount: sum }
|
|
@@ -12944,7 +13177,11 @@ function createUcpCheckoutKit(opts) {
|
|
|
12944
13177
|
...checkoutJwt && { checkoutJwt },
|
|
12945
13178
|
valueMajor: total(s) / 100,
|
|
12946
13179
|
agentArtifacts,
|
|
12947
|
-
metadata: {
|
|
13180
|
+
metadata: {
|
|
13181
|
+
kitSessionId: s.id,
|
|
13182
|
+
protocol: "ucp",
|
|
13183
|
+
...s._issuerProgram && { issuerProgram: s._issuerProgram }
|
|
13184
|
+
}
|
|
12948
13185
|
});
|
|
12949
13186
|
const binding2 = await bindAgent(req, result);
|
|
12950
13187
|
if (binding2) {
|
|
@@ -13083,7 +13320,11 @@ function createUcpCheckoutKit(opts) {
|
|
|
13083
13320
|
attemptId: s._attemptId,
|
|
13084
13321
|
...checkoutJwt && { checkoutJwt },
|
|
13085
13322
|
valueMajor: total(s) / 100,
|
|
13086
|
-
metadata: {
|
|
13323
|
+
metadata: {
|
|
13324
|
+
kitSessionId: s.id,
|
|
13325
|
+
protocol: "ucp",
|
|
13326
|
+
...s._issuerProgram && { issuerProgram: s._issuerProgram }
|
|
13327
|
+
},
|
|
13087
13328
|
resumed: { ...s._approvalId && { approvalId: s._approvalId } }
|
|
13088
13329
|
});
|
|
13089
13330
|
if (isHeld(result)) {
|
|
@@ -13198,7 +13439,10 @@ function createUcpCheckoutKit(opts) {
|
|
|
13198
13439
|
const caller = await resolveCallerScope(req, reqCtx, opts.resolveCallerId) ?? fallbackScope("ucp-profile", ctx.profileUrl);
|
|
13199
13440
|
if (req.method === "POST" && path === "/checkout-sessions") {
|
|
13200
13441
|
return withIdempotency2(req, body, path, caller, async () => {
|
|
13201
|
-
const priced = await priceLines(
|
|
13442
|
+
const priced = await priceLines(
|
|
13443
|
+
parsed.line_items ?? [],
|
|
13444
|
+
pricingContextFrom(req.headers)
|
|
13445
|
+
);
|
|
13202
13446
|
const webhookUrl = ctx.plat.ucp.capabilities?.[UCP_ORDER_CAPABILITY]?.[0]?.config?.webhook_url;
|
|
13203
13447
|
const s2 = {
|
|
13204
13448
|
id: `chk_${(0, import_crypto8.randomUUID)().replace(/-/g, "")}`,
|
|
@@ -13215,7 +13459,8 @@ function createUcpCheckoutKit(opts) {
|
|
|
13215
13459
|
...typeof webhookUrl === "string" && /^https:\/\//.test(webhookUrl) && { _webhookUrl: webhookUrl },
|
|
13216
13460
|
...req.headers.get("x-astra-checkout-session") && {
|
|
13217
13461
|
_astraCheckoutSessionId: req.headers.get("x-astra-checkout-session").slice(0, 64)
|
|
13218
|
-
}
|
|
13462
|
+
},
|
|
13463
|
+
...priced.issuerProgram && { _issuerProgram: priced.issuerProgram }
|
|
13219
13464
|
};
|
|
13220
13465
|
if (!priced.lines.length) {
|
|
13221
13466
|
return json2(
|
|
@@ -13260,8 +13505,13 @@ function createUcpCheckoutKit(opts) {
|
|
|
13260
13505
|
if (inFlight(s.status)) return busy(s);
|
|
13261
13506
|
if (s.status === "requires_escalation") return heldNoEdit(s);
|
|
13262
13507
|
if (parsed.line_items) {
|
|
13263
|
-
const priced = await priceLines(
|
|
13508
|
+
const priced = await priceLines(
|
|
13509
|
+
parsed.line_items,
|
|
13510
|
+
pricingContextFrom(req.headers)
|
|
13511
|
+
);
|
|
13264
13512
|
s.line_items = priced.lines;
|
|
13513
|
+
if (priced.issuerProgram) s._issuerProgram = priced.issuerProgram;
|
|
13514
|
+
else delete s._issuerProgram;
|
|
13265
13515
|
s.totals = priced.totals;
|
|
13266
13516
|
s.messages = priced.messages;
|
|
13267
13517
|
s.status = priced.lines.length && !priced.messages.length ? "ready_for_complete" : "incomplete";
|
|
@@ -13907,6 +14157,7 @@ function heldBody2(text) {
|
|
|
13907
14157
|
}
|
|
13908
14158
|
}
|
|
13909
14159
|
function createAcpCheckoutKit(opts) {
|
|
14160
|
+
opts.agentCommerce?.report({ protocols: ["acp"] });
|
|
13910
14161
|
const mem = /* @__PURE__ */ new Map();
|
|
13911
14162
|
const store = opts.store ?? {
|
|
13912
14163
|
get: async (id) => mem.get(id) ?? null,
|
|
@@ -13959,9 +14210,10 @@ function createAcpCheckoutKit(opts) {
|
|
|
13959
14210
|
...s.order && { order: s.order }
|
|
13960
14211
|
};
|
|
13961
14212
|
}
|
|
13962
|
-
async function price(items) {
|
|
14213
|
+
async function price(items, pricing = { verified: false }) {
|
|
13963
14214
|
const lines = [];
|
|
13964
14215
|
const messages = [];
|
|
14216
|
+
let issuerProgram;
|
|
13965
14217
|
for (const [i, it] of items.entries()) {
|
|
13966
14218
|
const q = Math.max(1, Math.floor(it.quantity ?? 1));
|
|
13967
14219
|
const found = it.id ? await opts.catalog(it.id, q) : null;
|
|
@@ -13976,6 +14228,21 @@ function createAcpCheckoutKit(opts) {
|
|
|
13976
14228
|
});
|
|
13977
14229
|
continue;
|
|
13978
14230
|
}
|
|
14231
|
+
if (opts.agentCommerce) {
|
|
14232
|
+
if (!opts.agentCommerce.visible(c.id, pricing)) {
|
|
14233
|
+
messages.push({
|
|
14234
|
+
type: "error",
|
|
14235
|
+
code: "not_found",
|
|
14236
|
+
content: `Item ${c.id} not found.`,
|
|
14237
|
+
resolution: "recoverable",
|
|
14238
|
+
param: `$.line_items[${i}]`
|
|
14239
|
+
});
|
|
14240
|
+
continue;
|
|
14241
|
+
}
|
|
14242
|
+
const priced = opts.agentCommerce.price(c.id, c.price, pricing);
|
|
14243
|
+
c.price = priced.priceMinor;
|
|
14244
|
+
if (priced.issuerProgram) issuerProgram = priced.issuerProgram;
|
|
14245
|
+
}
|
|
13979
14246
|
const amount = c.price * q;
|
|
13980
14247
|
lines.push({
|
|
13981
14248
|
id: `li_${i + 1}`,
|
|
@@ -13999,6 +14266,7 @@ function createAcpCheckoutKit(opts) {
|
|
|
13999
14266
|
return {
|
|
14000
14267
|
lines,
|
|
14001
14268
|
messages,
|
|
14269
|
+
issuerProgram,
|
|
14002
14270
|
totals: [
|
|
14003
14271
|
{ type: "subtotal", amount: sum },
|
|
14004
14272
|
{ type: "total", amount: sum }
|
|
@@ -14150,7 +14418,11 @@ function createAcpCheckoutKit(opts) {
|
|
|
14150
14418
|
attemptId,
|
|
14151
14419
|
valueMajor: total2(s) / 100,
|
|
14152
14420
|
agentArtifacts,
|
|
14153
|
-
metadata: {
|
|
14421
|
+
metadata: {
|
|
14422
|
+
kitSessionId: s.id,
|
|
14423
|
+
protocol: "acp",
|
|
14424
|
+
...s._issuerProgram && { issuerProgram: s._issuerProgram }
|
|
14425
|
+
}
|
|
14154
14426
|
});
|
|
14155
14427
|
if (isHeld(result)) {
|
|
14156
14428
|
s.status = "pending_approval";
|
|
@@ -14287,7 +14559,11 @@ function createAcpCheckoutKit(opts) {
|
|
|
14287
14559
|
astraId: s._astraId,
|
|
14288
14560
|
attemptId: s._attemptId,
|
|
14289
14561
|
valueMajor: total2(s) / 100,
|
|
14290
|
-
metadata: {
|
|
14562
|
+
metadata: {
|
|
14563
|
+
kitSessionId: s.id,
|
|
14564
|
+
protocol: "acp",
|
|
14565
|
+
...s._issuerProgram && { issuerProgram: s._issuerProgram }
|
|
14566
|
+
},
|
|
14291
14567
|
resumed: { ...s._approvalId && { approvalId: s._approvalId } }
|
|
14292
14568
|
});
|
|
14293
14569
|
if (isHeld(result)) {
|
|
@@ -14405,7 +14681,7 @@ function createAcpCheckoutKit(opts) {
|
|
|
14405
14681
|
const items = parsed.line_items ?? parsed.items;
|
|
14406
14682
|
if (!items?.length)
|
|
14407
14683
|
return apiError(400, "missing", "line_items is required.", "$.line_items");
|
|
14408
|
-
const p = await price(items);
|
|
14684
|
+
const p = await price(items, pricingContextFrom(req.headers));
|
|
14409
14685
|
const s2 = {
|
|
14410
14686
|
id: `cs_${(0, import_crypto12.randomUUID)().replace(/-/g, "")}`,
|
|
14411
14687
|
status: p.lines.length && !p.messages.length ? "ready_for_payment" : "not_ready_for_payment",
|
|
@@ -14416,7 +14692,8 @@ function createAcpCheckoutKit(opts) {
|
|
|
14416
14692
|
_caller: caller,
|
|
14417
14693
|
...req.headers.get("x-astra-checkout-session") && {
|
|
14418
14694
|
_astraCheckoutSessionId: req.headers.get("x-astra-checkout-session").slice(0, 64)
|
|
14419
|
-
}
|
|
14695
|
+
},
|
|
14696
|
+
...p.issuerProgram && { _issuerProgram: p.issuerProgram }
|
|
14420
14697
|
};
|
|
14421
14698
|
if (s2.status === "ready_for_payment") {
|
|
14422
14699
|
const v = await validate(s2);
|
|
@@ -14445,7 +14722,9 @@ function createAcpCheckoutKit(opts) {
|
|
|
14445
14722
|
);
|
|
14446
14723
|
const items = parsed.line_items ?? parsed.items;
|
|
14447
14724
|
if (items) {
|
|
14448
|
-
const p = await price(items);
|
|
14725
|
+
const p = await price(items, pricingContextFrom(req.headers));
|
|
14726
|
+
if (p.issuerProgram) s._issuerProgram = p.issuerProgram;
|
|
14727
|
+
else delete s._issuerProgram;
|
|
14449
14728
|
Object.assign(s, {
|
|
14450
14729
|
line_items: p.lines,
|
|
14451
14730
|
totals: p.totals,
|
|
@@ -14596,6 +14875,7 @@ function expressHandler(kit, options = {}) {
|
|
|
14596
14875
|
DECLARED_SOURCE_MAX,
|
|
14597
14876
|
DEFAULT_EDGE_CONFIG,
|
|
14598
14877
|
DEFAULT_IDEMPOTENCY_TTL_MS,
|
|
14878
|
+
ISSUER_PROGRAM_HEADER,
|
|
14599
14879
|
KYDRequiredError,
|
|
14600
14880
|
MAX_HEADERS,
|
|
14601
14881
|
MAX_HEADER_VALUE_BYTES,
|
|
@@ -14654,6 +14934,7 @@ function expressHandler(kit, options = {}) {
|
|
|
14654
14934
|
closedPaymentMandate,
|
|
14655
14935
|
contentDigest,
|
|
14656
14936
|
createAcpCheckoutKit,
|
|
14937
|
+
createAgentCommerce,
|
|
14657
14938
|
createKbHop,
|
|
14658
14939
|
createMcpMiddleware,
|
|
14659
14940
|
createUcpCheckoutKit,
|
|
@@ -14675,6 +14956,7 @@ function expressHandler(kit, options = {}) {
|
|
|
14675
14956
|
fetchRoutes,
|
|
14676
14957
|
fetchUcpProfile,
|
|
14677
14958
|
finishIdempotent,
|
|
14959
|
+
fromFeed,
|
|
14678
14960
|
getCachedWellKnownUrls,
|
|
14679
14961
|
getEdgeConfig,
|
|
14680
14962
|
getTrustLevel,
|
|
@@ -14690,6 +14972,7 @@ function expressHandler(kit, options = {}) {
|
|
|
14690
14972
|
isVerificationUnavailable,
|
|
14691
14973
|
isVerifiedHopValidFor,
|
|
14692
14974
|
issueDelegateSdJwt,
|
|
14975
|
+
issuerOfferPrice,
|
|
14693
14976
|
matchEdgePathRule,
|
|
14694
14977
|
matchPlatformSignature,
|
|
14695
14978
|
matchRoutePattern,
|
|
@@ -14700,6 +14983,7 @@ function expressHandler(kit, options = {}) {
|
|
|
14700
14983
|
onVerificationResult,
|
|
14701
14984
|
openCheckoutMandate,
|
|
14702
14985
|
openPaymentMandate,
|
|
14986
|
+
parseFeed,
|
|
14703
14987
|
parseLocalPolicyYaml,
|
|
14704
14988
|
parseMppCredential,
|
|
14705
14989
|
parseUcpAgentHeader,
|
|
@@ -14708,6 +14992,8 @@ function expressHandler(kit, options = {}) {
|
|
|
14708
14992
|
parseX402Payment,
|
|
14709
14993
|
pollStepUpStatus,
|
|
14710
14994
|
prefetchWellKnown,
|
|
14995
|
+
priceForAgent,
|
|
14996
|
+
pricingContextFrom,
|
|
14711
14997
|
quickVerify,
|
|
14712
14998
|
recordDecision,
|
|
14713
14999
|
reportAttempt,
|
|
@@ -14721,6 +15007,7 @@ function expressHandler(kit, options = {}) {
|
|
|
14721
15007
|
sdkFetch,
|
|
14722
15008
|
sendUcpWebhook,
|
|
14723
15009
|
serializeVerifiedHop,
|
|
15010
|
+
serveAgentCatalog,
|
|
14724
15011
|
setMcpMeta,
|
|
14725
15012
|
signHttpRequest,
|
|
14726
15013
|
signRootMandate,
|