@haven_ai/sdk 0.9.0-alpha.0 → 0.11.0-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/README.md +9 -6
- package/dist/{base64-BZDPJ8M1.d.ts → base64-D4VZhgUg.d.ts} +11 -3
- package/dist/{base64-Cyxhsvqd.d.cts → base64-DR4Gl8cD.d.cts} +11 -3
- package/dist/{chunk-VRKWNJ7H.js → chunk-34YJQFCM.js} +3 -3
- package/dist/{chunk-VRKWNJ7H.js.map → chunk-34YJQFCM.js.map} +1 -1
- package/dist/{chunk-7UTWSJC5.cjs → chunk-DXBAN4SN.cjs} +4 -4
- package/dist/{chunk-7UTWSJC5.cjs.map → chunk-DXBAN4SN.cjs.map} +1 -1
- package/dist/{chunk-J7N4LUZZ.js → chunk-I7SL4A6X.js} +23 -5
- package/dist/chunk-I7SL4A6X.js.map +1 -0
- package/dist/{chunk-ZDKNPNI3.cjs → chunk-IKQIIMM6.cjs} +41 -35
- package/dist/chunk-IKQIIMM6.cjs.map +1 -0
- package/dist/{chunk-4Z6ATE44.cjs → chunk-MZKLAHBK.cjs} +23 -5
- package/dist/chunk-MZKLAHBK.cjs.map +1 -0
- package/dist/{chunk-424S4QMG.js → chunk-ZDJ55LR7.js} +10 -6
- package/dist/chunk-ZDJ55LR7.js.map +1 -0
- package/dist/edge.cjs +99 -91
- package/dist/edge.d.cts +4 -4
- package/dist/edge.d.ts +4 -4
- package/dist/edge.js +4 -4
- package/dist/index.cjs +861 -459
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +88 -27
- package/dist/index.d.ts +88 -27
- package/dist/index.js +541 -148
- package/dist/index.js.map +1 -1
- package/dist/{receipt-WkXHZGbu.d.ts → receipt-CbD8L0WL.d.ts} +1 -1
- package/dist/{receipt-D4Roey3D.d.cts → receipt-_bWCELEH.d.cts} +1 -1
- package/dist/test-support.cjs +21 -21
- package/dist/test-support.d.cts +2 -2
- package/dist/test-support.d.ts +2 -2
- package/dist/test-support.js +2 -2
- package/dist/{types-CrszUJ7Z.d.cts → types-DKmvjXK6.d.cts} +96 -12
- package/dist/{types-CrszUJ7Z.d.ts → types-DKmvjXK6.d.ts} +96 -12
- package/package.json +1 -1
- package/dist/chunk-424S4QMG.js.map +0 -1
- package/dist/chunk-4Z6ATE44.cjs.map +0 -1
- package/dist/chunk-J7N4LUZZ.js.map +0 -1
- package/dist/chunk-ZDKNPNI3.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
3
|
+
var chunkIKQIIMM6_cjs = require('./chunk-IKQIIMM6.cjs');
|
|
4
|
+
var chunkDXBAN4SN_cjs = require('./chunk-DXBAN4SN.cjs');
|
|
5
|
+
var chunkMZKLAHBK_cjs = require('./chunk-MZKLAHBK.cjs');
|
|
6
6
|
var viem = require('viem');
|
|
7
7
|
var ethers = require('ethers');
|
|
8
8
|
var async_hooks = require('async_hooks');
|
|
@@ -15,7 +15,7 @@ function signHash(privateKey, hash) {
|
|
|
15
15
|
const sig = signingKey.sign(hash);
|
|
16
16
|
return sig.serialized;
|
|
17
17
|
} catch (err) {
|
|
18
|
-
throw new
|
|
18
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
19
19
|
`Failed to sign hash: ${err instanceof Error ? err.message : String(err)}`
|
|
20
20
|
);
|
|
21
21
|
}
|
|
@@ -31,7 +31,7 @@ async function signTypedDataVerbatim(privateKey, typedData, label) {
|
|
|
31
31
|
typedData.message
|
|
32
32
|
);
|
|
33
33
|
} catch (err) {
|
|
34
|
-
throw new
|
|
34
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
35
35
|
`Failed to sign ${label}: ${err instanceof Error ? err.message : String(err)}`
|
|
36
36
|
);
|
|
37
37
|
}
|
|
@@ -46,7 +46,7 @@ function addressFromKey(privateKey) {
|
|
|
46
46
|
try {
|
|
47
47
|
return new ethers.ethers.Wallet(privateKey).address;
|
|
48
48
|
} catch (err) {
|
|
49
|
-
throw new
|
|
49
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
50
50
|
`Invalid private key: ${err instanceof Error ? err.message : String(err)}`
|
|
51
51
|
);
|
|
52
52
|
}
|
|
@@ -62,7 +62,7 @@ function verifySignature(hash, signature, expectedAddress) {
|
|
|
62
62
|
var DEFAULT_BASE_URL = "http://localhost:3001";
|
|
63
63
|
var DEFAULT_REQUEST_TIMEOUT = 3e4;
|
|
64
64
|
function withoutClientHeader(headers) {
|
|
65
|
-
const target =
|
|
65
|
+
const target = chunkIKQIIMM6_cjs.HAVEN_CLIENT_HEADER.toLowerCase();
|
|
66
66
|
return Object.fromEntries(Object.entries(headers).filter(([name]) => name.toLowerCase() !== target));
|
|
67
67
|
}
|
|
68
68
|
var HavenApiTransport = class {
|
|
@@ -78,7 +78,7 @@ var HavenApiTransport = class {
|
|
|
78
78
|
this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
79
79
|
this.requestTimeout = config.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT;
|
|
80
80
|
this.defaultHeaders = { ...config.defaultHeaders ?? {} };
|
|
81
|
-
this.clientIdentity = config.clientIdentity ??
|
|
81
|
+
this.clientIdentity = config.clientIdentity ?? chunkIKQIIMM6_cjs.SDK_CLIENT_IDENTITY;
|
|
82
82
|
}
|
|
83
83
|
/**
|
|
84
84
|
* The newest `client_update` the backend sent (#3303): inside a
|
|
@@ -91,7 +91,7 @@ var HavenApiTransport = class {
|
|
|
91
91
|
}
|
|
92
92
|
recordClientUpdate(data) {
|
|
93
93
|
if (data === null || typeof data !== "object" || Array.isArray(data)) return;
|
|
94
|
-
const hint =
|
|
94
|
+
const hint = chunkIKQIIMM6_cjs.readClientUpdate(data.client_update);
|
|
95
95
|
if (!hint) return;
|
|
96
96
|
this.lastClientUpdate = hint;
|
|
97
97
|
const store = this.requestContext.getStore();
|
|
@@ -124,7 +124,7 @@ var HavenApiTransport = class {
|
|
|
124
124
|
// JOIN `x-haven-client` and `X-Haven-Client` into one unparseable
|
|
125
125
|
// value), so neither `defaultHeaders` nor a dispatch context can
|
|
126
126
|
// misname the client; `clientIdentity` is the one way to set it.
|
|
127
|
-
[
|
|
127
|
+
[chunkIKQIIMM6_cjs.HAVEN_CLIENT_HEADER]: this.clientIdentity
|
|
128
128
|
},
|
|
129
129
|
body: body ? JSON.stringify(body) : void 0,
|
|
130
130
|
signal: controller.signal
|
|
@@ -137,15 +137,15 @@ var HavenApiTransport = class {
|
|
|
137
137
|
const rawDetails = record.details ?? record.detail;
|
|
138
138
|
const detailsText = typeof rawDetails === "string" ? rawDetails : rawDetails != null ? JSON.stringify(rawDetails) : void 0;
|
|
139
139
|
const message = errorText && detailsText ? `${errorText}: ${detailsText}` : errorText ?? detailsText ?? "API request failed";
|
|
140
|
-
throw new
|
|
140
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(message, res.status, data);
|
|
141
141
|
}
|
|
142
142
|
return data;
|
|
143
143
|
} catch (err) {
|
|
144
|
-
if (err instanceof
|
|
144
|
+
if (err instanceof chunkMZKLAHBK_cjs.HavenApiError) throw err;
|
|
145
145
|
if (err instanceof Error && err.name === "AbortError") {
|
|
146
|
-
throw new
|
|
146
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(`Request to ${path} timed out`, 408);
|
|
147
147
|
}
|
|
148
|
-
throw new
|
|
148
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
149
149
|
`Request to ${path} failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
150
150
|
0
|
|
151
151
|
);
|
|
@@ -168,13 +168,13 @@ async function fetchUnsignedTaxDeclaration(client) {
|
|
|
168
168
|
if (reason === "feature_disabled" || reason === "disabled" || reason === "no_company_details" || reason === "vies_not_valid") {
|
|
169
169
|
return { available: false, reason };
|
|
170
170
|
}
|
|
171
|
-
throw new
|
|
171
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
172
172
|
"The tax-declaration endpoint answered a body that is neither the \xA72.1 content nor a named unavailability reason.",
|
|
173
173
|
502
|
|
174
174
|
);
|
|
175
175
|
}
|
|
176
176
|
async function resolveTaxDeclarationHeader(client, input) {
|
|
177
|
-
if (
|
|
177
|
+
if (chunkIKQIIMM6_cjs.isErc7710Option(input.accepted)) {
|
|
178
178
|
return { header: void 0 };
|
|
179
179
|
}
|
|
180
180
|
let content;
|
|
@@ -186,7 +186,7 @@ async function resolveTaxDeclarationHeader(client, input) {
|
|
|
186
186
|
if (!content.available) {
|
|
187
187
|
return { header: void 0 };
|
|
188
188
|
}
|
|
189
|
-
const signed =
|
|
189
|
+
const signed = chunkIKQIIMM6_cjs.buildSignedTaxDeclaration({
|
|
190
190
|
content: content.declaration,
|
|
191
191
|
network: input.accepted.network,
|
|
192
192
|
delegateKey: input.delegateKey
|
|
@@ -195,19 +195,19 @@ async function resolveTaxDeclarationHeader(client, input) {
|
|
|
195
195
|
`[haven-sdk] signing x402 tax declaration taxId=${JSON.stringify(content.declaration.taxId)} jurisdiction=${JSON.stringify(content.declaration.jurisdiction)} principalId=${signed.declaration.principalId}
|
|
196
196
|
`
|
|
197
197
|
);
|
|
198
|
-
return { header:
|
|
198
|
+
return { header: chunkIKQIIMM6_cjs.encodeTaxDeclarationHeader(signed) };
|
|
199
199
|
}
|
|
200
200
|
function withTaxDeclarationHeader(init, header) {
|
|
201
201
|
if (!header) {
|
|
202
|
-
if (init?.headers && new Headers(init.headers).has(
|
|
202
|
+
if (init?.headers && new Headers(init.headers).has(chunkIKQIIMM6_cjs.X_TAX_DECLARATION_HEADER)) {
|
|
203
203
|
const headers2 = new Headers(init.headers);
|
|
204
|
-
headers2.delete(
|
|
204
|
+
headers2.delete(chunkIKQIIMM6_cjs.X_TAX_DECLARATION_HEADER);
|
|
205
205
|
return { ...init, headers: headers2 };
|
|
206
206
|
}
|
|
207
207
|
return init ?? {};
|
|
208
208
|
}
|
|
209
209
|
const headers = new Headers(init?.headers);
|
|
210
|
-
headers.set(
|
|
210
|
+
headers.set(chunkIKQIIMM6_cjs.X_TAX_DECLARATION_HEADER, header);
|
|
211
211
|
return { ...init, headers };
|
|
212
212
|
}
|
|
213
213
|
|
|
@@ -373,29 +373,29 @@ function paymentStateStatusCode(status, fallback = 502) {
|
|
|
373
373
|
return PAYMENT_STATE_STATUS_CODES[status] ?? fallback;
|
|
374
374
|
}
|
|
375
375
|
function phaseForStatus(status) {
|
|
376
|
-
if (status === "pending_signature") return
|
|
377
|
-
if (status === "submitted") return
|
|
378
|
-
if (status === "confirmed") return
|
|
379
|
-
if (status === "pending" || status === "pending_approval") return
|
|
380
|
-
if (status === "approved") return
|
|
381
|
-
if (status === "proposed") return
|
|
382
|
-
if (status === "executed") return
|
|
383
|
-
if (status === "rejected") return
|
|
384
|
-
if (status === "expired") return
|
|
385
|
-
if (status === "failed") return
|
|
376
|
+
if (status === "pending_signature") return chunkMZKLAHBK_cjs.AgentPaymentPhase.AgentSignatureRequired;
|
|
377
|
+
if (status === "submitted") return chunkMZKLAHBK_cjs.AgentPaymentPhase.PaymentSubmitted;
|
|
378
|
+
if (status === "confirmed") return chunkMZKLAHBK_cjs.AgentPaymentPhase.PaymentConfirmed;
|
|
379
|
+
if (status === "pending" || status === "pending_approval") return chunkMZKLAHBK_cjs.AgentPaymentPhase.UserApprovalRequired;
|
|
380
|
+
if (status === "approved") return chunkMZKLAHBK_cjs.AgentPaymentPhase.UserExecutionRequired;
|
|
381
|
+
if (status === "proposed") return chunkMZKLAHBK_cjs.AgentPaymentPhase.WaitingForAdditionalApprovals;
|
|
382
|
+
if (status === "executed") return chunkMZKLAHBK_cjs.AgentPaymentPhase.FundingSent;
|
|
383
|
+
if (status === "rejected") return chunkMZKLAHBK_cjs.AgentPaymentPhase.Rejected;
|
|
384
|
+
if (status === "expired") return chunkMZKLAHBK_cjs.AgentPaymentPhase.Expired;
|
|
385
|
+
if (status === "failed") return chunkMZKLAHBK_cjs.AgentPaymentPhase.Failed;
|
|
386
386
|
return null;
|
|
387
387
|
}
|
|
388
388
|
function nextActionForStatus(status) {
|
|
389
|
-
if (status === "pending_signature") return
|
|
390
|
-
if (status === "submitted") return
|
|
391
|
-
if (status === "confirmed") return
|
|
392
|
-
if (status === "pending" || status === "pending_approval") return
|
|
393
|
-
if (status === "approved") return
|
|
394
|
-
if (status === "proposed") return
|
|
395
|
-
if (status === "executed") return
|
|
396
|
-
if (status === "rejected") return
|
|
397
|
-
if (status === "expired") return
|
|
398
|
-
if (status === "failed") return
|
|
389
|
+
if (status === "pending_signature") return chunkMZKLAHBK_cjs.AgentPaymentNextAction.SignAndSubmitPayment;
|
|
390
|
+
if (status === "submitted") return chunkMZKLAHBK_cjs.AgentPaymentNextAction.CheckStatusLater;
|
|
391
|
+
if (status === "confirmed") return chunkMZKLAHBK_cjs.AgentPaymentNextAction.None;
|
|
392
|
+
if (status === "pending" || status === "pending_approval") return chunkMZKLAHBK_cjs.AgentPaymentNextAction.StopAndTellUser;
|
|
393
|
+
if (status === "approved") return chunkMZKLAHBK_cjs.AgentPaymentNextAction.StopAndTellUser;
|
|
394
|
+
if (status === "proposed") return chunkMZKLAHBK_cjs.AgentPaymentNextAction.StopAndTellUser;
|
|
395
|
+
if (status === "executed") return chunkMZKLAHBK_cjs.AgentPaymentNextAction.StopAndTellUser;
|
|
396
|
+
if (status === "rejected") return chunkMZKLAHBK_cjs.AgentPaymentNextAction.StopAndTellUser;
|
|
397
|
+
if (status === "expired") return chunkMZKLAHBK_cjs.AgentPaymentNextAction.RequestAgainIfUserStillWantsIt;
|
|
398
|
+
if (status === "failed") return chunkMZKLAHBK_cjs.AgentPaymentNextAction.StopAndTellUser;
|
|
399
399
|
return null;
|
|
400
400
|
}
|
|
401
401
|
function messageForState(label, status, paymentId, nextAction) {
|
|
@@ -469,17 +469,17 @@ function throwPaymentStateError(label, raw) {
|
|
|
469
469
|
const statusCode = paymentStateStatusCode(raw.status);
|
|
470
470
|
const state = paymentStateFromRaw(label, raw);
|
|
471
471
|
if (state) {
|
|
472
|
-
throw new
|
|
472
|
+
throw new chunkMZKLAHBK_cjs.HavenPaymentStateError(state.message, statusCode, state, raw);
|
|
473
473
|
}
|
|
474
474
|
if (raw.status === "pending_approval") {
|
|
475
|
-
throw new
|
|
475
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
476
476
|
`${label} exceeds the agent's on-chain budget and was declined; no approval is pending and none will arrive (payment_id: ${raw.payment_id}).`,
|
|
477
477
|
statusCode,
|
|
478
478
|
raw
|
|
479
479
|
);
|
|
480
480
|
}
|
|
481
481
|
if (raw.status === "expired") {
|
|
482
|
-
throw new
|
|
482
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
483
483
|
`${label} expired before it could be completed (payment_id: ${raw.payment_id}).`,
|
|
484
484
|
statusCode,
|
|
485
485
|
raw
|
|
@@ -487,7 +487,7 @@ function throwPaymentStateError(label, raw) {
|
|
|
487
487
|
}
|
|
488
488
|
const paymentId = raw.payment_id ? ` (payment_id: ${raw.payment_id})` : "";
|
|
489
489
|
const message = raw.error ?? `${label} ${raw.status}${paymentId}`;
|
|
490
|
-
throw new
|
|
490
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(message, statusCode, raw);
|
|
491
491
|
}
|
|
492
492
|
|
|
493
493
|
// src/x402-retry-target.ts
|
|
@@ -519,7 +519,7 @@ function isSecureX402RetryTarget(url) {
|
|
|
519
519
|
return RESERVED_SUFFIXES.some((suffix) => host.endsWith(suffix));
|
|
520
520
|
}
|
|
521
521
|
var INSECURE_RETRY_TARGET_CODE = "INSECURE_RETRY_TARGET";
|
|
522
|
-
var HavenInsecureRetryTargetError = class extends
|
|
522
|
+
var HavenInsecureRetryTargetError = class extends chunkMZKLAHBK_cjs.HavenError {
|
|
523
523
|
constructor(url) {
|
|
524
524
|
super(
|
|
525
525
|
`Refusing to send a payment header to ${url}: the paid x402 retry must go to an https URL (or a loopback / reserved test host). The merchant's challenge declared this resource URL; retry with the https URL you quoted (pass it as \`url\`), and report a merchant whose challenge downgrades the scheme.`,
|
|
@@ -537,20 +537,38 @@ function assertSecureX402RetryTarget(url) {
|
|
|
537
537
|
|
|
538
538
|
// src/merchant-egress.ts
|
|
539
539
|
var MERCHANT_EGRESS_REFUSED_CODE = "MERCHANT_EGRESS_REFUSED";
|
|
540
|
-
var MerchantEgressRefusedError = class extends
|
|
540
|
+
var MerchantEgressRefusedError = class extends chunkMZKLAHBK_cjs.HavenError {
|
|
541
541
|
url;
|
|
542
542
|
refusal;
|
|
543
543
|
beforeRequest;
|
|
544
|
-
|
|
545
|
-
|
|
544
|
+
/** #4257: the redirect status that was not followed, when a redirect was refused. */
|
|
545
|
+
redirectStatus;
|
|
546
|
+
/**
|
|
547
|
+
* #4257: set only when `url` IS the redirect target (a cross-origin body
|
|
548
|
+
* re-send, a spent hop budget, a hop `assertUrl` refused). A refusal that
|
|
549
|
+
* stopped at the answering URL itself (a non-GET redirect, a missing or
|
|
550
|
+
* unresolvable Location) leaves it unset, and `url` is that answering URL.
|
|
551
|
+
*/
|
|
552
|
+
redirectTarget;
|
|
553
|
+
/**
|
|
554
|
+
* #4257: set when the refusal interrupted a PAID delivery and the local
|
|
555
|
+
* completion has re-thrown it with the payment it belongs to — the funded,
|
|
556
|
+
* undelivered state, never "nothing happened".
|
|
557
|
+
*/
|
|
558
|
+
settlementScheme;
|
|
559
|
+
constructor(message, url, refusal, beforeRequest, extra = {}) {
|
|
560
|
+
super(message, MERCHANT_EGRESS_REFUSED_CODE, 400, extra.paymentId);
|
|
546
561
|
this.name = "MerchantEgressRefusedError";
|
|
547
562
|
this.url = url;
|
|
548
563
|
this.refusal = refusal;
|
|
549
564
|
this.beforeRequest = beforeRequest;
|
|
565
|
+
this.redirectStatus = extra.redirectStatus;
|
|
566
|
+
this.redirectTarget = extra.redirectTarget;
|
|
567
|
+
this.settlementScheme = extra.settlementScheme;
|
|
550
568
|
}
|
|
551
569
|
};
|
|
552
570
|
var MERCHANT_EGRESS_RESPONSE_CAP_CODE = "MERCHANT_EGRESS_RESPONSE_CAP";
|
|
553
|
-
var MerchantEgressResponseCapError = class extends
|
|
571
|
+
var MerchantEgressResponseCapError = class extends chunkMZKLAHBK_cjs.HavenError {
|
|
554
572
|
url;
|
|
555
573
|
limitBytes;
|
|
556
574
|
constructor(message, limitBytes, url) {
|
|
@@ -661,6 +679,29 @@ var MCP_X402_PAYMENT_META_KEY = "x402/payment";
|
|
|
661
679
|
var MCP_X402_PAYMENT_RESPONSE_META_KEY = "x402/payment-response";
|
|
662
680
|
var X402_RETRY_REJECTED_STATUS = 402;
|
|
663
681
|
var SESSION_NOT_FOUND_NEXT_ACTION = "reinitialize_then_retry_same_payment_header";
|
|
682
|
+
var CROSS_ORIGIN_REDIRECT_HEADERS = /* @__PURE__ */ new Set([
|
|
683
|
+
"accept",
|
|
684
|
+
"accept-language",
|
|
685
|
+
"user-agent",
|
|
686
|
+
"x402-wallet"
|
|
687
|
+
]);
|
|
688
|
+
function crossOriginRedirectHeaders(headers) {
|
|
689
|
+
const kept = new Headers();
|
|
690
|
+
for (const [name, value] of new Headers(headers)) {
|
|
691
|
+
if (CROSS_ORIGIN_REDIRECT_HEADERS.has(name)) kept.set(name, value);
|
|
692
|
+
}
|
|
693
|
+
return kept;
|
|
694
|
+
}
|
|
695
|
+
var NO_POLICY_MAX_REDIRECTS = 20;
|
|
696
|
+
var REQUEST_BODY_HEADERS = ["content-encoding", "content-language", "content-location", "content-type", "content-length"];
|
|
697
|
+
function redirectedInit(init, status) {
|
|
698
|
+
const method = (init.method ?? "GET").toUpperCase();
|
|
699
|
+
const toGet = (status === 301 || status === 302) && method === "POST" || status === 303 && method !== "GET" && method !== "HEAD";
|
|
700
|
+
if (!toGet) return init;
|
|
701
|
+
const headers = new Headers(init.headers);
|
|
702
|
+
for (const name of REQUEST_BODY_HEADERS) headers.delete(name);
|
|
703
|
+
return { ...init, method: "GET", body: null, headers };
|
|
704
|
+
}
|
|
664
705
|
var McpMerchantTransport = class {
|
|
665
706
|
merchantTimeout;
|
|
666
707
|
fetchImpl;
|
|
@@ -691,99 +732,169 @@ var McpMerchantTransport = class {
|
|
|
691
732
|
}
|
|
692
733
|
/** Fetch a merchant with a settlement-sized timeout and caller cancellation. */
|
|
693
734
|
async fetch(url, init = {}, timeoutMs = this.merchantTimeout, maxBytes) {
|
|
735
|
+
return this.send(url, init, timeoutMs, maxBytes, false);
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* `fetch`, plus whether this request is the paid delivery (#4257). A paid
|
|
739
|
+
* delivery, or any body carrying an x402 payment in `_meta`, is never
|
|
740
|
+
* re-sent to another origin by a redirect that keeps the body; without a policy every other
|
|
741
|
+
* request follows that redirect as the platform would, headers reduced.
|
|
742
|
+
*/
|
|
743
|
+
async send(url, init, timeoutMs, maxBytes, paidDelivery) {
|
|
744
|
+
const carriesPayment = paidDelivery || bodyCarriesX402Payment(init.body);
|
|
694
745
|
if (!this.egress) {
|
|
695
746
|
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
696
747
|
const signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;
|
|
697
748
|
try {
|
|
698
|
-
|
|
749
|
+
if (init.redirect === "manual" || init.redirect === "error") {
|
|
750
|
+
return await this.fetchImpl(url, { ...init, signal });
|
|
751
|
+
}
|
|
752
|
+
return await this.followRedirects(url, init, signal, void 0, carriesPayment);
|
|
699
753
|
} catch (err) {
|
|
700
754
|
if (timeoutSignal.aborted) {
|
|
701
|
-
throw new
|
|
755
|
+
throw new chunkMZKLAHBK_cjs.MerchantTimeoutError(`Merchant request timed out after ${timeoutMs}ms: ${url}`);
|
|
702
756
|
}
|
|
703
757
|
throw err;
|
|
704
758
|
}
|
|
705
759
|
}
|
|
706
|
-
return this.fetchUnderPolicy(url, init, timeoutMs, maxBytes);
|
|
760
|
+
return this.fetchUnderPolicy(url, init, timeoutMs, maxBytes, carriesPayment);
|
|
707
761
|
}
|
|
708
762
|
/**
|
|
709
763
|
* #3747: the policy path. Every URL — the initial request and each redirect
|
|
710
764
|
* hop — is `assertUrl`-checked BEFORE it connects; redirects run `manual`
|
|
711
765
|
* so nothing is ever followed un-checked; GET redirects are followed up to
|
|
712
|
-
* `maxGetRedirects` (a redirect on any other method is refused);
|
|
713
|
-
*
|
|
766
|
+
* `maxGetRedirects` (a redirect on any other method is refused); a hop to
|
|
767
|
+
* another origin carries only `CROSS_ORIGIN_REDIRECT_HEADERS` (#4244);
|
|
768
|
+
* response bodies are capped WHILE being read, not after buffering. The timeout
|
|
714
769
|
* signal spans the WHOLE redirect chain, and `MerchantTimeoutError`
|
|
715
770
|
* classification is preserved.
|
|
716
771
|
*/
|
|
717
|
-
async fetchUnderPolicy(url, init, timeoutMs, maxBytes) {
|
|
772
|
+
async fetchUnderPolicy(url, init, timeoutMs, maxBytes, carriesPayment) {
|
|
718
773
|
const egress = this.egress;
|
|
719
774
|
try {
|
|
720
775
|
egress.assertUrl(url);
|
|
721
776
|
} catch (err) {
|
|
722
777
|
throw asRefusal(err, url, true);
|
|
723
778
|
}
|
|
724
|
-
const method = (init.method ?? "GET").toUpperCase();
|
|
725
779
|
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
726
780
|
const signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;
|
|
727
|
-
|
|
781
|
+
let finalUrl = url;
|
|
782
|
+
try {
|
|
783
|
+
const response = await this.followRedirects(url, init, signal, egress, carriesPayment, (hopUrl) => {
|
|
784
|
+
finalUrl = hopUrl;
|
|
785
|
+
});
|
|
786
|
+
return this.capResponse(response, finalUrl, maxBytes);
|
|
787
|
+
} catch (err) {
|
|
788
|
+
if (timeoutSignal.aborted) {
|
|
789
|
+
throw new chunkMZKLAHBK_cjs.MerchantTimeoutError(`Merchant request timed out after ${timeoutMs}ms: ${finalUrl}`);
|
|
790
|
+
}
|
|
791
|
+
throw err;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
/**
|
|
795
|
+
* The redirect follower both paths share (#3747, #4244, #4257). Redirects
|
|
796
|
+
* run `manual` and every hop is decided here:
|
|
797
|
+
*
|
|
798
|
+
* - Under a `policy`, every hop is `assertUrl`-checked before it connects,
|
|
799
|
+
* only GET redirects are followed (any other method is refused), up to
|
|
800
|
+
* `maxGetRedirects`; a missing or unresolvable Location is refused.
|
|
801
|
+
* - Without one, the platform's rules are kept: up to
|
|
802
|
+
* `NO_POLICY_MAX_REDIRECTS` hops, the Fetch spec's method/body rewrite,
|
|
803
|
+
* and a 3xx with no Location returned as the answer.
|
|
804
|
+
* - On both, a hop to another origin carries only
|
|
805
|
+
* `CROSS_ORIGIN_REDIRECT_HEADERS`, never restored on a later hop.
|
|
806
|
+
* - A hop that would re-send a request body to another origin is refused
|
|
807
|
+
* under a policy (which follows GET alone, so this is unreachable there),
|
|
808
|
+
* and without one only when `carriesPayment`: the paid delivery, or a body
|
|
809
|
+
* carrying an x402 payment in `_meta` (#4257). Any other body-keeping redirect is
|
|
810
|
+
* followed with its body, as the platform did, headers reduced.
|
|
811
|
+
*
|
|
812
|
+
* `onHop` sees every URL a request goes to, so the caller can name the hop
|
|
813
|
+
* it was on when the chain stops.
|
|
814
|
+
*/
|
|
815
|
+
async followRedirects(url, init, signal, policy, carriesPayment, onHop) {
|
|
816
|
+
const maxRedirects = policy ? policy.maxGetRedirects ?? 0 : NO_POLICY_MAX_REDIRECTS;
|
|
728
817
|
let currentUrl = url;
|
|
818
|
+
let hopInit = init;
|
|
729
819
|
let hops = 0;
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
820
|
+
while (true) {
|
|
821
|
+
onHop?.(currentUrl);
|
|
822
|
+
const response = await this.fetchImpl(currentUrl, {
|
|
823
|
+
...hopInit,
|
|
824
|
+
redirect: init.redirect === "error" ? "error" : "manual",
|
|
825
|
+
signal
|
|
826
|
+
});
|
|
827
|
+
if (!isRedirectStatus(response.status)) return response;
|
|
828
|
+
const method = (hopInit.method ?? "GET").toUpperCase();
|
|
829
|
+
if (policy && method !== "GET") {
|
|
830
|
+
throw new MerchantEgressRefusedError(
|
|
831
|
+
`Hosted egress policy refuses the ${response.status} redirect from ${currentUrl}: redirects are followed for GET requests only, and this was a ${method}. The request itself was already sent to the checked URL; nothing was sent to the redirect target.`,
|
|
832
|
+
currentUrl,
|
|
833
|
+
"redirect_on_non_get",
|
|
834
|
+
false,
|
|
835
|
+
{ redirectStatus: response.status }
|
|
836
|
+
);
|
|
837
|
+
}
|
|
838
|
+
const location = response.headers.get("location");
|
|
839
|
+
if (!location) {
|
|
840
|
+
if (!policy) return response;
|
|
841
|
+
throw new MerchantEgressRefusedError(
|
|
842
|
+
`Hosted egress policy refuses the ${response.status} redirect from ${currentUrl}: it carries no Location header, so there is no checked target to follow.`,
|
|
843
|
+
currentUrl,
|
|
844
|
+
"redirect_missing_location",
|
|
845
|
+
false,
|
|
846
|
+
{ redirectStatus: response.status }
|
|
847
|
+
);
|
|
848
|
+
}
|
|
849
|
+
let next;
|
|
850
|
+
try {
|
|
851
|
+
next = new URL(location, currentUrl).toString();
|
|
852
|
+
} catch {
|
|
853
|
+
if (!policy) throw new TypeError(`fetch failed: the redirect from ${currentUrl} has an unresolvable Location header`);
|
|
854
|
+
throw new MerchantEgressRefusedError(
|
|
855
|
+
`Hosted egress policy refuses the redirect from ${currentUrl}: its Location header is not a resolvable URL.`,
|
|
856
|
+
currentUrl,
|
|
857
|
+
"redirect_invalid_location",
|
|
858
|
+
false,
|
|
859
|
+
{ redirectStatus: response.status }
|
|
860
|
+
);
|
|
861
|
+
}
|
|
862
|
+
if (!policy && !/^https?:$/.test(new URL(next).protocol)) {
|
|
863
|
+
throw new TypeError(`fetch failed: the redirect from ${currentUrl} names a non-HTTP(S) URL`);
|
|
864
|
+
}
|
|
865
|
+
if (hops >= maxRedirects) {
|
|
866
|
+
if (!policy) throw new TypeError(`fetch failed: redirect count exceeded (${maxRedirects}) at ${currentUrl}`);
|
|
867
|
+
throw new MerchantEgressRefusedError(
|
|
868
|
+
`Hosted egress policy refuses the redirect from ${currentUrl} to ${next}: the ${maxRedirects}-redirect budget for this request is spent.`,
|
|
869
|
+
next,
|
|
870
|
+
"redirect_budget_exceeded",
|
|
871
|
+
false,
|
|
872
|
+
{ redirectStatus: response.status, redirectTarget: next }
|
|
873
|
+
);
|
|
874
|
+
}
|
|
875
|
+
if (policy) {
|
|
756
876
|
try {
|
|
757
|
-
|
|
758
|
-
} catch {
|
|
759
|
-
throw
|
|
760
|
-
`Hosted egress policy refuses the redirect from ${currentUrl}: its Location header is not a resolvable URL.`,
|
|
761
|
-
currentUrl,
|
|
762
|
-
"redirect_invalid_location",
|
|
763
|
-
false
|
|
764
|
-
);
|
|
877
|
+
policy.assertUrl(next);
|
|
878
|
+
} catch (err) {
|
|
879
|
+
throw asRefusal(err, next, false, { redirectStatus: response.status, redirectTarget: next });
|
|
765
880
|
}
|
|
766
|
-
|
|
881
|
+
}
|
|
882
|
+
hopInit = redirectedInit(hopInit, response.status);
|
|
883
|
+
if (new URL(next).origin !== new URL(currentUrl).origin) {
|
|
884
|
+
if (hopInit.body != null && (policy || carriesPayment)) {
|
|
767
885
|
throw new MerchantEgressRefusedError(
|
|
768
|
-
`
|
|
886
|
+
carriesPayment ? `The ${response.status} redirect of a paid request from ${currentUrl} to ${next} was not followed: following it would re-send the paid request to a different origin. The paid request, payment header and body included, was already delivered to ${currentUrl}; nothing was sent to ${next}.` : `Refusing the ${response.status} redirect from ${currentUrl} to ${next}: it would re-send the request body to a different origin. The request was already sent to the first URL; nothing was sent to the redirect target.`,
|
|
769
887
|
next,
|
|
770
|
-
"
|
|
771
|
-
false
|
|
888
|
+
"redirect_cross_origin_body",
|
|
889
|
+
false,
|
|
890
|
+
{ redirectStatus: response.status, redirectTarget: next }
|
|
772
891
|
);
|
|
773
892
|
}
|
|
774
|
-
|
|
775
|
-
egress.assertUrl(next);
|
|
776
|
-
} catch (err) {
|
|
777
|
-
throw asRefusal(err, next, false);
|
|
778
|
-
}
|
|
779
|
-
hops++;
|
|
780
|
-
currentUrl = next;
|
|
781
|
-
}
|
|
782
|
-
} catch (err) {
|
|
783
|
-
if (timeoutSignal.aborted) {
|
|
784
|
-
throw new chunk4Z6ATE44_cjs.MerchantTimeoutError(`Merchant request timed out after ${timeoutMs}ms: ${currentUrl}`);
|
|
893
|
+
hopInit = { ...hopInit, headers: crossOriginRedirectHeaders(hopInit.headers) };
|
|
785
894
|
}
|
|
786
|
-
|
|
895
|
+
await response.body?.cancel().catch(() => void 0);
|
|
896
|
+
hops++;
|
|
897
|
+
currentUrl = next;
|
|
787
898
|
}
|
|
788
899
|
}
|
|
789
900
|
/**
|
|
@@ -869,7 +980,7 @@ var McpMerchantTransport = class {
|
|
|
869
980
|
text = await response.clone().text();
|
|
870
981
|
} catch (err) {
|
|
871
982
|
if (err instanceof MerchantEgressResponseCapError) throw err;
|
|
872
|
-
if (isBodyPhaseTimeout(err)) throw new
|
|
983
|
+
if (isBodyPhaseTimeout(err)) throw new chunkMZKLAHBK_cjs.MerchantTimeoutError(`Merchant response body read timed out.`);
|
|
873
984
|
return void 0;
|
|
874
985
|
}
|
|
875
986
|
if ((response.headers.get("content-type") ?? "").includes("text/event-stream")) {
|
|
@@ -894,7 +1005,7 @@ var McpMerchantTransport = class {
|
|
|
894
1005
|
text = await response.clone().text();
|
|
895
1006
|
} catch (err) {
|
|
896
1007
|
if (err instanceof MerchantEgressResponseCapError) throw err;
|
|
897
|
-
if (isBodyPhaseTimeout(err)) throw new
|
|
1008
|
+
if (isBodyPhaseTimeout(err)) throw new chunkMZKLAHBK_cjs.MerchantTimeoutError(`Merchant response body read timed out.`);
|
|
898
1009
|
return response;
|
|
899
1010
|
}
|
|
900
1011
|
const message = selectJsonRpcResult(parseSseJsonRpcMessages(text));
|
|
@@ -956,12 +1067,12 @@ var McpMerchantTransport = class {
|
|
|
956
1067
|
async deliverPayment(url, init, paymentHeader) {
|
|
957
1068
|
assertSecureX402RetryTarget(url);
|
|
958
1069
|
const headers = new Headers(init?.headers);
|
|
959
|
-
const send =
|
|
960
|
-
for (const name of
|
|
1070
|
+
const send = chunkIKQIIMM6_cjs.x402PaymentHeaderNamesFor(paymentHeader);
|
|
1071
|
+
for (const name of chunkIKQIIMM6_cjs.X402_PAYMENT_HEADER_NAMES) {
|
|
961
1072
|
if (send.includes(name)) headers.set(name, paymentHeader);
|
|
962
1073
|
else headers.delete(name);
|
|
963
1074
|
}
|
|
964
|
-
return this.
|
|
1075
|
+
return this.send(url, withMcpPaymentMeta({ ...init, headers }, paymentHeader), this.budgetFor("delivery"), this.capFor("delivery"), true);
|
|
965
1076
|
}
|
|
966
1077
|
/**
|
|
967
1078
|
* #3171: deliver the payment; if the merchant answers its unknown-session
|
|
@@ -1044,7 +1155,7 @@ function mcpToolResultOf(value) {
|
|
|
1044
1155
|
function extractMcpPaymentRequired(toolResult) {
|
|
1045
1156
|
if (toolResult.isError !== true) return void 0;
|
|
1046
1157
|
if (isRecord(toolResult.structuredContent)) {
|
|
1047
|
-
const parsed =
|
|
1158
|
+
const parsed = chunkIKQIIMM6_cjs.normalizePaymentRequired(toolResult.structuredContent);
|
|
1048
1159
|
if (parsed) return parsed;
|
|
1049
1160
|
}
|
|
1050
1161
|
if (Array.isArray(toolResult.content)) {
|
|
@@ -1056,7 +1167,7 @@ function extractMcpPaymentRequired(toolResult) {
|
|
|
1056
1167
|
} catch {
|
|
1057
1168
|
continue;
|
|
1058
1169
|
}
|
|
1059
|
-
const parsed =
|
|
1170
|
+
const parsed = chunkIKQIIMM6_cjs.normalizePaymentRequired(candidate);
|
|
1060
1171
|
if (parsed) return parsed;
|
|
1061
1172
|
}
|
|
1062
1173
|
}
|
|
@@ -1080,7 +1191,7 @@ function withMcpPaymentMeta(init, paymentHeader) {
|
|
|
1080
1191
|
if (!request) return init;
|
|
1081
1192
|
let envelope;
|
|
1082
1193
|
try {
|
|
1083
|
-
envelope =
|
|
1194
|
+
envelope = chunkIKQIIMM6_cjs.decodeBase64Json(paymentHeader);
|
|
1084
1195
|
} catch {
|
|
1085
1196
|
return init;
|
|
1086
1197
|
}
|
|
@@ -1096,7 +1207,28 @@ function withMcpPaymentMeta(init, paymentHeader) {
|
|
|
1096
1207
|
};
|
|
1097
1208
|
}
|
|
1098
1209
|
function encodeMcpSettlementReceipt(settlement) {
|
|
1099
|
-
return
|
|
1210
|
+
return chunkIKQIIMM6_cjs.encodeBase64Json(settlement);
|
|
1211
|
+
}
|
|
1212
|
+
function bodyCarriesX402Payment(body) {
|
|
1213
|
+
let text;
|
|
1214
|
+
if (typeof body === "string") text = body;
|
|
1215
|
+
else if (body instanceof Uint8Array || body instanceof ArrayBuffer) {
|
|
1216
|
+
try {
|
|
1217
|
+
text = new TextDecoder("utf-8", { fatal: true }).decode(body);
|
|
1218
|
+
} catch {
|
|
1219
|
+
return false;
|
|
1220
|
+
}
|
|
1221
|
+
} else return false;
|
|
1222
|
+
let request;
|
|
1223
|
+
try {
|
|
1224
|
+
request = JSON.parse(text);
|
|
1225
|
+
} catch {
|
|
1226
|
+
return false;
|
|
1227
|
+
}
|
|
1228
|
+
return Array.isArray(request) ? request.some(messageCarriesX402Payment) : messageCarriesX402Payment(request);
|
|
1229
|
+
}
|
|
1230
|
+
function messageCarriesX402Payment(message) {
|
|
1231
|
+
return isRecord(message) && isRecord(message.params) && isRecord(message.params._meta) && message.params._meta[MCP_X402_PAYMENT_META_KEY] !== void 0;
|
|
1100
1232
|
}
|
|
1101
1233
|
function parseJsonRpcToolsCall(body) {
|
|
1102
1234
|
if (typeof body !== "string") return void 0;
|
|
@@ -1136,10 +1268,10 @@ function isRecord(value) {
|
|
|
1136
1268
|
function isRedirectStatus(status) {
|
|
1137
1269
|
return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
|
|
1138
1270
|
}
|
|
1139
|
-
function asRefusal(err, url, beforeRequest) {
|
|
1271
|
+
function asRefusal(err, url, beforeRequest, redirect) {
|
|
1140
1272
|
if (!(err instanceof MerchantEgressRefusedError)) return err;
|
|
1141
|
-
if (err.beforeRequest === beforeRequest) return err;
|
|
1142
|
-
return new MerchantEgressRefusedError(err.message, url, err.refusal, beforeRequest);
|
|
1273
|
+
if (err.beforeRequest === beforeRequest && !redirect) return err;
|
|
1274
|
+
return new MerchantEgressRefusedError(err.message, url, err.refusal, beforeRequest, redirect);
|
|
1143
1275
|
}
|
|
1144
1276
|
async function captureMerchantResponse(response) {
|
|
1145
1277
|
const merchant_body = await response.text().catch((err) => {
|
|
@@ -1214,7 +1346,7 @@ function deriveReadiness(status, allowances) {
|
|
|
1214
1346
|
return allowances.some((allowance) => safeBigInt(allowance.remainingAtomic) > 0n) ? "ready" : "needs_approval";
|
|
1215
1347
|
}
|
|
1216
1348
|
function formatRemainingDisplay(tokenAddress, tokenSymbol, remainingAtomic) {
|
|
1217
|
-
const token =
|
|
1349
|
+
const token = chunkIKQIIMM6_cjs.resolveTokenFromAddress(tokenAddress);
|
|
1218
1350
|
return token ? `${formatAtomicAmount(safeBigInt(remainingAtomic), token.decimals)} ${tokenSymbol}` : `${remainingAtomic} ${tokenSymbol} (atomic; unknown decimals)`;
|
|
1219
1351
|
}
|
|
1220
1352
|
function formatTokenAmount(atomic, decimals) {
|
|
@@ -1225,6 +1357,19 @@ function formatTokenAmount(atomic, decimals) {
|
|
|
1225
1357
|
const fracPart = digits.slice(digits.length - decimals).replace(/0+$/, "");
|
|
1226
1358
|
return fracPart ? `${intPart}.${fracPart}` : intPart;
|
|
1227
1359
|
}
|
|
1360
|
+
function mapSupersession(raw) {
|
|
1361
|
+
if (typeof raw !== "object" || raw === null) return null;
|
|
1362
|
+
const { agent_id: replacementAgentId, superseded_at: supersededAt } = raw;
|
|
1363
|
+
if (typeof replacementAgentId !== "string" || replacementAgentId === "") return null;
|
|
1364
|
+
if (typeof supersededAt !== "string" || supersededAt === "") return null;
|
|
1365
|
+
return {
|
|
1366
|
+
replacementAgentId,
|
|
1367
|
+
supersededAt,
|
|
1368
|
+
warning: `This agent was replaced on its machine by agent ${replacementAgentId} at ${supersededAt}. This session is still running as the old agent: restart the agent runtime so it loads the new agent, and ask the user to remove this agent on its Haven agent page if it is no longer used \u2014 it keeps any budget it still holds until then.`,
|
|
1369
|
+
nextAction: chunkMZKLAHBK_cjs.AgentPaymentNextAction.StopAndTellUser,
|
|
1370
|
+
nextToolOmittedReason: "The next step is the user's: restart this session, and remove the superseded agent in the Haven dashboard. No Haven tool does either."
|
|
1371
|
+
};
|
|
1372
|
+
}
|
|
1228
1373
|
function mapTaskBudget(raw) {
|
|
1229
1374
|
return {
|
|
1230
1375
|
id: raw.id,
|
|
@@ -1246,6 +1391,7 @@ function mapTaskBudget(raw) {
|
|
|
1246
1391
|
status: raw.status,
|
|
1247
1392
|
expiresAt: raw.expires_at,
|
|
1248
1393
|
isExpired: raw.is_expired,
|
|
1394
|
+
...raw.is_live === void 0 ? {} : { isLive: raw.is_live },
|
|
1249
1395
|
createdAt: raw.created_at,
|
|
1250
1396
|
openedAt: raw.opened_at,
|
|
1251
1397
|
closedAt: raw.closed_at,
|
|
@@ -1290,7 +1436,7 @@ function summarizePendingSubBudget(row) {
|
|
|
1290
1436
|
};
|
|
1291
1437
|
}
|
|
1292
1438
|
function summarizeTaskBudget(taskBudget) {
|
|
1293
|
-
const token =
|
|
1439
|
+
const token = chunkIKQIIMM6_cjs.resolveTokenFromAddress(taskBudget.tokenAddress);
|
|
1294
1440
|
const maxDisplay = token ? `${formatAtomicAmount(safeBigInt(taskBudget.maxAtomic), token.decimals)} ${token.symbol}` : `${taskBudget.maxAtomic} (atomic; unknown decimals)`;
|
|
1295
1441
|
const spendDisplay = (atomic) => {
|
|
1296
1442
|
if (atomic === null) return null;
|
|
@@ -1399,7 +1545,8 @@ var AccountReads = class {
|
|
|
1399
1545
|
* an agent can still act on, and read-by-id (`haven_get_task_budget`) is
|
|
1400
1546
|
* the any-status surface for everything else:
|
|
1401
1547
|
*
|
|
1402
|
-
* - `closing`
|
|
1548
|
+
* - `closing` stays visible until its expiry (#3773; an expired `closing`
|
|
1549
|
+
* row drops, #3923) — the close submit is
|
|
1403
1550
|
* in flight and the signer's close refusal tells the caller to re-check
|
|
1404
1551
|
* exactly this row's status;
|
|
1405
1552
|
* - `closed` rows drop (terminal — `closed_at` names what happened, and
|
|
@@ -1408,24 +1555,30 @@ var AccountReads = class {
|
|
|
1408
1555
|
* budget reserves nothing and pays nothing);
|
|
1409
1556
|
* - unexpired `pending` and `open` rows stay.
|
|
1410
1557
|
*
|
|
1411
|
-
*
|
|
1412
|
-
*
|
|
1413
|
-
*
|
|
1414
|
-
* `
|
|
1558
|
+
* A filter also runs here, client-side. A row carrying the backend's
|
|
1559
|
+
* `is_live` (#3922) is kept exactly when it is true — the server's own
|
|
1560
|
+
* `status=live` verdict. A row without it (an older backend) is derived by
|
|
1561
|
+
* the same rule: `closing` stays until its expiry, then drops (#3923), as
|
|
1562
|
+
* the backend does since #3773. That is
|
|
1563
|
+
* what keeps the list bounded against a backend that predates `status=live`,
|
|
1564
|
+
* which refuses the value with a 400 — that refusal (and only that) falls
|
|
1565
|
+
* back to `status=all`. A row whose wire carries
|
|
1415
1566
|
* no `is_expired` is treated as unexpired — the degraded read errs toward
|
|
1416
1567
|
* KEEPING rows, never toward hiding one the agent could still act on.
|
|
1417
1568
|
*/
|
|
1418
1569
|
async listTaskBudgetsSummary() {
|
|
1419
1570
|
try {
|
|
1420
1571
|
const raw = await this.transport.get("/task-budgets?status=live").catch((error) => {
|
|
1421
|
-
if (error instanceof
|
|
1572
|
+
if (error instanceof chunkMZKLAHBK_cjs.HavenApiError && error.statusCode === 400) {
|
|
1422
1573
|
return this.transport.get("/task-budgets?status=all");
|
|
1423
1574
|
}
|
|
1424
1575
|
throw error;
|
|
1425
1576
|
});
|
|
1426
1577
|
const rows = raw?.task_budgets;
|
|
1427
1578
|
if (!Array.isArray(rows)) return [];
|
|
1428
|
-
return rows.map((row) => mapTaskBudget(row)).filter(
|
|
1579
|
+
return rows.map((row) => mapTaskBudget(row)).filter(
|
|
1580
|
+
(tb) => tb.isLive !== void 0 ? tb.isLive : !tb.isExpired && tb.status !== "closed"
|
|
1581
|
+
).map((tb) => summarizeTaskBudget(tb));
|
|
1429
1582
|
} catch {
|
|
1430
1583
|
return [];
|
|
1431
1584
|
}
|
|
@@ -1460,6 +1613,7 @@ var AccountReads = class {
|
|
|
1460
1613
|
accountAddress: raw.account_address,
|
|
1461
1614
|
delegateAddress: raw.delegate_address,
|
|
1462
1615
|
chainId: raw.chain_id,
|
|
1616
|
+
supersededBy: mapSupersession(raw.superseded_by),
|
|
1463
1617
|
allowances: raw.allowances.map((allowance) => ({
|
|
1464
1618
|
id: allowance.id,
|
|
1465
1619
|
tokenAddress: allowance.token_address,
|
|
@@ -1525,7 +1679,7 @@ var AccountReads = class {
|
|
|
1525
1679
|
payment: payment2,
|
|
1526
1680
|
allowance: null,
|
|
1527
1681
|
warnings: [{
|
|
1528
|
-
code:
|
|
1682
|
+
code: chunkMZKLAHBK_cjs.AgentPaymentWarningCode.AllowanceCheckUnavailable,
|
|
1529
1683
|
message: `Could not read the post-purchase allowance/budget for payment ${paymentId} (${detail}). The payment itself succeeded \u2014 the on-chain policy remains the actual spend gate; this only affects the remaining-budget figure reported here.`
|
|
1530
1684
|
}]
|
|
1531
1685
|
});
|
|
@@ -1618,7 +1772,7 @@ var AccountReads = class {
|
|
|
1618
1772
|
*/
|
|
1619
1773
|
async getReceipt(paymentId) {
|
|
1620
1774
|
const { receipt } = await this.transport.get(`/payments/${paymentId}/receipt`);
|
|
1621
|
-
return { receipt, verification:
|
|
1775
|
+
return { receipt, verification: chunkDXBAN4SN_cjs.verifyPaymentReceipt(receipt) };
|
|
1622
1776
|
}
|
|
1623
1777
|
async fetchAgent() {
|
|
1624
1778
|
const raw = await this.transport.get("/machine-payments/agent");
|
|
@@ -1632,7 +1786,8 @@ var AccountReads = class {
|
|
|
1632
1786
|
accountAddress: raw.account_address,
|
|
1633
1787
|
delegateAddress: raw.delegate_address,
|
|
1634
1788
|
chainId: raw.chain_id,
|
|
1635
|
-
executionRail: raw.execution_rail === "delegation" ? "delegation" : "legacy"
|
|
1789
|
+
executionRail: raw.execution_rail === "delegation" ? "delegation" : "legacy",
|
|
1790
|
+
supersededBy: mapSupersession(raw.superseded_by)
|
|
1636
1791
|
};
|
|
1637
1792
|
}
|
|
1638
1793
|
};
|
|
@@ -1653,7 +1808,7 @@ function isWaitTimeout(err) {
|
|
|
1653
1808
|
async function waitForSweepTx(tx) {
|
|
1654
1809
|
let receipt;
|
|
1655
1810
|
try {
|
|
1656
|
-
receipt = await tx.wait(1,
|
|
1811
|
+
receipt = await tx.wait(1, chunkMZKLAHBK_cjs.DEFAULT_CONFIRMATION_TIMEOUT_MS);
|
|
1657
1812
|
} catch (err) {
|
|
1658
1813
|
if (!isWaitTimeout(err)) throw err;
|
|
1659
1814
|
return { txHash: tx.hash, confirmation: "unconfirmed" };
|
|
@@ -1667,16 +1822,16 @@ var DelegateSweepApi = class {
|
|
|
1667
1822
|
}
|
|
1668
1823
|
options;
|
|
1669
1824
|
async sweepDelegate() {
|
|
1670
|
-
if (!this.options.delegateKey) throw new
|
|
1825
|
+
if (!this.options.delegateKey) throw new chunkMZKLAHBK_cjs.HavenSigningError("delegateKey is required for sweepDelegate.");
|
|
1671
1826
|
const agent = await this.options.getAgent();
|
|
1672
|
-
if (!agent.delegateAddress) throw new
|
|
1827
|
+
if (!agent.delegateAddress) throw new chunkMZKLAHBK_cjs.HavenApiError("Agent has no delegate address.", 422);
|
|
1673
1828
|
const rpcUrl = this.options.chainRpcs[agent.chainId];
|
|
1674
|
-
if (!rpcUrl) throw new
|
|
1829
|
+
if (!rpcUrl) throw new chunkMZKLAHBK_cjs.HavenApiError(`chainRpcs[${agent.chainId}] must be configured to sweep the delegate wallet.`, 422);
|
|
1675
1830
|
const provider = createJsonRpcProvider(rpcUrl);
|
|
1676
1831
|
const wallet = createWallet(this.options.delegateKey, provider);
|
|
1677
1832
|
const transfers = [];
|
|
1678
|
-
if (
|
|
1679
|
-
const contract = createErc20Contract(
|
|
1833
|
+
if (chunkIKQIIMM6_cjs.isSweepableChain(agent.chainId)) {
|
|
1834
|
+
const contract = createErc20Contract(chunkIKQIIMM6_cjs.sweepUsdcAddress(agent.chainId), ["function balanceOf(address) view returns (uint256)", "function transfer(address to, uint256 amount) returns (bool)"], wallet);
|
|
1680
1835
|
const balance2 = await contract.balanceOf(agent.delegateAddress);
|
|
1681
1836
|
if (balance2 > 0n) {
|
|
1682
1837
|
const tx = await contract.transfer(agent.accountAddress, balance2);
|
|
@@ -1764,7 +1919,7 @@ function snapshotRequestBody(body) {
|
|
|
1764
1919
|
if (body == null) return void 0;
|
|
1765
1920
|
if (typeof body === "string") return body;
|
|
1766
1921
|
if (body instanceof URLSearchParams) return body.toString();
|
|
1767
|
-
throw new
|
|
1922
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
1768
1923
|
"Quote helpers can only capture resumable request bodies that are strings or URLSearchParams. For streams, blobs, or binary bodies, preserve the original request yourself and call the matching resume method with fresh init.",
|
|
1769
1924
|
400
|
|
1770
1925
|
);
|
|
@@ -1785,12 +1940,12 @@ function requestInitFromSnapshot(request) {
|
|
|
1785
1940
|
};
|
|
1786
1941
|
}
|
|
1787
1942
|
function noCompatiblePaymentOptionError(accepts) {
|
|
1788
|
-
const erc7710Only =
|
|
1943
|
+
const erc7710Only = chunkIKQIIMM6_cjs.selectErc7710PaymentOption(accepts) !== null;
|
|
1789
1944
|
const unsupportedOnly = !erc7710Only && accepts.some(
|
|
1790
|
-
(opt) => opt !== null && typeof opt === "object" && !
|
|
1945
|
+
(opt) => opt !== null && typeof opt === "object" && !chunkIKQIIMM6_cjs.isErc7710Option(opt) && (chunkIKQIIMM6_cjs.x402AssetTransferMethod(opt) !== null || opt.extra?.paymentFlow !== void 0)
|
|
1791
1946
|
);
|
|
1792
1947
|
const offeredSchemes = nonExactSchemesOnly(accepts);
|
|
1793
|
-
return new
|
|
1948
|
+
return new chunkMZKLAHBK_cjs.HavenApiError(
|
|
1794
1949
|
"No compatible payment option found in x402 requirements. Haven supports standard x402 exact payments on Base USDC." + (offeredSchemes ? ` The merchant offered only ${offeredSchemes}; Haven pays only the 'exact' scheme. For a request with a body, this often means the body or its Content-Type was missing or invalid: send the full request again (method, body, and Content-Type: application/json for a JSON API).` : erc7710Only ? " The only Haven-compatible option this merchant advertises is tagged extra.assetTransferMethod: 'erc7710' (direct settlement), which this EIP-3009 payment path cannot settle \u2014 the limitation is the settlement scheme, not the asset. Paying this merchant requires a delegation-rail erc7710 flow (settleX402Erc7710, or the hosted MCP purchase tools)." : unsupportedOnly ? " Every option this merchant advertises asks for a transfer method or payment flow Haven cannot construct (for example extra.assetTransferMethod: 'permit2', or an unrecognized extra.paymentFlow). No payment intent was created and no funds moved." : ""),
|
|
1795
1950
|
400
|
|
1796
1951
|
);
|
|
@@ -1809,15 +1964,15 @@ function nonExactSchemesOnly(accepts) {
|
|
|
1809
1964
|
return schemes.map((s) => `'${s}'`).join(", ");
|
|
1810
1965
|
}
|
|
1811
1966
|
function buildX402Quote(paymentRequired, request, idempotencyKey, mcpTransport) {
|
|
1812
|
-
const standard =
|
|
1813
|
-
const option = standard ??
|
|
1967
|
+
const standard = chunkIKQIIMM6_cjs.selectStandardPaymentOption(paymentRequired.accepts);
|
|
1968
|
+
const option = standard ?? chunkIKQIIMM6_cjs.selectErc7710PaymentOption(paymentRequired.accepts);
|
|
1814
1969
|
if (!option) {
|
|
1815
1970
|
throw noCompatiblePaymentOptionError(paymentRequired.accepts);
|
|
1816
1971
|
}
|
|
1817
|
-
const token =
|
|
1972
|
+
const token = chunkIKQIIMM6_cjs.resolveTokenFromAddress(option.asset, option.network);
|
|
1818
1973
|
return {
|
|
1819
1974
|
rail: "x402",
|
|
1820
|
-
idempotencyKey: idempotencyKey ??
|
|
1975
|
+
idempotencyKey: idempotencyKey ?? chunkIKQIIMM6_cjs.buildX402IdempotencyKey(paymentRequired, option),
|
|
1821
1976
|
paymentRequired,
|
|
1822
1977
|
accepted: option,
|
|
1823
1978
|
acceptedScheme: standard ? "standard" : "erc7710",
|
|
@@ -1831,8 +1986,8 @@ function buildX402Quote(paymentRequired, request, idempotencyKey, mcpTransport)
|
|
|
1831
1986
|
resourceUrlDiffersFromRequest: paymentRequired.resource.url !== request.url,
|
|
1832
1987
|
description: paymentRequired.resource.description ?? option.description ?? null,
|
|
1833
1988
|
mimeType: paymentRequired.resource.mimeType ?? option.mimeType ?? null,
|
|
1834
|
-
amountAtomic:
|
|
1835
|
-
amount: decimalFromUsdcAtomic(
|
|
1989
|
+
amountAtomic: chunkIKQIIMM6_cjs.x402AuthorizationAmount(option),
|
|
1990
|
+
amount: decimalFromUsdcAtomic(chunkIKQIIMM6_cjs.x402AuthorizationAmount(option)),
|
|
1836
1991
|
token: token?.symbol ?? "USDC",
|
|
1837
1992
|
// #1351: null when the asset is unrecognised on this network — the
|
|
1838
1993
|
// `token` fallback above is a LABEL, not evidence of 6 decimals, and a
|
|
@@ -1871,7 +2026,7 @@ function buildX402Receipt(input) {
|
|
|
1871
2026
|
payTo: input.merchantTo ?? input.accepted.payTo
|
|
1872
2027
|
},
|
|
1873
2028
|
x402: {
|
|
1874
|
-
amount:
|
|
2029
|
+
amount: chunkIKQIIMM6_cjs.x402AuthorizationAmount(input.accepted),
|
|
1875
2030
|
token: input.token,
|
|
1876
2031
|
network: input.accepted.network,
|
|
1877
2032
|
asset: input.accepted.asset,
|
|
@@ -1880,7 +2035,7 @@ function buildX402Receipt(input) {
|
|
|
1880
2035
|
};
|
|
1881
2036
|
}
|
|
1882
2037
|
function buildX402ResumeState(input) {
|
|
1883
|
-
const token =
|
|
2038
|
+
const token = chunkIKQIIMM6_cjs.resolveTokenFromAddress(input.accepted.asset, input.accepted.network);
|
|
1884
2039
|
return {
|
|
1885
2040
|
rail: "x402",
|
|
1886
2041
|
paymentId: input.paymentId,
|
|
@@ -1891,8 +2046,8 @@ function buildX402ResumeState(input) {
|
|
|
1891
2046
|
request: input.request,
|
|
1892
2047
|
resourceUrl: input.paymentRequired.resource.url,
|
|
1893
2048
|
description: input.paymentRequired.resource.description ?? input.accepted.description ?? null,
|
|
1894
|
-
amountAtomic:
|
|
1895
|
-
amount: decimalFromUsdcAtomic(
|
|
2049
|
+
amountAtomic: chunkIKQIIMM6_cjs.x402AuthorizationAmount(input.accepted),
|
|
2050
|
+
amount: decimalFromUsdcAtomic(chunkIKQIIMM6_cjs.x402AuthorizationAmount(input.accepted)),
|
|
1896
2051
|
token: token?.symbol ?? "USDC",
|
|
1897
2052
|
asset: input.accepted.asset,
|
|
1898
2053
|
network: input.accepted.network,
|
|
@@ -1901,7 +2056,7 @@ function buildX402ResumeState(input) {
|
|
|
1901
2056
|
};
|
|
1902
2057
|
}
|
|
1903
2058
|
function attachX402ResumeState(err, paymentRequired, accepted, idempotencyKey, request) {
|
|
1904
|
-
if (!(err instanceof
|
|
2059
|
+
if (!(err instanceof chunkMZKLAHBK_cjs.HavenPaymentStateError)) return;
|
|
1905
2060
|
if (err.state.rail !== "x402") return;
|
|
1906
2061
|
err.resumeState = buildX402ResumeState({
|
|
1907
2062
|
paymentId: err.state.paymentId,
|
|
@@ -1922,17 +2077,17 @@ function attachResumeState(err, input) {
|
|
|
1922
2077
|
}
|
|
1923
2078
|
function assertCanResumeX402(status, paymentRequired, option) {
|
|
1924
2079
|
if (status.rail !== "x402") {
|
|
1925
|
-
throw new
|
|
2080
|
+
throw new chunkMZKLAHBK_cjs.HavenPaymentStateError(
|
|
1926
2081
|
`Payment ${status.paymentId} is ${status.rail}, not x402.`,
|
|
1927
2082
|
409,
|
|
1928
2083
|
status
|
|
1929
2084
|
);
|
|
1930
2085
|
}
|
|
1931
|
-
if (status.nextAction !==
|
|
1932
|
-
throw new
|
|
2086
|
+
if (status.nextAction !== chunkMZKLAHBK_cjs.AgentPaymentNextAction.RetryOriginalX402Request) {
|
|
2087
|
+
throw new chunkMZKLAHBK_cjs.HavenPaymentStateError(status.message, paymentStateStatusCode(status.status, 409), status);
|
|
1933
2088
|
}
|
|
1934
2089
|
if (!status.txHash) {
|
|
1935
|
-
throw new
|
|
2090
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
1936
2091
|
`x402 payment ${status.paymentId} is ready to retry but has no Haven transaction hash.`,
|
|
1937
2092
|
502,
|
|
1938
2093
|
status,
|
|
@@ -1940,7 +2095,7 @@ function assertCanResumeX402(status, paymentRequired, option) {
|
|
|
1940
2095
|
);
|
|
1941
2096
|
}
|
|
1942
2097
|
if (status.resourceUrl && status.resourceUrl !== paymentRequired.resource.url) {
|
|
1943
|
-
throw new
|
|
2098
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
1944
2099
|
"x402 resume request does not match the approved resource URL.",
|
|
1945
2100
|
409,
|
|
1946
2101
|
{ status, paymentRequired },
|
|
@@ -1948,7 +2103,7 @@ function assertCanResumeX402(status, paymentRequired, option) {
|
|
|
1948
2103
|
);
|
|
1949
2104
|
}
|
|
1950
2105
|
if (status.merchantAddress && !sameAddress(status.merchantAddress, option.payTo)) {
|
|
1951
|
-
throw new
|
|
2106
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
1952
2107
|
"x402 resume request does not match the approved merchant.",
|
|
1953
2108
|
409,
|
|
1954
2109
|
{ status, selectedPayment: option },
|
|
@@ -1957,7 +2112,7 @@ function assertCanResumeX402(status, paymentRequired, option) {
|
|
|
1957
2112
|
}
|
|
1958
2113
|
const optionChainId = chainIdFromNetwork(option.network);
|
|
1959
2114
|
if (status.chainId && optionChainId && status.chainId !== optionChainId) {
|
|
1960
|
-
throw new
|
|
2115
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
1961
2116
|
"x402 resume request does not match the approved network.",
|
|
1962
2117
|
409,
|
|
1963
2118
|
{ status, selectedPayment: option },
|
|
@@ -1965,7 +2120,7 @@ function assertCanResumeX402(status, paymentRequired, option) {
|
|
|
1965
2120
|
);
|
|
1966
2121
|
}
|
|
1967
2122
|
if (status.token && status.token !== "USDC") {
|
|
1968
|
-
throw new
|
|
2123
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
1969
2124
|
"x402 resume request does not match the approved token.",
|
|
1970
2125
|
409,
|
|
1971
2126
|
{ status, selectedPayment: option },
|
|
@@ -1973,9 +2128,9 @@ function assertCanResumeX402(status, paymentRequired, option) {
|
|
|
1973
2128
|
);
|
|
1974
2129
|
}
|
|
1975
2130
|
const approvedAmount = status.amount ? normalizeDecimal(status.amount) : "";
|
|
1976
|
-
const requestedAmount = normalizeDecimal(decimalFromUsdcAtomic(
|
|
2131
|
+
const requestedAmount = normalizeDecimal(decimalFromUsdcAtomic(chunkIKQIIMM6_cjs.x402AuthorizationAmount(option)));
|
|
1977
2132
|
if (approvedAmount && approvedAmount !== requestedAmount) {
|
|
1978
|
-
throw new
|
|
2133
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
1979
2134
|
"x402 resume request does not match the approved amount.",
|
|
1980
2135
|
409,
|
|
1981
2136
|
{ status, selectedPayment: option },
|
|
@@ -2031,7 +2186,7 @@ var X402FundingLeg = class {
|
|
|
2031
2186
|
const cached = this.receiptCache.get(idempotencyKey);
|
|
2032
2187
|
if (!cached || cached.expiresAt <= Date.now()) return void 0;
|
|
2033
2188
|
if (!sameX402TaskBudget(cached.taskBudgetId, taskBudgetId) || !sameX402TaskBudget(cached.subBudgetId, subBudgetId)) {
|
|
2034
|
-
throw new
|
|
2189
|
+
throw new chunkMZKLAHBK_cjs.X402TaskBudgetMismatchError(
|
|
2035
2190
|
`The x402 idempotency key '${idempotencyKey}' was already used under a different authorizing budget (task '${cached.taskBudgetId ?? "none"}' vs '${taskBudgetId ?? "none"}', sub '${cached.subBudgetId ?? "none"}' vs '${subBudgetId ?? "none"}'). Pass a new idempotencyKey to pay under this budget.`,
|
|
2036
2191
|
idempotencyKey,
|
|
2037
2192
|
cached.taskBudgetId,
|
|
@@ -2052,7 +2207,7 @@ var X402FundingLeg = class {
|
|
|
2052
2207
|
url: paymentRequired.resource.url,
|
|
2053
2208
|
payTo: this.delegateAddress,
|
|
2054
2209
|
merchantPayTo: option.payTo,
|
|
2055
|
-
amount:
|
|
2210
|
+
amount: chunkIKQIIMM6_cjs.x402AuthorizationAmount(option),
|
|
2056
2211
|
asset: option.asset,
|
|
2057
2212
|
network: option.network,
|
|
2058
2213
|
description: paymentRequired.resource.description,
|
|
@@ -2071,41 +2226,41 @@ var X402FundingLeg = class {
|
|
|
2071
2226
|
...subBudgetId ? { subBudgetId } : {}
|
|
2072
2227
|
});
|
|
2073
2228
|
const state = paymentStateFromRaw("x402 payment", raw);
|
|
2074
|
-
const executedReplay = raw.success && raw.tx_hash ? "idempotency-collision" : state?.nextAction ===
|
|
2229
|
+
const executedReplay = raw.success && raw.tx_hash ? "idempotency-collision" : state?.nextAction === chunkMZKLAHBK_cjs.AgentPaymentNextAction.RetryOriginalX402Request ? "approval-resume" : null;
|
|
2075
2230
|
if (executedReplay) {
|
|
2076
2231
|
const canFund = await this.delegateCanFund(
|
|
2077
2232
|
raw.chain_id ?? state?.chainId ?? chainIdFromNetwork(option.network),
|
|
2078
2233
|
option.asset,
|
|
2079
|
-
|
|
2234
|
+
chunkIKQIIMM6_cjs.x402AuthorizationAmount(option)
|
|
2080
2235
|
);
|
|
2081
2236
|
const refuse = executedReplay === "idempotency-collision" ? canFund !== true : canFund === false;
|
|
2082
2237
|
if (refuse) {
|
|
2083
2238
|
const settledReceipt = state && executedReplay === "approval-resume" ? this.receiptFromStatus(paymentRequired, option, void 0, state) : this.receiptFromAuthorization(paymentRequired, option, void 0, raw);
|
|
2084
|
-
throw new
|
|
2239
|
+
throw new chunkMZKLAHBK_cjs.X402AlreadySettledError(
|
|
2085
2240
|
canFund === false ? "This x402 payment already settled \u2014 the delegate no longer holds the funds to authorize it again. To buy the same item a second time, pass a distinct `idempotencyKey`; the synthesised key intentionally collapses repeat calls for the same product within a 5-minute window so a retried request cannot pay twice." : "This x402 payment already settled, and whether the delegate can still fund a new authorization could not be verified (no `chainRpcs` entry for this chain). Refusing rather than issue an authorization that may be unfundable. To buy the same item a second time, pass a distinct `idempotencyKey`; to finish an interrupted payment, resume it by `paymentId`.",
|
|
2086
2241
|
settledReceipt,
|
|
2087
2242
|
canFund === false ? "settled" : "unverifiable"
|
|
2088
2243
|
);
|
|
2089
2244
|
}
|
|
2090
2245
|
}
|
|
2091
|
-
const paymentHeader = await this.createPaymentHeader(paymentRequired, option);
|
|
2246
|
+
const paymentHeader = await this.createPaymentHeader(paymentRequired, option, raw.payment_id ?? state?.paymentId);
|
|
2092
2247
|
if (raw.success && raw.tx_hash) {
|
|
2093
2248
|
const receipt2 = this.receiptFromAuthorization(paymentRequired, option, paymentHeader, raw);
|
|
2094
2249
|
this.cacheReceipt(idempotencyKey, paymentHeader, receipt2, taskBudgetId, subBudgetId);
|
|
2095
2250
|
return receipt2;
|
|
2096
2251
|
}
|
|
2097
|
-
if (state?.nextAction ===
|
|
2252
|
+
if (state?.nextAction === chunkMZKLAHBK_cjs.AgentPaymentNextAction.RetryOriginalX402Request) {
|
|
2098
2253
|
const receipt2 = this.receiptFromStatus(paymentRequired, option, paymentHeader, state);
|
|
2099
2254
|
this.cacheReceipt(idempotencyKey, paymentHeader, receipt2, taskBudgetId, subBudgetId);
|
|
2100
2255
|
return receipt2;
|
|
2101
2256
|
}
|
|
2102
2257
|
this.assertSignableAuthorizationState("x402 payment", raw);
|
|
2103
2258
|
if (!raw.sign_data?.hash) {
|
|
2104
|
-
throw new
|
|
2259
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError("No sign_hash returned from x402/authorize", 500, raw);
|
|
2105
2260
|
}
|
|
2106
2261
|
const sig = await this.signForData(raw.sign_data, {
|
|
2107
2262
|
asset: option.asset,
|
|
2108
|
-
amount:
|
|
2263
|
+
amount: chunkIKQIIMM6_cjs.x402AuthorizationAmount(option)
|
|
2109
2264
|
});
|
|
2110
2265
|
const execResult = await this.post(
|
|
2111
2266
|
`/payments/${raw.payment_id}/sign`,
|
|
@@ -2123,27 +2278,54 @@ var X402FundingLeg = class {
|
|
|
2123
2278
|
return receipt;
|
|
2124
2279
|
}
|
|
2125
2280
|
// ── Header minting ───────────────────────────────────────────────
|
|
2126
|
-
|
|
2281
|
+
/**
|
|
2282
|
+
* Mint the merchant-facing X-PAYMENT header with the delegate key.
|
|
2283
|
+
*
|
|
2284
|
+
* #3888: when `paymentId` is given, the EIP-3009 nonce is the shared
|
|
2285
|
+
* derivation from that Haven payment id instead of the x402 library's
|
|
2286
|
+
* random draw — that is what lets the backend attribute the merchant's
|
|
2287
|
+
* `AuthorizationUsed(delegate, nonce)` settlement to this payment when the
|
|
2288
|
+
* agent never reports it, and what makes a resume/retry re-sign of a
|
|
2289
|
+
* settled payment carry the SAME nonce (the merchant refuses it as already
|
|
2290
|
+
* used, closing the #3475 re-pay hazard). The signed typed data stays the
|
|
2291
|
+
* library's own: the nonce only overwrites the field on the unsigned
|
|
2292
|
+
* payload `preparePaymentHeader` built. Without a payment id the library's
|
|
2293
|
+
* random nonce is kept — an install too old to name its payment behaves
|
|
2294
|
+
* exactly as before.
|
|
2295
|
+
*/
|
|
2296
|
+
async createPaymentHeader(paymentRequired, option, paymentId) {
|
|
2127
2297
|
if (!this.delegateKey) {
|
|
2128
|
-
throw new
|
|
2298
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError("delegateKey is required to sign x402 payment headers.");
|
|
2129
2299
|
}
|
|
2130
2300
|
const account = accounts.privateKeyToAccount(this.delegateKey);
|
|
2131
|
-
const requirements =
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2301
|
+
const requirements = chunkIKQIIMM6_cjs.toStandardPaymentRequirements(paymentRequired, option);
|
|
2302
|
+
let header;
|
|
2303
|
+
if (paymentId) {
|
|
2304
|
+
const unsigned = schemes.exact.evm.preparePaymentHeader(
|
|
2305
|
+
account.address,
|
|
2306
|
+
paymentRequired.x402Version,
|
|
2307
|
+
requirements
|
|
2308
|
+
);
|
|
2309
|
+
unsigned.payload.authorization.nonce = chunkIKQIIMM6_cjs.deriveX402PaymentNonce(paymentId);
|
|
2310
|
+
const signed = await schemes.exact.evm.signPaymentHeader(account, requirements, unsigned);
|
|
2311
|
+
header = schemes.exact.evm.encodePayment(signed);
|
|
2312
|
+
} else {
|
|
2313
|
+
header = await schemes.exact.evm.createPaymentHeader(
|
|
2314
|
+
account,
|
|
2315
|
+
paymentRequired.x402Version,
|
|
2316
|
+
requirements
|
|
2317
|
+
);
|
|
2318
|
+
}
|
|
2137
2319
|
if (paymentRequired.x402Version < 2) return header;
|
|
2138
|
-
const payment =
|
|
2139
|
-
return
|
|
2320
|
+
const payment = chunkIKQIIMM6_cjs.decodeBase64Json(header);
|
|
2321
|
+
return chunkIKQIIMM6_cjs.encodeBase64Json(chunkIKQIIMM6_cjs.x402V2PaymentEnvelope(paymentRequired, option, payment.payload));
|
|
2140
2322
|
}
|
|
2141
2323
|
// ── Receipt mapping ──────────────────────────────────────────────
|
|
2142
2324
|
receiptFromAuthorization(paymentRequired, option, paymentHeader, raw, execResult) {
|
|
2143
2325
|
const txHash = execResult?.tx_hash ?? raw.tx_hash ?? "";
|
|
2144
2326
|
const chainId = execResult?.chain_id ?? raw.chain_id ?? chainIdFromNetwork(option.network);
|
|
2145
2327
|
const token = execResult?.token ?? raw.token ?? "USDC";
|
|
2146
|
-
const amount = execResult?.amount ?? raw.amount ?? decimalFromUsdcAtomic(
|
|
2328
|
+
const amount = execResult?.amount ?? raw.amount ?? decimalFromUsdcAtomic(chunkIKQIIMM6_cjs.x402AuthorizationAmount(option));
|
|
2147
2329
|
const to = execResult?.to ?? raw.to ?? this.delegateAddress ?? "";
|
|
2148
2330
|
const explorerUrl = execResult?.explorer_url ?? raw.explorer_url ?? explorerUrlOrEmpty(chainId, txHash);
|
|
2149
2331
|
const merchantTo = execResult?.merchant_to ?? raw.merchant_to ?? option.payTo;
|
|
@@ -2165,7 +2347,7 @@ var X402FundingLeg = class {
|
|
|
2165
2347
|
}
|
|
2166
2348
|
receiptFromStatus(paymentRequired, option, paymentHeader, status) {
|
|
2167
2349
|
if (!status.txHash) {
|
|
2168
|
-
throw new
|
|
2350
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
2169
2351
|
`x402 payment ${status.paymentId} is ready to retry but has no Haven transaction hash.`,
|
|
2170
2352
|
502,
|
|
2171
2353
|
status,
|
|
@@ -2176,7 +2358,7 @@ var X402FundingLeg = class {
|
|
|
2176
2358
|
paymentId: status.paymentId,
|
|
2177
2359
|
txHash: status.txHash,
|
|
2178
2360
|
token: status.token || "USDC",
|
|
2179
|
-
amount: status.amount || decimalFromUsdcAtomic(
|
|
2361
|
+
amount: status.amount || decimalFromUsdcAtomic(chunkIKQIIMM6_cjs.x402AuthorizationAmount(option)),
|
|
2180
2362
|
to: this.delegateAddress ?? "",
|
|
2181
2363
|
resourceUrl: paymentRequired.resource.url,
|
|
2182
2364
|
explorerUrl: explorerUrlOrEmpty(status.chainId, status.txHash),
|
|
@@ -2204,7 +2386,7 @@ var X402FundingLeg = class {
|
|
|
2204
2386
|
const provider = createJsonRpcProvider(rpcUrl);
|
|
2205
2387
|
const onChainReceipt = await provider.waitForTransaction(txHash, 1, timeoutMs);
|
|
2206
2388
|
if (!onChainReceipt || onChainReceipt.status !== 1) {
|
|
2207
|
-
throw new
|
|
2389
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
2208
2390
|
"Funding tx did not confirm on-chain within the timeout window.",
|
|
2209
2391
|
500,
|
|
2210
2392
|
{ txHash, chainId }
|
|
@@ -2253,7 +2435,7 @@ var X402FundingLeg = class {
|
|
|
2253
2435
|
};
|
|
2254
2436
|
function getPaymentHeaderValidBefore(paymentHeader) {
|
|
2255
2437
|
try {
|
|
2256
|
-
const payment =
|
|
2438
|
+
const payment = chunkIKQIIMM6_cjs.decodeBase64Json(
|
|
2257
2439
|
paymentHeader
|
|
2258
2440
|
);
|
|
2259
2441
|
const payload = payment.payload;
|
|
@@ -2308,7 +2490,7 @@ var X402Erc7710 = class {
|
|
|
2308
2490
|
*/
|
|
2309
2491
|
async settle(paymentRequired, options = {}) {
|
|
2310
2492
|
if (!this.delegateKey) {
|
|
2311
|
-
throw new
|
|
2493
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
2312
2494
|
"delegateKey is required for x402 payments. Pass it in the HavenClient config."
|
|
2313
2495
|
);
|
|
2314
2496
|
}
|
|
@@ -2333,21 +2515,21 @@ var X402Erc7710 = class {
|
|
|
2333
2515
|
async prepare(paymentRequired, options = {}) {
|
|
2334
2516
|
const delegationRail = options.delegationRail ?? (await this.getAgent()).executionRail === "delegation";
|
|
2335
2517
|
if (!delegationRail) {
|
|
2336
|
-
throw new
|
|
2518
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
2337
2519
|
"erc7710 settlement requires a delegation-rail account; this one is not on it. Use authorizeX402() for the standard EIP-3009 path.",
|
|
2338
2520
|
400
|
|
2339
2521
|
);
|
|
2340
2522
|
}
|
|
2341
|
-
const selection =
|
|
2523
|
+
const selection = chunkIKQIIMM6_cjs.selectX402SettlementScheme(paymentRequired.accepts, { delegationRail });
|
|
2342
2524
|
if (!selection || selection.scheme !== "erc7710") {
|
|
2343
|
-
throw new
|
|
2525
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
2344
2526
|
"This merchant does not advertise an erc7710 settlement option (no accepts[] entry carries extra.assetTransferMethod: 'erc7710'). Use authorizeX402() for the standard EIP-3009 path.",
|
|
2345
2527
|
400
|
|
2346
2528
|
);
|
|
2347
2529
|
}
|
|
2348
2530
|
const option = selection.option;
|
|
2349
2531
|
const merchantPayTo = option.payTo;
|
|
2350
|
-
const amountAtomic =
|
|
2532
|
+
const amountAtomic = chunkIKQIIMM6_cjs.x402AuthorizationAmount(option);
|
|
2351
2533
|
const raw = await this.post("/x402", {
|
|
2352
2534
|
url: options.resourceUrl ?? paymentRequired.resource?.url,
|
|
2353
2535
|
// #2373: the full 402 challenge, persisted verbatim by the backend
|
|
@@ -2391,24 +2573,24 @@ var X402Erc7710 = class {
|
|
|
2391
2573
|
...options.subBudgetId ? { subBudgetId: options.subBudgetId } : {}
|
|
2392
2574
|
});
|
|
2393
2575
|
if (!raw.payment_id) {
|
|
2394
|
-
throw new
|
|
2576
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError("No payment_id returned from x402/authorize", 500, raw);
|
|
2395
2577
|
}
|
|
2396
2578
|
if (raw.status === "confirmed" && raw.tx_hash) {
|
|
2397
2579
|
const requestedUrl = options.resourceUrl ?? paymentRequired.resource?.url;
|
|
2398
2580
|
const samePurchase = typeof raw.to === "string" && raw.to.toLowerCase() === merchantPayTo.toLowerCase() && raw.resource_url === requestedUrl;
|
|
2399
2581
|
if (!samePurchase) {
|
|
2400
|
-
throw new
|
|
2582
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
2401
2583
|
`Idempotency key already belongs to confirmed payment ${raw.payment_id}, which is not this erc7710 purchase (different payee or resource). Nothing was signed and nothing was charged. Check that payment's status before buying again: a funded but undelivered EIP-3009 payment is recovered, not paid twice. Otherwise use a new idempotency key for this purchase.`,
|
|
2402
2584
|
409,
|
|
2403
2585
|
raw,
|
|
2404
2586
|
raw.payment_id
|
|
2405
2587
|
);
|
|
2406
2588
|
}
|
|
2407
|
-
throw new
|
|
2589
|
+
throw new chunkMZKLAHBK_cjs.X402Erc7710AlreadySettledError(raw.payment_id, raw.tx_hash, raw);
|
|
2408
2590
|
}
|
|
2409
2591
|
const signData = raw.sign_data;
|
|
2410
2592
|
if (signData?.signature_scheme !== "eip712_delegation" || !signData.typed_data) {
|
|
2411
|
-
throw new
|
|
2593
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
2412
2594
|
`x402/authorize did not return an erc7710 settlement child (signature_scheme was ${JSON.stringify(signData?.signature_scheme)}). Refusing to sign a payload this path did not ask for.`,
|
|
2413
2595
|
500,
|
|
2414
2596
|
raw
|
|
@@ -2440,9 +2622,9 @@ var X402Erc7710 = class {
|
|
|
2440
2622
|
try {
|
|
2441
2623
|
settled = await this.post(`/x402/${paymentId}/settle`, { signature });
|
|
2442
2624
|
} catch (err) {
|
|
2443
|
-
const body = err instanceof
|
|
2444
|
-
if (err instanceof
|
|
2445
|
-
throw new
|
|
2625
|
+
const body = err instanceof chunkMZKLAHBK_cjs.HavenApiError ? err.body : void 0;
|
|
2626
|
+
if (err instanceof chunkMZKLAHBK_cjs.HavenApiError && err.statusCode === 409 && body?.code === "payment_already_settled" && typeof body.tx_hash === "string") {
|
|
2627
|
+
throw new chunkMZKLAHBK_cjs.X402Erc7710AlreadySettledError(
|
|
2446
2628
|
typeof body.payment_id === "string" ? body.payment_id : paymentId,
|
|
2447
2629
|
body.tx_hash,
|
|
2448
2630
|
body
|
|
@@ -2451,7 +2633,7 @@ var X402Erc7710 = class {
|
|
|
2451
2633
|
throw err;
|
|
2452
2634
|
}
|
|
2453
2635
|
if (!settled.payment_header) {
|
|
2454
|
-
throw new
|
|
2636
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
2455
2637
|
"x402 settle returned no payment_header \u2014 the merchant cannot be retried.",
|
|
2456
2638
|
500,
|
|
2457
2639
|
settled
|
|
@@ -2461,9 +2643,9 @@ var X402Erc7710 = class {
|
|
|
2461
2643
|
}
|
|
2462
2644
|
};
|
|
2463
2645
|
function settlementExpectationFromQuote(settlement) {
|
|
2464
|
-
const chainId =
|
|
2646
|
+
const chainId = chunkMZKLAHBK_cjs.chainIdForNetwork(settlement.network);
|
|
2465
2647
|
if (chainId === void 0) {
|
|
2466
|
-
throw new
|
|
2648
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
2467
2649
|
`Refusing to sign the x402 settlement child: the merchant's network ${JSON.stringify(settlement.network)} is not one this SDK can verify a settlement child on.`
|
|
2468
2650
|
);
|
|
2469
2651
|
}
|
|
@@ -2513,7 +2695,7 @@ function x402ToolReceipt(receipt) {
|
|
|
2513
2695
|
};
|
|
2514
2696
|
}
|
|
2515
2697
|
function toolError(err) {
|
|
2516
|
-
if (err instanceof
|
|
2698
|
+
if (err instanceof chunkMZKLAHBK_cjs.HavenPaymentStateError) {
|
|
2517
2699
|
return {
|
|
2518
2700
|
success: false,
|
|
2519
2701
|
payment_id: err.state.paymentId,
|
|
@@ -2558,7 +2740,7 @@ function toolError(err) {
|
|
|
2558
2740
|
error: err.message
|
|
2559
2741
|
};
|
|
2560
2742
|
}
|
|
2561
|
-
if (err instanceof
|
|
2743
|
+
if (err instanceof chunkMZKLAHBK_cjs.HavenApiError) {
|
|
2562
2744
|
return {
|
|
2563
2745
|
success: false,
|
|
2564
2746
|
status_code: err.statusCode,
|
|
@@ -2572,6 +2754,26 @@ function toolError(err) {
|
|
|
2572
2754
|
};
|
|
2573
2755
|
}
|
|
2574
2756
|
|
|
2757
|
+
// src/merchant-answer.ts
|
|
2758
|
+
function decidePostFundingMerchantAnswer(input) {
|
|
2759
|
+
const inBandChallenge = input.toolResult ? extractMcpPaymentRequired(input.toolResult) : void 0;
|
|
2760
|
+
const headerReceipt = input.paymentResponseHeader;
|
|
2761
|
+
const protocolReceiptHeaderName = headerReceipt ? "PAYMENT-RESPONSE" : input.metaSettlement ? `_meta.${MCP_X402_PAYMENT_RESPONSE_META_KEY}` : void 0;
|
|
2762
|
+
const protocolReceiptHeader = headerReceipt ?? (input.metaSettlement ? encodeMcpSettlementReceipt(input.metaSettlement) : void 0);
|
|
2763
|
+
const settlement = parseMerchantSettlement(headerReceipt ?? null);
|
|
2764
|
+
const settlementTxHash = settlement.settlementTxHash ?? (typeof input.metaSettlement?.transaction === "string" ? input.metaSettlement.transaction : void 0);
|
|
2765
|
+
const plainToolErrorAfterFunding = input.toolResult?.isError === true && inBandChallenge === void 0 && !settlementTxHash;
|
|
2766
|
+
const inBandRejection = inBandChallenge !== void 0 || input.metaSettlement?.success === false || plainToolErrorAfterFunding;
|
|
2767
|
+
return {
|
|
2768
|
+
accepted: input.httpOk && !inBandRejection,
|
|
2769
|
+
inBandRejection,
|
|
2770
|
+
plainToolErrorAfterFunding,
|
|
2771
|
+
settlementTxHash,
|
|
2772
|
+
protocolReceiptHeader,
|
|
2773
|
+
protocolReceiptHeaderName
|
|
2774
|
+
};
|
|
2775
|
+
}
|
|
2776
|
+
|
|
2575
2777
|
// src/merchant-completion.ts
|
|
2576
2778
|
var MERCHANT_BODY_SNIPPET_LIMIT = 1e3;
|
|
2577
2779
|
var EVIDENCE_RETRY_DELAYS_MS = [1e3, 2e3, 4e3];
|
|
@@ -2602,14 +2804,14 @@ var MerchantCompletion = class {
|
|
|
2602
2804
|
}
|
|
2603
2805
|
async retryRequest(url, initialInit, paymentRequired, receipt) {
|
|
2604
2806
|
if (!receipt.accepted) {
|
|
2605
|
-
throw new
|
|
2807
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError("No accepted x402 option was recorded for payment retry", 500);
|
|
2606
2808
|
}
|
|
2607
2809
|
if (!receipt.paymentHeader) {
|
|
2608
|
-
throw new
|
|
2810
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError("No x402 payment header was returned for payment retry", 500);
|
|
2609
2811
|
}
|
|
2610
2812
|
let retryInit = initialInit;
|
|
2611
2813
|
if (this.getTaxDeclarationHeader && this.delegateKey) {
|
|
2612
|
-
const scheme =
|
|
2814
|
+
const scheme = chunkIKQIIMM6_cjs.x402PaymentHeaderNamesFor(receipt.paymentHeader);
|
|
2613
2815
|
const isEip3009 = scheme.length > 1;
|
|
2614
2816
|
if (isEip3009) {
|
|
2615
2817
|
const resolved = await this.getTaxDeclarationHeader({
|
|
@@ -2621,16 +2823,31 @@ var MerchantCompletion = class {
|
|
|
2621
2823
|
retryInit = withTaxDeclarationHeader(initialInit, void 0);
|
|
2622
2824
|
}
|
|
2623
2825
|
}
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2826
|
+
let retryResponse;
|
|
2827
|
+
try {
|
|
2828
|
+
retryResponse = await this.merchantTransport.deliverPaymentRecoveringSession(
|
|
2829
|
+
url,
|
|
2830
|
+
retryInit,
|
|
2831
|
+
receipt.paymentHeader,
|
|
2832
|
+
() => this.merchantTransport.initialize(url, initialInit)
|
|
2833
|
+
);
|
|
2834
|
+
} catch (err) {
|
|
2835
|
+
if (err instanceof MerchantEgressRefusedError && !err.beforeRequest) {
|
|
2836
|
+
throw await this.paidDeliveryInterrupted(err, url, receipt, receipt.paymentHeader, retryInit?.body != null);
|
|
2837
|
+
}
|
|
2838
|
+
throw err;
|
|
2839
|
+
}
|
|
2630
2840
|
const toolResult = retryResponse.ok ? await this.merchantTransport.readToolResult(retryResponse) : void 0;
|
|
2631
|
-
const inBandChallenge = toolResult ? extractMcpPaymentRequired(toolResult) : void 0;
|
|
2632
2841
|
const metaSettlement = toolResult ? mcpSettlementFromToolResult(toolResult) : void 0;
|
|
2633
|
-
const
|
|
2842
|
+
const headerReceipt = retryResponse.headers.get("PAYMENT-RESPONSE");
|
|
2843
|
+
const answer = decidePostFundingMerchantAnswer({
|
|
2844
|
+
toolResult,
|
|
2845
|
+
httpOk: retryResponse.ok,
|
|
2846
|
+
paymentResponseHeader: headerReceipt ?? void 0,
|
|
2847
|
+
metaSettlement
|
|
2848
|
+
});
|
|
2849
|
+
const reportedSettlementTxHash = answer.settlementTxHash;
|
|
2850
|
+
const inBandRejection = answer.inBandRejection;
|
|
2634
2851
|
if (!retryResponse.ok || inBandRejection) {
|
|
2635
2852
|
const merchant = await captureMerchantResponse(retryResponse);
|
|
2636
2853
|
await this.recordRetryRejected({
|
|
@@ -2644,8 +2861,8 @@ var MerchantCompletion = class {
|
|
|
2644
2861
|
delegate_to: receipt.to
|
|
2645
2862
|
}
|
|
2646
2863
|
});
|
|
2647
|
-
throw new
|
|
2648
|
-
"x402 retry failed after Haven funded the delegate wallet; reconciliation may be required.",
|
|
2864
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
2865
|
+
"x402 retry failed after Haven funded the delegate wallet; reconciliation may be required. The merchant may still settle late: check the payment status before sweeping the delegate.",
|
|
2649
2866
|
inBandRejection ? X402_RETRY_REJECTED_STATUS : merchant.merchant_status,
|
|
2650
2867
|
{
|
|
2651
2868
|
marker: "x402_retry_rejected_after_funding",
|
|
@@ -2658,10 +2875,10 @@ var MerchantCompletion = class {
|
|
|
2658
2875
|
}
|
|
2659
2876
|
);
|
|
2660
2877
|
}
|
|
2661
|
-
const
|
|
2662
|
-
const
|
|
2663
|
-
|
|
2664
|
-
|
|
2878
|
+
const { protocolReceiptHeader, protocolReceiptHeaderName } = answer;
|
|
2879
|
+
const merchantSettlement = {
|
|
2880
|
+
settlementTxHash: reportedSettlementTxHash ?? null
|
|
2881
|
+
};
|
|
2665
2882
|
if (receipt.merchant && merchantSettlement.settlementTxHash) {
|
|
2666
2883
|
receipt.merchant.settlementTxHash = merchantSettlement.settlementTxHash;
|
|
2667
2884
|
receipt.merchant.settlementExplorerUrl = buildExplorerUrl(receipt.chainId, merchantSettlement.settlementTxHash) || null;
|
|
@@ -2674,14 +2891,19 @@ var MerchantCompletion = class {
|
|
|
2674
2891
|
merchantStatus: retryResponse.status,
|
|
2675
2892
|
challengePayload: paymentRequired,
|
|
2676
2893
|
selectedPayment: receipt.accepted,
|
|
2677
|
-
paymentProofHeaderName:
|
|
2894
|
+
paymentProofHeaderName: chunkIKQIIMM6_cjs.x402PaymentHeaderNamesSent(receipt.paymentHeader),
|
|
2678
2895
|
paymentProofHeader: receipt.paymentHeader,
|
|
2679
2896
|
protocolReceiptHeaderName,
|
|
2680
2897
|
protocolReceiptHeader
|
|
2681
2898
|
});
|
|
2682
2899
|
const settlementCandidate = merchantSettlement.settlementTxHash;
|
|
2683
2900
|
if (settlementCandidate && isWellFormedSettlementTxHash(settlementCandidate) && !isZeroSettlementTxHash(settlementCandidate) && settlementCandidate.toLowerCase() !== receipt.txHash.toLowerCase()) {
|
|
2684
|
-
await this.
|
|
2901
|
+
await this.reportEvidence({
|
|
2902
|
+
paymentId: receipt.paymentId,
|
|
2903
|
+
rail: "x402",
|
|
2904
|
+
txHash: settlementCandidate,
|
|
2905
|
+
...settlementProofFields(receipt.paymentHeader)
|
|
2906
|
+
});
|
|
2685
2907
|
}
|
|
2686
2908
|
await this.reportMerchantReceipt(receipt.paymentId, retryResponse);
|
|
2687
2909
|
return retryResponse;
|
|
@@ -2733,18 +2955,18 @@ var MerchantCompletion = class {
|
|
|
2733
2955
|
async resolveCompletionContext(input) {
|
|
2734
2956
|
const status = await this.getPaymentStatus(input.paymentId);
|
|
2735
2957
|
if (status.rail !== "x402") {
|
|
2736
|
-
throw new
|
|
2958
|
+
throw new chunkMZKLAHBK_cjs.HavenPaymentStateError(
|
|
2737
2959
|
`Payment ${status.paymentId} is ${status.rail}, not x402.`,
|
|
2738
2960
|
409,
|
|
2739
2961
|
status
|
|
2740
2962
|
);
|
|
2741
2963
|
}
|
|
2742
|
-
const readyForMerchantCompletion = input.noFundingLeg ? status.kind === "payment_intent" && status.status === "submitted" : status.nextAction ===
|
|
2964
|
+
const readyForMerchantCompletion = input.noFundingLeg ? status.kind === "payment_intent" && status.status === "submitted" : status.nextAction === chunkMZKLAHBK_cjs.AgentPaymentNextAction.RetryOriginalX402Request || status.kind === "payment_intent" && status.status === "confirmed" && status.phase === chunkMZKLAHBK_cjs.AgentPaymentPhase.PaymentConfirmed && status.nextAction === chunkMZKLAHBK_cjs.AgentPaymentNextAction.None;
|
|
2743
2965
|
if (!readyForMerchantCompletion) {
|
|
2744
|
-
throw new
|
|
2966
|
+
throw new chunkMZKLAHBK_cjs.HavenPaymentStateError(status.message, paymentStateStatusCode(status.status, 409), status);
|
|
2745
2967
|
}
|
|
2746
2968
|
if (!input.noFundingLeg && !status.txHash) {
|
|
2747
|
-
throw new
|
|
2969
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
2748
2970
|
`x402 payment ${status.paymentId} is ready for merchant completion but has no Haven transaction hash.`,
|
|
2749
2971
|
502,
|
|
2750
2972
|
status,
|
|
@@ -2753,7 +2975,7 @@ var MerchantCompletion = class {
|
|
|
2753
2975
|
}
|
|
2754
2976
|
const approvedResourceUrl = status.resourceUrl ?? status.x402?.resourceUrl ?? null;
|
|
2755
2977
|
if (approvedResourceUrl && approvedResourceUrl !== input.url) {
|
|
2756
|
-
throw new
|
|
2978
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
2757
2979
|
"x402 merchant completion does not match the approved resource URL.",
|
|
2758
2980
|
409,
|
|
2759
2981
|
{ status, url: input.url },
|
|
@@ -2784,6 +3006,51 @@ var MerchantCompletion = class {
|
|
|
2784
3006
|
// and MACHINE-PAYMENT-CHALLENGE was never produced by any other Haven
|
|
2785
3007
|
// surface. Use the x402 flow (authorizeX402 / fetch / quoteX402 / payX402Quote)
|
|
2786
3008
|
// for agent-to-merchant payments.
|
|
3009
|
+
/**
|
|
3010
|
+
* #4257: record a paid delivery that a refused redirect interrupted, and
|
|
3011
|
+
* return the refusal re-thrown with its payment and an accurate account:
|
|
3012
|
+
* the payment header (and the body, when there is one) reached `url`, the
|
|
3013
|
+
* merchant answered with a redirect Haven did not follow, and the merchant
|
|
3014
|
+
* may still settle. The record is the same
|
|
3015
|
+
* `merchant_retry_rejected_after_payment` event a non-2xx answer writes: its
|
|
3016
|
+
* `retry_status` is the redirect status, `retry_body` is null, and `details`
|
|
3017
|
+
* carry `refusal` plus `redirect_location` when the refusal names a redirect
|
|
3018
|
+
* target, or `refused_url` (the URL that answered) otherwise. The payment
|
|
3019
|
+
* reads as funded and undelivered.
|
|
3020
|
+
*/
|
|
3021
|
+
async paidDeliveryInterrupted(err, url, receipt, paymentHeader, hasBody) {
|
|
3022
|
+
const scheme = chunkIKQIIMM6_cjs.x402PaymentHeaderNamesFor(paymentHeader).length > 1 ? "eip3009" : "erc7710";
|
|
3023
|
+
const status = err.redirectStatus ?? 0;
|
|
3024
|
+
await this.recordRetryRejected({
|
|
3025
|
+
rail: "x402",
|
|
3026
|
+
paymentId: receipt.paymentId,
|
|
3027
|
+
txHash: receipt.txHash,
|
|
3028
|
+
resourceUrl: receipt.resourceUrl,
|
|
3029
|
+
merchant: {
|
|
3030
|
+
merchant_status: status,
|
|
3031
|
+
merchant_status_text: "redirect not followed",
|
|
3032
|
+
merchant_headers: {},
|
|
3033
|
+
merchant_body: ""
|
|
3034
|
+
},
|
|
3035
|
+
details: {
|
|
3036
|
+
merchant_to: receipt.merchantTo,
|
|
3037
|
+
delegate_to: receipt.to,
|
|
3038
|
+
refusal: err.refusal,
|
|
3039
|
+
// The refusal's url is the redirect target only when it carries one;
|
|
3040
|
+
// otherwise it is the URL that answered (a non-GET redirect, a missing
|
|
3041
|
+
// or unresolvable Location), recorded under a neutral key.
|
|
3042
|
+
...err.redirectTarget ? { redirect_location: err.redirectTarget } : { refused_url: err.url }
|
|
3043
|
+
}
|
|
3044
|
+
});
|
|
3045
|
+
const what = `The paid request was delivered to ${url}, ${hasBody ? "payment header and body" : "payment header"} included, and the merchant answered ${status ? `HTTP ${status} ` : ""}with a redirect${unfollowedRedirect(err)} Do not pay again: `;
|
|
3046
|
+
const next = scheme === "erc7710" ? "erc7710 has no funding leg, so there is no delegate balance to strand or sweep. The merchant may still redeem the settlement authorization within its window: check haven_get_payment_status after that window and re-quote only if it shows no settlement." : "the funding leg is confirmed on-chain and the merchant may still settle late. Check haven_get_payment_status before anything else, and sweep the delegate only if no settlement appears.";
|
|
3047
|
+
return new MerchantEgressRefusedError(what + next, err.url, err.refusal, false, {
|
|
3048
|
+
redirectStatus: err.redirectStatus,
|
|
3049
|
+
redirectTarget: err.redirectTarget,
|
|
3050
|
+
paymentId: receipt.paymentId,
|
|
3051
|
+
settlementScheme: scheme
|
|
3052
|
+
});
|
|
3053
|
+
}
|
|
2787
3054
|
async recordRetryRejected(input) {
|
|
2788
3055
|
try {
|
|
2789
3056
|
await this.post("/machine-payments/reconciliation-events", {
|
|
@@ -2839,7 +3106,7 @@ var MerchantCompletion = class {
|
|
|
2839
3106
|
*/
|
|
2840
3107
|
async reportMerchantOutcome(input) {
|
|
2841
3108
|
if (!Number.isInteger(input.merchantStatus) || input.merchantStatus < 100 || input.merchantStatus > 599) {
|
|
2842
|
-
throw new
|
|
3109
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
2843
3110
|
`merchant_status must be an integer HTTP status from 100 to 599 (received ${input.merchantStatus}).`,
|
|
2844
3111
|
400,
|
|
2845
3112
|
void 0,
|
|
@@ -2848,7 +3115,7 @@ var MerchantCompletion = class {
|
|
|
2848
3115
|
}
|
|
2849
3116
|
const looksAccepted = input.merchantStatus >= 200 && input.merchantStatus < 300;
|
|
2850
3117
|
if (looksAccepted !== (input.outcome === "accepted")) {
|
|
2851
|
-
throw new
|
|
3118
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
2852
3119
|
`outcome "${input.outcome}" contradicts merchant_status ${input.merchantStatus}: report "accepted" only for a 2xx and "rejected" only for a non-2xx.`,
|
|
2853
3120
|
400,
|
|
2854
3121
|
void 0,
|
|
@@ -2857,14 +3124,14 @@ var MerchantCompletion = class {
|
|
|
2857
3124
|
}
|
|
2858
3125
|
const status = await this.getPaymentStatus(input.paymentId);
|
|
2859
3126
|
if (status.rail !== "x402") {
|
|
2860
|
-
throw new
|
|
3127
|
+
throw new chunkMZKLAHBK_cjs.HavenPaymentStateError(
|
|
2861
3128
|
`Payment ${status.paymentId} is ${status.rail}, not x402 \u2014 there is no merchant retry to report.`,
|
|
2862
3129
|
409,
|
|
2863
3130
|
status
|
|
2864
3131
|
);
|
|
2865
3132
|
}
|
|
2866
3133
|
if (status.status !== "confirmed" || !status.txHash) {
|
|
2867
|
-
throw new
|
|
3134
|
+
throw new chunkMZKLAHBK_cjs.HavenPaymentStateError(
|
|
2868
3135
|
`Payment ${status.paymentId} has no confirmed Haven funding transaction to anchor a merchant report to (status ${status.status}). ${status.message}`,
|
|
2869
3136
|
paymentStateStatusCode(status.status, 409),
|
|
2870
3137
|
status
|
|
@@ -2872,7 +3139,7 @@ var MerchantCompletion = class {
|
|
|
2872
3139
|
}
|
|
2873
3140
|
const resourceUrl = status.resourceUrl ?? status.x402?.resourceUrl ?? null;
|
|
2874
3141
|
if (!resourceUrl) {
|
|
2875
|
-
throw new
|
|
3142
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
2876
3143
|
`Payment ${status.paymentId} has no recorded resource URL, so a merchant report cannot be stored.`,
|
|
2877
3144
|
409,
|
|
2878
3145
|
status,
|
|
@@ -2933,23 +3200,26 @@ var MerchantCompletion = class {
|
|
|
2933
3200
|
}
|
|
2934
3201
|
}
|
|
2935
3202
|
/**
|
|
2936
|
-
* ONE evidence attempt — the body of `reportEvidence`'s loop above
|
|
2937
|
-
*
|
|
2938
|
-
*
|
|
2939
|
-
*
|
|
3203
|
+
* ONE evidence attempt — the body of `reportEvidence`'s loop above. A 503
|
|
3204
|
+
* answers `retryable` immediately; the caller decides whether to sleep and
|
|
3205
|
+
* re-attempt (`reportEvidence`, and — #4215 — the local settlement report
|
|
3206
|
+
* in `retryRequest`) or hand the outcome to its consumer (#3764 D2, the
|
|
3207
|
+
* hosted settlement report).
|
|
2940
3208
|
*/
|
|
2941
3209
|
async postEvidenceOnce(body) {
|
|
2942
3210
|
try {
|
|
2943
3211
|
await this.post("/machine-payments/evidence", body);
|
|
2944
3212
|
return { outcome: "confirmed" };
|
|
2945
3213
|
} catch (err) {
|
|
2946
|
-
const statusCode = err instanceof
|
|
3214
|
+
const statusCode = err instanceof chunkMZKLAHBK_cjs.HavenApiError ? err.statusCode : void 0;
|
|
2947
3215
|
if (statusCode !== EVIDENCE_RETRYABLE_STATUS) {
|
|
2948
3216
|
const reason = refusalReasonFromBody(err);
|
|
3217
|
+
const errorCode = refusalErrorCodeFromBody(err);
|
|
2949
3218
|
return {
|
|
2950
3219
|
outcome: "refused",
|
|
2951
3220
|
statusCode: statusCode ?? 0,
|
|
2952
|
-
...reason ? { reason } : {}
|
|
3221
|
+
...reason ? { reason } : {},
|
|
3222
|
+
...errorCode ? { errorCode } : {}
|
|
2953
3223
|
};
|
|
2954
3224
|
}
|
|
2955
3225
|
return { outcome: "retryable", statusCode };
|
|
@@ -2986,46 +3256,78 @@ var MerchantCompletion = class {
|
|
|
2986
3256
|
* gate uses, so a caller cannot "fix" a missing hash by reporting the demo
|
|
2987
3257
|
* merchant's own marker and getting a different verdict than the settle
|
|
2988
3258
|
* path already gave it.
|
|
3259
|
+
*
|
|
3260
|
+
* #4061: `options.paymentHeader` is the payment header the caller sent to
|
|
3261
|
+
* the merchant on its paid retry. On eip3009 it is REQUIRED for the record
|
|
3262
|
+
* (#3925): its signed authorization proves the nonce the settlement burned
|
|
3263
|
+
* is this payment's, and a report without it is refused with
|
|
3264
|
+
* `errorCode: 'settlement_proof_header_missing'`. It is forwarded exactly
|
|
3265
|
+
* as the funding report forwards it (`paymentProofHeader` plus the names
|
|
3266
|
+
* `x402PaymentHeaderNamesSent` derives from the same payload). erc7710
|
|
3267
|
+
* needs none — Haven assembled that header itself.
|
|
2989
3268
|
*/
|
|
2990
|
-
async reportSettlementEvidence(paymentId, settlementTxHash) {
|
|
3269
|
+
async reportSettlementEvidence(paymentId, settlementTxHash, options = {}) {
|
|
2991
3270
|
if (isZeroSettlementTxHash(settlementTxHash)) {
|
|
2992
|
-
throw new
|
|
3271
|
+
throw new chunkMZKLAHBK_cjs.HavenZeroSettlementHashError(paymentId);
|
|
2993
3272
|
}
|
|
2994
3273
|
return this.reportEvidence({
|
|
2995
3274
|
paymentId,
|
|
2996
3275
|
rail: "x402",
|
|
2997
|
-
txHash: settlementTxHash
|
|
3276
|
+
txHash: settlementTxHash,
|
|
3277
|
+
...settlementProofFields(options.paymentHeader)
|
|
2998
3278
|
});
|
|
2999
3279
|
}
|
|
3000
3280
|
/**
|
|
3001
3281
|
* #3764: report the merchant's OWN EIP-3009 settlement transaction right
|
|
3002
|
-
* after a completed purchase — the second leg of a payment that
|
|
3003
|
-
* a funding-evidence row. Same endpoint and payload shape as
|
|
3282
|
+
* after a completed hosted purchase — the second leg of a payment that
|
|
3283
|
+
* already has a funding-evidence row. Same endpoint and payload shape as
|
|
3004
3284
|
* `reportSettlementEvidence` above, but with #3764's D2 budget: exactly ONE
|
|
3005
3285
|
* attempt, no `EVIDENCE_RETRY_DELAYS_MS` backoff. The resource is already
|
|
3006
3286
|
* paid for and delivered, so a retryable answer must not stretch the
|
|
3007
3287
|
* completed purchase — the HOSTED tools hand the outcome to the agent
|
|
3008
|
-
* (`settlementEvidenceOutcome` → `haven_report_settlement_evidence`)
|
|
3009
|
-
*
|
|
3010
|
-
*
|
|
3288
|
+
* (`settlementEvidenceOutcome` → `haven_report_settlement_evidence`). Since
|
|
3289
|
+
* #4215 this ONE-attempt form serves the HOSTED path only
|
|
3290
|
+
* (`completeX402MerchantCall`); the local `retryRequest` posts the same
|
|
3291
|
+
* report through `reportEvidence`, whose bounded loop re-attempts while
|
|
3292
|
+
* Haven answers `retryable`. Callers validate the hash before this call
|
|
3293
|
+
* (well-formed, non-zero, different from the funding hash
|
|
3011
3294
|
* case-insensitively), so there is no client-side refusal here — the
|
|
3012
3295
|
* backend verifies on-chain and is the only judge.
|
|
3296
|
+
*
|
|
3297
|
+
* #4061: `paymentHeader` is the header the paid retry sent — the #3925
|
|
3298
|
+
* nonce proof, forwarded as `reportSettlementEvidence` forwards it. Both
|
|
3299
|
+
* callers hold it; without it the backend refuses the record.
|
|
3013
3300
|
*/
|
|
3014
|
-
async reportSettlementEvidenceOnce(paymentId, settlementTxHash) {
|
|
3301
|
+
async reportSettlementEvidenceOnce(paymentId, settlementTxHash, paymentHeader) {
|
|
3015
3302
|
return this.postEvidenceOnce({
|
|
3016
3303
|
paymentId,
|
|
3017
3304
|
rail: "x402",
|
|
3018
|
-
txHash: settlementTxHash
|
|
3305
|
+
txHash: settlementTxHash,
|
|
3306
|
+
...settlementProofFields(paymentHeader)
|
|
3019
3307
|
});
|
|
3020
3308
|
}
|
|
3021
3309
|
};
|
|
3310
|
+
function settlementProofFields(paymentHeader) {
|
|
3311
|
+
if (!paymentHeader || !paymentHeader.trim()) return {};
|
|
3312
|
+
return {
|
|
3313
|
+
paymentProofHeaderName: chunkIKQIIMM6_cjs.x402PaymentHeaderNamesSent(paymentHeader),
|
|
3314
|
+
paymentProofHeader: paymentHeader
|
|
3315
|
+
};
|
|
3316
|
+
}
|
|
3022
3317
|
function refusalReasonFromBody(err) {
|
|
3023
|
-
if (!(err instanceof
|
|
3318
|
+
if (!(err instanceof chunkMZKLAHBK_cjs.HavenApiError)) return void 0;
|
|
3024
3319
|
const body = err.body;
|
|
3025
3320
|
if (body === null || typeof body !== "object" || Array.isArray(body)) return void 0;
|
|
3026
3321
|
const reason = body.reason;
|
|
3027
3322
|
return typeof reason === "string" && reason.length > 0 ? reason : void 0;
|
|
3028
3323
|
}
|
|
3324
|
+
function refusalErrorCodeFromBody(err) {
|
|
3325
|
+
if (!(err instanceof chunkMZKLAHBK_cjs.HavenApiError)) return void 0;
|
|
3326
|
+
const body = err.body;
|
|
3327
|
+
if (body === null || typeof body !== "object" || Array.isArray(body)) return void 0;
|
|
3328
|
+
const code = body.error_code;
|
|
3329
|
+
return typeof code === "string" && code.length > 0 ? code : void 0;
|
|
3330
|
+
}
|
|
3029
3331
|
function isZeroSettlementTxHash(hash) {
|
|
3030
3332
|
return typeof hash === "string" && /^0x0+$/i.test(hash);
|
|
3031
3333
|
}
|
|
@@ -3037,7 +3339,7 @@ function parseMerchantSettlement(header) {
|
|
|
3037
3339
|
}
|
|
3038
3340
|
function parseProtocolReceiptHeader(value) {
|
|
3039
3341
|
try {
|
|
3040
|
-
return
|
|
3342
|
+
return chunkIKQIIMM6_cjs.decodeBase64Json(value);
|
|
3041
3343
|
} catch {
|
|
3042
3344
|
try {
|
|
3043
3345
|
return JSON.parse(value);
|
|
@@ -3046,6 +3348,25 @@ function parseProtocolReceiptHeader(value) {
|
|
|
3046
3348
|
}
|
|
3047
3349
|
}
|
|
3048
3350
|
}
|
|
3351
|
+
function unfollowedRedirect(err) {
|
|
3352
|
+
const target = err.redirectTarget ?? err.url;
|
|
3353
|
+
switch (err.refusal) {
|
|
3354
|
+
case "redirect_cross_origin_body":
|
|
3355
|
+
return ` to a different origin (${target}). Haven did not follow it, so the payment was not re-sent there.`;
|
|
3356
|
+
case "redirect_on_non_get":
|
|
3357
|
+
return ". Under the egress policy only GET redirects are followed, so Haven did not follow it and nothing was sent to the redirect target.";
|
|
3358
|
+
case "redirect_missing_location":
|
|
3359
|
+
return " that named no target (no Location header). Haven did not follow it.";
|
|
3360
|
+
case "redirect_invalid_location":
|
|
3361
|
+
return " whose Location header is not a resolvable URL. Haven did not follow it.";
|
|
3362
|
+
case "redirect_budget_exceeded":
|
|
3363
|
+
return ` past the redirect budget. The chain stopped before ${target}, and nothing was sent there.`;
|
|
3364
|
+
case "url_not_allowed":
|
|
3365
|
+
return ` to a URL the egress policy does not allow (${target}). Haven did not follow it, so nothing was sent there.`;
|
|
3366
|
+
default:
|
|
3367
|
+
return ". Haven did not follow it.";
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3049
3370
|
|
|
3050
3371
|
// src/client.ts
|
|
3051
3372
|
var DEFAULT_POLLING_INTERVAL = 3e3;
|
|
@@ -3054,7 +3375,7 @@ function x402TypedDataDigest(typedData) {
|
|
|
3054
3375
|
try {
|
|
3055
3376
|
return viem.hashTypedData(typedData);
|
|
3056
3377
|
} catch (err) {
|
|
3057
|
-
throw new
|
|
3378
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
3058
3379
|
`The x402 funding intent carried a sign_data.typed_data that is not a valid EIP-712 payload (needs domain, types, primaryType, message), so its digest cannot be derived and no signer could accept it. Underlying error: ${err instanceof Error ? err.message : String(err)}`
|
|
3059
3380
|
);
|
|
3060
3381
|
}
|
|
@@ -3084,6 +3405,9 @@ function mapCatalogEntry(entry) {
|
|
|
3084
3405
|
priceAtomic: entry.price_atomic,
|
|
3085
3406
|
asset: entry.asset,
|
|
3086
3407
|
network: entry.network,
|
|
3408
|
+
// #3839: conditional like `merchant` — absent (not null) when the backend
|
|
3409
|
+
// does not send the field, so an older backend's exact shape is unchanged.
|
|
3410
|
+
...entry.asset_transfer_methods !== void 0 ? { assetTransferMethods: entry.asset_transfer_methods } : {},
|
|
3087
3411
|
status: entry.status,
|
|
3088
3412
|
verifiedAt: entry.verified_at,
|
|
3089
3413
|
source: entry.source,
|
|
@@ -3166,7 +3490,7 @@ var HavenClient = class {
|
|
|
3166
3490
|
this.x402Wallet = config.x402Wallet;
|
|
3167
3491
|
this.egressPolicy = config.merchantEgress;
|
|
3168
3492
|
this.merchantTransport = new McpMerchantTransport({ merchantTimeout: config.merchantTimeout, egress: config.merchantEgress });
|
|
3169
|
-
this.confirmationTimeout = config.confirmationTimeout ??
|
|
3493
|
+
this.confirmationTimeout = config.confirmationTimeout ?? chunkMZKLAHBK_cjs.DEFAULT_CONFIRMATION_TIMEOUT_MS;
|
|
3170
3494
|
this.pollingInterval = config.pollingInterval ?? DEFAULT_POLLING_INTERVAL;
|
|
3171
3495
|
this.chainRpcs = config.chainRpcs ?? {};
|
|
3172
3496
|
if (this.delegateKey) {
|
|
@@ -3247,7 +3571,7 @@ var HavenClient = class {
|
|
|
3247
3571
|
*/
|
|
3248
3572
|
async pay(request) {
|
|
3249
3573
|
if (!this.delegateKey) {
|
|
3250
|
-
throw new
|
|
3574
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
3251
3575
|
"Cannot use pay() without a delegateKey. Use createIntent() + submitSignature() for manual signing."
|
|
3252
3576
|
);
|
|
3253
3577
|
}
|
|
@@ -3303,15 +3627,15 @@ var HavenClient = class {
|
|
|
3303
3627
|
* on-chain allowance — there is nothing to sign until the user approves.
|
|
3304
3628
|
*/
|
|
3305
3629
|
async createX402Intent(paymentRequired, options = {}) {
|
|
3306
|
-
const option =
|
|
3630
|
+
const option = chunkIKQIIMM6_cjs.selectStandardPaymentOption(paymentRequired.accepts);
|
|
3307
3631
|
if (!option) {
|
|
3308
3632
|
throw noCompatiblePaymentOptionError(paymentRequired.accepts);
|
|
3309
3633
|
}
|
|
3310
3634
|
const fundingTo = options.delegateAddress ?? (await this.getAgent()).delegateAddress;
|
|
3311
3635
|
if (!fundingTo) {
|
|
3312
|
-
throw new
|
|
3636
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError("Authenticated agent has no delegate address registered.", 502);
|
|
3313
3637
|
}
|
|
3314
|
-
const idempotencyKey = options.idempotencyKey ??
|
|
3638
|
+
const idempotencyKey = options.idempotencyKey ?? chunkIKQIIMM6_cjs.buildX402IdempotencyKey(paymentRequired, option);
|
|
3315
3639
|
const raw = await this.post("/x402", {
|
|
3316
3640
|
url: paymentRequired.resource.url,
|
|
3317
3641
|
payTo: fundingTo,
|
|
@@ -3322,7 +3646,7 @@ var HavenClient = class {
|
|
|
3322
3646
|
// of a silent reroute to the erc7710 settlement branch (the #1358
|
|
3323
3647
|
// review's open-budget misroute). Legacy-rail backends ignore the field.
|
|
3324
3648
|
settlementScheme: "eip3009",
|
|
3325
|
-
amount:
|
|
3649
|
+
amount: chunkIKQIIMM6_cjs.x402AuthorizationAmount(option),
|
|
3326
3650
|
asset: option.asset,
|
|
3327
3651
|
network: option.network,
|
|
3328
3652
|
description: paymentRequired.resource.description,
|
|
@@ -3347,15 +3671,15 @@ var HavenClient = class {
|
|
|
3347
3671
|
throwPaymentStateError("x402 payment", raw);
|
|
3348
3672
|
}
|
|
3349
3673
|
if (!raw.sign_data?.hash) {
|
|
3350
|
-
throw new
|
|
3674
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError("No sign_hash returned from x402/authorize", 500, raw);
|
|
3351
3675
|
}
|
|
3352
3676
|
if (raw.sign_data.signature_scheme !== void 0 && !raw.sign_data.typed_data) {
|
|
3353
|
-
throw new
|
|
3677
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
3354
3678
|
`This account's x402 funding intent declares signature scheme '${raw.sign_data.signature_scheme}' but carried no typed_data to sign. Refusing to fall back to the bare hash \u2014 the account would reject that signature on-chain. This is a backend contract violation; report it rather than working around it.`
|
|
3355
3679
|
);
|
|
3356
3680
|
}
|
|
3357
3681
|
if (!raw.x402_expected_auth) {
|
|
3358
|
-
throw new
|
|
3682
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError("No x402 expected-context binding returned from x402/authorize", 500, raw);
|
|
3359
3683
|
}
|
|
3360
3684
|
return {
|
|
3361
3685
|
paymentId: raw.payment_id,
|
|
@@ -3366,7 +3690,7 @@ var HavenClient = class {
|
|
|
3366
3690
|
accepted: option,
|
|
3367
3691
|
resourceUrl: paymentRequired.resource.url,
|
|
3368
3692
|
merchantTo: raw.merchant_to ?? option.payTo,
|
|
3369
|
-
amountAtomic:
|
|
3693
|
+
amountAtomic: chunkIKQIIMM6_cjs.x402AuthorizationAmount(option),
|
|
3370
3694
|
asset: option.asset,
|
|
3371
3695
|
network: option.network,
|
|
3372
3696
|
expectedAuth: raw.x402_expected_auth,
|
|
@@ -3391,13 +3715,13 @@ var HavenClient = class {
|
|
|
3391
3715
|
*/
|
|
3392
3716
|
sign(hash) {
|
|
3393
3717
|
if (!this.delegateKey) {
|
|
3394
|
-
throw new
|
|
3718
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
3395
3719
|
"Cannot sign without a delegateKey. Pass the private key in HavenClient config, or sign externally."
|
|
3396
3720
|
);
|
|
3397
3721
|
}
|
|
3398
3722
|
const signature = signHash(this.delegateKey, hash);
|
|
3399
3723
|
if (!verifySignature(hash, signature, this.delegateAddress)) {
|
|
3400
|
-
throw new
|
|
3724
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
3401
3725
|
"Local signature verification failed \u2014 recovered address does not match delegate key."
|
|
3402
3726
|
);
|
|
3403
3727
|
}
|
|
@@ -3415,29 +3739,29 @@ var HavenClient = class {
|
|
|
3415
3739
|
*/
|
|
3416
3740
|
async signForData(signData, settlementExpectation, fundingExpectation) {
|
|
3417
3741
|
if (!this.delegateKey) {
|
|
3418
|
-
throw new
|
|
3742
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
3419
3743
|
"Cannot sign without a delegateKey. Pass the private key in HavenClient config, or sign externally."
|
|
3420
3744
|
);
|
|
3421
3745
|
}
|
|
3422
3746
|
const scheme = signData.signature_scheme;
|
|
3423
3747
|
if (scheme === "eip191_userop") {
|
|
3424
|
-
throw new
|
|
3748
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
3425
3749
|
"The session rail is retired \u2014 'eip191_userop' intents can no longer be signed. Re-onboard the account on the delegation rail."
|
|
3426
3750
|
);
|
|
3427
3751
|
}
|
|
3428
3752
|
if (scheme === "eip712_userop") {
|
|
3429
3753
|
if (!signData.typed_data) {
|
|
3430
|
-
throw new
|
|
3754
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
3431
3755
|
"sign_data.signature_scheme is eip712_userop but typed_data is missing \u2014 refusing to sign the bare hash (the account would reject it)."
|
|
3432
3756
|
);
|
|
3433
3757
|
}
|
|
3434
|
-
|
|
3435
|
-
|
|
3758
|
+
chunkMZKLAHBK_cjs.assertUserOpTypedDataBinding(signData.typed_data, signData.hash);
|
|
3759
|
+
chunkIKQIIMM6_cjs.assertBoundDirectPaymentUserOp(
|
|
3436
3760
|
signData.typed_data,
|
|
3437
3761
|
this.delegateAddress
|
|
3438
3762
|
);
|
|
3439
3763
|
if (fundingExpectation) {
|
|
3440
|
-
|
|
3764
|
+
chunkIKQIIMM6_cjs.assertFundingLegPaysDelegate(signData.typed_data, {
|
|
3441
3765
|
delegateAddress: this.delegateAddress,
|
|
3442
3766
|
asset: fundingExpectation.asset,
|
|
3443
3767
|
amount: fundingExpectation.amount
|
|
@@ -3447,24 +3771,24 @@ var HavenClient = class {
|
|
|
3447
3771
|
}
|
|
3448
3772
|
if (scheme === "eip712_delegation") {
|
|
3449
3773
|
if (!signData.typed_data) {
|
|
3450
|
-
throw new
|
|
3774
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
3451
3775
|
"sign_data.signature_scheme is eip712_delegation but typed_data is missing \u2014 refusing to sign the bare hash (the settlement would be rejected on redemption)."
|
|
3452
3776
|
);
|
|
3453
3777
|
}
|
|
3454
3778
|
if (!settlementExpectation) {
|
|
3455
|
-
throw new
|
|
3779
|
+
throw new chunkIKQIIMM6_cjs.HavenTypedDataRefusedError(
|
|
3456
3780
|
"Refusing to sign an x402 settlement child without an independent expectation of what it must pay (the merchant's 402). Pay erc7710 merchants through settleX402Erc7710(), which supplies it."
|
|
3457
3781
|
);
|
|
3458
3782
|
}
|
|
3459
|
-
|
|
3783
|
+
chunkIKQIIMM6_cjs.assertOwnSettlementChild(signData.typed_data, settlementExpectation, this.delegateAddress);
|
|
3460
3784
|
return signSettlementDelegationTypedData(this.delegateKey, signData.typed_data);
|
|
3461
3785
|
}
|
|
3462
3786
|
if (scheme === void 0) {
|
|
3463
|
-
throw new
|
|
3787
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
3464
3788
|
"sign_data.signature_scheme is required \u2014 the legacy AllowanceModule rail that signed the bare hash is retired (#2850). Refusing to guess a signing scheme."
|
|
3465
3789
|
);
|
|
3466
3790
|
}
|
|
3467
|
-
throw new
|
|
3791
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
3468
3792
|
`Unknown sign_data.signature_scheme '${scheme}' \u2014 refusing to guess a signing scheme. Update @haven_ai/sdk.`
|
|
3469
3793
|
);
|
|
3470
3794
|
}
|
|
@@ -3602,7 +3926,8 @@ var HavenClient = class {
|
|
|
3602
3926
|
amountAtomic: input.amountAtomic,
|
|
3603
3927
|
...input.merchantTo !== void 0 ? { merchantTo: input.merchantTo } : {},
|
|
3604
3928
|
...input.resourceUrl !== void 0 ? { resourceUrl: input.resourceUrl } : {},
|
|
3605
|
-
...input.idempotencyKey !== void 0 ? { idempotencyKey: input.idempotencyKey } : {}
|
|
3929
|
+
...input.idempotencyKey !== void 0 ? { idempotencyKey: input.idempotencyKey } : {},
|
|
3930
|
+
...input.recordRefusal !== void 0 ? { recordRefusal: input.recordRefusal } : {}
|
|
3606
3931
|
});
|
|
3607
3932
|
}
|
|
3608
3933
|
/**
|
|
@@ -3654,7 +3979,7 @@ var HavenClient = class {
|
|
|
3654
3979
|
*/
|
|
3655
3980
|
async getPaymentStatusWithPostPurchaseAllowance(paymentId) {
|
|
3656
3981
|
const status = await this.getPaymentStatus(paymentId);
|
|
3657
|
-
if (status.rail ===
|
|
3982
|
+
if (status.rail === chunkMZKLAHBK_cjs.AgentPaymentRail.X402 && status.phase === chunkMZKLAHBK_cjs.AgentPaymentPhase.PaymentConfirmed) {
|
|
3658
3983
|
const { allowance, warnings } = await this.getPostPurchaseAllowanceSummary(paymentId);
|
|
3659
3984
|
return { ...status, allowance, ...warnings.length > 0 ? { warnings } : {} };
|
|
3660
3985
|
}
|
|
@@ -3709,10 +4034,10 @@ var HavenClient = class {
|
|
|
3709
4034
|
return this.get(`/catalog/submit/${encodeURIComponent(id)}`);
|
|
3710
4035
|
}
|
|
3711
4036
|
/**
|
|
3712
|
-
* Fetch one
|
|
4037
|
+
* Fetch one catalog entry by id (#1306).
|
|
3713
4038
|
*
|
|
3714
4039
|
* Chain-scoped for free by the backend's SQL when the client is
|
|
3715
|
-
* agent-authenticated (#1299): an unknown id and an id
|
|
4040
|
+
* agent-authenticated (#1299): an unknown id and an id listed for a
|
|
3716
4041
|
* DIFFERENT chain than this agent's both 404 identically — this method does
|
|
3717
4042
|
* not (and must not) re-filter by chain in JS. Read-only, like
|
|
3718
4043
|
* {@link discoverTools}.
|
|
@@ -3868,9 +4193,10 @@ var HavenClient = class {
|
|
|
3868
4193
|
return this.accountReads.listPendingSubBudgetSignatures();
|
|
3869
4194
|
}
|
|
3870
4195
|
/**
|
|
3871
|
-
* Close a sub-budget row (delegating agent only). A `pending` or
|
|
3872
|
-
* closes immediately; a live child
|
|
3873
|
-
*
|
|
4196
|
+
* Close a sub-budget row (delegating agent only). A `pending` row, or an
|
|
4197
|
+
* `open` one already expired, closes immediately; otherwise (a live child, or
|
|
4198
|
+
* any `closing` row — its disable is still owed, #3923) it returns `signData`
|
|
4199
|
+
* for the on-chain revocation — sign it (`haven_sign` with `sub_budget_id`) and call
|
|
3874
4200
|
* `submitSubBudget`.
|
|
3875
4201
|
*/
|
|
3876
4202
|
async closeSubBudget(id) {
|
|
@@ -3904,7 +4230,7 @@ var HavenClient = class {
|
|
|
3904
4230
|
}
|
|
3905
4231
|
await sleep(this.pollingInterval);
|
|
3906
4232
|
}
|
|
3907
|
-
throw new
|
|
4233
|
+
throw new chunkMZKLAHBK_cjs.HavenTimeoutError(paymentId);
|
|
3908
4234
|
}
|
|
3909
4235
|
// ── x402 Protocol Support ────────────────────────────────────────
|
|
3910
4236
|
/**
|
|
@@ -3918,24 +4244,24 @@ var HavenClient = class {
|
|
|
3918
4244
|
*/
|
|
3919
4245
|
async authorizeX402(paymentRequired, options = {}) {
|
|
3920
4246
|
if (!this.delegateKey) {
|
|
3921
|
-
throw new
|
|
4247
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
3922
4248
|
"delegateKey is required for x402 payments. Pass it in the HavenClient config."
|
|
3923
4249
|
);
|
|
3924
4250
|
}
|
|
3925
4251
|
if (!this.delegateAddress) {
|
|
3926
|
-
throw new
|
|
4252
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError("delegateAddress could not be derived from delegateKey.");
|
|
3927
4253
|
}
|
|
3928
|
-
const option =
|
|
4254
|
+
const option = chunkIKQIIMM6_cjs.selectStandardPaymentOption(paymentRequired.accepts);
|
|
3929
4255
|
if (!option) {
|
|
3930
4256
|
throw noCompatiblePaymentOptionError(paymentRequired.accepts);
|
|
3931
4257
|
}
|
|
3932
|
-
const idempotencyKey = options.idempotencyKey ??
|
|
4258
|
+
const idempotencyKey = options.idempotencyKey ?? chunkIKQIIMM6_cjs.buildX402IdempotencyKey(paymentRequired, option);
|
|
3933
4259
|
const cached = this.fundingLeg.cachedReceipt(idempotencyKey, options.taskBudgetId, options.subBudgetId);
|
|
3934
4260
|
if (cached) return cached;
|
|
3935
4261
|
const inFlight = this.inFlightX402.get(idempotencyKey);
|
|
3936
4262
|
if (inFlight) {
|
|
3937
4263
|
if (!sameX402TaskBudget(this.inFlightX402TaskBudget.get(idempotencyKey), options.taskBudgetId) || !sameX402TaskBudget(this.inFlightX402SubBudget.get(idempotencyKey), options.subBudgetId)) {
|
|
3938
|
-
throw new
|
|
4264
|
+
throw new chunkMZKLAHBK_cjs.X402TaskBudgetMismatchError(
|
|
3939
4265
|
`The x402 idempotency key '${idempotencyKey}' has an in-flight payment created under a different authorizing budget (task '${this.inFlightX402TaskBudget.get(idempotencyKey) ?? "none"}' vs '${options.taskBudgetId ?? "none"}', sub '${this.inFlightX402SubBudget.get(idempotencyKey) ?? "none"}' vs '${options.subBudgetId ?? "none"}'). Pass a new idempotencyKey to pay under this budget.`,
|
|
3940
4266
|
idempotencyKey,
|
|
3941
4267
|
this.inFlightX402TaskBudget.get(idempotencyKey),
|
|
@@ -3990,16 +4316,16 @@ var HavenClient = class {
|
|
|
3990
4316
|
if (err instanceof MerchantEgressResponseCapError) throw err;
|
|
3991
4317
|
body = void 0;
|
|
3992
4318
|
}
|
|
3993
|
-
throw new
|
|
4319
|
+
throw new chunkMZKLAHBK_cjs.X402UnexpectedStatusError(
|
|
3994
4320
|
`Expected an x402 quote response with HTTP 402, got HTTP ${response.status}.`,
|
|
3995
4321
|
response.status || 400,
|
|
3996
4322
|
body
|
|
3997
4323
|
);
|
|
3998
4324
|
}
|
|
3999
4325
|
if (response.headers.get("MACHINE-PAYMENT-CHALLENGE")) {
|
|
4000
|
-
throw new
|
|
4326
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError("quoteX402 only supports standard x402 Payment Required responses.", 400);
|
|
4001
4327
|
}
|
|
4002
|
-
const paymentRequired = await
|
|
4328
|
+
const paymentRequired = await chunkIKQIIMM6_cjs.parsePaymentRequiredResponse(response);
|
|
4003
4329
|
const mcpTransport = await this.merchantTransport.detect(url, paymentRequired, response);
|
|
4004
4330
|
return buildX402Quote(paymentRequired, request, options.idempotencyKey, mcpTransport);
|
|
4005
4331
|
}
|
|
@@ -4017,7 +4343,7 @@ var HavenClient = class {
|
|
|
4017
4343
|
const wallet = await this.merchantCompletion.resolveWalletForMerchantCall();
|
|
4018
4344
|
const sessionId = await this.merchantTransport.initialize(url, init, wallet);
|
|
4019
4345
|
if (!sessionId) {
|
|
4020
|
-
throw new
|
|
4346
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError(
|
|
4021
4347
|
"The merchant did not establish an MCP session before the x402 quote. No payment was created.",
|
|
4022
4348
|
502,
|
|
4023
4349
|
{ mcpSessionNotEstablished: true }
|
|
@@ -4091,18 +4417,18 @@ var HavenClient = class {
|
|
|
4091
4417
|
}
|
|
4092
4418
|
async resumeAuthorizedX402(input) {
|
|
4093
4419
|
if (!this.delegateKey) {
|
|
4094
|
-
throw new
|
|
4420
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError(
|
|
4095
4421
|
"delegateKey is required for x402 payments. Pass it in the HavenClient config."
|
|
4096
4422
|
);
|
|
4097
4423
|
}
|
|
4098
4424
|
if (!this.delegateAddress) {
|
|
4099
|
-
throw new
|
|
4425
|
+
throw new chunkMZKLAHBK_cjs.HavenSigningError("delegateAddress could not be derived from delegateKey.");
|
|
4100
4426
|
}
|
|
4101
|
-
const option =
|
|
4427
|
+
const option = chunkIKQIIMM6_cjs.selectStandardPaymentOption(input.paymentRequired.accepts);
|
|
4102
4428
|
if (!option) {
|
|
4103
4429
|
throw noCompatiblePaymentOptionError(input.paymentRequired.accepts);
|
|
4104
4430
|
}
|
|
4105
|
-
const idempotencyKey = input.idempotencyKey ??
|
|
4431
|
+
const idempotencyKey = input.idempotencyKey ?? chunkIKQIIMM6_cjs.buildX402IdempotencyKey(input.paymentRequired, option);
|
|
4106
4432
|
const cached = this.fundingLeg.cachedReceipt(idempotencyKey, input.taskBudgetId);
|
|
4107
4433
|
if (cached) return cached;
|
|
4108
4434
|
const status = await this.getPaymentStatus(input.paymentId);
|
|
@@ -4110,16 +4436,16 @@ var HavenClient = class {
|
|
|
4110
4436
|
const canFund = await this.fundingLeg.delegateCanFund(
|
|
4111
4437
|
status.chainId ?? chainIdFromNetwork(option.network),
|
|
4112
4438
|
option.asset,
|
|
4113
|
-
|
|
4439
|
+
chunkIKQIIMM6_cjs.x402AuthorizationAmount(option)
|
|
4114
4440
|
);
|
|
4115
4441
|
if (canFund === false) {
|
|
4116
|
-
throw new
|
|
4442
|
+
throw new chunkMZKLAHBK_cjs.X402AlreadySettledError(
|
|
4117
4443
|
`x402 payment ${status.paymentId} has already settled \u2014 the delegate no longer holds the funds to authorize it again, so there is nothing left to resume.`,
|
|
4118
4444
|
this.fundingLeg.receiptFromStatus(input.paymentRequired, option, void 0, status),
|
|
4119
4445
|
"settled"
|
|
4120
4446
|
);
|
|
4121
4447
|
}
|
|
4122
|
-
const paymentHeader = await this.fundingLeg.createPaymentHeader(input.paymentRequired, option);
|
|
4448
|
+
const paymentHeader = await this.fundingLeg.createPaymentHeader(input.paymentRequired, option, status.paymentId);
|
|
4123
4449
|
const receipt = this.fundingLeg.receiptFromStatus(input.paymentRequired, option, paymentHeader, status);
|
|
4124
4450
|
this.fundingLeg.cacheReceipt(idempotencyKey, paymentHeader, receipt, input.taskBudgetId);
|
|
4125
4451
|
return receipt;
|
|
@@ -4134,13 +4460,13 @@ var HavenClient = class {
|
|
|
4134
4460
|
const url = input.url ?? input.request?.url;
|
|
4135
4461
|
if (!paymentRequired) {
|
|
4136
4462
|
if (!url) {
|
|
4137
|
-
throw new
|
|
4463
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError("x402 resume requires the original URL or a captured request snapshot.", 400);
|
|
4138
4464
|
}
|
|
4139
4465
|
const response = await this.merchantTransport.fetch(url, initialInit, this.merchantTransport.budgetFor("quote"), this.merchantTransport.capFor("quote"));
|
|
4140
4466
|
if (response.status !== 402) {
|
|
4141
|
-
throw new
|
|
4467
|
+
throw new chunkMZKLAHBK_cjs.HavenApiError("Expected the original x402 request to return HTTP 402 before resuming.", 400);
|
|
4142
4468
|
}
|
|
4143
|
-
paymentRequired = await
|
|
4469
|
+
paymentRequired = await chunkIKQIIMM6_cjs.parsePaymentRequiredResponse(response);
|
|
4144
4470
|
}
|
|
4145
4471
|
const receipt = await this.resumeAuthorizedX402({
|
|
4146
4472
|
paymentId: input.paymentId,
|
|
@@ -4193,7 +4519,7 @@ var HavenClient = class {
|
|
|
4193
4519
|
nativeChallenge = true;
|
|
4194
4520
|
} else {
|
|
4195
4521
|
try {
|
|
4196
|
-
paymentRequired = await
|
|
4522
|
+
paymentRequired = await chunkIKQIIMM6_cjs.parsePaymentRequiredResponse(response);
|
|
4197
4523
|
} catch (err) {
|
|
4198
4524
|
if (err instanceof MerchantEgressResponseCapError) throw err;
|
|
4199
4525
|
return response;
|
|
@@ -4204,8 +4530,8 @@ var HavenClient = class {
|
|
|
4204
4530
|
if (mcpSessionId) requestInit = this.merchantTransport.withSessionHeaders(requestInit, mcpSessionId);
|
|
4205
4531
|
}
|
|
4206
4532
|
const request = snapshotX402Request(url, requestInit);
|
|
4207
|
-
const option =
|
|
4208
|
-
const idempotencyKey = options.idempotencyKey ?? (option ?
|
|
4533
|
+
const option = chunkIKQIIMM6_cjs.selectStandardPaymentOption(paymentRequired.accepts);
|
|
4534
|
+
const idempotencyKey = options.idempotencyKey ?? (option ? chunkIKQIIMM6_cjs.buildX402IdempotencyKey(paymentRequired, option) : void 0);
|
|
4209
4535
|
let receipt;
|
|
4210
4536
|
try {
|
|
4211
4537
|
receipt = await this.authorizeX402(paymentRequired, options);
|
|
@@ -4296,13 +4622,15 @@ var HavenClient = class {
|
|
|
4296
4622
|
body = text;
|
|
4297
4623
|
}
|
|
4298
4624
|
const toolResult = mcpToolResultOf(body);
|
|
4299
|
-
const inBandChallenge = toolResult ? extractMcpPaymentRequired(toolResult) : void 0;
|
|
4300
4625
|
const metaSettlement = toolResult ? mcpSettlementFromToolResult(toolResult) : void 0;
|
|
4301
4626
|
const headerReceipt = surfaced.headers.get("PAYMENT-RESPONSE") ?? void 0;
|
|
4302
|
-
const
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4627
|
+
const answer = decidePostFundingMerchantAnswer({
|
|
4628
|
+
toolResult,
|
|
4629
|
+
httpOk: surfaced.ok,
|
|
4630
|
+
paymentResponseHeader: headerReceipt,
|
|
4631
|
+
metaSettlement
|
|
4632
|
+
});
|
|
4633
|
+
const merchantAccepted = answer.accepted;
|
|
4306
4634
|
let evidenceOutcome;
|
|
4307
4635
|
let settlementEvidenceOutcome;
|
|
4308
4636
|
if (!merchantAccepted) {
|
|
@@ -4324,7 +4652,7 @@ var HavenClient = class {
|
|
|
4324
4652
|
});
|
|
4325
4653
|
}
|
|
4326
4654
|
} else {
|
|
4327
|
-
const rawEvidenceTxHash = input.noFundingLeg ?
|
|
4655
|
+
const rawEvidenceTxHash = input.noFundingLeg ? answer.settlementTxHash ?? void 0 : fundingTxHash ?? void 0;
|
|
4328
4656
|
const evidenceTxHash = rawEvidenceTxHash && !isZeroSettlementTxHash(rawEvidenceTxHash) ? rawEvidenceTxHash : void 0;
|
|
4329
4657
|
if (evidenceTxHash) {
|
|
4330
4658
|
evidenceOutcome = await this.merchantCompletion.reportEvidence({
|
|
@@ -4333,21 +4661,22 @@ var HavenClient = class {
|
|
|
4333
4661
|
txHash: evidenceTxHash,
|
|
4334
4662
|
resourceUrl: evidenceContext.resourceUrl,
|
|
4335
4663
|
merchantStatus: surfaced.status,
|
|
4336
|
-
paymentProofHeaderName:
|
|
4664
|
+
paymentProofHeaderName: chunkIKQIIMM6_cjs.x402PaymentHeaderNamesSent(input.paymentHeader),
|
|
4337
4665
|
paymentProofHeader: input.paymentHeader,
|
|
4338
|
-
protocolReceiptHeaderName,
|
|
4339
|
-
protocolReceiptHeader,
|
|
4666
|
+
protocolReceiptHeaderName: answer.protocolReceiptHeaderName,
|
|
4667
|
+
protocolReceiptHeader: answer.protocolReceiptHeader,
|
|
4340
4668
|
// #3778: the delivery pointer rides the accepted arm's evidence
|
|
4341
4669
|
// report — a rejection delivered nothing to point at.
|
|
4342
4670
|
...input.deliveryReference ? { deliveryReference: input.deliveryReference } : {}
|
|
4343
4671
|
});
|
|
4344
4672
|
}
|
|
4345
4673
|
if (!input.noFundingLeg) {
|
|
4346
|
-
const settlementCandidate =
|
|
4674
|
+
const settlementCandidate = answer.settlementTxHash;
|
|
4347
4675
|
if (settlementCandidate && isWellFormedSettlementTxHash(settlementCandidate) && !isZeroSettlementTxHash(settlementCandidate) && fundingTxHash && settlementCandidate.toLowerCase() !== fundingTxHash.toLowerCase()) {
|
|
4348
4676
|
settlementEvidenceOutcome = await this.merchantCompletion.reportSettlementEvidenceOnce(
|
|
4349
4677
|
evidenceContext.paymentId,
|
|
4350
|
-
settlementCandidate
|
|
4678
|
+
settlementCandidate,
|
|
4679
|
+
input.paymentHeader
|
|
4351
4680
|
);
|
|
4352
4681
|
}
|
|
4353
4682
|
}
|
|
@@ -4358,7 +4687,7 @@ var HavenClient = class {
|
|
|
4358
4687
|
ok: merchantAccepted,
|
|
4359
4688
|
body,
|
|
4360
4689
|
// #3155 review S3: a transaction beside a rejection is not a settlement.
|
|
4361
|
-
settlementTxHash: merchantAccepted ?
|
|
4690
|
+
settlementTxHash: merchantAccepted ? answer.settlementTxHash ?? void 0 : void 0,
|
|
4362
4691
|
evidenceOutcome,
|
|
4363
4692
|
settlementEvidenceOutcome
|
|
4364
4693
|
};
|
|
@@ -4391,9 +4720,15 @@ var HavenClient = class {
|
|
|
4391
4720
|
* Haven verifies the delegate → merchant transfer on-chain
|
|
4392
4721
|
* (`observeEip3009MerchantSettlement`) and records it beside the funding
|
|
4393
4722
|
* hash, so receipts name the merchant's settlement.
|
|
4723
|
+
*
|
|
4724
|
+
* #4061: on eip3009 pass `options.paymentHeader` — the payment header you
|
|
4725
|
+
* sent the merchant on your paid retry. Since #3925 it is the proof the
|
|
4726
|
+
* settlement is recorded against; without it the report is `refused` with
|
|
4727
|
+
* `errorCode: 'settlement_proof_header_missing'`, and repeating it WITH the
|
|
4728
|
+
* header can succeed.
|
|
4394
4729
|
*/
|
|
4395
|
-
async reportSettlementEvidence(paymentId, settlementTxHash) {
|
|
4396
|
-
return await this.merchantCompletion.reportSettlementEvidence(paymentId, settlementTxHash);
|
|
4730
|
+
async reportSettlementEvidence(paymentId, settlementTxHash, options = {}) {
|
|
4731
|
+
return await this.merchantCompletion.reportSettlementEvidence(paymentId, settlementTxHash, options);
|
|
4397
4732
|
}
|
|
4398
4733
|
/**
|
|
4399
4734
|
* #3770: record the agent's evidence-only delivery verdict on a settled
|
|
@@ -4452,7 +4787,7 @@ var HavenClient = class {
|
|
|
4452
4787
|
try {
|
|
4453
4788
|
raw = await this.get(`/x402/by-idempotency-key/${encodeURIComponent(key)}`);
|
|
4454
4789
|
} catch (err) {
|
|
4455
|
-
if (err instanceof
|
|
4790
|
+
if (err instanceof chunkMZKLAHBK_cjs.HavenApiError && err.statusCode === 404) return null;
|
|
4456
4791
|
throw err;
|
|
4457
4792
|
}
|
|
4458
4793
|
return {
|
|
@@ -4587,6 +4922,7 @@ function sleep(ms) {
|
|
|
4587
4922
|
function composeDescription(d) {
|
|
4588
4923
|
return [d.summary, d.selectionGuidance, d.behavior, d.nextActionGuidance].filter(Boolean).join(" ");
|
|
4589
4924
|
}
|
|
4925
|
+
var FUNDING_LEG_DISCOVERY_GUIDANCE = `funding_leg_expected is a catalog hint: among equivalent entries prefer false (erc7710, no funding leg); "unknown" is no preference; never hide true entries. A recipient-pinned budget can pay erc7710 merchants only. The quote's expected_funding_leg is authoritative.`;
|
|
4590
4926
|
var toolDescriptions = {
|
|
4591
4927
|
quoteX402: {
|
|
4592
4928
|
summary: "Inspect an HTTP 402 x402 paid resource without creating a Haven payment, signature, approval, or on-chain transaction.",
|
|
@@ -4641,7 +4977,7 @@ var toolDescriptions = {
|
|
|
4641
4977
|
checkFunds: {
|
|
4642
4978
|
summary: "Check whether the agent's account actually holds at least the given amount of a token \u2014 funds held, not spend permitted.",
|
|
4643
4979
|
selectionGuidance: "Use this before attempting a payment when it matters whether the money is really there: allowance answers say what you are PERMITTED to spend, never whether the account HOLDS it. For allowance, budget, spend-limit, remaining-budget, reset-period, or what-can-I-spend questions use the allowance lookup tool instead.",
|
|
4644
|
-
behavior: "Returns covered: true (the account holds at least the checked amount), false (a live chain read reports
|
|
4980
|
+
behavior: "Returns covered: true (the account holds at least the checked amount), false (a live chain read reports the account holds less than the checked amount; stop and tell the user it is short), or null (the chain read failed \u2014 unverifiable, never treat it as absence; coverageError says why). The account balance itself is deliberately not returned: this is a sufficiency signal, not a balance read. budget_remaining_atomic is the permitted figure from the allowance lookup (the SDK spells it budgetRemainingAtomic), named so it can never be confused with holdings.",
|
|
4645
4981
|
nextActionGuidance: "On covered=false, do not attempt the payment \u2014 tell the user the account is short and let them fund it; on covered=null, retry the check shortly or proceed knowing the payment may fail on-chain."
|
|
4646
4982
|
},
|
|
4647
4983
|
listReceipts: {
|
|
@@ -4669,9 +5005,9 @@ var toolDescriptions = {
|
|
|
4669
5005
|
nextActionGuidance: "On a decline, report the reason to the user and ask them to raise the budget in Haven \u2014 there is no approval queue to wait on. This tool retries the merchant itself while it runs, so do not wait on a signal mid-call. If the process crashes after payment, a later haven_get_payment_status call may report nextAction=retry_original_x402_request \u2014 resume via haven_resume_x402_payment instead of paying again."
|
|
4670
5006
|
},
|
|
4671
5007
|
discoverTools: {
|
|
4672
|
-
summary: "Step 1 of a purchase: discover payable services from Haven's
|
|
4673
|
-
selectionGuidance: "Use this when the user asks what the agent can buy, pay for, or which paid services exist \u2014 or when you need a resource URL for a service the user described. Use verified=verified for entries Haven watched pass a live quote probe (
|
|
4674
|
-
behavior: "Use each entry's suggested_tool + suggested_arguments first; an entry without them says why. Read-only lookup against Haven's
|
|
5008
|
+
summary: "Step 1 of a purchase: discover payable services from Haven's merchant catalog \u2014 names, prices, the next call.",
|
|
5009
|
+
selectionGuidance: "Use this when the user asks what the agent can buy, pay for, or which paid services exist \u2014 or when you need a resource URL for a service the user described. Use verified=verified for entries Haven watched pass a live quote probe (any source; bazaar seller-asserted) \u2014 domain_verified is the only ownership claim; never treat these badges as proof of merchant honesty, quality, or reliability. Do NOT use for balance, budget, or spend-limit questions \u2014 use haven_get_allowances. Do NOT use to pay \u2014 each returned entry names the next tool to call.",
|
|
5010
|
+
behavior: "Use each entry's suggested_tool + suggested_arguments first; an entry without them says why. Read-only lookup against Haven's catalog; entries are periodically re-verified against the live merchant and degraded entries are flagged. Use category for a case-insensitive category filter (for example, VPN or vpn), or search for a product name, category, or description term. Returns name, description, price, rail, resource URL, tool_name, tool_arguments, the hint, and the provenance badges source/domain_verified/verified_payable. " + FUNDING_LEG_DISCOVERY_GUIDANCE + " The catalog price (price_display/price_atomic, marked price_is_indicative) is a last-verified hint, NOT authoritative \u2014 the real price comes from the merchant's live 402 at pay time. Never creates a payment, signature, or approval.",
|
|
4675
5011
|
nextActionGuidance: `Call suggested_tool with suggested_arguments VERBATIM (no hint: read suggested_tool_omitted_reason). Confirm the price from the live quote or pay result, not the catalog; if the next tool takes a cap, pass the user's cap as max_amount_human in whole tokens ("no more than 1 USDC" \u2192 max_amount_human: "1"), never atomic units by hand.`
|
|
4676
5012
|
},
|
|
4677
5013
|
submitCatalogEntry: {
|
|
@@ -4694,8 +5030,8 @@ var toolDescriptions = {
|
|
|
4694
5030
|
},
|
|
4695
5031
|
reportSettlementEvidence: {
|
|
4696
5032
|
summary: "Report a payment's real merchant settlement transaction hash so Haven can verify it on-chain and record it.",
|
|
4697
|
-
behavior: "Pass payment_id and, when you hold one, settlement_tx_hash (0x + 64 hex chars) \u2014 from PAYMENT-RESPONSE or a prior settlement_tx_hash. Omitting settlement_tx_hash succeeds as a no-op \u2014 nothing is checked or recorded, and no network call is made. Haven verifies on-chain before recording a hash; a zero, mismatched, or reverted hash is refused. Your own payments only.",
|
|
4698
|
-
nextActionGuidance: "code SETTLEMENT_NOT_RECORDED (refusal_reason present): the payment's funding is confirmed and this hash was not accepted for it \u2014 do not retry it; refusal_reason carries why, verbatim. code DELIVERED_UNSETTLED: not verified, do not retry \u2014 poll haven_get_payment_status. code SETTLEMENT_PENDING (retryable:true): not mined or RPC unreachable \u2014 report the same hash again shortly."
|
|
5033
|
+
behavior: "Pass payment_id and, when you hold one, settlement_tx_hash (0x + 64 hex chars) \u2014 from PAYMENT-RESPONSE or a prior settlement_tx_hash. On EIP-3009 also pass payment_header (the header you retried the merchant with) or the report is refused. Omitting settlement_tx_hash succeeds as a no-op \u2014 nothing is checked or recorded, and no network call is made. Haven verifies on-chain before recording a hash; a zero, mismatched, or reverted hash is refused. Your own payments only.",
|
|
5034
|
+
nextActionGuidance: "code SETTLEMENT_PROOF_HEADER_MISSING: call again adding payment_header. code SETTLEMENT_NOT_RECORDED (refusal_reason present): the payment's funding is confirmed and this hash was not accepted for it \u2014 do not retry it; refusal_reason carries why, verbatim. code DELIVERED_UNSETTLED: not verified, do not retry \u2014 poll haven_get_payment_status. code SETTLEMENT_PENDING (retryable:true): not mined or RPC unreachable \u2014 report the same hash again shortly."
|
|
4699
5035
|
}
|
|
4700
5036
|
};
|
|
4701
5037
|
|
|
@@ -4913,9 +5249,17 @@ var havenTools = {
|
|
|
4913
5249
|
openai: openaiTools
|
|
4914
5250
|
};
|
|
4915
5251
|
|
|
5252
|
+
// src/catalog-funding-leg.ts
|
|
5253
|
+
function catalogFundingLegExpected(assetTransferMethods) {
|
|
5254
|
+
if (typeof assetTransferMethods !== "string") return "unknown";
|
|
5255
|
+
const methods = assetTransferMethods.split(",").map((method) => method.trim()).filter((method) => method.length > 0);
|
|
5256
|
+
if (methods.length === 0) return "unknown";
|
|
5257
|
+
return !methods.includes("erc7710");
|
|
5258
|
+
}
|
|
5259
|
+
|
|
4916
5260
|
// src/agent-guidance.ts
|
|
4917
5261
|
var AGENT_SECRET_HYGIENE_SENTENCE = "Do not print private keys, API keys, credential file contents, or config secrets in chat or logs.";
|
|
4918
|
-
var AGENT_CLIENT_UPDATE_SENTENCE = "If a Haven result carries `client_update`, that client is out of date: run its `upgrade_command` as given
|
|
5262
|
+
var AGENT_CLIENT_UPDATE_SENTENCE = "If a Haven result carries `client_update`, that client is out of date: run its `upgrade_command` exactly as given \u2014 a connector command may name your pair with `--name <slug>` \u2014 then any repair line it prints, then retry. `required: true` means payments are refused until you do.";
|
|
4919
5263
|
var AGENT_LOCAL_KEY_SENTENCE = "The Haven connector generates the signing key locally and sends Haven only the public signing address plus proof.";
|
|
4920
5264
|
var AGENT_NETWORK_ACCESS_SENTENCE = "Network access is expected: this command downloads the npm package and contacts the Haven API, so if your environment is sandboxed, run it with network access enabled or request network access escalation; that changes the execution environment, not the command, and is not a command modification.";
|
|
4921
5265
|
var AGENT_JSON_MODE_SENTENCE = "If you are an AI agent running this command yourself rather than a human pasting it, you should append --json: the connector then emits one machine-readable, secret-free result object on stdout with progress on stderr, and returns promptly instead of blocking while it waits for the budget approval.";
|
|
@@ -4947,7 +5291,7 @@ Your user gives you a **budget on their own account** \u2014 not their wallet, a
|
|
|
4947
5291
|
|
|
4948
5292
|
Four of the six steps are your user's \u2014 each needs a human signature or a human decision. The rest is yours. If they already have a funded account, start at step 3.
|
|
4949
5293
|
|
|
4950
|
-
1. **HUMAN \u2014 create the account.** Name, email, password, then a passkey
|
|
5294
|
+
1. **HUMAN \u2014 create the account.** Name, email, password, then a passkey or a wallet. Never offer to enter any of it: you must not have their password, and the passkey is bound to their device. With a terminal, \`<packages.cli.one_liner> login --api <api-url>\` afterwards gets you a scoped session for steps 3-4 (that flag or \`HAVEN_API_URL\`, on the first command \u2014 the session then remembers the backend; **the CLI's built-in default is Haven's hosted production backend**, so on any other deployment an omitted flag connects you somewhere real and wrong rather than failing) \u2014 they approve a code in the browser, you never hold their password. That command is the manifest's \`packages.cli.one_liner\` (\`/.well-known/haven.json\`) \u2014 run it as given: \`packages.cli.channel\` serves the full spec. Do not hold the process open while you wait: under \`--json\`, pass \`--no-wait\` to get the link object back at once, then poll it with \`haven login --poll <device_code>\` \u2014 one round per invocation, exit 3 while it is still pending, 0 once approved. It can set up agents and read the account; it cannot sign, approve a budget, move funds, or rotate any agent's keys.
|
|
4951
5295
|
2. **HUMAN \u2014 fund it.** USDC only, no ETH: Haven sponsors the gas. \`/.well-known/haven.json\` names \`chains.default\` as the deployment's expected chain, but after login \`haven wallets funding\` prints the address, the amount and which chain in one place; confirm that chain before you message your user. Without a CLI session, the dashboard's funding card shows the address and amount and its Receive-funds screen names the chain; never assume one: a testnet deployment and production both call themselves Haven. Before you write that message, read the manifest: \`environment\` says whether this deployment is \`production\`, and each \`chains.supported\` entry says whether that chain is a \`testnet\`. Real money is at stake only on a non-testnet chain of a \`production\` deployment \u2014 tell your user which case theirs is.
|
|
4952
5296
|
3. **HUMAN \u2014 create the agent, set its budget**, and paste you the **setup prompt** it hands back. With a CLI session (step 1) you can do this step yourself: \`haven agents connect --name <n> --budget <amount> --token USDC --period <minutes>\` prints the same connector command and approval link; add \`--run\` to do step 4 too.
|
|
4953
5297
|
4. **YOU \u2014 run the connector command** in that prompt (see What you run). It makes your signing key locally, registering only the public address.
|
|
@@ -4963,7 +5307,7 @@ haven budget grant <agentId> --amount <n> --token USDC --period <minutes> [--rec
|
|
|
4963
5307
|
haven budget revoke <agentId> <delegationHash> [--wait]
|
|
4964
5308
|
\`\`\`
|
|
4965
5309
|
|
|
4966
|
-
The CLI never signs: it prints a dashboard link, your user opens it and signs with their passkey or wallet. \`--wait\` polls until the human's signature lands. The hash for \`revoke\` is in \`haven
|
|
5310
|
+
The CLI never signs: it prints a dashboard link, your user opens it and signs with their passkey or wallet. \`--wait\` polls until the human's signature lands. The hash for \`revoke\` is in \`haven budget show <agentId> --hashes\`.
|
|
4967
5311
|
|
|
4968
5312
|
## Hand-off scripts
|
|
4969
5313
|
|
|
@@ -4971,7 +5315,7 @@ Send these as your own message, \`<host>\` replaced by the host you fetched this
|
|
|
4971
5315
|
|
|
4972
5316
|
**Before signup** (step 1):
|
|
4973
5317
|
|
|
4974
|
-
> I can do everything except the parts that need your signature. Please open \`<host>/signup?next=/agents&via=agent\` \u2014 name, email, password, then a passkey
|
|
5318
|
+
> I can do everything except the parts that need your signature. Please open \`<host>/signup?next=/agents&via=agent\` \u2014 name, email, password, then a passkey or a wallet. That is your account's key: I should not have it, and I will never ask for your password. Already have one? \`<host>/login?next=/agents\`.
|
|
4975
5319
|
|
|
4976
5320
|
**At the passkey step:**
|
|
4977
5321
|
|
|
@@ -5305,7 +5649,25 @@ the FINAL URL after redirects \u2014 and retry the merchant with the
|
|
|
5305
5649
|
\`SIGN-IN-WITH-X\` header it returns: the delegate
|
|
5306
5650
|
wallet signs in as the wallet that paid, moving no funds. NEVER follow a
|
|
5307
5651
|
redirect with \`SIGN-IN-WITH-X\` (or a resulting session token) attached; if
|
|
5308
|
-
the final origin differs, re-sign there.
|
|
5652
|
+
the final origin differs, re-sign there.
|
|
5653
|
+
|
|
5654
|
+
Sign in BEFORE a multi-call flow: if a merchant documents or offers a
|
|
5655
|
+
sign-in session (its docs, or a 402 whose \`sign-in-with-x\` extension names
|
|
5656
|
+
a free sign-in route), do not pay call by call. Send the unsigned sign-in
|
|
5657
|
+
request yourself, take the \`sign-in-with-x\` extension from its 402, and
|
|
5658
|
+
call \`mcp__haven-signer__haven_sign_siwx\` with it. The session token (often
|
|
5659
|
+
about 2 h) waives the merchant's micro-fees, so make every now-free call
|
|
5660
|
+
YOURSELF with the \`SIGN-IN-WITH-X\` header set \u2014 never pass a merchant
|
|
5661
|
+
session token to \`mcp__haven__haven_quote_x402\` or
|
|
5662
|
+
\`mcp__haven__haven_pay_x402_quote\` (their unpaid probe refuses a 200 with
|
|
5663
|
+
X402_PROBE_NOT_PAYMENT_REQUIRED) \u2014 and pay only where the merchant still
|
|
5664
|
+
charges (on Bitrefill, \`invoice/pay\`; keep sending the session token
|
|
5665
|
+
there). Sign at the FINAL URL after redirects, and never forward
|
|
5666
|
+
\`SIGN-IN-WITH-X\` or a session token across a redirect. If the signer's
|
|
5667
|
+
tools/list has no \`haven_sign_siwx\` (a signer older than 0.9.0-alpha.0),
|
|
5668
|
+
or the sign-in is refused, pay each call normally instead.
|
|
5669
|
+
|
|
5670
|
+
On THIS path Haven never sends the
|
|
5309
5671
|
paid request (it sends only unpaid probes):
|
|
5310
5672
|
on the **EIP-3009** scheme (the pay result names
|
|
5311
5673
|
\`mcp__haven-signer__haven_sign_x402\`), that tool returns both
|
|
@@ -5321,10 +5683,13 @@ request, this is the only way it can learn the purchase failed \u2014 without it
|
|
|
5321
5683
|
failed purchase reads as complete for fifteen minutes. If the merchant's
|
|
5322
5684
|
\`PAYMENT-RESPONSE\` header names a \`transaction\`, pass that raw header as
|
|
5323
5685
|
\`payment_response\` on the SAME \`mcp__haven__haven_report_x402_outcome\`
|
|
5324
|
-
call
|
|
5325
|
-
|
|
5686
|
+
call, together with \`payment_header\`: the exact header you retried the
|
|
5687
|
+
merchant with. Haven records a reported settlement only with that header,
|
|
5688
|
+
which proves the settlement is this payment's. It decodes the response,
|
|
5689
|
+
verifies the settlement on-chain, and the receipt then shows the merchant's
|
|
5690
|
+
settlement, not only the funding transaction. Call
|
|
5326
5691
|
\`mcp__haven__haven_report_settlement_evidence\` only when the outcome answer
|
|
5327
|
-
names it as the next step. On the **erc7710** scheme (the pay result says
|
|
5692
|
+
names it as the next step, and pass the same \`payment_header\` there too. On the **erc7710** scheme (the pay result says
|
|
5328
5693
|
\`settlement_scheme: "erc7710"\`), sign with \`mcp__haven-signer__haven_sign\`,
|
|
5329
5694
|
then \`mcp__haven__haven_submit\` with \`settlement_scheme: "erc7710"\`
|
|
5330
5695
|
returns the \`payment_header\`; retry the merchant yourself with it as
|
|
@@ -5354,7 +5719,9 @@ for example, an invoice carrying an \`x402_payment_url\` to POST with its
|
|
|
5354
5719
|
\`invoice_id\`, beside a raw deposit address and a web payment link.
|
|
5355
5720
|
- **Quote the exact request:** \`mcp__haven__haven_quote_x402\` with \`url\`,
|
|
5356
5721
|
\`method\`, \`headers\` and \`body\`, exactly as the merchant described it.
|
|
5357
|
-
\`body\` is a JSON **string**, not an object.
|
|
5722
|
+
\`body\` is a JSON **string**, not an object. When the price is stated up
|
|
5723
|
+
front (an invoice total, say), also pass \`expected_amount\` \u2014 the price you
|
|
5724
|
+
expect, in whole tokens (\`"0.10"\`). On a JSON POST always pass
|
|
5358
5725
|
\`headers: {"Content-Type": "application/json"}\` \u2014 the tool does not infer
|
|
5359
5726
|
it, and a merchant may answer a request without it with a generic challenge
|
|
5360
5727
|
Haven cannot pay (for example, only the \`upto\` scheme).
|
|
@@ -5383,6 +5750,16 @@ for example, an invoice carrying an \`x402_payment_url\` to POST with its
|
|
|
5383
5750
|
report it, the merchant's settlement evidence. (A deposit transfer is bound
|
|
5384
5751
|
to its payee and amount on-chain too; the difference is the record, not
|
|
5385
5752
|
the binding.)
|
|
5753
|
+
- **If the quote says stop, stop.** The quote checks the agent's remaining
|
|
5754
|
+
budget at quote time, and it can check a price you state (\`expected_amount\`).
|
|
5755
|
+
When it returns \`safe_to_continue: false\` \u2014 the amount exceeds the budget, or
|
|
5756
|
+
the price does not match what you expected \u2014 it prefills no cap and names no
|
|
5757
|
+
next tool: stop and tell the user. If the x402 challenge itself is wrong (a
|
|
5758
|
+
price wildly off the invoice) and NOTHING has been paid via x402, the
|
|
5759
|
+
invoice's own deposit address MAY be an alternative, but only with the
|
|
5760
|
+
user's explicit go-ahead \u2014 never automatically. Once an x402 payment has
|
|
5761
|
+
been attempted or refused, never pay the deposit address: it can pay the
|
|
5762
|
+
invoice twice.
|
|
5386
5763
|
- **Pay exactly one route, and never fall back silently.** If the x402 route
|
|
5387
5764
|
is refused or fails, do not then pay the deposit address \u2014 that pays the
|
|
5388
5765
|
invoice twice. Follow the result's guidance fields instead: on EIP-3009, a
|
|
@@ -5424,6 +5801,20 @@ check on in-flight payments. Do not poll in a tight loop.
|
|
|
5424
5801
|
reports a missing or invalid credential, tell the user to re-run the Haven
|
|
5425
5802
|
connector command.
|
|
5426
5803
|
|
|
5804
|
+
## Stale tool list
|
|
5805
|
+
|
|
5806
|
+
Every hosted Haven result carries \`contract_fingerprint\` and
|
|
5807
|
+
\`server_version\` at the top level of its JSON. If a result's
|
|
5808
|
+
\`contract_fingerprint\` differs from the one in the server instructions you
|
|
5809
|
+
loaded at connect, or a \`next_arguments\` doesn't fit the schema you loaded
|
|
5810
|
+
for the hosted tool it names, your tool list is stale \u2014 reconnect or restart
|
|
5811
|
+
the session before continuing, and never hand-build or reshape a payload to
|
|
5812
|
+
make it fit; defer to the live schema and the \`next_arguments\` Haven returns.
|
|
5813
|
+
(A misfit on a signer tool is signer skew, not a stale list.) If a payment is
|
|
5814
|
+
already prepared or funded, keep its \`payment_id\`: after reconnecting,
|
|
5815
|
+
resume through \`haven_get_payment_status\` or \`haven_resume_x402_payment\`
|
|
5816
|
+
(\`haven_sweep_delegate\` for a stranded bridge balance). Never pay again.
|
|
5817
|
+
|
|
5427
5818
|
## Failure handling
|
|
5428
5819
|
|
|
5429
5820
|
Haven tool failures are shaped like \`{ success: false, code, message, ... }\`
|
|
@@ -5448,7 +5839,9 @@ fields a success does; follow them first, then branch on \`code\` and surface
|
|
|
5448
5839
|
"cannot settle right now" signal (a 503 \`merchant_not_ready\` with a
|
|
5449
5840
|
\`reason_code\`) instead of a 402. No payment was created. Tell the user;
|
|
5450
5841
|
retry later (the message carries \`retry_after_s\` when the merchant gave
|
|
5451
|
-
one) \u2014 this is not a wrong or broken endpoint.
|
|
5842
|
+
one) \u2014 this is not a wrong or broken endpoint. An out-of-gas refusal
|
|
5843
|
+
(\`settlement_wallet_out_of_gas\`) needs the merchant's operator to top up
|
|
5844
|
+
its settlement wallet first; retrying before then is refused again.
|
|
5452
5845
|
- \`MERCHANT_REJECTED_AFTER_FUNDING\`: the merchant refused the paid retry.
|
|
5453
5846
|
On eip3009 (\`rail\` not \`erc7710\`): Stop-and-sweep \u2014 stop retrying the
|
|
5454
5847
|
merchant and use \`mcp__haven__haven_sweep_delegate\` to recover stranded
|
|
@@ -5576,7 +5969,7 @@ async function discoverMerchantMcpUrl(inputUrl, egress) {
|
|
|
5576
5969
|
} catch (err) {
|
|
5577
5970
|
if (err instanceof MerchantEgressRefusedError || err instanceof MerchantEgressResponseCapError) throw err;
|
|
5578
5971
|
if (isBodyPhaseTimeout(err)) {
|
|
5579
|
-
throw new
|
|
5972
|
+
throw new chunkMZKLAHBK_cjs.MerchantTimeoutError(`Merchant discovery document read timed out after ${timeoutMs}ms.`);
|
|
5580
5973
|
}
|
|
5581
5974
|
continue;
|
|
5582
5975
|
}
|
|
@@ -5595,491 +5988,499 @@ function sameUrl(a, b) {
|
|
|
5595
5988
|
|
|
5596
5989
|
Object.defineProperty(exports, "DEFAULT_NEXT_TOOL_BY_ACTION", {
|
|
5597
5990
|
enumerable: true,
|
|
5598
|
-
get: function () { return
|
|
5991
|
+
get: function () { return chunkIKQIIMM6_cjs.DEFAULT_NEXT_TOOL_BY_ACTION; }
|
|
5599
5992
|
});
|
|
5600
5993
|
Object.defineProperty(exports, "ERC7710_ASSET_TRANSFER_METHOD", {
|
|
5601
5994
|
enumerable: true,
|
|
5602
|
-
get: function () { return
|
|
5995
|
+
get: function () { return chunkIKQIIMM6_cjs.ERC7710_ASSET_TRANSFER_METHOD; }
|
|
5603
5996
|
});
|
|
5604
5997
|
Object.defineProperty(exports, "HAVEN_CLIENT_HEADER", {
|
|
5605
5998
|
enumerable: true,
|
|
5606
|
-
get: function () { return
|
|
5999
|
+
get: function () { return chunkIKQIIMM6_cjs.HAVEN_CLIENT_HEADER; }
|
|
5607
6000
|
});
|
|
5608
6001
|
Object.defineProperty(exports, "HAVEN_MINIMUM_NODE_VERSION", {
|
|
5609
6002
|
enumerable: true,
|
|
5610
|
-
get: function () { return
|
|
6003
|
+
get: function () { return chunkIKQIIMM6_cjs.HAVEN_MINIMUM_NODE_VERSION; }
|
|
5611
6004
|
});
|
|
5612
6005
|
Object.defineProperty(exports, "HavenTypedDataRefusedError", {
|
|
5613
6006
|
enumerable: true,
|
|
5614
|
-
get: function () { return
|
|
6007
|
+
get: function () { return chunkIKQIIMM6_cjs.HavenTypedDataRefusedError; }
|
|
5615
6008
|
});
|
|
5616
6009
|
Object.defineProperty(exports, "MAX_TASK_BUDGET_TTL_SECONDS", {
|
|
5617
6010
|
enumerable: true,
|
|
5618
|
-
get: function () { return
|
|
6011
|
+
get: function () { return chunkIKQIIMM6_cjs.MAX_TASK_BUDGET_TTL_SECONDS; }
|
|
5619
6012
|
});
|
|
5620
6013
|
Object.defineProperty(exports, "NEXT_TOOL_SERVER_NAMES", {
|
|
5621
6014
|
enumerable: true,
|
|
5622
|
-
get: function () { return
|
|
6015
|
+
get: function () { return chunkIKQIIMM6_cjs.NEXT_TOOL_SERVER_NAMES; }
|
|
5623
6016
|
});
|
|
5624
6017
|
Object.defineProperty(exports, "NEXT_TOOL_SERVER_ROLES", {
|
|
5625
6018
|
enumerable: true,
|
|
5626
|
-
get: function () { return
|
|
6019
|
+
get: function () { return chunkIKQIIMM6_cjs.NEXT_TOOL_SERVER_ROLES; }
|
|
5627
6020
|
});
|
|
5628
6021
|
Object.defineProperty(exports, "SDK_CLIENT_IDENTITY", {
|
|
5629
6022
|
enumerable: true,
|
|
5630
|
-
get: function () { return
|
|
6023
|
+
get: function () { return chunkIKQIIMM6_cjs.SDK_CLIENT_IDENTITY; }
|
|
5631
6024
|
});
|
|
5632
6025
|
Object.defineProperty(exports, "SDK_VERSION", {
|
|
5633
6026
|
enumerable: true,
|
|
5634
|
-
get: function () { return
|
|
6027
|
+
get: function () { return chunkIKQIIMM6_cjs.SDK_VERSION; }
|
|
5635
6028
|
});
|
|
5636
6029
|
Object.defineProperty(exports, "SWEEP_BASE_CHAIN_ID", {
|
|
5637
6030
|
enumerable: true,
|
|
5638
|
-
get: function () { return
|
|
6031
|
+
get: function () { return chunkIKQIIMM6_cjs.SWEEP_BASE_CHAIN_ID; }
|
|
5639
6032
|
});
|
|
5640
6033
|
Object.defineProperty(exports, "SWEEP_BASE_SEPOLIA_CHAIN_ID", {
|
|
5641
6034
|
enumerable: true,
|
|
5642
|
-
get: function () { return
|
|
6035
|
+
get: function () { return chunkIKQIIMM6_cjs.SWEEP_BASE_SEPOLIA_CHAIN_ID; }
|
|
5643
6036
|
});
|
|
5644
6037
|
Object.defineProperty(exports, "SWEEP_BASE_SEPOLIA_USDC_ADDRESS", {
|
|
5645
6038
|
enumerable: true,
|
|
5646
|
-
get: function () { return
|
|
6039
|
+
get: function () { return chunkIKQIIMM6_cjs.SWEEP_BASE_SEPOLIA_USDC_ADDRESS; }
|
|
5647
6040
|
});
|
|
5648
6041
|
Object.defineProperty(exports, "SWEEP_BASE_USDC_ADDRESS", {
|
|
5649
6042
|
enumerable: true,
|
|
5650
|
-
get: function () { return
|
|
6043
|
+
get: function () { return chunkIKQIIMM6_cjs.SWEEP_BASE_USDC_ADDRESS; }
|
|
5651
6044
|
});
|
|
5652
6045
|
Object.defineProperty(exports, "TRANSFER_WITH_AUTHORIZATION_TYPES", {
|
|
5653
6046
|
enumerable: true,
|
|
5654
|
-
get: function () { return
|
|
6047
|
+
get: function () { return chunkIKQIIMM6_cjs.TRANSFER_WITH_AUTHORIZATION_TYPES; }
|
|
5655
6048
|
});
|
|
5656
6049
|
Object.defineProperty(exports, "TYPED_DATA_NOT_ALLOWED", {
|
|
5657
6050
|
enumerable: true,
|
|
5658
|
-
get: function () { return
|
|
6051
|
+
get: function () { return chunkIKQIIMM6_cjs.TYPED_DATA_NOT_ALLOWED; }
|
|
5659
6052
|
});
|
|
5660
6053
|
Object.defineProperty(exports, "X402PaymentHeaderValidationError", {
|
|
5661
6054
|
enumerable: true,
|
|
5662
|
-
get: function () { return
|
|
6055
|
+
get: function () { return chunkIKQIIMM6_cjs.X402PaymentHeaderValidationError; }
|
|
5663
6056
|
});
|
|
5664
6057
|
Object.defineProperty(exports, "X402_LEGACY_PAYMENT_HEADER_NAME", {
|
|
5665
6058
|
enumerable: true,
|
|
5666
|
-
get: function () { return
|
|
6059
|
+
get: function () { return chunkIKQIIMM6_cjs.X402_LEGACY_PAYMENT_HEADER_NAME; }
|
|
5667
6060
|
});
|
|
5668
6061
|
Object.defineProperty(exports, "X402_MAX_AUTHORIZATION_WINDOW_SECONDS", {
|
|
5669
6062
|
enumerable: true,
|
|
5670
|
-
get: function () { return
|
|
6063
|
+
get: function () { return chunkIKQIIMM6_cjs.X402_MAX_AUTHORIZATION_WINDOW_SECONDS; }
|
|
5671
6064
|
});
|
|
5672
6065
|
Object.defineProperty(exports, "X402_PAYMENT_HEADER_NAME", {
|
|
5673
6066
|
enumerable: true,
|
|
5674
|
-
get: function () { return
|
|
6067
|
+
get: function () { return chunkIKQIIMM6_cjs.X402_PAYMENT_HEADER_NAME; }
|
|
5675
6068
|
});
|
|
5676
6069
|
Object.defineProperty(exports, "X402_PAYMENT_HEADER_NAMES_SENT", {
|
|
5677
6070
|
enumerable: true,
|
|
5678
|
-
get: function () { return
|
|
6071
|
+
get: function () { return chunkIKQIIMM6_cjs.X402_PAYMENT_HEADER_NAMES_SENT; }
|
|
6072
|
+
});
|
|
6073
|
+
Object.defineProperty(exports, "X402_PAYMENT_NONCE_TAG", {
|
|
6074
|
+
enumerable: true,
|
|
6075
|
+
get: function () { return chunkIKQIIMM6_cjs.X402_PAYMENT_NONCE_TAG; }
|
|
5679
6076
|
});
|
|
5680
6077
|
Object.defineProperty(exports, "X402_PAYMENT_REQUIRED_HEADER_NAME", {
|
|
5681
6078
|
enumerable: true,
|
|
5682
|
-
get: function () { return
|
|
6079
|
+
get: function () { return chunkIKQIIMM6_cjs.X402_PAYMENT_REQUIRED_HEADER_NAME; }
|
|
5683
6080
|
});
|
|
5684
6081
|
Object.defineProperty(exports, "X402_PAYMENT_RESPONSE_HEADER_NAME", {
|
|
5685
6082
|
enumerable: true,
|
|
5686
|
-
get: function () { return
|
|
6083
|
+
get: function () { return chunkIKQIIMM6_cjs.X402_PAYMENT_RESPONSE_HEADER_NAME; }
|
|
5687
6084
|
});
|
|
5688
6085
|
Object.defineProperty(exports, "X402_SETTLEMENT_FORWARD_MARGIN_SECONDS", {
|
|
5689
6086
|
enumerable: true,
|
|
5690
|
-
get: function () { return
|
|
6087
|
+
get: function () { return chunkIKQIIMM6_cjs.X402_SETTLEMENT_FORWARD_MARGIN_SECONDS; }
|
|
5691
6088
|
});
|
|
5692
6089
|
Object.defineProperty(exports, "assertBoundDirectPaymentUserOp", {
|
|
5693
6090
|
enumerable: true,
|
|
5694
|
-
get: function () { return
|
|
6091
|
+
get: function () { return chunkIKQIIMM6_cjs.assertBoundDirectPaymentUserOp; }
|
|
5695
6092
|
});
|
|
5696
6093
|
Object.defineProperty(exports, "assertOwnTaskBudgetCloseUserOp", {
|
|
5697
6094
|
enumerable: true,
|
|
5698
|
-
get: function () { return
|
|
6095
|
+
get: function () { return chunkIKQIIMM6_cjs.assertOwnTaskBudgetCloseUserOp; }
|
|
5699
6096
|
});
|
|
5700
6097
|
Object.defineProperty(exports, "assertOwnTaskChild", {
|
|
5701
6098
|
enumerable: true,
|
|
5702
|
-
get: function () { return
|
|
6099
|
+
get: function () { return chunkIKQIIMM6_cjs.assertOwnTaskChild; }
|
|
5703
6100
|
});
|
|
5704
6101
|
Object.defineProperty(exports, "buildSweepAuthorizationMessage", {
|
|
5705
6102
|
enumerable: true,
|
|
5706
|
-
get: function () { return
|
|
6103
|
+
get: function () { return chunkIKQIIMM6_cjs.buildSweepAuthorizationMessage; }
|
|
5707
6104
|
});
|
|
5708
6105
|
Object.defineProperty(exports, "buildSweepTypedData", {
|
|
5709
6106
|
enumerable: true,
|
|
5710
|
-
get: function () { return
|
|
6107
|
+
get: function () { return chunkIKQIIMM6_cjs.buildSweepTypedData; }
|
|
5711
6108
|
});
|
|
5712
6109
|
Object.defineProperty(exports, "buildX402ExpectedMessage", {
|
|
5713
6110
|
enumerable: true,
|
|
5714
|
-
get: function () { return
|
|
6111
|
+
get: function () { return chunkIKQIIMM6_cjs.buildX402ExpectedMessage; }
|
|
5715
6112
|
});
|
|
5716
6113
|
Object.defineProperty(exports, "compareNodeVersions", {
|
|
5717
6114
|
enumerable: true,
|
|
5718
|
-
get: function () { return
|
|
6115
|
+
get: function () { return chunkIKQIIMM6_cjs.compareNodeVersions; }
|
|
5719
6116
|
});
|
|
5720
6117
|
Object.defineProperty(exports, "createNextStepBuilder", {
|
|
5721
6118
|
enumerable: true,
|
|
5722
|
-
get: function () { return
|
|
6119
|
+
get: function () { return chunkIKQIIMM6_cjs.createNextStepBuilder; }
|
|
5723
6120
|
});
|
|
5724
6121
|
Object.defineProperty(exports, "decodeBase64Json", {
|
|
5725
6122
|
enumerable: true,
|
|
5726
|
-
get: function () { return
|
|
6123
|
+
get: function () { return chunkIKQIIMM6_cjs.decodeBase64Json; }
|
|
5727
6124
|
});
|
|
5728
6125
|
Object.defineProperty(exports, "decodeBase64Utf8", {
|
|
5729
6126
|
enumerable: true,
|
|
5730
|
-
get: function () { return
|
|
6127
|
+
get: function () { return chunkIKQIIMM6_cjs.decodeBase64Utf8; }
|
|
5731
6128
|
});
|
|
5732
6129
|
Object.defineProperty(exports, "defaultNextToolFor", {
|
|
5733
6130
|
enumerable: true,
|
|
5734
|
-
get: function () { return
|
|
6131
|
+
get: function () { return chunkIKQIIMM6_cjs.defaultNextToolFor; }
|
|
6132
|
+
});
|
|
6133
|
+
Object.defineProperty(exports, "deriveX402PaymentNonce", {
|
|
6134
|
+
enumerable: true,
|
|
6135
|
+
get: function () { return chunkIKQIIMM6_cjs.deriveX402PaymentNonce; }
|
|
5735
6136
|
});
|
|
5736
6137
|
Object.defineProperty(exports, "encodeBase64Json", {
|
|
5737
6138
|
enumerable: true,
|
|
5738
|
-
get: function () { return
|
|
6139
|
+
get: function () { return chunkIKQIIMM6_cjs.encodeBase64Json; }
|
|
5739
6140
|
});
|
|
5740
6141
|
Object.defineProperty(exports, "encodeBase64Utf8", {
|
|
5741
6142
|
enumerable: true,
|
|
5742
|
-
get: function () { return
|
|
6143
|
+
get: function () { return chunkIKQIIMM6_cjs.encodeBase64Utf8; }
|
|
5743
6144
|
});
|
|
5744
6145
|
Object.defineProperty(exports, "encodePaymentProof", {
|
|
5745
6146
|
enumerable: true,
|
|
5746
|
-
get: function () { return
|
|
6147
|
+
get: function () { return chunkIKQIIMM6_cjs.encodePaymentProof; }
|
|
5747
6148
|
});
|
|
5748
6149
|
Object.defineProperty(exports, "hashDelegation", {
|
|
5749
6150
|
enumerable: true,
|
|
5750
|
-
get: function () { return
|
|
6151
|
+
get: function () { return chunkIKQIIMM6_cjs.hashDelegation; }
|
|
5751
6152
|
});
|
|
5752
6153
|
Object.defineProperty(exports, "havenClientIdentity", {
|
|
5753
6154
|
enumerable: true,
|
|
5754
|
-
get: function () { return
|
|
6155
|
+
get: function () { return chunkIKQIIMM6_cjs.havenClientIdentity; }
|
|
5755
6156
|
});
|
|
5756
6157
|
Object.defineProperty(exports, "isErc7710Option", {
|
|
5757
6158
|
enumerable: true,
|
|
5758
|
-
get: function () { return
|
|
6159
|
+
get: function () { return chunkIKQIIMM6_cjs.isErc7710Option; }
|
|
5759
6160
|
});
|
|
5760
6161
|
Object.defineProperty(exports, "isSupportedNodeVersion", {
|
|
5761
6162
|
enumerable: true,
|
|
5762
|
-
get: function () { return
|
|
6163
|
+
get: function () { return chunkIKQIIMM6_cjs.isSupportedNodeVersion; }
|
|
5763
6164
|
});
|
|
5764
6165
|
Object.defineProperty(exports, "isSweepableChain", {
|
|
5765
6166
|
enumerable: true,
|
|
5766
|
-
get: function () { return
|
|
6167
|
+
get: function () { return chunkIKQIIMM6_cjs.isSweepableChain; }
|
|
5767
6168
|
});
|
|
5768
6169
|
Object.defineProperty(exports, "isTaskChildTypedData", {
|
|
5769
6170
|
enumerable: true,
|
|
5770
|
-
get: function () { return
|
|
6171
|
+
get: function () { return chunkIKQIIMM6_cjs.isTaskChildTypedData; }
|
|
5771
6172
|
});
|
|
5772
6173
|
Object.defineProperty(exports, "normalizePaymentRequired", {
|
|
5773
6174
|
enumerable: true,
|
|
5774
|
-
get: function () { return
|
|
6175
|
+
get: function () { return chunkIKQIIMM6_cjs.normalizePaymentRequired; }
|
|
5775
6176
|
});
|
|
5776
6177
|
Object.defineProperty(exports, "parseNextTool", {
|
|
5777
6178
|
enumerable: true,
|
|
5778
|
-
get: function () { return
|
|
6179
|
+
get: function () { return chunkIKQIIMM6_cjs.parseNextTool; }
|
|
5779
6180
|
});
|
|
5780
6181
|
Object.defineProperty(exports, "parsePaymentRequired", {
|
|
5781
6182
|
enumerable: true,
|
|
5782
|
-
get: function () { return
|
|
6183
|
+
get: function () { return chunkIKQIIMM6_cjs.parsePaymentRequired; }
|
|
5783
6184
|
});
|
|
5784
6185
|
Object.defineProperty(exports, "parsePaymentRequiredResponse", {
|
|
5785
6186
|
enumerable: true,
|
|
5786
|
-
get: function () { return
|
|
6187
|
+
get: function () { return chunkIKQIIMM6_cjs.parsePaymentRequiredResponse; }
|
|
5787
6188
|
});
|
|
5788
6189
|
Object.defineProperty(exports, "readClientUpdate", {
|
|
5789
6190
|
enumerable: true,
|
|
5790
|
-
get: function () { return
|
|
6191
|
+
get: function () { return chunkIKQIIMM6_cjs.readClientUpdate; }
|
|
5791
6192
|
});
|
|
5792
6193
|
Object.defineProperty(exports, "renderNextTool", {
|
|
5793
6194
|
enumerable: true,
|
|
5794
|
-
get: function () { return
|
|
6195
|
+
get: function () { return chunkIKQIIMM6_cjs.renderNextTool; }
|
|
5795
6196
|
});
|
|
5796
6197
|
Object.defineProperty(exports, "resolveTokenBySymbol", {
|
|
5797
6198
|
enumerable: true,
|
|
5798
|
-
get: function () { return
|
|
6199
|
+
get: function () { return chunkIKQIIMM6_cjs.resolveTokenBySymbol; }
|
|
5799
6200
|
});
|
|
5800
6201
|
Object.defineProperty(exports, "resolveTokenFromAddress", {
|
|
5801
6202
|
enumerable: true,
|
|
5802
|
-
get: function () { return
|
|
6203
|
+
get: function () { return chunkIKQIIMM6_cjs.resolveTokenFromAddress; }
|
|
5803
6204
|
});
|
|
5804
6205
|
Object.defineProperty(exports, "selectErc7710PaymentOption", {
|
|
5805
6206
|
enumerable: true,
|
|
5806
|
-
get: function () { return
|
|
6207
|
+
get: function () { return chunkIKQIIMM6_cjs.selectErc7710PaymentOption; }
|
|
5807
6208
|
});
|
|
5808
6209
|
Object.defineProperty(exports, "selectPaymentOption", {
|
|
5809
6210
|
enumerable: true,
|
|
5810
|
-
get: function () { return
|
|
6211
|
+
get: function () { return chunkIKQIIMM6_cjs.selectPaymentOption; }
|
|
5811
6212
|
});
|
|
5812
6213
|
Object.defineProperty(exports, "selectStandardPaymentOption", {
|
|
5813
6214
|
enumerable: true,
|
|
5814
|
-
get: function () { return
|
|
6215
|
+
get: function () { return chunkIKQIIMM6_cjs.selectStandardPaymentOption; }
|
|
5815
6216
|
});
|
|
5816
6217
|
Object.defineProperty(exports, "selectX402SettlementScheme", {
|
|
5817
6218
|
enumerable: true,
|
|
5818
|
-
get: function () { return
|
|
6219
|
+
get: function () { return chunkIKQIIMM6_cjs.selectX402SettlementScheme; }
|
|
5819
6220
|
});
|
|
5820
6221
|
Object.defineProperty(exports, "sweepUsdcAddress", {
|
|
5821
6222
|
enumerable: true,
|
|
5822
|
-
get: function () { return
|
|
6223
|
+
get: function () { return chunkIKQIIMM6_cjs.sweepUsdcAddress; }
|
|
5823
6224
|
});
|
|
5824
6225
|
Object.defineProperty(exports, "sweepUsdcDomain", {
|
|
5825
6226
|
enumerable: true,
|
|
5826
|
-
get: function () { return
|
|
6227
|
+
get: function () { return chunkIKQIIMM6_cjs.sweepUsdcDomain; }
|
|
5827
6228
|
});
|
|
5828
6229
|
Object.defineProperty(exports, "toStandardPaymentRequirements", {
|
|
5829
6230
|
enumerable: true,
|
|
5830
|
-
get: function () { return
|
|
6231
|
+
get: function () { return chunkIKQIIMM6_cjs.toStandardPaymentRequirements; }
|
|
5831
6232
|
});
|
|
5832
6233
|
Object.defineProperty(exports, "unsupportedNodeVersionMessage", {
|
|
5833
6234
|
enumerable: true,
|
|
5834
|
-
get: function () { return
|
|
6235
|
+
get: function () { return chunkIKQIIMM6_cjs.unsupportedNodeVersionMessage; }
|
|
5835
6236
|
});
|
|
5836
6237
|
Object.defineProperty(exports, "validateStandardX402PaymentHeader", {
|
|
5837
6238
|
enumerable: true,
|
|
5838
|
-
get: function () { return
|
|
6239
|
+
get: function () { return chunkIKQIIMM6_cjs.validateStandardX402PaymentHeader; }
|
|
5839
6240
|
});
|
|
5840
6241
|
Object.defineProperty(exports, "x402AssetTransferMethod", {
|
|
5841
6242
|
enumerable: true,
|
|
5842
|
-
get: function () { return
|
|
6243
|
+
get: function () { return chunkIKQIIMM6_cjs.x402AssetTransferMethod; }
|
|
5843
6244
|
});
|
|
5844
6245
|
Object.defineProperty(exports, "x402AuthorizationAmount", {
|
|
5845
6246
|
enumerable: true,
|
|
5846
|
-
get: function () { return
|
|
6247
|
+
get: function () { return chunkIKQIIMM6_cjs.x402AuthorizationAmount; }
|
|
5847
6248
|
});
|
|
5848
6249
|
Object.defineProperty(exports, "x402FacilitatorAddresses", {
|
|
5849
6250
|
enumerable: true,
|
|
5850
|
-
get: function () { return
|
|
6251
|
+
get: function () { return chunkIKQIIMM6_cjs.x402FacilitatorAddresses; }
|
|
5851
6252
|
});
|
|
5852
6253
|
Object.defineProperty(exports, "x402PaymentHeaderNamesFor", {
|
|
5853
6254
|
enumerable: true,
|
|
5854
|
-
get: function () { return
|
|
6255
|
+
get: function () { return chunkIKQIIMM6_cjs.x402PaymentHeaderNamesFor; }
|
|
5855
6256
|
});
|
|
5856
6257
|
Object.defineProperty(exports, "x402RetryHeadersFor", {
|
|
5857
6258
|
enumerable: true,
|
|
5858
|
-
get: function () { return
|
|
6259
|
+
get: function () { return chunkIKQIIMM6_cjs.x402RetryHeadersFor; }
|
|
5859
6260
|
});
|
|
5860
6261
|
Object.defineProperty(exports, "x402V2PaymentEnvelope", {
|
|
5861
6262
|
enumerable: true,
|
|
5862
|
-
get: function () { return
|
|
6263
|
+
get: function () { return chunkIKQIIMM6_cjs.x402V2PaymentEnvelope; }
|
|
5863
6264
|
});
|
|
5864
6265
|
Object.defineProperty(exports, "RECEIPT_VERSION", {
|
|
5865
6266
|
enumerable: true,
|
|
5866
|
-
get: function () { return
|
|
6267
|
+
get: function () { return chunkDXBAN4SN_cjs.RECEIPT_VERSION; }
|
|
5867
6268
|
});
|
|
5868
6269
|
Object.defineProperty(exports, "verifyPaymentReceipt", {
|
|
5869
6270
|
enumerable: true,
|
|
5870
|
-
get: function () { return
|
|
6271
|
+
get: function () { return chunkDXBAN4SN_cjs.verifyPaymentReceipt; }
|
|
5871
6272
|
});
|
|
5872
6273
|
Object.defineProperty(exports, "AGENT_PAYMENT_FAILURE_CODE_VALUES", {
|
|
5873
6274
|
enumerable: true,
|
|
5874
|
-
get: function () { return
|
|
6275
|
+
get: function () { return chunkMZKLAHBK_cjs.AGENT_PAYMENT_FAILURE_CODE_VALUES; }
|
|
5875
6276
|
});
|
|
5876
6277
|
Object.defineProperty(exports, "AGENT_PAYMENT_NEXT_ACTION_VALUES", {
|
|
5877
6278
|
enumerable: true,
|
|
5878
|
-
get: function () { return
|
|
6279
|
+
get: function () { return chunkMZKLAHBK_cjs.AGENT_PAYMENT_NEXT_ACTION_VALUES; }
|
|
5879
6280
|
});
|
|
5880
6281
|
Object.defineProperty(exports, "AGENT_PAYMENT_PHASE_VALUES", {
|
|
5881
6282
|
enumerable: true,
|
|
5882
|
-
get: function () { return
|
|
6283
|
+
get: function () { return chunkMZKLAHBK_cjs.AGENT_PAYMENT_PHASE_VALUES; }
|
|
5883
6284
|
});
|
|
5884
6285
|
Object.defineProperty(exports, "AGENT_PAYMENT_RAIL_VALUES", {
|
|
5885
6286
|
enumerable: true,
|
|
5886
|
-
get: function () { return
|
|
6287
|
+
get: function () { return chunkMZKLAHBK_cjs.AGENT_PAYMENT_RAIL_VALUES; }
|
|
5887
6288
|
});
|
|
5888
6289
|
Object.defineProperty(exports, "AgentPaymentFailureCode", {
|
|
5889
6290
|
enumerable: true,
|
|
5890
|
-
get: function () { return
|
|
6291
|
+
get: function () { return chunkMZKLAHBK_cjs.AgentPaymentFailureCode; }
|
|
5891
6292
|
});
|
|
5892
6293
|
Object.defineProperty(exports, "AgentPaymentFailureCodeDescriptions", {
|
|
5893
6294
|
enumerable: true,
|
|
5894
|
-
get: function () { return
|
|
6295
|
+
get: function () { return chunkMZKLAHBK_cjs.AgentPaymentFailureCodeDescriptions; }
|
|
5895
6296
|
});
|
|
5896
6297
|
Object.defineProperty(exports, "AgentPaymentFailureCodeSchema", {
|
|
5897
6298
|
enumerable: true,
|
|
5898
|
-
get: function () { return
|
|
6299
|
+
get: function () { return chunkMZKLAHBK_cjs.AgentPaymentFailureCodeSchema; }
|
|
5899
6300
|
});
|
|
5900
6301
|
Object.defineProperty(exports, "AgentPaymentNextAction", {
|
|
5901
6302
|
enumerable: true,
|
|
5902
|
-
get: function () { return
|
|
6303
|
+
get: function () { return chunkMZKLAHBK_cjs.AgentPaymentNextAction; }
|
|
5903
6304
|
});
|
|
5904
6305
|
Object.defineProperty(exports, "AgentPaymentNextActionDescriptions", {
|
|
5905
6306
|
enumerable: true,
|
|
5906
|
-
get: function () { return
|
|
6307
|
+
get: function () { return chunkMZKLAHBK_cjs.AgentPaymentNextActionDescriptions; }
|
|
5907
6308
|
});
|
|
5908
6309
|
Object.defineProperty(exports, "AgentPaymentNextActionSchema", {
|
|
5909
6310
|
enumerable: true,
|
|
5910
|
-
get: function () { return
|
|
6311
|
+
get: function () { return chunkMZKLAHBK_cjs.AgentPaymentNextActionSchema; }
|
|
5911
6312
|
});
|
|
5912
6313
|
Object.defineProperty(exports, "AgentPaymentPhase", {
|
|
5913
6314
|
enumerable: true,
|
|
5914
|
-
get: function () { return
|
|
6315
|
+
get: function () { return chunkMZKLAHBK_cjs.AgentPaymentPhase; }
|
|
5915
6316
|
});
|
|
5916
6317
|
Object.defineProperty(exports, "AgentPaymentPhaseDescriptions", {
|
|
5917
6318
|
enumerable: true,
|
|
5918
|
-
get: function () { return
|
|
6319
|
+
get: function () { return chunkMZKLAHBK_cjs.AgentPaymentPhaseDescriptions; }
|
|
5919
6320
|
});
|
|
5920
6321
|
Object.defineProperty(exports, "AgentPaymentPhaseSchema", {
|
|
5921
6322
|
enumerable: true,
|
|
5922
|
-
get: function () { return
|
|
6323
|
+
get: function () { return chunkMZKLAHBK_cjs.AgentPaymentPhaseSchema; }
|
|
5923
6324
|
});
|
|
5924
6325
|
Object.defineProperty(exports, "AgentPaymentRail", {
|
|
5925
6326
|
enumerable: true,
|
|
5926
|
-
get: function () { return
|
|
6327
|
+
get: function () { return chunkMZKLAHBK_cjs.AgentPaymentRail; }
|
|
5927
6328
|
});
|
|
5928
6329
|
Object.defineProperty(exports, "AgentPaymentRailDescriptions", {
|
|
5929
6330
|
enumerable: true,
|
|
5930
|
-
get: function () { return
|
|
6331
|
+
get: function () { return chunkMZKLAHBK_cjs.AgentPaymentRailDescriptions; }
|
|
5931
6332
|
});
|
|
5932
6333
|
Object.defineProperty(exports, "AgentPaymentRailSchema", {
|
|
5933
6334
|
enumerable: true,
|
|
5934
|
-
get: function () { return
|
|
6335
|
+
get: function () { return chunkMZKLAHBK_cjs.AgentPaymentRailSchema; }
|
|
5935
6336
|
});
|
|
5936
6337
|
Object.defineProperty(exports, "AgentPaymentWarningCode", {
|
|
5937
6338
|
enumerable: true,
|
|
5938
|
-
get: function () { return
|
|
6339
|
+
get: function () { return chunkMZKLAHBK_cjs.AgentPaymentWarningCode; }
|
|
5939
6340
|
});
|
|
5940
6341
|
Object.defineProperty(exports, "CONNECTOR_PACKAGE_NAME", {
|
|
5941
6342
|
enumerable: true,
|
|
5942
|
-
get: function () { return
|
|
6343
|
+
get: function () { return chunkMZKLAHBK_cjs.CONNECTOR_PACKAGE_NAME; }
|
|
5943
6344
|
});
|
|
5944
6345
|
Object.defineProperty(exports, "DEFAULT_CONFIRMATION_TIMEOUT_MS", {
|
|
5945
6346
|
enumerable: true,
|
|
5946
|
-
get: function () { return
|
|
6347
|
+
get: function () { return chunkMZKLAHBK_cjs.DEFAULT_CONFIRMATION_TIMEOUT_MS; }
|
|
5947
6348
|
});
|
|
5948
6349
|
Object.defineProperty(exports, "DIRECT_SIGN_CONTEXT_VERSION", {
|
|
5949
6350
|
enumerable: true,
|
|
5950
|
-
get: function () { return
|
|
6351
|
+
get: function () { return chunkMZKLAHBK_cjs.DIRECT_SIGN_CONTEXT_VERSION; }
|
|
5951
6352
|
});
|
|
5952
6353
|
Object.defineProperty(exports, "ENTRY_POINT_V07", {
|
|
5953
6354
|
enumerable: true,
|
|
5954
|
-
get: function () { return
|
|
6355
|
+
get: function () { return chunkMZKLAHBK_cjs.ENTRY_POINT_V07; }
|
|
5955
6356
|
});
|
|
5956
6357
|
Object.defineProperty(exports, "HAVEN_CONNECTOR_CHANNEL", {
|
|
5957
6358
|
enumerable: true,
|
|
5958
|
-
get: function () { return
|
|
6359
|
+
get: function () { return chunkMZKLAHBK_cjs.HAVEN_CONNECTOR_CHANNEL; }
|
|
5959
6360
|
});
|
|
5960
6361
|
Object.defineProperty(exports, "HYBRID_DELEGATOR_DOMAIN_NAME", {
|
|
5961
6362
|
enumerable: true,
|
|
5962
|
-
get: function () { return
|
|
6363
|
+
get: function () { return chunkMZKLAHBK_cjs.HYBRID_DELEGATOR_DOMAIN_NAME; }
|
|
5963
6364
|
});
|
|
5964
6365
|
Object.defineProperty(exports, "HYBRID_DELEGATOR_DOMAIN_VERSION", {
|
|
5965
6366
|
enumerable: true,
|
|
5966
|
-
get: function () { return
|
|
6367
|
+
get: function () { return chunkMZKLAHBK_cjs.HYBRID_DELEGATOR_DOMAIN_VERSION; }
|
|
5967
6368
|
});
|
|
5968
6369
|
Object.defineProperty(exports, "HavenApiError", {
|
|
5969
6370
|
enumerable: true,
|
|
5970
|
-
get: function () { return
|
|
6371
|
+
get: function () { return chunkMZKLAHBK_cjs.HavenApiError; }
|
|
5971
6372
|
});
|
|
5972
6373
|
Object.defineProperty(exports, "HavenError", {
|
|
5973
6374
|
enumerable: true,
|
|
5974
|
-
get: function () { return
|
|
6375
|
+
get: function () { return chunkMZKLAHBK_cjs.HavenError; }
|
|
5975
6376
|
});
|
|
5976
6377
|
Object.defineProperty(exports, "HavenPaymentStateError", {
|
|
5977
6378
|
enumerable: true,
|
|
5978
|
-
get: function () { return
|
|
6379
|
+
get: function () { return chunkMZKLAHBK_cjs.HavenPaymentStateError; }
|
|
5979
6380
|
});
|
|
5980
6381
|
Object.defineProperty(exports, "HavenSigningError", {
|
|
5981
6382
|
enumerable: true,
|
|
5982
|
-
get: function () { return
|
|
6383
|
+
get: function () { return chunkMZKLAHBK_cjs.HavenSigningError; }
|
|
5983
6384
|
});
|
|
5984
6385
|
Object.defineProperty(exports, "HavenTimeoutError", {
|
|
5985
6386
|
enumerable: true,
|
|
5986
|
-
get: function () { return
|
|
6387
|
+
get: function () { return chunkMZKLAHBK_cjs.HavenTimeoutError; }
|
|
5987
6388
|
});
|
|
5988
6389
|
Object.defineProperty(exports, "HavenUnsupportedSignerVersionError", {
|
|
5989
6390
|
enumerable: true,
|
|
5990
|
-
get: function () { return
|
|
6391
|
+
get: function () { return chunkMZKLAHBK_cjs.HavenUnsupportedSignerVersionError; }
|
|
5991
6392
|
});
|
|
5992
6393
|
Object.defineProperty(exports, "HavenUserOpBindingError", {
|
|
5993
6394
|
enumerable: true,
|
|
5994
|
-
get: function () { return
|
|
6395
|
+
get: function () { return chunkMZKLAHBK_cjs.HavenUserOpBindingError; }
|
|
5995
6396
|
});
|
|
5996
6397
|
Object.defineProperty(exports, "HavenZeroSettlementHashError", {
|
|
5997
6398
|
enumerable: true,
|
|
5998
|
-
get: function () { return
|
|
6399
|
+
get: function () { return chunkMZKLAHBK_cjs.HavenZeroSettlementHashError; }
|
|
5999
6400
|
});
|
|
6000
6401
|
Object.defineProperty(exports, "MerchantTimeoutError", {
|
|
6001
6402
|
enumerable: true,
|
|
6002
|
-
get: function () { return
|
|
6403
|
+
get: function () { return chunkMZKLAHBK_cjs.MerchantTimeoutError; }
|
|
6003
6404
|
});
|
|
6004
6405
|
Object.defineProperty(exports, "PACKED_USER_OPERATION_FIELDS", {
|
|
6005
6406
|
enumerable: true,
|
|
6006
|
-
get: function () { return
|
|
6407
|
+
get: function () { return chunkMZKLAHBK_cjs.PACKED_USER_OPERATION_FIELDS; }
|
|
6007
6408
|
});
|
|
6008
6409
|
Object.defineProperty(exports, "ROOT_AUTHORITY", {
|
|
6009
6410
|
enumerable: true,
|
|
6010
|
-
get: function () { return
|
|
6411
|
+
get: function () { return chunkMZKLAHBK_cjs.ROOT_AUTHORITY; }
|
|
6011
6412
|
});
|
|
6012
6413
|
Object.defineProperty(exports, "SIGNER_UPDATE_FALLBACK", {
|
|
6013
6414
|
enumerable: true,
|
|
6014
|
-
get: function () { return
|
|
6415
|
+
get: function () { return chunkMZKLAHBK_cjs.SIGNER_UPDATE_FALLBACK; }
|
|
6015
6416
|
});
|
|
6016
6417
|
Object.defineProperty(exports, "SignerRefusalCode", {
|
|
6017
6418
|
enumerable: true,
|
|
6018
|
-
get: function () { return
|
|
6419
|
+
get: function () { return chunkMZKLAHBK_cjs.SignerRefusalCode; }
|
|
6019
6420
|
});
|
|
6020
6421
|
Object.defineProperty(exports, "TASK_SIGN_CONTEXT_VERSION", {
|
|
6021
6422
|
enumerable: true,
|
|
6022
|
-
get: function () { return
|
|
6423
|
+
get: function () { return chunkMZKLAHBK_cjs.TASK_SIGN_CONTEXT_VERSION; }
|
|
6023
6424
|
});
|
|
6024
6425
|
Object.defineProperty(exports, "X402AlreadySettledError", {
|
|
6025
6426
|
enumerable: true,
|
|
6026
|
-
get: function () { return
|
|
6427
|
+
get: function () { return chunkMZKLAHBK_cjs.X402AlreadySettledError; }
|
|
6027
6428
|
});
|
|
6028
6429
|
Object.defineProperty(exports, "X402Erc7710AlreadySettledError", {
|
|
6029
6430
|
enumerable: true,
|
|
6030
|
-
get: function () { return
|
|
6431
|
+
get: function () { return chunkMZKLAHBK_cjs.X402Erc7710AlreadySettledError; }
|
|
6031
6432
|
});
|
|
6032
6433
|
Object.defineProperty(exports, "X402TaskBudgetMismatchError", {
|
|
6033
6434
|
enumerable: true,
|
|
6034
|
-
get: function () { return
|
|
6435
|
+
get: function () { return chunkMZKLAHBK_cjs.X402TaskBudgetMismatchError; }
|
|
6035
6436
|
});
|
|
6036
6437
|
Object.defineProperty(exports, "X402UnexpectedStatusError", {
|
|
6037
6438
|
enumerable: true,
|
|
6038
|
-
get: function () { return
|
|
6439
|
+
get: function () { return chunkMZKLAHBK_cjs.X402UnexpectedStatusError; }
|
|
6039
6440
|
});
|
|
6040
6441
|
Object.defineProperty(exports, "assertUserOpTypedDataBinding", {
|
|
6041
6442
|
enumerable: true,
|
|
6042
|
-
get: function () { return
|
|
6443
|
+
get: function () { return chunkMZKLAHBK_cjs.assertUserOpTypedDataBinding; }
|
|
6043
6444
|
});
|
|
6044
6445
|
Object.defineProperty(exports, "connectorRerunCommand", {
|
|
6045
6446
|
enumerable: true,
|
|
6046
|
-
get: function () { return
|
|
6447
|
+
get: function () { return chunkMZKLAHBK_cjs.connectorRerunCommand; }
|
|
6047
6448
|
});
|
|
6048
6449
|
Object.defineProperty(exports, "connectorSpec", {
|
|
6049
6450
|
enumerable: true,
|
|
6050
|
-
get: function () { return
|
|
6451
|
+
get: function () { return chunkMZKLAHBK_cjs.connectorSpec; }
|
|
6051
6452
|
});
|
|
6052
6453
|
Object.defineProperty(exports, "connectorUpgradeCommand", {
|
|
6053
6454
|
enumerable: true,
|
|
6054
|
-
get: function () { return
|
|
6455
|
+
get: function () { return chunkMZKLAHBK_cjs.connectorUpgradeCommand; }
|
|
6055
6456
|
});
|
|
6056
6457
|
Object.defineProperty(exports, "deriveDelegateAccountAddress", {
|
|
6057
6458
|
enumerable: true,
|
|
6058
|
-
get: function () { return
|
|
6459
|
+
get: function () { return chunkMZKLAHBK_cjs.deriveDelegateAccountAddress; }
|
|
6059
6460
|
});
|
|
6060
6461
|
Object.defineProperty(exports, "isConnectorChannel", {
|
|
6061
6462
|
enumerable: true,
|
|
6062
|
-
get: function () { return
|
|
6463
|
+
get: function () { return chunkMZKLAHBK_cjs.isConnectorChannel; }
|
|
6063
6464
|
});
|
|
6064
6465
|
Object.defineProperty(exports, "isPackedUserOperationTypedData", {
|
|
6065
6466
|
enumerable: true,
|
|
6066
|
-
get: function () { return
|
|
6467
|
+
get: function () { return chunkMZKLAHBK_cjs.isPackedUserOperationTypedData; }
|
|
6067
6468
|
});
|
|
6068
6469
|
Object.defineProperty(exports, "packedUserOperationHash", {
|
|
6069
6470
|
enumerable: true,
|
|
6070
|
-
get: function () { return
|
|
6471
|
+
get: function () { return chunkMZKLAHBK_cjs.packedUserOperationHash; }
|
|
6071
6472
|
});
|
|
6072
6473
|
Object.defineProperty(exports, "resolveConnectorChannel", {
|
|
6073
6474
|
enumerable: true,
|
|
6074
|
-
get: function () { return
|
|
6475
|
+
get: function () { return chunkMZKLAHBK_cjs.resolveConnectorChannel; }
|
|
6075
6476
|
});
|
|
6076
6477
|
Object.defineProperty(exports, "signerUpdateFallback", {
|
|
6077
6478
|
enumerable: true,
|
|
6078
|
-
get: function () { return
|
|
6479
|
+
get: function () { return chunkMZKLAHBK_cjs.signerUpdateFallback; }
|
|
6079
6480
|
});
|
|
6080
6481
|
Object.defineProperty(exports, "verifySettlementChild", {
|
|
6081
6482
|
enumerable: true,
|
|
6082
|
-
get: function () { return
|
|
6483
|
+
get: function () { return chunkMZKLAHBK_cjs.verifySettlementChild; }
|
|
6083
6484
|
});
|
|
6084
6485
|
exports.AGENT_APPROVAL_RELAY_JSON_SENTENCE = AGENT_APPROVAL_RELAY_JSON_SENTENCE;
|
|
6085
6486
|
exports.AGENT_APPROVAL_RELAY_PROSE_SENTENCE = AGENT_APPROVAL_RELAY_PROSE_SENTENCE;
|
|
@@ -6111,6 +6512,7 @@ exports.SKILL_FOLDER_NAME = SKILL_FOLDER_NAME;
|
|
|
6111
6512
|
exports.addressFromKey = addressFromKey;
|
|
6112
6513
|
exports.assertPublicHttpsMerchantUrl = assertPublicHttpsMerchantUrl;
|
|
6113
6514
|
exports.assertSecureX402RetryTarget = assertSecureX402RetryTarget;
|
|
6515
|
+
exports.catalogFundingLegExpected = catalogFundingLegExpected;
|
|
6114
6516
|
exports.composeDescription = composeDescription;
|
|
6115
6517
|
exports.discoverMerchantMcpUrl = discoverMerchantMcpUrl;
|
|
6116
6518
|
exports.formatTokenAmount = formatTokenAmount;
|