@haven_ai/sdk 0.1.33-alpha.0 → 0.1.34-alpha.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/dist/index.cjs +43 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -2
- package/dist/index.d.ts +23 -2
- package/dist/index.js +43 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -617,6 +617,7 @@ function normalizePaymentRequired(value) {
|
|
|
617
617
|
const resourceUrl = candidate.resource?.url ?? first.resource;
|
|
618
618
|
if (!resourceUrl) return null;
|
|
619
619
|
const resource = {
|
|
620
|
+
...candidate.resource && typeof candidate.resource === "object" ? candidate.resource : {},
|
|
620
621
|
url: resourceUrl,
|
|
621
622
|
description: candidate.resource?.description ?? first.description,
|
|
622
623
|
mimeType: candidate.resource?.mimeType ?? first.mimeType
|
|
@@ -691,6 +692,17 @@ function x402PaymentHeaderNamesFor(paymentHeader) {
|
|
|
691
692
|
function x402PaymentHeaderNamesSent(paymentHeader) {
|
|
692
693
|
return x402PaymentHeaderNamesFor(paymentHeader).join(", ");
|
|
693
694
|
}
|
|
695
|
+
function x402V2PaymentEnvelope(paymentRequired, accepted, payload) {
|
|
696
|
+
const resource = paymentRequired.resource;
|
|
697
|
+
const extensions = paymentRequired.extensions;
|
|
698
|
+
return {
|
|
699
|
+
x402Version: paymentRequired.x402Version,
|
|
700
|
+
...resource && typeof resource === "object" && !Array.isArray(resource) ? { resource } : {},
|
|
701
|
+
accepted,
|
|
702
|
+
payload,
|
|
703
|
+
...extensions && typeof extensions === "object" && !Array.isArray(extensions) ? { extensions } : {}
|
|
704
|
+
};
|
|
705
|
+
}
|
|
694
706
|
function parsePaymentRequired(response) {
|
|
695
707
|
const v2Header = response.headers.get("PAYMENT-REQUIRED");
|
|
696
708
|
if (v2Header) {
|
|
@@ -870,7 +882,15 @@ async function validateStandardX402PaymentHeader(paymentHeader, context) {
|
|
|
870
882
|
throw new Error("context");
|
|
871
883
|
}
|
|
872
884
|
} else {
|
|
873
|
-
if (!hasOnlyKeys(decoded, ["x402Version", "accepted", "payload"]
|
|
885
|
+
if (!hasOnlyKeys(decoded, ["x402Version", "accepted", "payload"], ["resource", "extensions"])) {
|
|
886
|
+
throw new Error("shape");
|
|
887
|
+
}
|
|
888
|
+
if ("resource" in decoded && (!decoded.resource || typeof decoded.resource !== "object" || Array.isArray(decoded.resource))) {
|
|
889
|
+
throw new Error("shape");
|
|
890
|
+
}
|
|
891
|
+
if ("extensions" in decoded && (!decoded.extensions || typeof decoded.extensions !== "object" || Array.isArray(decoded.extensions))) {
|
|
892
|
+
throw new Error("shape");
|
|
893
|
+
}
|
|
874
894
|
const accepted = selectStandardPaymentOption([decoded.accepted]);
|
|
875
895
|
if (!accepted || !matchesHeaderContext(accepted, context)) throw new Error("context");
|
|
876
896
|
}
|
|
@@ -922,8 +942,8 @@ async function validateStandardX402PaymentHeader(paymentHeader, context) {
|
|
|
922
942
|
throw new X402PaymentHeaderValidationError();
|
|
923
943
|
}
|
|
924
944
|
}
|
|
925
|
-
function hasOnlyKeys(value,
|
|
926
|
-
return Object.keys(value).every((key) =>
|
|
945
|
+
function hasOnlyKeys(value, required, optional = []) {
|
|
946
|
+
return Object.keys(value).every((key) => required.includes(key) || optional.includes(key)) && required.every((key) => key in value);
|
|
927
947
|
}
|
|
928
948
|
function sameAddress2(left, right) {
|
|
929
949
|
return left.toLowerCase() === right.toLowerCase();
|
|
@@ -2128,11 +2148,7 @@ var X402FundingLeg = class {
|
|
|
2128
2148
|
);
|
|
2129
2149
|
if (paymentRequired.x402Version < 2) return header;
|
|
2130
2150
|
const payment = decodeBase64Json(header);
|
|
2131
|
-
return encodeBase64Json(
|
|
2132
|
-
x402Version: paymentRequired.x402Version,
|
|
2133
|
-
accepted: option,
|
|
2134
|
-
payload: payment.payload
|
|
2135
|
-
});
|
|
2151
|
+
return encodeBase64Json(x402V2PaymentEnvelope(paymentRequired, option, payment.payload));
|
|
2136
2152
|
}
|
|
2137
2153
|
// ── Receipt mapping ──────────────────────────────────────────────
|
|
2138
2154
|
receiptFromAuthorization(paymentRequired, option, paymentHeader, raw, execResult) {
|
|
@@ -2343,6 +2359,16 @@ var X402Erc7710 = class {
|
|
|
2343
2359
|
const amountAtomic = x402AuthorizationAmount(option);
|
|
2344
2360
|
const raw = await this.post("/x402", {
|
|
2345
2361
|
url: options.resourceUrl ?? paymentRequired.resource?.url,
|
|
2362
|
+
// #2373: the full 402 challenge, persisted verbatim by the backend
|
|
2363
|
+
// (#1355) so the settle handoff can echo its resource/extensions into
|
|
2364
|
+
// the X-PAYMENT envelope (#2361). This scheme decomposes the challenge
|
|
2365
|
+
// into the fields below for AUTHORITY; the stored copy exists for the
|
|
2366
|
+
// echo, which cannot be reconstructed from the decomposition — omitting
|
|
2367
|
+
// it is how every erc7710 payment failed a merchant that enforces the
|
|
2368
|
+
// spec's extensions-echo MUST. Same ≤64KB guard and omission behaviour
|
|
2369
|
+
// as the 3009 path (client.ts): an oversized challenge omits the field
|
|
2370
|
+
// rather than failing the payment, and the settle echo then omits too.
|
|
2371
|
+
...new TextEncoder().encode(JSON.stringify(paymentRequired)).length <= 65536 ? { paymentRequired } : {},
|
|
2346
2372
|
// payTo = the MERCHANT is what selects direct settlement server-side.
|
|
2347
2373
|
// The explicit settlementScheme must AGREE with that shape (#1360) —
|
|
2348
2374
|
// disagreement is a 400 by design, so that a stale delegate address
|
|
@@ -4369,8 +4395,14 @@ The paid call always obtains a fresh quote before it creates any intent. Then
|
|
|
4369
4395
|
continue \`mcp__haven__haven_pay_mcp_tool\` \u2192
|
|
4370
4396
|
\`mcp__haven-signer__haven_sign\` \u2192 \`mcp__haven__haven_submit\` \u2192
|
|
4371
4397
|
\`mcp__haven-signer__haven_x402_sign_header\` \u2192
|
|
4372
|
-
\`mcp__haven__haven_complete_mcp_tool\`.
|
|
4373
|
-
\`
|
|
4398
|
+
\`mcp__haven__haven_complete_mcp_tool\`. Call that last step with
|
|
4399
|
+
\`payment_id\` and the signer's \`payment_header\` ONLY. It does not take
|
|
4400
|
+
\`payment_required\`: Haven rehydrates the merchant call context
|
|
4401
|
+
(\`merchant_url\`, \`tool_name\`, \`arguments\`, \`mcp_transport\`) and the
|
|
4402
|
+
402 server-side from \`payment_id\`, exactly as at settle. Pass that context
|
|
4403
|
+
explicitly only as a version-skew fallback when Haven has no stored context
|
|
4404
|
+
for the id \u2014 \`merchant_url\` and \`tool_name\` both or none together, never
|
|
4405
|
+
just one.
|
|
4374
4406
|
The returned \`expires_at\` is the signing window; if a tool returns
|
|
4375
4407
|
\`PAYMENT_WINDOW_EXPIRED\`, re-run the same quote/prepare tool with the same
|
|
4376
4408
|
\`idempotency_key\`. Do not call the merchant yourself \u2014 Haven completes the
|
|
@@ -4652,5 +4684,6 @@ exports.verifySignature = verifySignature;
|
|
|
4652
4684
|
exports.x402AssetTransferMethod = x402AssetTransferMethod;
|
|
4653
4685
|
exports.x402AuthorizationAmount = x402AuthorizationAmount;
|
|
4654
4686
|
exports.x402FacilitatorAddresses = x402FacilitatorAddresses;
|
|
4687
|
+
exports.x402V2PaymentEnvelope = x402V2PaymentEnvelope;
|
|
4655
4688
|
//# sourceMappingURL=index.cjs.map
|
|
4656
4689
|
//# sourceMappingURL=index.cjs.map
|