@haven_ai/sdk 0.10.0-alpha.0 → 0.12.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 +45 -9
- package/dist/{base64-CiR5BJhk.d.cts → base64-C5OrJLij.d.ts} +10 -2
- package/dist/{base64-CxkinHPQ.d.ts → base64-COaV1Sis.d.cts} +10 -2
- package/dist/{chunk-6LEXYQ7J.cjs → chunk-4JTLJVBS.cjs} +4 -4
- package/dist/chunk-4JTLJVBS.cjs.map +1 -0
- package/dist/{chunk-MLUWABVT.js → chunk-7M3CIW7W.js} +7 -6
- package/dist/chunk-7M3CIW7W.js.map +1 -0
- package/dist/{chunk-TD2PHUYP.js → chunk-UPEDQLAL.js} +72 -6
- package/dist/chunk-UPEDQLAL.js.map +1 -0
- package/dist/{chunk-22FJ4JQO.cjs → chunk-V2ODMLDD.cjs} +38 -37
- package/dist/chunk-V2ODMLDD.cjs.map +1 -0
- package/dist/{chunk-EWTHDEIW.js → chunk-WFTGZS24.js} +3 -3
- package/dist/chunk-WFTGZS24.js.map +1 -0
- package/dist/{chunk-H37YVYZA.cjs → chunk-ZA3NOSO2.cjs} +73 -5
- package/dist/chunk-ZA3NOSO2.cjs.map +1 -0
- package/dist/edge.cjs +93 -93
- package/dist/edge.d.cts +11 -8
- package/dist/edge.d.ts +11 -8
- package/dist/edge.js +4 -4
- package/dist/index.cjs +866 -475
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -33
- package/dist/index.d.ts +69 -33
- package/dist/index.js +554 -171
- package/dist/index.js.map +1 -1
- package/dist/{receipt-q7ez8Zb2.d.cts → receipt-Dy77vCea.d.cts} +5 -4
- package/dist/{receipt-Cg9a5Seq.d.ts → receipt-DyUInpvF.d.ts} +5 -4
- 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-BKgqzvnk.d.ts → types-CAvsjRKi.d.cts} +209 -12
- package/dist/{types-BKgqzvnk.d.cts → types-CAvsjRKi.d.ts} +209 -12
- package/package.json +1 -1
- package/dist/chunk-22FJ4JQO.cjs.map +0 -1
- package/dist/chunk-6LEXYQ7J.cjs.map +0 -1
- package/dist/chunk-EWTHDEIW.js.map +0 -1
- package/dist/chunk-H37YVYZA.cjs.map +0 -1
- package/dist/chunk-MLUWABVT.js.map +0 -1
- package/dist/chunk-TD2PHUYP.js.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 chunkV2ODMLDD_cjs = require('./chunk-V2ODMLDD.cjs');
|
|
4
|
+
var chunk4JTLJVBS_cjs = require('./chunk-4JTLJVBS.cjs');
|
|
5
|
+
var chunkZA3NOSO2_cjs = require('./chunk-ZA3NOSO2.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 chunkZA3NOSO2_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 chunkZA3NOSO2_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 chunkZA3NOSO2_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 = chunkV2ODMLDD_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 ?? chunkV2ODMLDD_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 = chunkV2ODMLDD_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
|
+
[chunkV2ODMLDD_cjs.HAVEN_CLIENT_HEADER]: this.clientIdentity
|
|
128
128
|
},
|
|
129
129
|
body: body ? JSON.stringify(body) : void 0,
|
|
130
130
|
signal: controller.signal
|
|
@@ -137,17 +137,21 @@ 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 chunkZA3NOSO2_cjs.HavenApiError(message, res.status, data);
|
|
141
141
|
}
|
|
142
142
|
return data;
|
|
143
143
|
} catch (err) {
|
|
144
|
-
if (err instanceof
|
|
144
|
+
if (err instanceof chunkZA3NOSO2_cjs.HavenApiError) throw err;
|
|
145
|
+
const failureCause = { kind: "no_answer", method };
|
|
145
146
|
if (err instanceof Error && err.name === "AbortError") {
|
|
146
|
-
throw new
|
|
147
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(`Request to ${path} timed out`, 408, void 0, void 0, failureCause);
|
|
147
148
|
}
|
|
148
|
-
throw new
|
|
149
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
149
150
|
`Request to ${path} failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
150
|
-
0
|
|
151
|
+
0,
|
|
152
|
+
void 0,
|
|
153
|
+
void 0,
|
|
154
|
+
failureCause
|
|
151
155
|
);
|
|
152
156
|
} finally {
|
|
153
157
|
clearTimeout(timeout);
|
|
@@ -168,13 +172,13 @@ async function fetchUnsignedTaxDeclaration(client) {
|
|
|
168
172
|
if (reason === "feature_disabled" || reason === "disabled" || reason === "no_company_details" || reason === "vies_not_valid") {
|
|
169
173
|
return { available: false, reason };
|
|
170
174
|
}
|
|
171
|
-
throw new
|
|
175
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
172
176
|
"The tax-declaration endpoint answered a body that is neither the \xA72.1 content nor a named unavailability reason.",
|
|
173
177
|
502
|
|
174
178
|
);
|
|
175
179
|
}
|
|
176
180
|
async function resolveTaxDeclarationHeader(client, input) {
|
|
177
|
-
if (
|
|
181
|
+
if (chunkV2ODMLDD_cjs.isErc7710Option(input.accepted)) {
|
|
178
182
|
return { header: void 0 };
|
|
179
183
|
}
|
|
180
184
|
let content;
|
|
@@ -186,7 +190,7 @@ async function resolveTaxDeclarationHeader(client, input) {
|
|
|
186
190
|
if (!content.available) {
|
|
187
191
|
return { header: void 0 };
|
|
188
192
|
}
|
|
189
|
-
const signed =
|
|
193
|
+
const signed = chunkV2ODMLDD_cjs.buildSignedTaxDeclaration({
|
|
190
194
|
content: content.declaration,
|
|
191
195
|
network: input.accepted.network,
|
|
192
196
|
delegateKey: input.delegateKey
|
|
@@ -195,19 +199,19 @@ async function resolveTaxDeclarationHeader(client, input) {
|
|
|
195
199
|
`[haven-sdk] signing x402 tax declaration taxId=${JSON.stringify(content.declaration.taxId)} jurisdiction=${JSON.stringify(content.declaration.jurisdiction)} principalId=${signed.declaration.principalId}
|
|
196
200
|
`
|
|
197
201
|
);
|
|
198
|
-
return { header:
|
|
202
|
+
return { header: chunkV2ODMLDD_cjs.encodeTaxDeclarationHeader(signed) };
|
|
199
203
|
}
|
|
200
204
|
function withTaxDeclarationHeader(init, header) {
|
|
201
205
|
if (!header) {
|
|
202
|
-
if (init?.headers && new Headers(init.headers).has(
|
|
206
|
+
if (init?.headers && new Headers(init.headers).has(chunkV2ODMLDD_cjs.X_TAX_DECLARATION_HEADER)) {
|
|
203
207
|
const headers2 = new Headers(init.headers);
|
|
204
|
-
headers2.delete(
|
|
208
|
+
headers2.delete(chunkV2ODMLDD_cjs.X_TAX_DECLARATION_HEADER);
|
|
205
209
|
return { ...init, headers: headers2 };
|
|
206
210
|
}
|
|
207
211
|
return init ?? {};
|
|
208
212
|
}
|
|
209
213
|
const headers = new Headers(init?.headers);
|
|
210
|
-
headers.set(
|
|
214
|
+
headers.set(chunkV2ODMLDD_cjs.X_TAX_DECLARATION_HEADER, header);
|
|
211
215
|
return { ...init, headers };
|
|
212
216
|
}
|
|
213
217
|
|
|
@@ -353,6 +357,24 @@ function mapPaymentReceipt(raw) {
|
|
|
353
357
|
if ("approval_request_id" in raw) {
|
|
354
358
|
receipt.approvalRequestId = raw.approval_request_id ?? null;
|
|
355
359
|
}
|
|
360
|
+
if ("settlement_scheme" in raw) {
|
|
361
|
+
receipt.settlementScheme = raw.settlement_scheme ?? null;
|
|
362
|
+
}
|
|
363
|
+
if ("budget_delegation_hash" in raw) {
|
|
364
|
+
receipt.budgetDelegationHash = raw.budget_delegation_hash ?? null;
|
|
365
|
+
}
|
|
366
|
+
if ("delivery_quality" in raw) {
|
|
367
|
+
receipt.deliveryQuality = raw.delivery_quality ?? null;
|
|
368
|
+
}
|
|
369
|
+
if ("delivery_note" in raw) {
|
|
370
|
+
receipt.deliveryNote = raw.delivery_note ?? null;
|
|
371
|
+
}
|
|
372
|
+
if ("delivery_reported_at" in raw) {
|
|
373
|
+
receipt.deliveryReportedAt = raw.delivery_reported_at ?? null;
|
|
374
|
+
}
|
|
375
|
+
if ("delivery_reference" in raw) {
|
|
376
|
+
receipt.deliveryReference = raw.delivery_reference ?? null;
|
|
377
|
+
}
|
|
356
378
|
return receipt;
|
|
357
379
|
}
|
|
358
380
|
|
|
@@ -373,29 +395,29 @@ function paymentStateStatusCode(status, fallback = 502) {
|
|
|
373
395
|
return PAYMENT_STATE_STATUS_CODES[status] ?? fallback;
|
|
374
396
|
}
|
|
375
397
|
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
|
|
398
|
+
if (status === "pending_signature") return chunkZA3NOSO2_cjs.AgentPaymentPhase.AgentSignatureRequired;
|
|
399
|
+
if (status === "submitted") return chunkZA3NOSO2_cjs.AgentPaymentPhase.PaymentSubmitted;
|
|
400
|
+
if (status === "confirmed") return chunkZA3NOSO2_cjs.AgentPaymentPhase.PaymentConfirmed;
|
|
401
|
+
if (status === "pending" || status === "pending_approval") return chunkZA3NOSO2_cjs.AgentPaymentPhase.UserApprovalRequired;
|
|
402
|
+
if (status === "approved") return chunkZA3NOSO2_cjs.AgentPaymentPhase.UserExecutionRequired;
|
|
403
|
+
if (status === "proposed") return chunkZA3NOSO2_cjs.AgentPaymentPhase.WaitingForAdditionalApprovals;
|
|
404
|
+
if (status === "executed") return chunkZA3NOSO2_cjs.AgentPaymentPhase.FundingSent;
|
|
405
|
+
if (status === "rejected") return chunkZA3NOSO2_cjs.AgentPaymentPhase.Rejected;
|
|
406
|
+
if (status === "expired") return chunkZA3NOSO2_cjs.AgentPaymentPhase.Expired;
|
|
407
|
+
if (status === "failed") return chunkZA3NOSO2_cjs.AgentPaymentPhase.Failed;
|
|
386
408
|
return null;
|
|
387
409
|
}
|
|
388
410
|
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
|
|
411
|
+
if (status === "pending_signature") return chunkZA3NOSO2_cjs.AgentPaymentNextAction.SignAndSubmitPayment;
|
|
412
|
+
if (status === "submitted") return chunkZA3NOSO2_cjs.AgentPaymentNextAction.CheckStatusLater;
|
|
413
|
+
if (status === "confirmed") return chunkZA3NOSO2_cjs.AgentPaymentNextAction.None;
|
|
414
|
+
if (status === "pending" || status === "pending_approval") return chunkZA3NOSO2_cjs.AgentPaymentNextAction.StopAndTellUser;
|
|
415
|
+
if (status === "approved") return chunkZA3NOSO2_cjs.AgentPaymentNextAction.StopAndTellUser;
|
|
416
|
+
if (status === "proposed") return chunkZA3NOSO2_cjs.AgentPaymentNextAction.StopAndTellUser;
|
|
417
|
+
if (status === "executed") return chunkZA3NOSO2_cjs.AgentPaymentNextAction.StopAndTellUser;
|
|
418
|
+
if (status === "rejected") return chunkZA3NOSO2_cjs.AgentPaymentNextAction.StopAndTellUser;
|
|
419
|
+
if (status === "expired") return chunkZA3NOSO2_cjs.AgentPaymentNextAction.RequestAgainIfUserStillWantsIt;
|
|
420
|
+
if (status === "failed") return chunkZA3NOSO2_cjs.AgentPaymentNextAction.StopAndTellUser;
|
|
399
421
|
return null;
|
|
400
422
|
}
|
|
401
423
|
function messageForState(label, status, paymentId, nextAction) {
|
|
@@ -469,17 +491,17 @@ function throwPaymentStateError(label, raw) {
|
|
|
469
491
|
const statusCode = paymentStateStatusCode(raw.status);
|
|
470
492
|
const state = paymentStateFromRaw(label, raw);
|
|
471
493
|
if (state) {
|
|
472
|
-
throw new
|
|
494
|
+
throw new chunkZA3NOSO2_cjs.HavenPaymentStateError(state.message, statusCode, state, raw);
|
|
473
495
|
}
|
|
474
496
|
if (raw.status === "pending_approval") {
|
|
475
|
-
throw
|
|
497
|
+
throw chunkZA3NOSO2_cjs.HavenApiError.deterministic(
|
|
476
498
|
`${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
499
|
statusCode,
|
|
478
500
|
raw
|
|
479
501
|
);
|
|
480
502
|
}
|
|
481
503
|
if (raw.status === "expired") {
|
|
482
|
-
throw new
|
|
504
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
483
505
|
`${label} expired before it could be completed (payment_id: ${raw.payment_id}).`,
|
|
484
506
|
statusCode,
|
|
485
507
|
raw
|
|
@@ -487,7 +509,8 @@ function throwPaymentStateError(label, raw) {
|
|
|
487
509
|
}
|
|
488
510
|
const paymentId = raw.payment_id ? ` (payment_id: ${raw.payment_id})` : "";
|
|
489
511
|
const message = raw.error ?? `${label} ${raw.status}${paymentId}`;
|
|
490
|
-
throw
|
|
512
|
+
if (statusCode >= 500) throw chunkZA3NOSO2_cjs.HavenApiError.deterministic(message, statusCode, raw);
|
|
513
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(message, statusCode, raw);
|
|
491
514
|
}
|
|
492
515
|
|
|
493
516
|
// src/x402-retry-target.ts
|
|
@@ -519,7 +542,7 @@ function isSecureX402RetryTarget(url) {
|
|
|
519
542
|
return RESERVED_SUFFIXES.some((suffix) => host.endsWith(suffix));
|
|
520
543
|
}
|
|
521
544
|
var INSECURE_RETRY_TARGET_CODE = "INSECURE_RETRY_TARGET";
|
|
522
|
-
var HavenInsecureRetryTargetError = class extends
|
|
545
|
+
var HavenInsecureRetryTargetError = class extends chunkZA3NOSO2_cjs.HavenError {
|
|
523
546
|
constructor(url) {
|
|
524
547
|
super(
|
|
525
548
|
`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 +560,38 @@ function assertSecureX402RetryTarget(url) {
|
|
|
537
560
|
|
|
538
561
|
// src/merchant-egress.ts
|
|
539
562
|
var MERCHANT_EGRESS_REFUSED_CODE = "MERCHANT_EGRESS_REFUSED";
|
|
540
|
-
var MerchantEgressRefusedError = class extends
|
|
563
|
+
var MerchantEgressRefusedError = class extends chunkZA3NOSO2_cjs.HavenError {
|
|
541
564
|
url;
|
|
542
565
|
refusal;
|
|
543
566
|
beforeRequest;
|
|
544
|
-
|
|
545
|
-
|
|
567
|
+
/** #4257: the redirect status that was not followed, when a redirect was refused. */
|
|
568
|
+
redirectStatus;
|
|
569
|
+
/**
|
|
570
|
+
* #4257: set only when `url` IS the redirect target (a cross-origin body
|
|
571
|
+
* re-send, a spent hop budget, a hop `assertUrl` refused). A refusal that
|
|
572
|
+
* stopped at the answering URL itself (a non-GET redirect, a missing or
|
|
573
|
+
* unresolvable Location) leaves it unset, and `url` is that answering URL.
|
|
574
|
+
*/
|
|
575
|
+
redirectTarget;
|
|
576
|
+
/**
|
|
577
|
+
* #4257: set when the refusal interrupted a PAID delivery and the local
|
|
578
|
+
* completion has re-thrown it with the payment it belongs to — the funded,
|
|
579
|
+
* undelivered state, never "nothing happened".
|
|
580
|
+
*/
|
|
581
|
+
settlementScheme;
|
|
582
|
+
constructor(message, url, refusal, beforeRequest, extra = {}) {
|
|
583
|
+
super(message, MERCHANT_EGRESS_REFUSED_CODE, 400, extra.paymentId);
|
|
546
584
|
this.name = "MerchantEgressRefusedError";
|
|
547
585
|
this.url = url;
|
|
548
586
|
this.refusal = refusal;
|
|
549
587
|
this.beforeRequest = beforeRequest;
|
|
588
|
+
this.redirectStatus = extra.redirectStatus;
|
|
589
|
+
this.redirectTarget = extra.redirectTarget;
|
|
590
|
+
this.settlementScheme = extra.settlementScheme;
|
|
550
591
|
}
|
|
551
592
|
};
|
|
552
593
|
var MERCHANT_EGRESS_RESPONSE_CAP_CODE = "MERCHANT_EGRESS_RESPONSE_CAP";
|
|
553
|
-
var MerchantEgressResponseCapError = class extends
|
|
594
|
+
var MerchantEgressResponseCapError = class extends chunkZA3NOSO2_cjs.HavenError {
|
|
554
595
|
url;
|
|
555
596
|
limitBytes;
|
|
556
597
|
constructor(message, limitBytes, url) {
|
|
@@ -661,6 +702,29 @@ var MCP_X402_PAYMENT_META_KEY = "x402/payment";
|
|
|
661
702
|
var MCP_X402_PAYMENT_RESPONSE_META_KEY = "x402/payment-response";
|
|
662
703
|
var X402_RETRY_REJECTED_STATUS = 402;
|
|
663
704
|
var SESSION_NOT_FOUND_NEXT_ACTION = "reinitialize_then_retry_same_payment_header";
|
|
705
|
+
var CROSS_ORIGIN_REDIRECT_HEADERS = /* @__PURE__ */ new Set([
|
|
706
|
+
"accept",
|
|
707
|
+
"accept-language",
|
|
708
|
+
"user-agent",
|
|
709
|
+
"x402-wallet"
|
|
710
|
+
]);
|
|
711
|
+
function crossOriginRedirectHeaders(headers) {
|
|
712
|
+
const kept = new Headers();
|
|
713
|
+
for (const [name, value] of new Headers(headers)) {
|
|
714
|
+
if (CROSS_ORIGIN_REDIRECT_HEADERS.has(name)) kept.set(name, value);
|
|
715
|
+
}
|
|
716
|
+
return kept;
|
|
717
|
+
}
|
|
718
|
+
var NO_POLICY_MAX_REDIRECTS = 20;
|
|
719
|
+
var REQUEST_BODY_HEADERS = ["content-encoding", "content-language", "content-location", "content-type", "content-length"];
|
|
720
|
+
function redirectedInit(init, status) {
|
|
721
|
+
const method = (init.method ?? "GET").toUpperCase();
|
|
722
|
+
const toGet = (status === 301 || status === 302) && method === "POST" || status === 303 && method !== "GET" && method !== "HEAD";
|
|
723
|
+
if (!toGet) return init;
|
|
724
|
+
const headers = new Headers(init.headers);
|
|
725
|
+
for (const name of REQUEST_BODY_HEADERS) headers.delete(name);
|
|
726
|
+
return { ...init, method: "GET", body: null, headers };
|
|
727
|
+
}
|
|
664
728
|
var McpMerchantTransport = class {
|
|
665
729
|
merchantTimeout;
|
|
666
730
|
fetchImpl;
|
|
@@ -691,99 +755,169 @@ var McpMerchantTransport = class {
|
|
|
691
755
|
}
|
|
692
756
|
/** Fetch a merchant with a settlement-sized timeout and caller cancellation. */
|
|
693
757
|
async fetch(url, init = {}, timeoutMs = this.merchantTimeout, maxBytes) {
|
|
758
|
+
return this.send(url, init, timeoutMs, maxBytes, false);
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* `fetch`, plus whether this request is the paid delivery (#4257). A paid
|
|
762
|
+
* delivery, or any body carrying an x402 payment in `_meta`, is never
|
|
763
|
+
* re-sent to another origin by a redirect that keeps the body; without a policy every other
|
|
764
|
+
* request follows that redirect as the platform would, headers reduced.
|
|
765
|
+
*/
|
|
766
|
+
async send(url, init, timeoutMs, maxBytes, paidDelivery) {
|
|
767
|
+
const carriesPayment = paidDelivery || bodyCarriesX402Payment(init.body);
|
|
694
768
|
if (!this.egress) {
|
|
695
769
|
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
696
770
|
const signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;
|
|
697
771
|
try {
|
|
698
|
-
|
|
772
|
+
if (init.redirect === "manual" || init.redirect === "error") {
|
|
773
|
+
return await this.fetchImpl(url, { ...init, signal });
|
|
774
|
+
}
|
|
775
|
+
return await this.followRedirects(url, init, signal, void 0, carriesPayment);
|
|
699
776
|
} catch (err) {
|
|
700
777
|
if (timeoutSignal.aborted) {
|
|
701
|
-
throw new
|
|
778
|
+
throw new chunkZA3NOSO2_cjs.MerchantTimeoutError(`Merchant request timed out after ${timeoutMs}ms: ${url}`);
|
|
702
779
|
}
|
|
703
780
|
throw err;
|
|
704
781
|
}
|
|
705
782
|
}
|
|
706
|
-
return this.fetchUnderPolicy(url, init, timeoutMs, maxBytes);
|
|
783
|
+
return this.fetchUnderPolicy(url, init, timeoutMs, maxBytes, carriesPayment);
|
|
707
784
|
}
|
|
708
785
|
/**
|
|
709
786
|
* #3747: the policy path. Every URL — the initial request and each redirect
|
|
710
787
|
* hop — is `assertUrl`-checked BEFORE it connects; redirects run `manual`
|
|
711
788
|
* so nothing is ever followed un-checked; GET redirects are followed up to
|
|
712
|
-
* `maxGetRedirects` (a redirect on any other method is refused);
|
|
713
|
-
*
|
|
789
|
+
* `maxGetRedirects` (a redirect on any other method is refused); a hop to
|
|
790
|
+
* another origin carries only `CROSS_ORIGIN_REDIRECT_HEADERS` (#4244);
|
|
791
|
+
* response bodies are capped WHILE being read, not after buffering. The timeout
|
|
714
792
|
* signal spans the WHOLE redirect chain, and `MerchantTimeoutError`
|
|
715
793
|
* classification is preserved.
|
|
716
794
|
*/
|
|
717
|
-
async fetchUnderPolicy(url, init, timeoutMs, maxBytes) {
|
|
795
|
+
async fetchUnderPolicy(url, init, timeoutMs, maxBytes, carriesPayment) {
|
|
718
796
|
const egress = this.egress;
|
|
719
797
|
try {
|
|
720
798
|
egress.assertUrl(url);
|
|
721
799
|
} catch (err) {
|
|
722
800
|
throw asRefusal(err, url, true);
|
|
723
801
|
}
|
|
724
|
-
const method = (init.method ?? "GET").toUpperCase();
|
|
725
802
|
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
726
803
|
const signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;
|
|
727
|
-
|
|
804
|
+
let finalUrl = url;
|
|
805
|
+
try {
|
|
806
|
+
const response = await this.followRedirects(url, init, signal, egress, carriesPayment, (hopUrl) => {
|
|
807
|
+
finalUrl = hopUrl;
|
|
808
|
+
});
|
|
809
|
+
return this.capResponse(response, finalUrl, maxBytes);
|
|
810
|
+
} catch (err) {
|
|
811
|
+
if (timeoutSignal.aborted) {
|
|
812
|
+
throw new chunkZA3NOSO2_cjs.MerchantTimeoutError(`Merchant request timed out after ${timeoutMs}ms: ${finalUrl}`);
|
|
813
|
+
}
|
|
814
|
+
throw err;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* The redirect follower both paths share (#3747, #4244, #4257). Redirects
|
|
819
|
+
* run `manual` and every hop is decided here:
|
|
820
|
+
*
|
|
821
|
+
* - Under a `policy`, every hop is `assertUrl`-checked before it connects,
|
|
822
|
+
* only GET redirects are followed (any other method is refused), up to
|
|
823
|
+
* `maxGetRedirects`; a missing or unresolvable Location is refused.
|
|
824
|
+
* - Without one, the platform's rules are kept: up to
|
|
825
|
+
* `NO_POLICY_MAX_REDIRECTS` hops, the Fetch spec's method/body rewrite,
|
|
826
|
+
* and a 3xx with no Location returned as the answer.
|
|
827
|
+
* - On both, a hop to another origin carries only
|
|
828
|
+
* `CROSS_ORIGIN_REDIRECT_HEADERS`, never restored on a later hop.
|
|
829
|
+
* - A hop that would re-send a request body to another origin is refused
|
|
830
|
+
* under a policy (which follows GET alone, so this is unreachable there),
|
|
831
|
+
* and without one only when `carriesPayment`: the paid delivery, or a body
|
|
832
|
+
* carrying an x402 payment in `_meta` (#4257). Any other body-keeping redirect is
|
|
833
|
+
* followed with its body, as the platform did, headers reduced.
|
|
834
|
+
*
|
|
835
|
+
* `onHop` sees every URL a request goes to, so the caller can name the hop
|
|
836
|
+
* it was on when the chain stops.
|
|
837
|
+
*/
|
|
838
|
+
async followRedirects(url, init, signal, policy, carriesPayment, onHop) {
|
|
839
|
+
const maxRedirects = policy ? policy.maxGetRedirects ?? 0 : NO_POLICY_MAX_REDIRECTS;
|
|
728
840
|
let currentUrl = url;
|
|
841
|
+
let hopInit = init;
|
|
729
842
|
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
|
-
|
|
843
|
+
while (true) {
|
|
844
|
+
onHop?.(currentUrl);
|
|
845
|
+
const response = await this.fetchImpl(currentUrl, {
|
|
846
|
+
...hopInit,
|
|
847
|
+
redirect: init.redirect === "error" ? "error" : "manual",
|
|
848
|
+
signal
|
|
849
|
+
});
|
|
850
|
+
if (!isRedirectStatus(response.status)) return response;
|
|
851
|
+
const method = (hopInit.method ?? "GET").toUpperCase();
|
|
852
|
+
if (policy && method !== "GET") {
|
|
853
|
+
throw new MerchantEgressRefusedError(
|
|
854
|
+
`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.`,
|
|
855
|
+
currentUrl,
|
|
856
|
+
"redirect_on_non_get",
|
|
857
|
+
false,
|
|
858
|
+
{ redirectStatus: response.status }
|
|
859
|
+
);
|
|
860
|
+
}
|
|
861
|
+
const location = response.headers.get("location");
|
|
862
|
+
if (!location) {
|
|
863
|
+
if (!policy) return response;
|
|
864
|
+
throw new MerchantEgressRefusedError(
|
|
865
|
+
`Hosted egress policy refuses the ${response.status} redirect from ${currentUrl}: it carries no Location header, so there is no checked target to follow.`,
|
|
866
|
+
currentUrl,
|
|
867
|
+
"redirect_missing_location",
|
|
868
|
+
false,
|
|
869
|
+
{ redirectStatus: response.status }
|
|
870
|
+
);
|
|
871
|
+
}
|
|
872
|
+
let next;
|
|
873
|
+
try {
|
|
874
|
+
next = new URL(location, currentUrl).toString();
|
|
875
|
+
} catch {
|
|
876
|
+
if (!policy) throw new TypeError(`fetch failed: the redirect from ${currentUrl} has an unresolvable Location header`);
|
|
877
|
+
throw new MerchantEgressRefusedError(
|
|
878
|
+
`Hosted egress policy refuses the redirect from ${currentUrl}: its Location header is not a resolvable URL.`,
|
|
879
|
+
currentUrl,
|
|
880
|
+
"redirect_invalid_location",
|
|
881
|
+
false,
|
|
882
|
+
{ redirectStatus: response.status }
|
|
883
|
+
);
|
|
884
|
+
}
|
|
885
|
+
if (!policy && !/^https?:$/.test(new URL(next).protocol)) {
|
|
886
|
+
throw new TypeError(`fetch failed: the redirect from ${currentUrl} names a non-HTTP(S) URL`);
|
|
887
|
+
}
|
|
888
|
+
if (hops >= maxRedirects) {
|
|
889
|
+
if (!policy) throw new TypeError(`fetch failed: redirect count exceeded (${maxRedirects}) at ${currentUrl}`);
|
|
890
|
+
throw new MerchantEgressRefusedError(
|
|
891
|
+
`Hosted egress policy refuses the redirect from ${currentUrl} to ${next}: the ${maxRedirects}-redirect budget for this request is spent.`,
|
|
892
|
+
next,
|
|
893
|
+
"redirect_budget_exceeded",
|
|
894
|
+
false,
|
|
895
|
+
{ redirectStatus: response.status, redirectTarget: next }
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
if (policy) {
|
|
756
899
|
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
|
-
);
|
|
900
|
+
policy.assertUrl(next);
|
|
901
|
+
} catch (err) {
|
|
902
|
+
throw asRefusal(err, next, false, { redirectStatus: response.status, redirectTarget: next });
|
|
765
903
|
}
|
|
766
|
-
|
|
904
|
+
}
|
|
905
|
+
hopInit = redirectedInit(hopInit, response.status);
|
|
906
|
+
if (new URL(next).origin !== new URL(currentUrl).origin) {
|
|
907
|
+
if (hopInit.body != null && (policy || carriesPayment)) {
|
|
767
908
|
throw new MerchantEgressRefusedError(
|
|
768
|
-
`
|
|
909
|
+
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
910
|
next,
|
|
770
|
-
"
|
|
771
|
-
false
|
|
911
|
+
"redirect_cross_origin_body",
|
|
912
|
+
false,
|
|
913
|
+
{ redirectStatus: response.status, redirectTarget: next }
|
|
772
914
|
);
|
|
773
915
|
}
|
|
774
|
-
|
|
775
|
-
egress.assertUrl(next);
|
|
776
|
-
} catch (err) {
|
|
777
|
-
throw asRefusal(err, next, false);
|
|
778
|
-
}
|
|
779
|
-
hops++;
|
|
780
|
-
currentUrl = next;
|
|
916
|
+
hopInit = { ...hopInit, headers: crossOriginRedirectHeaders(hopInit.headers) };
|
|
781
917
|
}
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
}
|
|
786
|
-
throw err;
|
|
918
|
+
await response.body?.cancel().catch(() => void 0);
|
|
919
|
+
hops++;
|
|
920
|
+
currentUrl = next;
|
|
787
921
|
}
|
|
788
922
|
}
|
|
789
923
|
/**
|
|
@@ -869,7 +1003,7 @@ var McpMerchantTransport = class {
|
|
|
869
1003
|
text = await response.clone().text();
|
|
870
1004
|
} catch (err) {
|
|
871
1005
|
if (err instanceof MerchantEgressResponseCapError) throw err;
|
|
872
|
-
if (isBodyPhaseTimeout(err)) throw new
|
|
1006
|
+
if (isBodyPhaseTimeout(err)) throw new chunkZA3NOSO2_cjs.MerchantTimeoutError(`Merchant response body read timed out.`);
|
|
873
1007
|
return void 0;
|
|
874
1008
|
}
|
|
875
1009
|
if ((response.headers.get("content-type") ?? "").includes("text/event-stream")) {
|
|
@@ -894,7 +1028,7 @@ var McpMerchantTransport = class {
|
|
|
894
1028
|
text = await response.clone().text();
|
|
895
1029
|
} catch (err) {
|
|
896
1030
|
if (err instanceof MerchantEgressResponseCapError) throw err;
|
|
897
|
-
if (isBodyPhaseTimeout(err)) throw new
|
|
1031
|
+
if (isBodyPhaseTimeout(err)) throw new chunkZA3NOSO2_cjs.MerchantTimeoutError(`Merchant response body read timed out.`);
|
|
898
1032
|
return response;
|
|
899
1033
|
}
|
|
900
1034
|
const message = selectJsonRpcResult(parseSseJsonRpcMessages(text));
|
|
@@ -956,12 +1090,12 @@ var McpMerchantTransport = class {
|
|
|
956
1090
|
async deliverPayment(url, init, paymentHeader) {
|
|
957
1091
|
assertSecureX402RetryTarget(url);
|
|
958
1092
|
const headers = new Headers(init?.headers);
|
|
959
|
-
const send =
|
|
960
|
-
for (const name of
|
|
1093
|
+
const send = chunkV2ODMLDD_cjs.x402PaymentHeaderNamesFor(paymentHeader);
|
|
1094
|
+
for (const name of chunkV2ODMLDD_cjs.X402_PAYMENT_HEADER_NAMES) {
|
|
961
1095
|
if (send.includes(name)) headers.set(name, paymentHeader);
|
|
962
1096
|
else headers.delete(name);
|
|
963
1097
|
}
|
|
964
|
-
return this.
|
|
1098
|
+
return this.send(url, withMcpPaymentMeta({ ...init, headers }, paymentHeader), this.budgetFor("delivery"), this.capFor("delivery"), true);
|
|
965
1099
|
}
|
|
966
1100
|
/**
|
|
967
1101
|
* #3171: deliver the payment; if the merchant answers its unknown-session
|
|
@@ -1044,7 +1178,7 @@ function mcpToolResultOf(value) {
|
|
|
1044
1178
|
function extractMcpPaymentRequired(toolResult) {
|
|
1045
1179
|
if (toolResult.isError !== true) return void 0;
|
|
1046
1180
|
if (isRecord(toolResult.structuredContent)) {
|
|
1047
|
-
const parsed =
|
|
1181
|
+
const parsed = chunkV2ODMLDD_cjs.normalizePaymentRequired(toolResult.structuredContent);
|
|
1048
1182
|
if (parsed) return parsed;
|
|
1049
1183
|
}
|
|
1050
1184
|
if (Array.isArray(toolResult.content)) {
|
|
@@ -1056,7 +1190,7 @@ function extractMcpPaymentRequired(toolResult) {
|
|
|
1056
1190
|
} catch {
|
|
1057
1191
|
continue;
|
|
1058
1192
|
}
|
|
1059
|
-
const parsed =
|
|
1193
|
+
const parsed = chunkV2ODMLDD_cjs.normalizePaymentRequired(candidate);
|
|
1060
1194
|
if (parsed) return parsed;
|
|
1061
1195
|
}
|
|
1062
1196
|
}
|
|
@@ -1080,7 +1214,7 @@ function withMcpPaymentMeta(init, paymentHeader) {
|
|
|
1080
1214
|
if (!request) return init;
|
|
1081
1215
|
let envelope;
|
|
1082
1216
|
try {
|
|
1083
|
-
envelope =
|
|
1217
|
+
envelope = chunkV2ODMLDD_cjs.decodeBase64Json(paymentHeader);
|
|
1084
1218
|
} catch {
|
|
1085
1219
|
return init;
|
|
1086
1220
|
}
|
|
@@ -1096,7 +1230,28 @@ function withMcpPaymentMeta(init, paymentHeader) {
|
|
|
1096
1230
|
};
|
|
1097
1231
|
}
|
|
1098
1232
|
function encodeMcpSettlementReceipt(settlement) {
|
|
1099
|
-
return
|
|
1233
|
+
return chunkV2ODMLDD_cjs.encodeBase64Json(settlement);
|
|
1234
|
+
}
|
|
1235
|
+
function bodyCarriesX402Payment(body) {
|
|
1236
|
+
let text;
|
|
1237
|
+
if (typeof body === "string") text = body;
|
|
1238
|
+
else if (body instanceof Uint8Array || body instanceof ArrayBuffer) {
|
|
1239
|
+
try {
|
|
1240
|
+
text = new TextDecoder("utf-8", { fatal: true }).decode(body);
|
|
1241
|
+
} catch {
|
|
1242
|
+
return false;
|
|
1243
|
+
}
|
|
1244
|
+
} else return false;
|
|
1245
|
+
let request;
|
|
1246
|
+
try {
|
|
1247
|
+
request = JSON.parse(text);
|
|
1248
|
+
} catch {
|
|
1249
|
+
return false;
|
|
1250
|
+
}
|
|
1251
|
+
return Array.isArray(request) ? request.some(messageCarriesX402Payment) : messageCarriesX402Payment(request);
|
|
1252
|
+
}
|
|
1253
|
+
function messageCarriesX402Payment(message) {
|
|
1254
|
+
return isRecord(message) && isRecord(message.params) && isRecord(message.params._meta) && message.params._meta[MCP_X402_PAYMENT_META_KEY] !== void 0;
|
|
1100
1255
|
}
|
|
1101
1256
|
function parseJsonRpcToolsCall(body) {
|
|
1102
1257
|
if (typeof body !== "string") return void 0;
|
|
@@ -1136,10 +1291,10 @@ function isRecord(value) {
|
|
|
1136
1291
|
function isRedirectStatus(status) {
|
|
1137
1292
|
return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
|
|
1138
1293
|
}
|
|
1139
|
-
function asRefusal(err, url, beforeRequest) {
|
|
1294
|
+
function asRefusal(err, url, beforeRequest, redirect) {
|
|
1140
1295
|
if (!(err instanceof MerchantEgressRefusedError)) return err;
|
|
1141
|
-
if (err.beforeRequest === beforeRequest) return err;
|
|
1142
|
-
return new MerchantEgressRefusedError(err.message, url, err.refusal, beforeRequest);
|
|
1296
|
+
if (err.beforeRequest === beforeRequest && !redirect) return err;
|
|
1297
|
+
return new MerchantEgressRefusedError(err.message, url, err.refusal, beforeRequest, redirect);
|
|
1143
1298
|
}
|
|
1144
1299
|
async function captureMerchantResponse(response) {
|
|
1145
1300
|
const merchant_body = await response.text().catch((err) => {
|
|
@@ -1213,8 +1368,19 @@ function deriveReadiness(status, allowances) {
|
|
|
1213
1368
|
if (status !== "active") return "revoked";
|
|
1214
1369
|
return allowances.some((allowance) => safeBigInt(allowance.remainingAtomic) > 0n) ? "ready" : "needs_approval";
|
|
1215
1370
|
}
|
|
1371
|
+
function deriveBudgetRefillsAt(readiness, allowances) {
|
|
1372
|
+
if (readiness !== "needs_approval" || allowances.length === 0) return null;
|
|
1373
|
+
const times = allowances.map((allowance) => allowance.nextRefillAt).filter((at) => at !== null && !Number.isNaN(Date.parse(at)));
|
|
1374
|
+
if (times.length === 0) return null;
|
|
1375
|
+
return times.reduce((earliest, at) => Date.parse(at) < Date.parse(earliest) ? at : earliest);
|
|
1376
|
+
}
|
|
1377
|
+
function deriveBudgetEndedAt(readiness, allowances, budgetEndedAt) {
|
|
1378
|
+
if (readiness !== "needs_approval" || allowances.length > 0) return null;
|
|
1379
|
+
if (!budgetEndedAt || Number.isNaN(Date.parse(budgetEndedAt))) return null;
|
|
1380
|
+
return budgetEndedAt;
|
|
1381
|
+
}
|
|
1216
1382
|
function formatRemainingDisplay(tokenAddress, tokenSymbol, remainingAtomic) {
|
|
1217
|
-
const token =
|
|
1383
|
+
const token = chunkV2ODMLDD_cjs.resolveTokenFromAddress(tokenAddress);
|
|
1218
1384
|
return token ? `${formatAtomicAmount(safeBigInt(remainingAtomic), token.decimals)} ${tokenSymbol}` : `${remainingAtomic} ${tokenSymbol} (atomic; unknown decimals)`;
|
|
1219
1385
|
}
|
|
1220
1386
|
function formatTokenAmount(atomic, decimals) {
|
|
@@ -1234,7 +1400,7 @@ function mapSupersession(raw) {
|
|
|
1234
1400
|
replacementAgentId,
|
|
1235
1401
|
supersededAt,
|
|
1236
1402
|
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.`,
|
|
1237
|
-
nextAction:
|
|
1403
|
+
nextAction: chunkZA3NOSO2_cjs.AgentPaymentNextAction.StopAndTellUser,
|
|
1238
1404
|
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."
|
|
1239
1405
|
};
|
|
1240
1406
|
}
|
|
@@ -1259,6 +1425,7 @@ function mapTaskBudget(raw) {
|
|
|
1259
1425
|
status: raw.status,
|
|
1260
1426
|
expiresAt: raw.expires_at,
|
|
1261
1427
|
isExpired: raw.is_expired,
|
|
1428
|
+
...raw.is_live === void 0 ? {} : { isLive: raw.is_live },
|
|
1262
1429
|
createdAt: raw.created_at,
|
|
1263
1430
|
openedAt: raw.opened_at,
|
|
1264
1431
|
closedAt: raw.closed_at,
|
|
@@ -1303,7 +1470,7 @@ function summarizePendingSubBudget(row) {
|
|
|
1303
1470
|
};
|
|
1304
1471
|
}
|
|
1305
1472
|
function summarizeTaskBudget(taskBudget) {
|
|
1306
|
-
const token =
|
|
1473
|
+
const token = chunkV2ODMLDD_cjs.resolveTokenFromAddress(taskBudget.tokenAddress);
|
|
1307
1474
|
const maxDisplay = token ? `${formatAtomicAmount(safeBigInt(taskBudget.maxAtomic), token.decimals)} ${token.symbol}` : `${taskBudget.maxAtomic} (atomic; unknown decimals)`;
|
|
1308
1475
|
const spendDisplay = (atomic) => {
|
|
1309
1476
|
if (atomic === null) return null;
|
|
@@ -1380,11 +1547,23 @@ var AccountReads = class {
|
|
|
1380
1547
|
isResetPending: allowance.onchain.isResetPending,
|
|
1381
1548
|
// #3731: same provenance as the detailed read's field — the compact
|
|
1382
1549
|
// row is a projection of the same allowance, never a second source.
|
|
1383
|
-
fundsCoverRemaining: allowance.fundsCoverRemaining
|
|
1550
|
+
fundsCoverRemaining: allowance.fundsCoverRemaining,
|
|
1551
|
+
nextRefillAt: allowance.nextRefillAt
|
|
1384
1552
|
};
|
|
1385
1553
|
});
|
|
1386
1554
|
const readiness = deriveReadiness(agent.status, allowances);
|
|
1387
|
-
|
|
1555
|
+
const budgetRefillsAt = deriveBudgetRefillsAt(readiness, allowances);
|
|
1556
|
+
const budgetEndedAt = deriveBudgetEndedAt(readiness, allowances, allowanceSummary.budgetEndedAt);
|
|
1557
|
+
return {
|
|
1558
|
+
...agent,
|
|
1559
|
+
readiness,
|
|
1560
|
+
spend_authority_readiness: readiness,
|
|
1561
|
+
budgetRefillsAt,
|
|
1562
|
+
budgetEndedAt,
|
|
1563
|
+
allowances,
|
|
1564
|
+
taskBudgets,
|
|
1565
|
+
pendingSubBudgetSignatures
|
|
1566
|
+
};
|
|
1388
1567
|
}
|
|
1389
1568
|
/**
|
|
1390
1569
|
* #3329: `GET /task-budgets?status=open`, mapped to the condensed summary
|
|
@@ -1412,7 +1591,8 @@ var AccountReads = class {
|
|
|
1412
1591
|
* an agent can still act on, and read-by-id (`haven_get_task_budget`) is
|
|
1413
1592
|
* the any-status surface for everything else:
|
|
1414
1593
|
*
|
|
1415
|
-
* - `closing`
|
|
1594
|
+
* - `closing` stays visible until its expiry (#3773; an expired `closing`
|
|
1595
|
+
* row drops, #3923) — the close submit is
|
|
1416
1596
|
* in flight and the signer's close refusal tells the caller to re-check
|
|
1417
1597
|
* exactly this row's status;
|
|
1418
1598
|
* - `closed` rows drop (terminal — `closed_at` names what happened, and
|
|
@@ -1421,24 +1601,30 @@ var AccountReads = class {
|
|
|
1421
1601
|
* budget reserves nothing and pays nothing);
|
|
1422
1602
|
* - unexpired `pending` and `open` rows stay.
|
|
1423
1603
|
*
|
|
1424
|
-
*
|
|
1425
|
-
*
|
|
1426
|
-
*
|
|
1427
|
-
* `
|
|
1604
|
+
* A filter also runs here, client-side. A row carrying the backend's
|
|
1605
|
+
* `is_live` (#3922) is kept exactly when it is true — the server's own
|
|
1606
|
+
* `status=live` verdict. A row without it (an older backend) is derived by
|
|
1607
|
+
* the same rule: `closing` stays until its expiry, then drops (#3923), as
|
|
1608
|
+
* the backend does since #3773. That is
|
|
1609
|
+
* what keeps the list bounded against a backend that predates `status=live`,
|
|
1610
|
+
* which refuses the value with a 400 — that refusal (and only that) falls
|
|
1611
|
+
* back to `status=all`. A row whose wire carries
|
|
1428
1612
|
* no `is_expired` is treated as unexpired — the degraded read errs toward
|
|
1429
1613
|
* KEEPING rows, never toward hiding one the agent could still act on.
|
|
1430
1614
|
*/
|
|
1431
1615
|
async listTaskBudgetsSummary() {
|
|
1432
1616
|
try {
|
|
1433
1617
|
const raw = await this.transport.get("/task-budgets?status=live").catch((error) => {
|
|
1434
|
-
if (error instanceof
|
|
1618
|
+
if (error instanceof chunkZA3NOSO2_cjs.HavenApiError && error.statusCode === 400) {
|
|
1435
1619
|
return this.transport.get("/task-budgets?status=all");
|
|
1436
1620
|
}
|
|
1437
1621
|
throw error;
|
|
1438
1622
|
});
|
|
1439
1623
|
const rows = raw?.task_budgets;
|
|
1440
1624
|
if (!Array.isArray(rows)) return [];
|
|
1441
|
-
return rows.map((row) => mapTaskBudget(row)).filter(
|
|
1625
|
+
return rows.map((row) => mapTaskBudget(row)).filter(
|
|
1626
|
+
(tb) => tb.isLive !== void 0 ? tb.isLive : !tb.isExpired && tb.status !== "closed"
|
|
1627
|
+
).map((tb) => summarizeTaskBudget(tb));
|
|
1442
1628
|
} catch {
|
|
1443
1629
|
return [];
|
|
1444
1630
|
}
|
|
@@ -1473,6 +1659,9 @@ var AccountReads = class {
|
|
|
1473
1659
|
accountAddress: raw.account_address,
|
|
1474
1660
|
delegateAddress: raw.delegate_address,
|
|
1475
1661
|
chainId: raw.chain_id,
|
|
1662
|
+
// #4352: a non-empty parseable date → itself; anything else (absent on
|
|
1663
|
+
// an older backend, null when no budget has ended) → null.
|
|
1664
|
+
budgetEndedAt: typeof raw.budget_ended_at === "string" && !Number.isNaN(Date.parse(raw.budget_ended_at)) ? raw.budget_ended_at : null,
|
|
1476
1665
|
supersededBy: mapSupersession(raw.superseded_by),
|
|
1477
1666
|
allowances: raw.allowances.map((allowance) => ({
|
|
1478
1667
|
id: allowance.id,
|
|
@@ -1491,6 +1680,9 @@ var AccountReads = class {
|
|
|
1491
1680
|
// "unverifiable", not a missing key. The key is absent on the wire
|
|
1492
1681
|
// when the remaining is 0; that maps to null here too.
|
|
1493
1682
|
fundsCoverRemaining: allowance.funds_cover_remaining === true || allowance.funds_cover_remaining === false ? allowance.funds_cover_remaining : null,
|
|
1683
|
+
// #4355: a non-empty string → itself; anything else (absent on an
|
|
1684
|
+
// older backend, null when the budget never refills) → null.
|
|
1685
|
+
nextRefillAt: typeof allowance.next_refill_at === "string" && allowance.next_refill_at !== "" ? allowance.next_refill_at : null,
|
|
1494
1686
|
remainingDisplay: formatRemainingDisplay(allowance.token_address, allowance.token_symbol, allowance.onchain.remaining),
|
|
1495
1687
|
onchain: {
|
|
1496
1688
|
amount: allowance.onchain.amount,
|
|
@@ -1539,7 +1731,7 @@ var AccountReads = class {
|
|
|
1539
1731
|
payment: payment2,
|
|
1540
1732
|
allowance: null,
|
|
1541
1733
|
warnings: [{
|
|
1542
|
-
code:
|
|
1734
|
+
code: chunkZA3NOSO2_cjs.AgentPaymentWarningCode.AllowanceCheckUnavailable,
|
|
1543
1735
|
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.`
|
|
1544
1736
|
}]
|
|
1545
1737
|
});
|
|
@@ -1632,7 +1824,7 @@ var AccountReads = class {
|
|
|
1632
1824
|
*/
|
|
1633
1825
|
async getReceipt(paymentId) {
|
|
1634
1826
|
const { receipt } = await this.transport.get(`/payments/${paymentId}/receipt`);
|
|
1635
|
-
return { receipt, verification:
|
|
1827
|
+
return { receipt, verification: chunk4JTLJVBS_cjs.verifyPaymentReceipt(receipt) };
|
|
1636
1828
|
}
|
|
1637
1829
|
async fetchAgent() {
|
|
1638
1830
|
const raw = await this.transport.get("/machine-payments/agent");
|
|
@@ -1668,7 +1860,7 @@ function isWaitTimeout(err) {
|
|
|
1668
1860
|
async function waitForSweepTx(tx) {
|
|
1669
1861
|
let receipt;
|
|
1670
1862
|
try {
|
|
1671
|
-
receipt = await tx.wait(1,
|
|
1863
|
+
receipt = await tx.wait(1, chunkZA3NOSO2_cjs.DEFAULT_CONFIRMATION_TIMEOUT_MS);
|
|
1672
1864
|
} catch (err) {
|
|
1673
1865
|
if (!isWaitTimeout(err)) throw err;
|
|
1674
1866
|
return { txHash: tx.hash, confirmation: "unconfirmed" };
|
|
@@ -1682,16 +1874,16 @@ var DelegateSweepApi = class {
|
|
|
1682
1874
|
}
|
|
1683
1875
|
options;
|
|
1684
1876
|
async sweepDelegate() {
|
|
1685
|
-
if (!this.options.delegateKey) throw new
|
|
1877
|
+
if (!this.options.delegateKey) throw new chunkZA3NOSO2_cjs.HavenSigningError("delegateKey is required for sweepDelegate.");
|
|
1686
1878
|
const agent = await this.options.getAgent();
|
|
1687
|
-
if (!agent.delegateAddress) throw new
|
|
1879
|
+
if (!agent.delegateAddress) throw new chunkZA3NOSO2_cjs.HavenApiError("Agent has no delegate address.", 422);
|
|
1688
1880
|
const rpcUrl = this.options.chainRpcs[agent.chainId];
|
|
1689
|
-
if (!rpcUrl) throw new
|
|
1881
|
+
if (!rpcUrl) throw new chunkZA3NOSO2_cjs.HavenApiError(`chainRpcs[${agent.chainId}] must be configured to sweep the delegate wallet.`, 422);
|
|
1690
1882
|
const provider = createJsonRpcProvider(rpcUrl);
|
|
1691
1883
|
const wallet = createWallet(this.options.delegateKey, provider);
|
|
1692
1884
|
const transfers = [];
|
|
1693
|
-
if (
|
|
1694
|
-
const contract = createErc20Contract(
|
|
1885
|
+
if (chunkV2ODMLDD_cjs.isSweepableChain(agent.chainId)) {
|
|
1886
|
+
const contract = createErc20Contract(chunkV2ODMLDD_cjs.sweepUsdcAddress(agent.chainId), ["function balanceOf(address) view returns (uint256)", "function transfer(address to, uint256 amount) returns (bool)"], wallet);
|
|
1695
1887
|
const balance2 = await contract.balanceOf(agent.delegateAddress);
|
|
1696
1888
|
if (balance2 > 0n) {
|
|
1697
1889
|
const tx = await contract.transfer(agent.accountAddress, balance2);
|
|
@@ -1779,7 +1971,7 @@ function snapshotRequestBody(body) {
|
|
|
1779
1971
|
if (body == null) return void 0;
|
|
1780
1972
|
if (typeof body === "string") return body;
|
|
1781
1973
|
if (body instanceof URLSearchParams) return body.toString();
|
|
1782
|
-
throw new
|
|
1974
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
1783
1975
|
"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.",
|
|
1784
1976
|
400
|
|
1785
1977
|
);
|
|
@@ -1800,12 +1992,12 @@ function requestInitFromSnapshot(request) {
|
|
|
1800
1992
|
};
|
|
1801
1993
|
}
|
|
1802
1994
|
function noCompatiblePaymentOptionError(accepts) {
|
|
1803
|
-
const erc7710Only =
|
|
1995
|
+
const erc7710Only = chunkV2ODMLDD_cjs.selectErc7710PaymentOption(accepts) !== null;
|
|
1804
1996
|
const unsupportedOnly = !erc7710Only && accepts.some(
|
|
1805
|
-
(opt) => opt !== null && typeof opt === "object" && !
|
|
1997
|
+
(opt) => opt !== null && typeof opt === "object" && !chunkV2ODMLDD_cjs.isErc7710Option(opt) && (chunkV2ODMLDD_cjs.x402AssetTransferMethod(opt) !== null || opt.extra?.paymentFlow !== void 0)
|
|
1806
1998
|
);
|
|
1807
1999
|
const offeredSchemes = nonExactSchemesOnly(accepts);
|
|
1808
|
-
return new
|
|
2000
|
+
return new chunkZA3NOSO2_cjs.HavenApiError(
|
|
1809
2001
|
"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." : ""),
|
|
1810
2002
|
400
|
|
1811
2003
|
);
|
|
@@ -1824,15 +2016,15 @@ function nonExactSchemesOnly(accepts) {
|
|
|
1824
2016
|
return schemes.map((s) => `'${s}'`).join(", ");
|
|
1825
2017
|
}
|
|
1826
2018
|
function buildX402Quote(paymentRequired, request, idempotencyKey, mcpTransport) {
|
|
1827
|
-
const standard =
|
|
1828
|
-
const option = standard ??
|
|
2019
|
+
const standard = chunkV2ODMLDD_cjs.selectStandardPaymentOption(paymentRequired.accepts);
|
|
2020
|
+
const option = standard ?? chunkV2ODMLDD_cjs.selectErc7710PaymentOption(paymentRequired.accepts);
|
|
1829
2021
|
if (!option) {
|
|
1830
2022
|
throw noCompatiblePaymentOptionError(paymentRequired.accepts);
|
|
1831
2023
|
}
|
|
1832
|
-
const token =
|
|
2024
|
+
const token = chunkV2ODMLDD_cjs.resolveTokenFromAddress(option.asset, option.network);
|
|
1833
2025
|
return {
|
|
1834
2026
|
rail: "x402",
|
|
1835
|
-
idempotencyKey: idempotencyKey ??
|
|
2027
|
+
idempotencyKey: idempotencyKey ?? chunkV2ODMLDD_cjs.buildX402IdempotencyKey(paymentRequired, option),
|
|
1836
2028
|
paymentRequired,
|
|
1837
2029
|
accepted: option,
|
|
1838
2030
|
acceptedScheme: standard ? "standard" : "erc7710",
|
|
@@ -1846,8 +2038,8 @@ function buildX402Quote(paymentRequired, request, idempotencyKey, mcpTransport)
|
|
|
1846
2038
|
resourceUrlDiffersFromRequest: paymentRequired.resource.url !== request.url,
|
|
1847
2039
|
description: paymentRequired.resource.description ?? option.description ?? null,
|
|
1848
2040
|
mimeType: paymentRequired.resource.mimeType ?? option.mimeType ?? null,
|
|
1849
|
-
amountAtomic:
|
|
1850
|
-
amount: decimalFromUsdcAtomic(
|
|
2041
|
+
amountAtomic: chunkV2ODMLDD_cjs.x402AuthorizationAmount(option),
|
|
2042
|
+
amount: decimalFromUsdcAtomic(chunkV2ODMLDD_cjs.x402AuthorizationAmount(option)),
|
|
1851
2043
|
token: token?.symbol ?? "USDC",
|
|
1852
2044
|
// #1351: null when the asset is unrecognised on this network — the
|
|
1853
2045
|
// `token` fallback above is a LABEL, not evidence of 6 decimals, and a
|
|
@@ -1886,7 +2078,7 @@ function buildX402Receipt(input) {
|
|
|
1886
2078
|
payTo: input.merchantTo ?? input.accepted.payTo
|
|
1887
2079
|
},
|
|
1888
2080
|
x402: {
|
|
1889
|
-
amount:
|
|
2081
|
+
amount: chunkV2ODMLDD_cjs.x402AuthorizationAmount(input.accepted),
|
|
1890
2082
|
token: input.token,
|
|
1891
2083
|
network: input.accepted.network,
|
|
1892
2084
|
asset: input.accepted.asset,
|
|
@@ -1895,7 +2087,7 @@ function buildX402Receipt(input) {
|
|
|
1895
2087
|
};
|
|
1896
2088
|
}
|
|
1897
2089
|
function buildX402ResumeState(input) {
|
|
1898
|
-
const token =
|
|
2090
|
+
const token = chunkV2ODMLDD_cjs.resolveTokenFromAddress(input.accepted.asset, input.accepted.network);
|
|
1899
2091
|
return {
|
|
1900
2092
|
rail: "x402",
|
|
1901
2093
|
paymentId: input.paymentId,
|
|
@@ -1906,8 +2098,8 @@ function buildX402ResumeState(input) {
|
|
|
1906
2098
|
request: input.request,
|
|
1907
2099
|
resourceUrl: input.paymentRequired.resource.url,
|
|
1908
2100
|
description: input.paymentRequired.resource.description ?? input.accepted.description ?? null,
|
|
1909
|
-
amountAtomic:
|
|
1910
|
-
amount: decimalFromUsdcAtomic(
|
|
2101
|
+
amountAtomic: chunkV2ODMLDD_cjs.x402AuthorizationAmount(input.accepted),
|
|
2102
|
+
amount: decimalFromUsdcAtomic(chunkV2ODMLDD_cjs.x402AuthorizationAmount(input.accepted)),
|
|
1911
2103
|
token: token?.symbol ?? "USDC",
|
|
1912
2104
|
asset: input.accepted.asset,
|
|
1913
2105
|
network: input.accepted.network,
|
|
@@ -1916,7 +2108,7 @@ function buildX402ResumeState(input) {
|
|
|
1916
2108
|
};
|
|
1917
2109
|
}
|
|
1918
2110
|
function attachX402ResumeState(err, paymentRequired, accepted, idempotencyKey, request) {
|
|
1919
|
-
if (!(err instanceof
|
|
2111
|
+
if (!(err instanceof chunkZA3NOSO2_cjs.HavenPaymentStateError)) return;
|
|
1920
2112
|
if (err.state.rail !== "x402") return;
|
|
1921
2113
|
err.resumeState = buildX402ResumeState({
|
|
1922
2114
|
paymentId: err.state.paymentId,
|
|
@@ -1937,17 +2129,17 @@ function attachResumeState(err, input) {
|
|
|
1937
2129
|
}
|
|
1938
2130
|
function assertCanResumeX402(status, paymentRequired, option) {
|
|
1939
2131
|
if (status.rail !== "x402") {
|
|
1940
|
-
throw new
|
|
2132
|
+
throw new chunkZA3NOSO2_cjs.HavenPaymentStateError(
|
|
1941
2133
|
`Payment ${status.paymentId} is ${status.rail}, not x402.`,
|
|
1942
2134
|
409,
|
|
1943
2135
|
status
|
|
1944
2136
|
);
|
|
1945
2137
|
}
|
|
1946
|
-
if (status.nextAction !==
|
|
1947
|
-
throw new
|
|
2138
|
+
if (status.nextAction !== chunkZA3NOSO2_cjs.AgentPaymentNextAction.RetryOriginalX402Request) {
|
|
2139
|
+
throw new chunkZA3NOSO2_cjs.HavenPaymentStateError(status.message, paymentStateStatusCode(status.status, 409), status);
|
|
1948
2140
|
}
|
|
1949
2141
|
if (!status.txHash) {
|
|
1950
|
-
throw new
|
|
2142
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
1951
2143
|
`x402 payment ${status.paymentId} is ready to retry but has no Haven transaction hash.`,
|
|
1952
2144
|
502,
|
|
1953
2145
|
status,
|
|
@@ -1955,7 +2147,7 @@ function assertCanResumeX402(status, paymentRequired, option) {
|
|
|
1955
2147
|
);
|
|
1956
2148
|
}
|
|
1957
2149
|
if (status.resourceUrl && status.resourceUrl !== paymentRequired.resource.url) {
|
|
1958
|
-
throw new
|
|
2150
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
1959
2151
|
"x402 resume request does not match the approved resource URL.",
|
|
1960
2152
|
409,
|
|
1961
2153
|
{ status, paymentRequired },
|
|
@@ -1963,7 +2155,7 @@ function assertCanResumeX402(status, paymentRequired, option) {
|
|
|
1963
2155
|
);
|
|
1964
2156
|
}
|
|
1965
2157
|
if (status.merchantAddress && !sameAddress(status.merchantAddress, option.payTo)) {
|
|
1966
|
-
throw new
|
|
2158
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
1967
2159
|
"x402 resume request does not match the approved merchant.",
|
|
1968
2160
|
409,
|
|
1969
2161
|
{ status, selectedPayment: option },
|
|
@@ -1972,7 +2164,7 @@ function assertCanResumeX402(status, paymentRequired, option) {
|
|
|
1972
2164
|
}
|
|
1973
2165
|
const optionChainId = chainIdFromNetwork(option.network);
|
|
1974
2166
|
if (status.chainId && optionChainId && status.chainId !== optionChainId) {
|
|
1975
|
-
throw new
|
|
2167
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
1976
2168
|
"x402 resume request does not match the approved network.",
|
|
1977
2169
|
409,
|
|
1978
2170
|
{ status, selectedPayment: option },
|
|
@@ -1980,7 +2172,7 @@ function assertCanResumeX402(status, paymentRequired, option) {
|
|
|
1980
2172
|
);
|
|
1981
2173
|
}
|
|
1982
2174
|
if (status.token && status.token !== "USDC") {
|
|
1983
|
-
throw new
|
|
2175
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
1984
2176
|
"x402 resume request does not match the approved token.",
|
|
1985
2177
|
409,
|
|
1986
2178
|
{ status, selectedPayment: option },
|
|
@@ -1988,9 +2180,9 @@ function assertCanResumeX402(status, paymentRequired, option) {
|
|
|
1988
2180
|
);
|
|
1989
2181
|
}
|
|
1990
2182
|
const approvedAmount = status.amount ? normalizeDecimal(status.amount) : "";
|
|
1991
|
-
const requestedAmount = normalizeDecimal(decimalFromUsdcAtomic(
|
|
2183
|
+
const requestedAmount = normalizeDecimal(decimalFromUsdcAtomic(chunkV2ODMLDD_cjs.x402AuthorizationAmount(option)));
|
|
1992
2184
|
if (approvedAmount && approvedAmount !== requestedAmount) {
|
|
1993
|
-
throw new
|
|
2185
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
1994
2186
|
"x402 resume request does not match the approved amount.",
|
|
1995
2187
|
409,
|
|
1996
2188
|
{ status, selectedPayment: option },
|
|
@@ -2046,7 +2238,7 @@ var X402FundingLeg = class {
|
|
|
2046
2238
|
const cached = this.receiptCache.get(idempotencyKey);
|
|
2047
2239
|
if (!cached || cached.expiresAt <= Date.now()) return void 0;
|
|
2048
2240
|
if (!sameX402TaskBudget(cached.taskBudgetId, taskBudgetId) || !sameX402TaskBudget(cached.subBudgetId, subBudgetId)) {
|
|
2049
|
-
throw new
|
|
2241
|
+
throw new chunkZA3NOSO2_cjs.X402TaskBudgetMismatchError(
|
|
2050
2242
|
`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.`,
|
|
2051
2243
|
idempotencyKey,
|
|
2052
2244
|
cached.taskBudgetId,
|
|
@@ -2067,7 +2259,7 @@ var X402FundingLeg = class {
|
|
|
2067
2259
|
url: paymentRequired.resource.url,
|
|
2068
2260
|
payTo: this.delegateAddress,
|
|
2069
2261
|
merchantPayTo: option.payTo,
|
|
2070
|
-
amount:
|
|
2262
|
+
amount: chunkV2ODMLDD_cjs.x402AuthorizationAmount(option),
|
|
2071
2263
|
asset: option.asset,
|
|
2072
2264
|
network: option.network,
|
|
2073
2265
|
description: paymentRequired.resource.description,
|
|
@@ -2086,17 +2278,17 @@ var X402FundingLeg = class {
|
|
|
2086
2278
|
...subBudgetId ? { subBudgetId } : {}
|
|
2087
2279
|
});
|
|
2088
2280
|
const state = paymentStateFromRaw("x402 payment", raw);
|
|
2089
|
-
const executedReplay = raw.success && raw.tx_hash ? "idempotency-collision" : state?.nextAction ===
|
|
2281
|
+
const executedReplay = raw.success && raw.tx_hash ? "idempotency-collision" : state?.nextAction === chunkZA3NOSO2_cjs.AgentPaymentNextAction.RetryOriginalX402Request ? "approval-resume" : null;
|
|
2090
2282
|
if (executedReplay) {
|
|
2091
2283
|
const canFund = await this.delegateCanFund(
|
|
2092
2284
|
raw.chain_id ?? state?.chainId ?? chainIdFromNetwork(option.network),
|
|
2093
2285
|
option.asset,
|
|
2094
|
-
|
|
2286
|
+
chunkV2ODMLDD_cjs.x402AuthorizationAmount(option)
|
|
2095
2287
|
);
|
|
2096
2288
|
const refuse = executedReplay === "idempotency-collision" ? canFund !== true : canFund === false;
|
|
2097
2289
|
if (refuse) {
|
|
2098
2290
|
const settledReceipt = state && executedReplay === "approval-resume" ? this.receiptFromStatus(paymentRequired, option, void 0, state) : this.receiptFromAuthorization(paymentRequired, option, void 0, raw);
|
|
2099
|
-
throw new
|
|
2291
|
+
throw new chunkZA3NOSO2_cjs.X402AlreadySettledError(
|
|
2100
2292
|
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`.",
|
|
2101
2293
|
settledReceipt,
|
|
2102
2294
|
canFund === false ? "settled" : "unverifiable"
|
|
@@ -2109,18 +2301,18 @@ var X402FundingLeg = class {
|
|
|
2109
2301
|
this.cacheReceipt(idempotencyKey, paymentHeader, receipt2, taskBudgetId, subBudgetId);
|
|
2110
2302
|
return receipt2;
|
|
2111
2303
|
}
|
|
2112
|
-
if (state?.nextAction ===
|
|
2304
|
+
if (state?.nextAction === chunkZA3NOSO2_cjs.AgentPaymentNextAction.RetryOriginalX402Request) {
|
|
2113
2305
|
const receipt2 = this.receiptFromStatus(paymentRequired, option, paymentHeader, state);
|
|
2114
2306
|
this.cacheReceipt(idempotencyKey, paymentHeader, receipt2, taskBudgetId, subBudgetId);
|
|
2115
2307
|
return receipt2;
|
|
2116
2308
|
}
|
|
2117
2309
|
this.assertSignableAuthorizationState("x402 payment", raw);
|
|
2118
2310
|
if (!raw.sign_data?.hash) {
|
|
2119
|
-
throw
|
|
2311
|
+
throw chunkZA3NOSO2_cjs.HavenApiError.deterministic("No sign_hash returned from x402/authorize", 500, raw);
|
|
2120
2312
|
}
|
|
2121
2313
|
const sig = await this.signForData(raw.sign_data, {
|
|
2122
2314
|
asset: option.asset,
|
|
2123
|
-
amount:
|
|
2315
|
+
amount: chunkV2ODMLDD_cjs.x402AuthorizationAmount(option)
|
|
2124
2316
|
});
|
|
2125
2317
|
const execResult = await this.post(
|
|
2126
2318
|
`/payments/${raw.payment_id}/sign`,
|
|
@@ -2155,10 +2347,10 @@ var X402FundingLeg = class {
|
|
|
2155
2347
|
*/
|
|
2156
2348
|
async createPaymentHeader(paymentRequired, option, paymentId) {
|
|
2157
2349
|
if (!this.delegateKey) {
|
|
2158
|
-
throw new
|
|
2350
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError("delegateKey is required to sign x402 payment headers.");
|
|
2159
2351
|
}
|
|
2160
2352
|
const account = accounts.privateKeyToAccount(this.delegateKey);
|
|
2161
|
-
const requirements =
|
|
2353
|
+
const requirements = chunkV2ODMLDD_cjs.toStandardPaymentRequirements(paymentRequired, option);
|
|
2162
2354
|
let header;
|
|
2163
2355
|
if (paymentId) {
|
|
2164
2356
|
const unsigned = schemes.exact.evm.preparePaymentHeader(
|
|
@@ -2166,7 +2358,7 @@ var X402FundingLeg = class {
|
|
|
2166
2358
|
paymentRequired.x402Version,
|
|
2167
2359
|
requirements
|
|
2168
2360
|
);
|
|
2169
|
-
unsigned.payload.authorization.nonce =
|
|
2361
|
+
unsigned.payload.authorization.nonce = chunkV2ODMLDD_cjs.deriveX402PaymentNonce(paymentId);
|
|
2170
2362
|
const signed = await schemes.exact.evm.signPaymentHeader(account, requirements, unsigned);
|
|
2171
2363
|
header = schemes.exact.evm.encodePayment(signed);
|
|
2172
2364
|
} else {
|
|
@@ -2177,15 +2369,15 @@ var X402FundingLeg = class {
|
|
|
2177
2369
|
);
|
|
2178
2370
|
}
|
|
2179
2371
|
if (paymentRequired.x402Version < 2) return header;
|
|
2180
|
-
const payment =
|
|
2181
|
-
return
|
|
2372
|
+
const payment = chunkV2ODMLDD_cjs.decodeBase64Json(header);
|
|
2373
|
+
return chunkV2ODMLDD_cjs.encodeBase64Json(chunkV2ODMLDD_cjs.x402V2PaymentEnvelope(paymentRequired, option, payment.payload));
|
|
2182
2374
|
}
|
|
2183
2375
|
// ── Receipt mapping ──────────────────────────────────────────────
|
|
2184
2376
|
receiptFromAuthorization(paymentRequired, option, paymentHeader, raw, execResult) {
|
|
2185
2377
|
const txHash = execResult?.tx_hash ?? raw.tx_hash ?? "";
|
|
2186
2378
|
const chainId = execResult?.chain_id ?? raw.chain_id ?? chainIdFromNetwork(option.network);
|
|
2187
2379
|
const token = execResult?.token ?? raw.token ?? "USDC";
|
|
2188
|
-
const amount = execResult?.amount ?? raw.amount ?? decimalFromUsdcAtomic(
|
|
2380
|
+
const amount = execResult?.amount ?? raw.amount ?? decimalFromUsdcAtomic(chunkV2ODMLDD_cjs.x402AuthorizationAmount(option));
|
|
2189
2381
|
const to = execResult?.to ?? raw.to ?? this.delegateAddress ?? "";
|
|
2190
2382
|
const explorerUrl = execResult?.explorer_url ?? raw.explorer_url ?? explorerUrlOrEmpty(chainId, txHash);
|
|
2191
2383
|
const merchantTo = execResult?.merchant_to ?? raw.merchant_to ?? option.payTo;
|
|
@@ -2207,7 +2399,7 @@ var X402FundingLeg = class {
|
|
|
2207
2399
|
}
|
|
2208
2400
|
receiptFromStatus(paymentRequired, option, paymentHeader, status) {
|
|
2209
2401
|
if (!status.txHash) {
|
|
2210
|
-
throw new
|
|
2402
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
2211
2403
|
`x402 payment ${status.paymentId} is ready to retry but has no Haven transaction hash.`,
|
|
2212
2404
|
502,
|
|
2213
2405
|
status,
|
|
@@ -2218,7 +2410,7 @@ var X402FundingLeg = class {
|
|
|
2218
2410
|
paymentId: status.paymentId,
|
|
2219
2411
|
txHash: status.txHash,
|
|
2220
2412
|
token: status.token || "USDC",
|
|
2221
|
-
amount: status.amount || decimalFromUsdcAtomic(
|
|
2413
|
+
amount: status.amount || decimalFromUsdcAtomic(chunkV2ODMLDD_cjs.x402AuthorizationAmount(option)),
|
|
2222
2414
|
to: this.delegateAddress ?? "",
|
|
2223
2415
|
resourceUrl: paymentRequired.resource.url,
|
|
2224
2416
|
explorerUrl: explorerUrlOrEmpty(status.chainId, status.txHash),
|
|
@@ -2238,20 +2430,27 @@ var X402FundingLeg = class {
|
|
|
2238
2430
|
* Skipped when `chainRpcs` does not include the chain; in that case Haven's
|
|
2239
2431
|
* backend has already confirmed on-chain submission and callers accept the
|
|
2240
2432
|
* small propagation window as a trade-off for not configuring an RPC URL.
|
|
2433
|
+
*
|
|
2434
|
+
* #4470: the two outcomes are typed apart. ethers 6 `waitForTransaction`
|
|
2435
|
+
* REJECTS on its timeout (and on an RPC failure) rather than resolving
|
|
2436
|
+
* null, so that path is `FundingConfirmationUnknownError` — funding may
|
|
2437
|
+
* have moved. A mined receipt with `status !== 1` is `FundingRevertedError`.
|
|
2241
2438
|
*/
|
|
2242
2439
|
async waitForFundingTx(txHash, chainId, timeoutMs = 3e4) {
|
|
2243
2440
|
if (!txHash || !chainId) return;
|
|
2244
2441
|
const rpcUrl = this.chainRpcs[chainId];
|
|
2245
2442
|
if (!rpcUrl) return;
|
|
2246
2443
|
const provider = createJsonRpcProvider(rpcUrl);
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2444
|
+
let onChainReceipt;
|
|
2445
|
+
try {
|
|
2446
|
+
onChainReceipt = await provider.waitForTransaction(txHash, 1, timeoutMs);
|
|
2447
|
+
} catch (err) {
|
|
2448
|
+
throw new chunkZA3NOSO2_cjs.FundingConfirmationUnknownError(txHash, chainId, err instanceof Error ? err.message : String(err));
|
|
2449
|
+
}
|
|
2450
|
+
if (!onChainReceipt) {
|
|
2451
|
+
throw new chunkZA3NOSO2_cjs.FundingConfirmationUnknownError(txHash, chainId, "no receipt within the timeout window");
|
|
2254
2452
|
}
|
|
2453
|
+
if (onChainReceipt.status !== 1) throw new chunkZA3NOSO2_cjs.FundingRevertedError(txHash, chainId);
|
|
2255
2454
|
}
|
|
2256
2455
|
/**
|
|
2257
2456
|
* Can the delegate EOA still fund an authorization for `amountAtomic`?
|
|
@@ -2295,7 +2494,7 @@ var X402FundingLeg = class {
|
|
|
2295
2494
|
};
|
|
2296
2495
|
function getPaymentHeaderValidBefore(paymentHeader) {
|
|
2297
2496
|
try {
|
|
2298
|
-
const payment =
|
|
2497
|
+
const payment = chunkV2ODMLDD_cjs.decodeBase64Json(
|
|
2299
2498
|
paymentHeader
|
|
2300
2499
|
);
|
|
2301
2500
|
const payload = payment.payload;
|
|
@@ -2350,7 +2549,7 @@ var X402Erc7710 = class {
|
|
|
2350
2549
|
*/
|
|
2351
2550
|
async settle(paymentRequired, options = {}) {
|
|
2352
2551
|
if (!this.delegateKey) {
|
|
2353
|
-
throw new
|
|
2552
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError(
|
|
2354
2553
|
"delegateKey is required for x402 payments. Pass it in the HavenClient config."
|
|
2355
2554
|
);
|
|
2356
2555
|
}
|
|
@@ -2375,21 +2574,21 @@ var X402Erc7710 = class {
|
|
|
2375
2574
|
async prepare(paymentRequired, options = {}) {
|
|
2376
2575
|
const delegationRail = options.delegationRail ?? (await this.getAgent()).executionRail === "delegation";
|
|
2377
2576
|
if (!delegationRail) {
|
|
2378
|
-
throw new
|
|
2577
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
2379
2578
|
"erc7710 settlement requires a delegation-rail account; this one is not on it. Use authorizeX402() for the standard EIP-3009 path.",
|
|
2380
2579
|
400
|
|
2381
2580
|
);
|
|
2382
2581
|
}
|
|
2383
|
-
const selection =
|
|
2582
|
+
const selection = chunkV2ODMLDD_cjs.selectX402SettlementScheme(paymentRequired.accepts, { delegationRail });
|
|
2384
2583
|
if (!selection || selection.scheme !== "erc7710") {
|
|
2385
|
-
throw new
|
|
2584
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
2386
2585
|
"This merchant does not advertise an erc7710 settlement option (no accepts[] entry carries extra.assetTransferMethod: 'erc7710'). Use authorizeX402() for the standard EIP-3009 path.",
|
|
2387
2586
|
400
|
|
2388
2587
|
);
|
|
2389
2588
|
}
|
|
2390
2589
|
const option = selection.option;
|
|
2391
2590
|
const merchantPayTo = option.payTo;
|
|
2392
|
-
const amountAtomic =
|
|
2591
|
+
const amountAtomic = chunkV2ODMLDD_cjs.x402AuthorizationAmount(option);
|
|
2393
2592
|
const raw = await this.post("/x402", {
|
|
2394
2593
|
url: options.resourceUrl ?? paymentRequired.resource?.url,
|
|
2395
2594
|
// #2373: the full 402 challenge, persisted verbatim by the backend
|
|
@@ -2433,24 +2632,24 @@ var X402Erc7710 = class {
|
|
|
2433
2632
|
...options.subBudgetId ? { subBudgetId: options.subBudgetId } : {}
|
|
2434
2633
|
});
|
|
2435
2634
|
if (!raw.payment_id) {
|
|
2436
|
-
throw
|
|
2635
|
+
throw chunkZA3NOSO2_cjs.HavenApiError.deterministic("No payment_id returned from x402/authorize", 500, raw);
|
|
2437
2636
|
}
|
|
2438
2637
|
if (raw.status === "confirmed" && raw.tx_hash) {
|
|
2439
2638
|
const requestedUrl = options.resourceUrl ?? paymentRequired.resource?.url;
|
|
2440
2639
|
const samePurchase = typeof raw.to === "string" && raw.to.toLowerCase() === merchantPayTo.toLowerCase() && raw.resource_url === requestedUrl;
|
|
2441
2640
|
if (!samePurchase) {
|
|
2442
|
-
throw new
|
|
2641
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
2443
2642
|
`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.`,
|
|
2444
2643
|
409,
|
|
2445
2644
|
raw,
|
|
2446
2645
|
raw.payment_id
|
|
2447
2646
|
);
|
|
2448
2647
|
}
|
|
2449
|
-
throw new
|
|
2648
|
+
throw new chunkZA3NOSO2_cjs.X402Erc7710AlreadySettledError(raw.payment_id, raw.tx_hash, raw);
|
|
2450
2649
|
}
|
|
2451
2650
|
const signData = raw.sign_data;
|
|
2452
2651
|
if (signData?.signature_scheme !== "eip712_delegation" || !signData.typed_data) {
|
|
2453
|
-
throw
|
|
2652
|
+
throw chunkZA3NOSO2_cjs.HavenApiError.deterministic(
|
|
2454
2653
|
`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.`,
|
|
2455
2654
|
500,
|
|
2456
2655
|
raw
|
|
@@ -2482,9 +2681,9 @@ var X402Erc7710 = class {
|
|
|
2482
2681
|
try {
|
|
2483
2682
|
settled = await this.post(`/x402/${paymentId}/settle`, { signature });
|
|
2484
2683
|
} catch (err) {
|
|
2485
|
-
const body = err instanceof
|
|
2486
|
-
if (err instanceof
|
|
2487
|
-
throw new
|
|
2684
|
+
const body = err instanceof chunkZA3NOSO2_cjs.HavenApiError ? err.body : void 0;
|
|
2685
|
+
if (err instanceof chunkZA3NOSO2_cjs.HavenApiError && err.statusCode === 409 && body?.code === "payment_already_settled" && typeof body.tx_hash === "string") {
|
|
2686
|
+
throw new chunkZA3NOSO2_cjs.X402Erc7710AlreadySettledError(
|
|
2488
2687
|
typeof body.payment_id === "string" ? body.payment_id : paymentId,
|
|
2489
2688
|
body.tx_hash,
|
|
2490
2689
|
body
|
|
@@ -2493,7 +2692,7 @@ var X402Erc7710 = class {
|
|
|
2493
2692
|
throw err;
|
|
2494
2693
|
}
|
|
2495
2694
|
if (!settled.payment_header) {
|
|
2496
|
-
throw
|
|
2695
|
+
throw chunkZA3NOSO2_cjs.HavenApiError.deterministic(
|
|
2497
2696
|
"x402 settle returned no payment_header \u2014 the merchant cannot be retried.",
|
|
2498
2697
|
500,
|
|
2499
2698
|
settled
|
|
@@ -2503,9 +2702,9 @@ var X402Erc7710 = class {
|
|
|
2503
2702
|
}
|
|
2504
2703
|
};
|
|
2505
2704
|
function settlementExpectationFromQuote(settlement) {
|
|
2506
|
-
const chainId =
|
|
2705
|
+
const chainId = chunkZA3NOSO2_cjs.chainIdForNetwork(settlement.network);
|
|
2507
2706
|
if (chainId === void 0) {
|
|
2508
|
-
throw new
|
|
2707
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError(
|
|
2509
2708
|
`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.`
|
|
2510
2709
|
);
|
|
2511
2710
|
}
|
|
@@ -2555,7 +2754,7 @@ function x402ToolReceipt(receipt) {
|
|
|
2555
2754
|
};
|
|
2556
2755
|
}
|
|
2557
2756
|
function toolError(err) {
|
|
2558
|
-
if (err instanceof
|
|
2757
|
+
if (err instanceof chunkZA3NOSO2_cjs.HavenPaymentStateError) {
|
|
2559
2758
|
return {
|
|
2560
2759
|
success: false,
|
|
2561
2760
|
payment_id: err.state.paymentId,
|
|
@@ -2600,7 +2799,7 @@ function toolError(err) {
|
|
|
2600
2799
|
error: err.message
|
|
2601
2800
|
};
|
|
2602
2801
|
}
|
|
2603
|
-
if (err instanceof
|
|
2802
|
+
if (err instanceof chunkZA3NOSO2_cjs.HavenApiError) {
|
|
2604
2803
|
return {
|
|
2605
2804
|
success: false,
|
|
2606
2805
|
status_code: err.statusCode,
|
|
@@ -2614,6 +2813,26 @@ function toolError(err) {
|
|
|
2614
2813
|
};
|
|
2615
2814
|
}
|
|
2616
2815
|
|
|
2816
|
+
// src/merchant-answer.ts
|
|
2817
|
+
function decidePostFundingMerchantAnswer(input) {
|
|
2818
|
+
const inBandChallenge = input.toolResult ? extractMcpPaymentRequired(input.toolResult) : void 0;
|
|
2819
|
+
const headerReceipt = input.paymentResponseHeader;
|
|
2820
|
+
const protocolReceiptHeaderName = headerReceipt ? "PAYMENT-RESPONSE" : input.metaSettlement ? `_meta.${MCP_X402_PAYMENT_RESPONSE_META_KEY}` : void 0;
|
|
2821
|
+
const protocolReceiptHeader = headerReceipt ?? (input.metaSettlement ? encodeMcpSettlementReceipt(input.metaSettlement) : void 0);
|
|
2822
|
+
const settlement = parseMerchantSettlement(headerReceipt ?? null);
|
|
2823
|
+
const settlementTxHash = settlement.settlementTxHash ?? (typeof input.metaSettlement?.transaction === "string" ? input.metaSettlement.transaction : void 0);
|
|
2824
|
+
const plainToolErrorAfterFunding = input.toolResult?.isError === true && inBandChallenge === void 0 && !settlementTxHash;
|
|
2825
|
+
const inBandRejection = inBandChallenge !== void 0 || input.metaSettlement?.success === false || plainToolErrorAfterFunding;
|
|
2826
|
+
return {
|
|
2827
|
+
accepted: input.httpOk && !inBandRejection,
|
|
2828
|
+
inBandRejection,
|
|
2829
|
+
plainToolErrorAfterFunding,
|
|
2830
|
+
settlementTxHash,
|
|
2831
|
+
protocolReceiptHeader,
|
|
2832
|
+
protocolReceiptHeaderName
|
|
2833
|
+
};
|
|
2834
|
+
}
|
|
2835
|
+
|
|
2617
2836
|
// src/merchant-completion.ts
|
|
2618
2837
|
var MERCHANT_BODY_SNIPPET_LIMIT = 1e3;
|
|
2619
2838
|
var EVIDENCE_RETRY_DELAYS_MS = [1e3, 2e3, 4e3];
|
|
@@ -2644,14 +2863,14 @@ var MerchantCompletion = class {
|
|
|
2644
2863
|
}
|
|
2645
2864
|
async retryRequest(url, initialInit, paymentRequired, receipt) {
|
|
2646
2865
|
if (!receipt.accepted) {
|
|
2647
|
-
throw
|
|
2866
|
+
throw chunkZA3NOSO2_cjs.HavenApiError.deterministic("No accepted x402 option was recorded for payment retry", 500);
|
|
2648
2867
|
}
|
|
2649
2868
|
if (!receipt.paymentHeader) {
|
|
2650
|
-
throw
|
|
2869
|
+
throw chunkZA3NOSO2_cjs.HavenApiError.deterministic("No x402 payment header was returned for payment retry", 500);
|
|
2651
2870
|
}
|
|
2652
2871
|
let retryInit = initialInit;
|
|
2653
2872
|
if (this.getTaxDeclarationHeader && this.delegateKey) {
|
|
2654
|
-
const scheme =
|
|
2873
|
+
const scheme = chunkV2ODMLDD_cjs.x402PaymentHeaderNamesFor(receipt.paymentHeader);
|
|
2655
2874
|
const isEip3009 = scheme.length > 1;
|
|
2656
2875
|
if (isEip3009) {
|
|
2657
2876
|
const resolved = await this.getTaxDeclarationHeader({
|
|
@@ -2663,16 +2882,31 @@ var MerchantCompletion = class {
|
|
|
2663
2882
|
retryInit = withTaxDeclarationHeader(initialInit, void 0);
|
|
2664
2883
|
}
|
|
2665
2884
|
}
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2885
|
+
let retryResponse;
|
|
2886
|
+
try {
|
|
2887
|
+
retryResponse = await this.merchantTransport.deliverPaymentRecoveringSession(
|
|
2888
|
+
url,
|
|
2889
|
+
retryInit,
|
|
2890
|
+
receipt.paymentHeader,
|
|
2891
|
+
() => this.merchantTransport.initialize(url, initialInit)
|
|
2892
|
+
);
|
|
2893
|
+
} catch (err) {
|
|
2894
|
+
if (err instanceof MerchantEgressRefusedError && !err.beforeRequest) {
|
|
2895
|
+
throw await this.paidDeliveryInterrupted(err, url, receipt, receipt.paymentHeader, retryInit?.body != null);
|
|
2896
|
+
}
|
|
2897
|
+
throw err;
|
|
2898
|
+
}
|
|
2672
2899
|
const toolResult = retryResponse.ok ? await this.merchantTransport.readToolResult(retryResponse) : void 0;
|
|
2673
|
-
const inBandChallenge = toolResult ? extractMcpPaymentRequired(toolResult) : void 0;
|
|
2674
2900
|
const metaSettlement = toolResult ? mcpSettlementFromToolResult(toolResult) : void 0;
|
|
2675
|
-
const
|
|
2901
|
+
const headerReceipt = retryResponse.headers.get("PAYMENT-RESPONSE");
|
|
2902
|
+
const answer = decidePostFundingMerchantAnswer({
|
|
2903
|
+
toolResult,
|
|
2904
|
+
httpOk: retryResponse.ok,
|
|
2905
|
+
paymentResponseHeader: headerReceipt ?? void 0,
|
|
2906
|
+
metaSettlement
|
|
2907
|
+
});
|
|
2908
|
+
const reportedSettlementTxHash = answer.settlementTxHash;
|
|
2909
|
+
const inBandRejection = answer.inBandRejection;
|
|
2676
2910
|
if (!retryResponse.ok || inBandRejection) {
|
|
2677
2911
|
const merchant = await captureMerchantResponse(retryResponse);
|
|
2678
2912
|
await this.recordRetryRejected({
|
|
@@ -2686,8 +2920,8 @@ var MerchantCompletion = class {
|
|
|
2686
2920
|
delegate_to: receipt.to
|
|
2687
2921
|
}
|
|
2688
2922
|
});
|
|
2689
|
-
throw new
|
|
2690
|
-
"x402 retry failed after Haven funded the delegate wallet; reconciliation may be required.",
|
|
2923
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
2924
|
+
"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.",
|
|
2691
2925
|
inBandRejection ? X402_RETRY_REJECTED_STATUS : merchant.merchant_status,
|
|
2692
2926
|
{
|
|
2693
2927
|
marker: "x402_retry_rejected_after_funding",
|
|
@@ -2700,10 +2934,10 @@ var MerchantCompletion = class {
|
|
|
2700
2934
|
}
|
|
2701
2935
|
);
|
|
2702
2936
|
}
|
|
2703
|
-
const
|
|
2704
|
-
const
|
|
2705
|
-
|
|
2706
|
-
|
|
2937
|
+
const { protocolReceiptHeader, protocolReceiptHeaderName } = answer;
|
|
2938
|
+
const merchantSettlement = {
|
|
2939
|
+
settlementTxHash: reportedSettlementTxHash ?? null
|
|
2940
|
+
};
|
|
2707
2941
|
if (receipt.merchant && merchantSettlement.settlementTxHash) {
|
|
2708
2942
|
receipt.merchant.settlementTxHash = merchantSettlement.settlementTxHash;
|
|
2709
2943
|
receipt.merchant.settlementExplorerUrl = buildExplorerUrl(receipt.chainId, merchantSettlement.settlementTxHash) || null;
|
|
@@ -2716,14 +2950,19 @@ var MerchantCompletion = class {
|
|
|
2716
2950
|
merchantStatus: retryResponse.status,
|
|
2717
2951
|
challengePayload: paymentRequired,
|
|
2718
2952
|
selectedPayment: receipt.accepted,
|
|
2719
|
-
paymentProofHeaderName:
|
|
2953
|
+
paymentProofHeaderName: chunkV2ODMLDD_cjs.x402PaymentHeaderNamesSent(receipt.paymentHeader),
|
|
2720
2954
|
paymentProofHeader: receipt.paymentHeader,
|
|
2721
2955
|
protocolReceiptHeaderName,
|
|
2722
2956
|
protocolReceiptHeader
|
|
2723
2957
|
});
|
|
2724
2958
|
const settlementCandidate = merchantSettlement.settlementTxHash;
|
|
2725
2959
|
if (settlementCandidate && isWellFormedSettlementTxHash(settlementCandidate) && !isZeroSettlementTxHash(settlementCandidate) && settlementCandidate.toLowerCase() !== receipt.txHash.toLowerCase()) {
|
|
2726
|
-
await this.
|
|
2960
|
+
await this.reportEvidence({
|
|
2961
|
+
paymentId: receipt.paymentId,
|
|
2962
|
+
rail: "x402",
|
|
2963
|
+
txHash: settlementCandidate,
|
|
2964
|
+
...settlementProofFields(receipt.paymentHeader)
|
|
2965
|
+
});
|
|
2727
2966
|
}
|
|
2728
2967
|
await this.reportMerchantReceipt(receipt.paymentId, retryResponse);
|
|
2729
2968
|
return retryResponse;
|
|
@@ -2775,18 +3014,18 @@ var MerchantCompletion = class {
|
|
|
2775
3014
|
async resolveCompletionContext(input) {
|
|
2776
3015
|
const status = await this.getPaymentStatus(input.paymentId);
|
|
2777
3016
|
if (status.rail !== "x402") {
|
|
2778
|
-
throw new
|
|
3017
|
+
throw new chunkZA3NOSO2_cjs.HavenPaymentStateError(
|
|
2779
3018
|
`Payment ${status.paymentId} is ${status.rail}, not x402.`,
|
|
2780
3019
|
409,
|
|
2781
3020
|
status
|
|
2782
3021
|
);
|
|
2783
3022
|
}
|
|
2784
|
-
const readyForMerchantCompletion = input.noFundingLeg ? status.kind === "payment_intent" && status.status === "submitted" : status.nextAction ===
|
|
3023
|
+
const readyForMerchantCompletion = input.noFundingLeg ? status.kind === "payment_intent" && status.status === "submitted" : status.nextAction === chunkZA3NOSO2_cjs.AgentPaymentNextAction.RetryOriginalX402Request || status.kind === "payment_intent" && status.status === "confirmed" && status.phase === chunkZA3NOSO2_cjs.AgentPaymentPhase.PaymentConfirmed && status.nextAction === chunkZA3NOSO2_cjs.AgentPaymentNextAction.None;
|
|
2785
3024
|
if (!readyForMerchantCompletion) {
|
|
2786
|
-
throw new
|
|
3025
|
+
throw new chunkZA3NOSO2_cjs.HavenPaymentStateError(status.message, paymentStateStatusCode(status.status, 409), status);
|
|
2787
3026
|
}
|
|
2788
3027
|
if (!input.noFundingLeg && !status.txHash) {
|
|
2789
|
-
throw new
|
|
3028
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
2790
3029
|
`x402 payment ${status.paymentId} is ready for merchant completion but has no Haven transaction hash.`,
|
|
2791
3030
|
502,
|
|
2792
3031
|
status,
|
|
@@ -2795,7 +3034,7 @@ var MerchantCompletion = class {
|
|
|
2795
3034
|
}
|
|
2796
3035
|
const approvedResourceUrl = status.resourceUrl ?? status.x402?.resourceUrl ?? null;
|
|
2797
3036
|
if (approvedResourceUrl && approvedResourceUrl !== input.url) {
|
|
2798
|
-
throw new
|
|
3037
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
2799
3038
|
"x402 merchant completion does not match the approved resource URL.",
|
|
2800
3039
|
409,
|
|
2801
3040
|
{ status, url: input.url },
|
|
@@ -2826,6 +3065,51 @@ var MerchantCompletion = class {
|
|
|
2826
3065
|
// and MACHINE-PAYMENT-CHALLENGE was never produced by any other Haven
|
|
2827
3066
|
// surface. Use the x402 flow (authorizeX402 / fetch / quoteX402 / payX402Quote)
|
|
2828
3067
|
// for agent-to-merchant payments.
|
|
3068
|
+
/**
|
|
3069
|
+
* #4257: record a paid delivery that a refused redirect interrupted, and
|
|
3070
|
+
* return the refusal re-thrown with its payment and an accurate account:
|
|
3071
|
+
* the payment header (and the body, when there is one) reached `url`, the
|
|
3072
|
+
* merchant answered with a redirect Haven did not follow, and the merchant
|
|
3073
|
+
* may still settle. The record is the same
|
|
3074
|
+
* `merchant_retry_rejected_after_payment` event a non-2xx answer writes: its
|
|
3075
|
+
* `retry_status` is the redirect status, `retry_body` is null, and `details`
|
|
3076
|
+
* carry `refusal` plus `redirect_location` when the refusal names a redirect
|
|
3077
|
+
* target, or `refused_url` (the URL that answered) otherwise. The payment
|
|
3078
|
+
* reads as funded and undelivered.
|
|
3079
|
+
*/
|
|
3080
|
+
async paidDeliveryInterrupted(err, url, receipt, paymentHeader, hasBody) {
|
|
3081
|
+
const scheme = chunkV2ODMLDD_cjs.x402PaymentHeaderNamesFor(paymentHeader).length > 1 ? "eip3009" : "erc7710";
|
|
3082
|
+
const status = err.redirectStatus ?? 0;
|
|
3083
|
+
await this.recordRetryRejected({
|
|
3084
|
+
rail: "x402",
|
|
3085
|
+
paymentId: receipt.paymentId,
|
|
3086
|
+
txHash: receipt.txHash,
|
|
3087
|
+
resourceUrl: receipt.resourceUrl,
|
|
3088
|
+
merchant: {
|
|
3089
|
+
merchant_status: status,
|
|
3090
|
+
merchant_status_text: "redirect not followed",
|
|
3091
|
+
merchant_headers: {},
|
|
3092
|
+
merchant_body: ""
|
|
3093
|
+
},
|
|
3094
|
+
details: {
|
|
3095
|
+
merchant_to: receipt.merchantTo,
|
|
3096
|
+
delegate_to: receipt.to,
|
|
3097
|
+
refusal: err.refusal,
|
|
3098
|
+
// The refusal's url is the redirect target only when it carries one;
|
|
3099
|
+
// otherwise it is the URL that answered (a non-GET redirect, a missing
|
|
3100
|
+
// or unresolvable Location), recorded under a neutral key.
|
|
3101
|
+
...err.redirectTarget ? { redirect_location: err.redirectTarget } : { refused_url: err.url }
|
|
3102
|
+
}
|
|
3103
|
+
});
|
|
3104
|
+
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: `;
|
|
3105
|
+
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.";
|
|
3106
|
+
return new MerchantEgressRefusedError(what + next, err.url, err.refusal, false, {
|
|
3107
|
+
redirectStatus: err.redirectStatus,
|
|
3108
|
+
redirectTarget: err.redirectTarget,
|
|
3109
|
+
paymentId: receipt.paymentId,
|
|
3110
|
+
settlementScheme: scheme
|
|
3111
|
+
});
|
|
3112
|
+
}
|
|
2829
3113
|
async recordRetryRejected(input) {
|
|
2830
3114
|
try {
|
|
2831
3115
|
await this.post("/machine-payments/reconciliation-events", {
|
|
@@ -2881,7 +3165,7 @@ var MerchantCompletion = class {
|
|
|
2881
3165
|
*/
|
|
2882
3166
|
async reportMerchantOutcome(input) {
|
|
2883
3167
|
if (!Number.isInteger(input.merchantStatus) || input.merchantStatus < 100 || input.merchantStatus > 599) {
|
|
2884
|
-
throw new
|
|
3168
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
2885
3169
|
`merchant_status must be an integer HTTP status from 100 to 599 (received ${input.merchantStatus}).`,
|
|
2886
3170
|
400,
|
|
2887
3171
|
void 0,
|
|
@@ -2890,7 +3174,7 @@ var MerchantCompletion = class {
|
|
|
2890
3174
|
}
|
|
2891
3175
|
const looksAccepted = input.merchantStatus >= 200 && input.merchantStatus < 300;
|
|
2892
3176
|
if (looksAccepted !== (input.outcome === "accepted")) {
|
|
2893
|
-
throw new
|
|
3177
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
2894
3178
|
`outcome "${input.outcome}" contradicts merchant_status ${input.merchantStatus}: report "accepted" only for a 2xx and "rejected" only for a non-2xx.`,
|
|
2895
3179
|
400,
|
|
2896
3180
|
void 0,
|
|
@@ -2899,14 +3183,14 @@ var MerchantCompletion = class {
|
|
|
2899
3183
|
}
|
|
2900
3184
|
const status = await this.getPaymentStatus(input.paymentId);
|
|
2901
3185
|
if (status.rail !== "x402") {
|
|
2902
|
-
throw new
|
|
3186
|
+
throw new chunkZA3NOSO2_cjs.HavenPaymentStateError(
|
|
2903
3187
|
`Payment ${status.paymentId} is ${status.rail}, not x402 \u2014 there is no merchant retry to report.`,
|
|
2904
3188
|
409,
|
|
2905
3189
|
status
|
|
2906
3190
|
);
|
|
2907
3191
|
}
|
|
2908
3192
|
if (status.status !== "confirmed" || !status.txHash) {
|
|
2909
|
-
throw new
|
|
3193
|
+
throw new chunkZA3NOSO2_cjs.HavenPaymentStateError(
|
|
2910
3194
|
`Payment ${status.paymentId} has no confirmed Haven funding transaction to anchor a merchant report to (status ${status.status}). ${status.message}`,
|
|
2911
3195
|
paymentStateStatusCode(status.status, 409),
|
|
2912
3196
|
status
|
|
@@ -2914,7 +3198,7 @@ var MerchantCompletion = class {
|
|
|
2914
3198
|
}
|
|
2915
3199
|
const resourceUrl = status.resourceUrl ?? status.x402?.resourceUrl ?? null;
|
|
2916
3200
|
if (!resourceUrl) {
|
|
2917
|
-
throw new
|
|
3201
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
2918
3202
|
`Payment ${status.paymentId} has no recorded resource URL, so a merchant report cannot be stored.`,
|
|
2919
3203
|
409,
|
|
2920
3204
|
status,
|
|
@@ -2968,30 +3252,35 @@ var MerchantCompletion = class {
|
|
|
2968
3252
|
};
|
|
2969
3253
|
for (let attempt = 0; ; attempt += 1) {
|
|
2970
3254
|
const result = await this.postEvidenceOnce(body);
|
|
2971
|
-
if (result.outcome !== "retryable" || attempt >= EVIDENCE_RETRY_DELAYS_MS.length) {
|
|
3255
|
+
if (result.outcome !== "retryable" || result.statusCode !== EVIDENCE_RETRYABLE_STATUS || attempt >= EVIDENCE_RETRY_DELAYS_MS.length) {
|
|
2972
3256
|
return result;
|
|
2973
3257
|
}
|
|
2974
3258
|
await this.sleep(EVIDENCE_RETRY_DELAYS_MS[attempt]);
|
|
2975
3259
|
}
|
|
2976
3260
|
}
|
|
2977
3261
|
/**
|
|
2978
|
-
* ONE evidence attempt — the body of `reportEvidence`'s loop above
|
|
2979
|
-
*
|
|
2980
|
-
* immediately; the caller decides whether to sleep and
|
|
2981
|
-
* (`reportEvidence
|
|
3262
|
+
* ONE evidence attempt — the body of `reportEvidence`'s loop above. A 503,
|
|
3263
|
+
* or no verdict at all (a non-answer or a 408, #4470), answers `retryable`
|
|
3264
|
+
* immediately; the caller decides whether to sleep and
|
|
3265
|
+
* re-attempt (`reportEvidence`, and — #4215 — the local settlement report
|
|
3266
|
+
* in `retryRequest`) or hand the outcome to its consumer (#3764 D2, the
|
|
3267
|
+
* hosted settlement report).
|
|
2982
3268
|
*/
|
|
2983
3269
|
async postEvidenceOnce(body) {
|
|
2984
3270
|
try {
|
|
2985
3271
|
await this.post("/machine-payments/evidence", body);
|
|
2986
3272
|
return { outcome: "confirmed" };
|
|
2987
3273
|
} catch (err) {
|
|
2988
|
-
const statusCode = err instanceof
|
|
2989
|
-
|
|
3274
|
+
const statusCode = err instanceof chunkZA3NOSO2_cjs.HavenApiError ? err.statusCode : void 0;
|
|
3275
|
+
const noVerdict = statusCode === 408 || err instanceof chunkZA3NOSO2_cjs.HavenApiError && err.failureCause?.kind === "no_answer";
|
|
3276
|
+
if (statusCode !== EVIDENCE_RETRYABLE_STATUS && !noVerdict) {
|
|
2990
3277
|
const reason = refusalReasonFromBody(err);
|
|
3278
|
+
const errorCode = refusalErrorCodeFromBody(err);
|
|
2991
3279
|
return {
|
|
2992
3280
|
outcome: "refused",
|
|
2993
3281
|
statusCode: statusCode ?? 0,
|
|
2994
|
-
...reason ? { reason } : {}
|
|
3282
|
+
...reason ? { reason } : {},
|
|
3283
|
+
...errorCode ? { errorCode } : {}
|
|
2995
3284
|
};
|
|
2996
3285
|
}
|
|
2997
3286
|
return { outcome: "retryable", statusCode };
|
|
@@ -3028,46 +3317,78 @@ var MerchantCompletion = class {
|
|
|
3028
3317
|
* gate uses, so a caller cannot "fix" a missing hash by reporting the demo
|
|
3029
3318
|
* merchant's own marker and getting a different verdict than the settle
|
|
3030
3319
|
* path already gave it.
|
|
3320
|
+
*
|
|
3321
|
+
* #4061: `options.paymentHeader` is the payment header the caller sent to
|
|
3322
|
+
* the merchant on its paid retry. On eip3009 it is REQUIRED for the record
|
|
3323
|
+
* (#3925): its signed authorization proves the nonce the settlement burned
|
|
3324
|
+
* is this payment's, and a report without it is refused with
|
|
3325
|
+
* `errorCode: 'settlement_proof_header_missing'`. It is forwarded exactly
|
|
3326
|
+
* as the funding report forwards it (`paymentProofHeader` plus the names
|
|
3327
|
+
* `x402PaymentHeaderNamesSent` derives from the same payload). erc7710
|
|
3328
|
+
* needs none — Haven assembled that header itself.
|
|
3031
3329
|
*/
|
|
3032
|
-
async reportSettlementEvidence(paymentId, settlementTxHash) {
|
|
3330
|
+
async reportSettlementEvidence(paymentId, settlementTxHash, options = {}) {
|
|
3033
3331
|
if (isZeroSettlementTxHash(settlementTxHash)) {
|
|
3034
|
-
throw new
|
|
3332
|
+
throw new chunkZA3NOSO2_cjs.HavenZeroSettlementHashError(paymentId);
|
|
3035
3333
|
}
|
|
3036
3334
|
return this.reportEvidence({
|
|
3037
3335
|
paymentId,
|
|
3038
3336
|
rail: "x402",
|
|
3039
|
-
txHash: settlementTxHash
|
|
3337
|
+
txHash: settlementTxHash,
|
|
3338
|
+
...settlementProofFields(options.paymentHeader)
|
|
3040
3339
|
});
|
|
3041
3340
|
}
|
|
3042
3341
|
/**
|
|
3043
3342
|
* #3764: report the merchant's OWN EIP-3009 settlement transaction right
|
|
3044
|
-
* after a completed purchase — the second leg of a payment that
|
|
3045
|
-
* a funding-evidence row. Same endpoint and payload shape as
|
|
3343
|
+
* after a completed hosted purchase — the second leg of a payment that
|
|
3344
|
+
* already has a funding-evidence row. Same endpoint and payload shape as
|
|
3046
3345
|
* `reportSettlementEvidence` above, but with #3764's D2 budget: exactly ONE
|
|
3047
3346
|
* attempt, no `EVIDENCE_RETRY_DELAYS_MS` backoff. The resource is already
|
|
3048
3347
|
* paid for and delivered, so a retryable answer must not stretch the
|
|
3049
3348
|
* completed purchase — the HOSTED tools hand the outcome to the agent
|
|
3050
|
-
* (`settlementEvidenceOutcome` → `haven_report_settlement_evidence`)
|
|
3051
|
-
*
|
|
3052
|
-
*
|
|
3349
|
+
* (`settlementEvidenceOutcome` → `haven_report_settlement_evidence`). Since
|
|
3350
|
+
* #4215 this ONE-attempt form serves the HOSTED path only
|
|
3351
|
+
* (`completeX402MerchantCall`); the local `retryRequest` posts the same
|
|
3352
|
+
* report through `reportEvidence`, whose bounded loop re-attempts while
|
|
3353
|
+
* Haven answers `retryable`. Callers validate the hash before this call
|
|
3354
|
+
* (well-formed, non-zero, different from the funding hash
|
|
3053
3355
|
* case-insensitively), so there is no client-side refusal here — the
|
|
3054
3356
|
* backend verifies on-chain and is the only judge.
|
|
3357
|
+
*
|
|
3358
|
+
* #4061: `paymentHeader` is the header the paid retry sent — the #3925
|
|
3359
|
+
* nonce proof, forwarded as `reportSettlementEvidence` forwards it. Both
|
|
3360
|
+
* callers hold it; without it the backend refuses the record.
|
|
3055
3361
|
*/
|
|
3056
|
-
async reportSettlementEvidenceOnce(paymentId, settlementTxHash) {
|
|
3362
|
+
async reportSettlementEvidenceOnce(paymentId, settlementTxHash, paymentHeader) {
|
|
3057
3363
|
return this.postEvidenceOnce({
|
|
3058
3364
|
paymentId,
|
|
3059
3365
|
rail: "x402",
|
|
3060
|
-
txHash: settlementTxHash
|
|
3366
|
+
txHash: settlementTxHash,
|
|
3367
|
+
...settlementProofFields(paymentHeader)
|
|
3061
3368
|
});
|
|
3062
3369
|
}
|
|
3063
3370
|
};
|
|
3371
|
+
function settlementProofFields(paymentHeader) {
|
|
3372
|
+
if (!paymentHeader || !paymentHeader.trim()) return {};
|
|
3373
|
+
return {
|
|
3374
|
+
paymentProofHeaderName: chunkV2ODMLDD_cjs.x402PaymentHeaderNamesSent(paymentHeader),
|
|
3375
|
+
paymentProofHeader: paymentHeader
|
|
3376
|
+
};
|
|
3377
|
+
}
|
|
3064
3378
|
function refusalReasonFromBody(err) {
|
|
3065
|
-
if (!(err instanceof
|
|
3379
|
+
if (!(err instanceof chunkZA3NOSO2_cjs.HavenApiError)) return void 0;
|
|
3066
3380
|
const body = err.body;
|
|
3067
3381
|
if (body === null || typeof body !== "object" || Array.isArray(body)) return void 0;
|
|
3068
3382
|
const reason = body.reason;
|
|
3069
3383
|
return typeof reason === "string" && reason.length > 0 ? reason : void 0;
|
|
3070
3384
|
}
|
|
3385
|
+
function refusalErrorCodeFromBody(err) {
|
|
3386
|
+
if (!(err instanceof chunkZA3NOSO2_cjs.HavenApiError)) return void 0;
|
|
3387
|
+
const body = err.body;
|
|
3388
|
+
if (body === null || typeof body !== "object" || Array.isArray(body)) return void 0;
|
|
3389
|
+
const code = body.error_code;
|
|
3390
|
+
return typeof code === "string" && code.length > 0 ? code : void 0;
|
|
3391
|
+
}
|
|
3071
3392
|
function isZeroSettlementTxHash(hash) {
|
|
3072
3393
|
return typeof hash === "string" && /^0x0+$/i.test(hash);
|
|
3073
3394
|
}
|
|
@@ -3079,7 +3400,7 @@ function parseMerchantSettlement(header) {
|
|
|
3079
3400
|
}
|
|
3080
3401
|
function parseProtocolReceiptHeader(value) {
|
|
3081
3402
|
try {
|
|
3082
|
-
return
|
|
3403
|
+
return chunkV2ODMLDD_cjs.decodeBase64Json(value);
|
|
3083
3404
|
} catch {
|
|
3084
3405
|
try {
|
|
3085
3406
|
return JSON.parse(value);
|
|
@@ -3088,6 +3409,25 @@ function parseProtocolReceiptHeader(value) {
|
|
|
3088
3409
|
}
|
|
3089
3410
|
}
|
|
3090
3411
|
}
|
|
3412
|
+
function unfollowedRedirect(err) {
|
|
3413
|
+
const target = err.redirectTarget ?? err.url;
|
|
3414
|
+
switch (err.refusal) {
|
|
3415
|
+
case "redirect_cross_origin_body":
|
|
3416
|
+
return ` to a different origin (${target}). Haven did not follow it, so the payment was not re-sent there.`;
|
|
3417
|
+
case "redirect_on_non_get":
|
|
3418
|
+
return ". Under the egress policy only GET redirects are followed, so Haven did not follow it and nothing was sent to the redirect target.";
|
|
3419
|
+
case "redirect_missing_location":
|
|
3420
|
+
return " that named no target (no Location header). Haven did not follow it.";
|
|
3421
|
+
case "redirect_invalid_location":
|
|
3422
|
+
return " whose Location header is not a resolvable URL. Haven did not follow it.";
|
|
3423
|
+
case "redirect_budget_exceeded":
|
|
3424
|
+
return ` past the redirect budget. The chain stopped before ${target}, and nothing was sent there.`;
|
|
3425
|
+
case "url_not_allowed":
|
|
3426
|
+
return ` to a URL the egress policy does not allow (${target}). Haven did not follow it, so nothing was sent there.`;
|
|
3427
|
+
default:
|
|
3428
|
+
return ". Haven did not follow it.";
|
|
3429
|
+
}
|
|
3430
|
+
}
|
|
3091
3431
|
|
|
3092
3432
|
// src/client.ts
|
|
3093
3433
|
var DEFAULT_POLLING_INTERVAL = 3e3;
|
|
@@ -3096,7 +3436,7 @@ function x402TypedDataDigest(typedData) {
|
|
|
3096
3436
|
try {
|
|
3097
3437
|
return viem.hashTypedData(typedData);
|
|
3098
3438
|
} catch (err) {
|
|
3099
|
-
throw new
|
|
3439
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError(
|
|
3100
3440
|
`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)}`
|
|
3101
3441
|
);
|
|
3102
3442
|
}
|
|
@@ -3211,7 +3551,7 @@ var HavenClient = class {
|
|
|
3211
3551
|
this.x402Wallet = config.x402Wallet;
|
|
3212
3552
|
this.egressPolicy = config.merchantEgress;
|
|
3213
3553
|
this.merchantTransport = new McpMerchantTransport({ merchantTimeout: config.merchantTimeout, egress: config.merchantEgress });
|
|
3214
|
-
this.confirmationTimeout = config.confirmationTimeout ??
|
|
3554
|
+
this.confirmationTimeout = config.confirmationTimeout ?? chunkZA3NOSO2_cjs.DEFAULT_CONFIRMATION_TIMEOUT_MS;
|
|
3215
3555
|
this.pollingInterval = config.pollingInterval ?? DEFAULT_POLLING_INTERVAL;
|
|
3216
3556
|
this.chainRpcs = config.chainRpcs ?? {};
|
|
3217
3557
|
if (this.delegateKey) {
|
|
@@ -3292,7 +3632,7 @@ var HavenClient = class {
|
|
|
3292
3632
|
*/
|
|
3293
3633
|
async pay(request) {
|
|
3294
3634
|
if (!this.delegateKey) {
|
|
3295
|
-
throw new
|
|
3635
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError(
|
|
3296
3636
|
"Cannot use pay() without a delegateKey. Use createIntent() + submitSignature() for manual signing."
|
|
3297
3637
|
);
|
|
3298
3638
|
}
|
|
@@ -3348,15 +3688,15 @@ var HavenClient = class {
|
|
|
3348
3688
|
* on-chain allowance — there is nothing to sign until the user approves.
|
|
3349
3689
|
*/
|
|
3350
3690
|
async createX402Intent(paymentRequired, options = {}) {
|
|
3351
|
-
const option =
|
|
3691
|
+
const option = chunkV2ODMLDD_cjs.selectStandardPaymentOption(paymentRequired.accepts);
|
|
3352
3692
|
if (!option) {
|
|
3353
3693
|
throw noCompatiblePaymentOptionError(paymentRequired.accepts);
|
|
3354
3694
|
}
|
|
3355
3695
|
const fundingTo = options.delegateAddress ?? (await this.getAgent()).delegateAddress;
|
|
3356
3696
|
if (!fundingTo) {
|
|
3357
|
-
throw
|
|
3697
|
+
throw chunkZA3NOSO2_cjs.HavenApiError.deterministic("Authenticated agent has no delegate address registered.", 502);
|
|
3358
3698
|
}
|
|
3359
|
-
const idempotencyKey = options.idempotencyKey ??
|
|
3699
|
+
const idempotencyKey = options.idempotencyKey ?? chunkV2ODMLDD_cjs.buildX402IdempotencyKey(paymentRequired, option);
|
|
3360
3700
|
const raw = await this.post("/x402", {
|
|
3361
3701
|
url: paymentRequired.resource.url,
|
|
3362
3702
|
payTo: fundingTo,
|
|
@@ -3367,7 +3707,7 @@ var HavenClient = class {
|
|
|
3367
3707
|
// of a silent reroute to the erc7710 settlement branch (the #1358
|
|
3368
3708
|
// review's open-budget misroute). Legacy-rail backends ignore the field.
|
|
3369
3709
|
settlementScheme: "eip3009",
|
|
3370
|
-
amount:
|
|
3710
|
+
amount: chunkV2ODMLDD_cjs.x402AuthorizationAmount(option),
|
|
3371
3711
|
asset: option.asset,
|
|
3372
3712
|
network: option.network,
|
|
3373
3713
|
description: paymentRequired.resource.description,
|
|
@@ -3392,15 +3732,15 @@ var HavenClient = class {
|
|
|
3392
3732
|
throwPaymentStateError("x402 payment", raw);
|
|
3393
3733
|
}
|
|
3394
3734
|
if (!raw.sign_data?.hash) {
|
|
3395
|
-
throw
|
|
3735
|
+
throw chunkZA3NOSO2_cjs.HavenApiError.deterministic("No sign_hash returned from x402/authorize", 500, raw);
|
|
3396
3736
|
}
|
|
3397
3737
|
if (raw.sign_data.signature_scheme !== void 0 && !raw.sign_data.typed_data) {
|
|
3398
|
-
throw new
|
|
3738
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError(
|
|
3399
3739
|
`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.`
|
|
3400
3740
|
);
|
|
3401
3741
|
}
|
|
3402
3742
|
if (!raw.x402_expected_auth) {
|
|
3403
|
-
throw
|
|
3743
|
+
throw chunkZA3NOSO2_cjs.HavenApiError.deterministic("No x402 expected-context binding returned from x402/authorize", 500, raw);
|
|
3404
3744
|
}
|
|
3405
3745
|
return {
|
|
3406
3746
|
paymentId: raw.payment_id,
|
|
@@ -3411,7 +3751,7 @@ var HavenClient = class {
|
|
|
3411
3751
|
accepted: option,
|
|
3412
3752
|
resourceUrl: paymentRequired.resource.url,
|
|
3413
3753
|
merchantTo: raw.merchant_to ?? option.payTo,
|
|
3414
|
-
amountAtomic:
|
|
3754
|
+
amountAtomic: chunkV2ODMLDD_cjs.x402AuthorizationAmount(option),
|
|
3415
3755
|
asset: option.asset,
|
|
3416
3756
|
network: option.network,
|
|
3417
3757
|
expectedAuth: raw.x402_expected_auth,
|
|
@@ -3436,13 +3776,13 @@ var HavenClient = class {
|
|
|
3436
3776
|
*/
|
|
3437
3777
|
sign(hash) {
|
|
3438
3778
|
if (!this.delegateKey) {
|
|
3439
|
-
throw new
|
|
3779
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError(
|
|
3440
3780
|
"Cannot sign without a delegateKey. Pass the private key in HavenClient config, or sign externally."
|
|
3441
3781
|
);
|
|
3442
3782
|
}
|
|
3443
3783
|
const signature = signHash(this.delegateKey, hash);
|
|
3444
3784
|
if (!verifySignature(hash, signature, this.delegateAddress)) {
|
|
3445
|
-
throw new
|
|
3785
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError(
|
|
3446
3786
|
"Local signature verification failed \u2014 recovered address does not match delegate key."
|
|
3447
3787
|
);
|
|
3448
3788
|
}
|
|
@@ -3460,29 +3800,29 @@ var HavenClient = class {
|
|
|
3460
3800
|
*/
|
|
3461
3801
|
async signForData(signData, settlementExpectation, fundingExpectation) {
|
|
3462
3802
|
if (!this.delegateKey) {
|
|
3463
|
-
throw new
|
|
3803
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError(
|
|
3464
3804
|
"Cannot sign without a delegateKey. Pass the private key in HavenClient config, or sign externally."
|
|
3465
3805
|
);
|
|
3466
3806
|
}
|
|
3467
3807
|
const scheme = signData.signature_scheme;
|
|
3468
3808
|
if (scheme === "eip191_userop") {
|
|
3469
|
-
throw new
|
|
3809
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError(
|
|
3470
3810
|
"The session rail is retired \u2014 'eip191_userop' intents can no longer be signed. Re-onboard the account on the delegation rail."
|
|
3471
3811
|
);
|
|
3472
3812
|
}
|
|
3473
3813
|
if (scheme === "eip712_userop") {
|
|
3474
3814
|
if (!signData.typed_data) {
|
|
3475
|
-
throw new
|
|
3815
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError(
|
|
3476
3816
|
"sign_data.signature_scheme is eip712_userop but typed_data is missing \u2014 refusing to sign the bare hash (the account would reject it)."
|
|
3477
3817
|
);
|
|
3478
3818
|
}
|
|
3479
|
-
|
|
3480
|
-
|
|
3819
|
+
chunkZA3NOSO2_cjs.assertUserOpTypedDataBinding(signData.typed_data, signData.hash);
|
|
3820
|
+
chunkV2ODMLDD_cjs.assertBoundDirectPaymentUserOp(
|
|
3481
3821
|
signData.typed_data,
|
|
3482
3822
|
this.delegateAddress
|
|
3483
3823
|
);
|
|
3484
3824
|
if (fundingExpectation) {
|
|
3485
|
-
|
|
3825
|
+
chunkV2ODMLDD_cjs.assertFundingLegPaysDelegate(signData.typed_data, {
|
|
3486
3826
|
delegateAddress: this.delegateAddress,
|
|
3487
3827
|
asset: fundingExpectation.asset,
|
|
3488
3828
|
amount: fundingExpectation.amount
|
|
@@ -3492,24 +3832,24 @@ var HavenClient = class {
|
|
|
3492
3832
|
}
|
|
3493
3833
|
if (scheme === "eip712_delegation") {
|
|
3494
3834
|
if (!signData.typed_data) {
|
|
3495
|
-
throw new
|
|
3835
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError(
|
|
3496
3836
|
"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)."
|
|
3497
3837
|
);
|
|
3498
3838
|
}
|
|
3499
3839
|
if (!settlementExpectation) {
|
|
3500
|
-
throw new
|
|
3840
|
+
throw new chunkV2ODMLDD_cjs.HavenTypedDataRefusedError(
|
|
3501
3841
|
"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."
|
|
3502
3842
|
);
|
|
3503
3843
|
}
|
|
3504
|
-
|
|
3844
|
+
chunkV2ODMLDD_cjs.assertOwnSettlementChild(signData.typed_data, settlementExpectation, this.delegateAddress);
|
|
3505
3845
|
return signSettlementDelegationTypedData(this.delegateKey, signData.typed_data);
|
|
3506
3846
|
}
|
|
3507
3847
|
if (scheme === void 0) {
|
|
3508
|
-
throw new
|
|
3848
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError(
|
|
3509
3849
|
"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."
|
|
3510
3850
|
);
|
|
3511
3851
|
}
|
|
3512
|
-
throw new
|
|
3852
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError(
|
|
3513
3853
|
`Unknown sign_data.signature_scheme '${scheme}' \u2014 refusing to guess a signing scheme. Update @haven_ai/sdk.`
|
|
3514
3854
|
);
|
|
3515
3855
|
}
|
|
@@ -3630,6 +3970,12 @@ var HavenClient = class {
|
|
|
3630
3970
|
* degrade-to-warning path and the ledger row would still land while the
|
|
3631
3971
|
* purchase proceeded.
|
|
3632
3972
|
*
|
|
3973
|
+
* #4458: an agent whose only budget for the token has ENDED is refused the
|
|
3974
|
+
* same way with `error_code: 'delegation_expired'` and `budget_ended_at`
|
|
3975
|
+
* (ISO 8601) — also thrown, also recorded (`source: 'hosted_prepare'`).
|
|
3976
|
+
* The remedy differs: the owner sets a NEW budget, waiting for a period to
|
|
3977
|
+
* reset cannot help.
|
|
3978
|
+
*
|
|
3633
3979
|
* #3518: without `merchantTo`, an agent whose budgets for the token are all
|
|
3634
3980
|
* merchant-locked gets 409 `budget_requires_recipient` (thrown, nothing
|
|
3635
3981
|
* recorded) naming the pins in `budget_recipient_addresses` — repeat the
|
|
@@ -3647,18 +3993,20 @@ var HavenClient = class {
|
|
|
3647
3993
|
amountAtomic: input.amountAtomic,
|
|
3648
3994
|
...input.merchantTo !== void 0 ? { merchantTo: input.merchantTo } : {},
|
|
3649
3995
|
...input.resourceUrl !== void 0 ? { resourceUrl: input.resourceUrl } : {},
|
|
3650
|
-
...input.idempotencyKey !== void 0 ? { idempotencyKey: input.idempotencyKey } : {}
|
|
3996
|
+
...input.idempotencyKey !== void 0 ? { idempotencyKey: input.idempotencyKey } : {},
|
|
3997
|
+
...input.recordRefusal !== void 0 ? { recordRefusal: input.recordRefusal } : {}
|
|
3651
3998
|
});
|
|
3652
3999
|
}
|
|
3653
4000
|
/**
|
|
3654
4001
|
* Post-purchase allowance/budget summary for a settled payment (#1310).
|
|
3655
4002
|
*
|
|
3656
|
-
* Reuses the EXACT rail-aware read path {@link getAllowances}
|
|
3657
|
-
*
|
|
3658
|
-
*
|
|
3659
|
-
* the #1090 `deriveDelegationBudgets`-backed enforcer read, never
|
|
4003
|
+
* Reuses the EXACT rail-aware read path {@link getAllowances} uses —
|
|
4004
|
+
* `GET /machine-payments/allowances`, with delegation-rail values coming
|
|
4005
|
+
* from the #1090 `deriveDelegationBudgets`-backed enforcer read, never
|
|
3660
4006
|
* `agent_allowances` — so this can never disagree with
|
|
3661
|
-
* {@link getAllowances} for the same fixture.
|
|
4007
|
+
* {@link getAllowances} for the same fixture. (#1306's catalog-purchase
|
|
4008
|
+
* preflight read the same path until #3054; it now calls
|
|
4009
|
+
* `POST /machine-payments/budget-precheck` instead.) The settled token is
|
|
3662
4010
|
* resolved from {@link getPaymentStatus} so callers pass only
|
|
3663
4011
|
* `paymentId`, never a second haven_get_agent-style round trip.
|
|
3664
4012
|
*
|
|
@@ -3699,7 +4047,7 @@ var HavenClient = class {
|
|
|
3699
4047
|
*/
|
|
3700
4048
|
async getPaymentStatusWithPostPurchaseAllowance(paymentId) {
|
|
3701
4049
|
const status = await this.getPaymentStatus(paymentId);
|
|
3702
|
-
if (status.rail ===
|
|
4050
|
+
if (status.rail === chunkZA3NOSO2_cjs.AgentPaymentRail.X402 && status.phase === chunkZA3NOSO2_cjs.AgentPaymentPhase.PaymentConfirmed) {
|
|
3703
4051
|
const { allowance, warnings } = await this.getPostPurchaseAllowanceSummary(paymentId);
|
|
3704
4052
|
return { ...status, allowance, ...warnings.length > 0 ? { warnings } : {} };
|
|
3705
4053
|
}
|
|
@@ -3754,10 +4102,10 @@ var HavenClient = class {
|
|
|
3754
4102
|
return this.get(`/catalog/submit/${encodeURIComponent(id)}`);
|
|
3755
4103
|
}
|
|
3756
4104
|
/**
|
|
3757
|
-
* Fetch one
|
|
4105
|
+
* Fetch one catalog entry by id (#1306).
|
|
3758
4106
|
*
|
|
3759
4107
|
* Chain-scoped for free by the backend's SQL when the client is
|
|
3760
|
-
* agent-authenticated (#1299): an unknown id and an id
|
|
4108
|
+
* agent-authenticated (#1299): an unknown id and an id listed for a
|
|
3761
4109
|
* DIFFERENT chain than this agent's both 404 identically — this method does
|
|
3762
4110
|
* not (and must not) re-filter by chain in JS. Read-only, like
|
|
3763
4111
|
* {@link discoverTools}.
|
|
@@ -3913,9 +4261,10 @@ var HavenClient = class {
|
|
|
3913
4261
|
return this.accountReads.listPendingSubBudgetSignatures();
|
|
3914
4262
|
}
|
|
3915
4263
|
/**
|
|
3916
|
-
* Close a sub-budget row (delegating agent only). A `pending` or
|
|
3917
|
-
* closes immediately; a live child
|
|
3918
|
-
*
|
|
4264
|
+
* Close a sub-budget row (delegating agent only). A `pending` row, or an
|
|
4265
|
+
* `open` one already expired, closes immediately; otherwise (a live child, or
|
|
4266
|
+
* any `closing` row — its disable is still owed, #3923) it returns `signData`
|
|
4267
|
+
* for the on-chain revocation — sign it (`haven_sign` with `sub_budget_id`) and call
|
|
3919
4268
|
* `submitSubBudget`.
|
|
3920
4269
|
*/
|
|
3921
4270
|
async closeSubBudget(id) {
|
|
@@ -3949,7 +4298,7 @@ var HavenClient = class {
|
|
|
3949
4298
|
}
|
|
3950
4299
|
await sleep(this.pollingInterval);
|
|
3951
4300
|
}
|
|
3952
|
-
throw new
|
|
4301
|
+
throw new chunkZA3NOSO2_cjs.HavenTimeoutError(paymentId);
|
|
3953
4302
|
}
|
|
3954
4303
|
// ── x402 Protocol Support ────────────────────────────────────────
|
|
3955
4304
|
/**
|
|
@@ -3963,24 +4312,24 @@ var HavenClient = class {
|
|
|
3963
4312
|
*/
|
|
3964
4313
|
async authorizeX402(paymentRequired, options = {}) {
|
|
3965
4314
|
if (!this.delegateKey) {
|
|
3966
|
-
throw new
|
|
4315
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError(
|
|
3967
4316
|
"delegateKey is required for x402 payments. Pass it in the HavenClient config."
|
|
3968
4317
|
);
|
|
3969
4318
|
}
|
|
3970
4319
|
if (!this.delegateAddress) {
|
|
3971
|
-
throw new
|
|
4320
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError("delegateAddress could not be derived from delegateKey.");
|
|
3972
4321
|
}
|
|
3973
|
-
const option =
|
|
4322
|
+
const option = chunkV2ODMLDD_cjs.selectStandardPaymentOption(paymentRequired.accepts);
|
|
3974
4323
|
if (!option) {
|
|
3975
4324
|
throw noCompatiblePaymentOptionError(paymentRequired.accepts);
|
|
3976
4325
|
}
|
|
3977
|
-
const idempotencyKey = options.idempotencyKey ??
|
|
4326
|
+
const idempotencyKey = options.idempotencyKey ?? chunkV2ODMLDD_cjs.buildX402IdempotencyKey(paymentRequired, option);
|
|
3978
4327
|
const cached = this.fundingLeg.cachedReceipt(idempotencyKey, options.taskBudgetId, options.subBudgetId);
|
|
3979
4328
|
if (cached) return cached;
|
|
3980
4329
|
const inFlight = this.inFlightX402.get(idempotencyKey);
|
|
3981
4330
|
if (inFlight) {
|
|
3982
4331
|
if (!sameX402TaskBudget(this.inFlightX402TaskBudget.get(idempotencyKey), options.taskBudgetId) || !sameX402TaskBudget(this.inFlightX402SubBudget.get(idempotencyKey), options.subBudgetId)) {
|
|
3983
|
-
throw new
|
|
4332
|
+
throw new chunkZA3NOSO2_cjs.X402TaskBudgetMismatchError(
|
|
3984
4333
|
`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.`,
|
|
3985
4334
|
idempotencyKey,
|
|
3986
4335
|
this.inFlightX402TaskBudget.get(idempotencyKey),
|
|
@@ -4035,16 +4384,16 @@ var HavenClient = class {
|
|
|
4035
4384
|
if (err instanceof MerchantEgressResponseCapError) throw err;
|
|
4036
4385
|
body = void 0;
|
|
4037
4386
|
}
|
|
4038
|
-
throw new
|
|
4387
|
+
throw new chunkZA3NOSO2_cjs.X402UnexpectedStatusError(
|
|
4039
4388
|
`Expected an x402 quote response with HTTP 402, got HTTP ${response.status}.`,
|
|
4040
4389
|
response.status || 400,
|
|
4041
4390
|
body
|
|
4042
4391
|
);
|
|
4043
4392
|
}
|
|
4044
4393
|
if (response.headers.get("MACHINE-PAYMENT-CHALLENGE")) {
|
|
4045
|
-
throw new
|
|
4394
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError("quoteX402 only supports standard x402 Payment Required responses.", 400);
|
|
4046
4395
|
}
|
|
4047
|
-
const paymentRequired = await
|
|
4396
|
+
const paymentRequired = await chunkV2ODMLDD_cjs.parsePaymentRequiredResponse(response);
|
|
4048
4397
|
const mcpTransport = await this.merchantTransport.detect(url, paymentRequired, response);
|
|
4049
4398
|
return buildX402Quote(paymentRequired, request, options.idempotencyKey, mcpTransport);
|
|
4050
4399
|
}
|
|
@@ -4062,7 +4411,7 @@ var HavenClient = class {
|
|
|
4062
4411
|
const wallet = await this.merchantCompletion.resolveWalletForMerchantCall();
|
|
4063
4412
|
const sessionId = await this.merchantTransport.initialize(url, init, wallet);
|
|
4064
4413
|
if (!sessionId) {
|
|
4065
|
-
throw new
|
|
4414
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError(
|
|
4066
4415
|
"The merchant did not establish an MCP session before the x402 quote. No payment was created.",
|
|
4067
4416
|
502,
|
|
4068
4417
|
{ mcpSessionNotEstablished: true }
|
|
@@ -4136,18 +4485,18 @@ var HavenClient = class {
|
|
|
4136
4485
|
}
|
|
4137
4486
|
async resumeAuthorizedX402(input) {
|
|
4138
4487
|
if (!this.delegateKey) {
|
|
4139
|
-
throw new
|
|
4488
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError(
|
|
4140
4489
|
"delegateKey is required for x402 payments. Pass it in the HavenClient config."
|
|
4141
4490
|
);
|
|
4142
4491
|
}
|
|
4143
4492
|
if (!this.delegateAddress) {
|
|
4144
|
-
throw new
|
|
4493
|
+
throw new chunkZA3NOSO2_cjs.HavenSigningError("delegateAddress could not be derived from delegateKey.");
|
|
4145
4494
|
}
|
|
4146
|
-
const option =
|
|
4495
|
+
const option = chunkV2ODMLDD_cjs.selectStandardPaymentOption(input.paymentRequired.accepts);
|
|
4147
4496
|
if (!option) {
|
|
4148
4497
|
throw noCompatiblePaymentOptionError(input.paymentRequired.accepts);
|
|
4149
4498
|
}
|
|
4150
|
-
const idempotencyKey = input.idempotencyKey ??
|
|
4499
|
+
const idempotencyKey = input.idempotencyKey ?? chunkV2ODMLDD_cjs.buildX402IdempotencyKey(input.paymentRequired, option);
|
|
4151
4500
|
const cached = this.fundingLeg.cachedReceipt(idempotencyKey, input.taskBudgetId);
|
|
4152
4501
|
if (cached) return cached;
|
|
4153
4502
|
const status = await this.getPaymentStatus(input.paymentId);
|
|
@@ -4155,10 +4504,10 @@ var HavenClient = class {
|
|
|
4155
4504
|
const canFund = await this.fundingLeg.delegateCanFund(
|
|
4156
4505
|
status.chainId ?? chainIdFromNetwork(option.network),
|
|
4157
4506
|
option.asset,
|
|
4158
|
-
|
|
4507
|
+
chunkV2ODMLDD_cjs.x402AuthorizationAmount(option)
|
|
4159
4508
|
);
|
|
4160
4509
|
if (canFund === false) {
|
|
4161
|
-
throw new
|
|
4510
|
+
throw new chunkZA3NOSO2_cjs.X402AlreadySettledError(
|
|
4162
4511
|
`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.`,
|
|
4163
4512
|
this.fundingLeg.receiptFromStatus(input.paymentRequired, option, void 0, status),
|
|
4164
4513
|
"settled"
|
|
@@ -4179,13 +4528,13 @@ var HavenClient = class {
|
|
|
4179
4528
|
const url = input.url ?? input.request?.url;
|
|
4180
4529
|
if (!paymentRequired) {
|
|
4181
4530
|
if (!url) {
|
|
4182
|
-
throw new
|
|
4531
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError("x402 resume requires the original URL or a captured request snapshot.", 400);
|
|
4183
4532
|
}
|
|
4184
4533
|
const response = await this.merchantTransport.fetch(url, initialInit, this.merchantTransport.budgetFor("quote"), this.merchantTransport.capFor("quote"));
|
|
4185
4534
|
if (response.status !== 402) {
|
|
4186
|
-
throw new
|
|
4535
|
+
throw new chunkZA3NOSO2_cjs.HavenApiError("Expected the original x402 request to return HTTP 402 before resuming.", 400);
|
|
4187
4536
|
}
|
|
4188
|
-
paymentRequired = await
|
|
4537
|
+
paymentRequired = await chunkV2ODMLDD_cjs.parsePaymentRequiredResponse(response);
|
|
4189
4538
|
}
|
|
4190
4539
|
const receipt = await this.resumeAuthorizedX402({
|
|
4191
4540
|
paymentId: input.paymentId,
|
|
@@ -4238,7 +4587,7 @@ var HavenClient = class {
|
|
|
4238
4587
|
nativeChallenge = true;
|
|
4239
4588
|
} else {
|
|
4240
4589
|
try {
|
|
4241
|
-
paymentRequired = await
|
|
4590
|
+
paymentRequired = await chunkV2ODMLDD_cjs.parsePaymentRequiredResponse(response);
|
|
4242
4591
|
} catch (err) {
|
|
4243
4592
|
if (err instanceof MerchantEgressResponseCapError) throw err;
|
|
4244
4593
|
return response;
|
|
@@ -4249,8 +4598,8 @@ var HavenClient = class {
|
|
|
4249
4598
|
if (mcpSessionId) requestInit = this.merchantTransport.withSessionHeaders(requestInit, mcpSessionId);
|
|
4250
4599
|
}
|
|
4251
4600
|
const request = snapshotX402Request(url, requestInit);
|
|
4252
|
-
const option =
|
|
4253
|
-
const idempotencyKey = options.idempotencyKey ?? (option ?
|
|
4601
|
+
const option = chunkV2ODMLDD_cjs.selectStandardPaymentOption(paymentRequired.accepts);
|
|
4602
|
+
const idempotencyKey = options.idempotencyKey ?? (option ? chunkV2ODMLDD_cjs.buildX402IdempotencyKey(paymentRequired, option) : void 0);
|
|
4254
4603
|
let receipt;
|
|
4255
4604
|
try {
|
|
4256
4605
|
receipt = await this.authorizeX402(paymentRequired, options);
|
|
@@ -4341,13 +4690,15 @@ var HavenClient = class {
|
|
|
4341
4690
|
body = text;
|
|
4342
4691
|
}
|
|
4343
4692
|
const toolResult = mcpToolResultOf(body);
|
|
4344
|
-
const inBandChallenge = toolResult ? extractMcpPaymentRequired(toolResult) : void 0;
|
|
4345
4693
|
const metaSettlement = toolResult ? mcpSettlementFromToolResult(toolResult) : void 0;
|
|
4346
4694
|
const headerReceipt = surfaced.headers.get("PAYMENT-RESPONSE") ?? void 0;
|
|
4347
|
-
const
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4695
|
+
const answer = decidePostFundingMerchantAnswer({
|
|
4696
|
+
toolResult,
|
|
4697
|
+
httpOk: surfaced.ok,
|
|
4698
|
+
paymentResponseHeader: headerReceipt,
|
|
4699
|
+
metaSettlement
|
|
4700
|
+
});
|
|
4701
|
+
const merchantAccepted = answer.accepted;
|
|
4351
4702
|
let evidenceOutcome;
|
|
4352
4703
|
let settlementEvidenceOutcome;
|
|
4353
4704
|
if (!merchantAccepted) {
|
|
@@ -4369,7 +4720,7 @@ var HavenClient = class {
|
|
|
4369
4720
|
});
|
|
4370
4721
|
}
|
|
4371
4722
|
} else {
|
|
4372
|
-
const rawEvidenceTxHash = input.noFundingLeg ?
|
|
4723
|
+
const rawEvidenceTxHash = input.noFundingLeg ? answer.settlementTxHash ?? void 0 : fundingTxHash ?? void 0;
|
|
4373
4724
|
const evidenceTxHash = rawEvidenceTxHash && !isZeroSettlementTxHash(rawEvidenceTxHash) ? rawEvidenceTxHash : void 0;
|
|
4374
4725
|
if (evidenceTxHash) {
|
|
4375
4726
|
evidenceOutcome = await this.merchantCompletion.reportEvidence({
|
|
@@ -4378,21 +4729,22 @@ var HavenClient = class {
|
|
|
4378
4729
|
txHash: evidenceTxHash,
|
|
4379
4730
|
resourceUrl: evidenceContext.resourceUrl,
|
|
4380
4731
|
merchantStatus: surfaced.status,
|
|
4381
|
-
paymentProofHeaderName:
|
|
4732
|
+
paymentProofHeaderName: chunkV2ODMLDD_cjs.x402PaymentHeaderNamesSent(input.paymentHeader),
|
|
4382
4733
|
paymentProofHeader: input.paymentHeader,
|
|
4383
|
-
protocolReceiptHeaderName,
|
|
4384
|
-
protocolReceiptHeader,
|
|
4734
|
+
protocolReceiptHeaderName: answer.protocolReceiptHeaderName,
|
|
4735
|
+
protocolReceiptHeader: answer.protocolReceiptHeader,
|
|
4385
4736
|
// #3778: the delivery pointer rides the accepted arm's evidence
|
|
4386
4737
|
// report — a rejection delivered nothing to point at.
|
|
4387
4738
|
...input.deliveryReference ? { deliveryReference: input.deliveryReference } : {}
|
|
4388
4739
|
});
|
|
4389
4740
|
}
|
|
4390
4741
|
if (!input.noFundingLeg) {
|
|
4391
|
-
const settlementCandidate =
|
|
4742
|
+
const settlementCandidate = answer.settlementTxHash;
|
|
4392
4743
|
if (settlementCandidate && isWellFormedSettlementTxHash(settlementCandidate) && !isZeroSettlementTxHash(settlementCandidate) && fundingTxHash && settlementCandidate.toLowerCase() !== fundingTxHash.toLowerCase()) {
|
|
4393
4744
|
settlementEvidenceOutcome = await this.merchantCompletion.reportSettlementEvidenceOnce(
|
|
4394
4745
|
evidenceContext.paymentId,
|
|
4395
|
-
settlementCandidate
|
|
4746
|
+
settlementCandidate,
|
|
4747
|
+
input.paymentHeader
|
|
4396
4748
|
);
|
|
4397
4749
|
}
|
|
4398
4750
|
}
|
|
@@ -4403,7 +4755,7 @@ var HavenClient = class {
|
|
|
4403
4755
|
ok: merchantAccepted,
|
|
4404
4756
|
body,
|
|
4405
4757
|
// #3155 review S3: a transaction beside a rejection is not a settlement.
|
|
4406
|
-
settlementTxHash: merchantAccepted ?
|
|
4758
|
+
settlementTxHash: merchantAccepted ? answer.settlementTxHash ?? void 0 : void 0,
|
|
4407
4759
|
evidenceOutcome,
|
|
4408
4760
|
settlementEvidenceOutcome
|
|
4409
4761
|
};
|
|
@@ -4436,9 +4788,15 @@ var HavenClient = class {
|
|
|
4436
4788
|
* Haven verifies the delegate → merchant transfer on-chain
|
|
4437
4789
|
* (`observeEip3009MerchantSettlement`) and records it beside the funding
|
|
4438
4790
|
* hash, so receipts name the merchant's settlement.
|
|
4791
|
+
*
|
|
4792
|
+
* #4061: on eip3009 pass `options.paymentHeader` — the payment header you
|
|
4793
|
+
* sent the merchant on your paid retry. Since #3925 it is the proof the
|
|
4794
|
+
* settlement is recorded against; without it the report is `refused` with
|
|
4795
|
+
* `errorCode: 'settlement_proof_header_missing'`, and repeating it WITH the
|
|
4796
|
+
* header can succeed.
|
|
4439
4797
|
*/
|
|
4440
|
-
async reportSettlementEvidence(paymentId, settlementTxHash) {
|
|
4441
|
-
return await this.merchantCompletion.reportSettlementEvidence(paymentId, settlementTxHash);
|
|
4798
|
+
async reportSettlementEvidence(paymentId, settlementTxHash, options = {}) {
|
|
4799
|
+
return await this.merchantCompletion.reportSettlementEvidence(paymentId, settlementTxHash, options);
|
|
4442
4800
|
}
|
|
4443
4801
|
/**
|
|
4444
4802
|
* #3770: record the agent's evidence-only delivery verdict on a settled
|
|
@@ -4497,7 +4855,7 @@ var HavenClient = class {
|
|
|
4497
4855
|
try {
|
|
4498
4856
|
raw = await this.get(`/x402/by-idempotency-key/${encodeURIComponent(key)}`);
|
|
4499
4857
|
} catch (err) {
|
|
4500
|
-
if (err instanceof
|
|
4858
|
+
if (err instanceof chunkZA3NOSO2_cjs.HavenApiError && err.statusCode === 404) return null;
|
|
4501
4859
|
throw err;
|
|
4502
4860
|
}
|
|
4503
4861
|
return {
|
|
@@ -4673,7 +5031,7 @@ var toolDescriptions = {
|
|
|
4673
5031
|
getAgent: {
|
|
4674
5032
|
summary: "Return the authenticated agent identity AND its live spend authority in one call: Haven wallet, delegate, chain, raw status, spend_authority_readiness, per-token remaining allowance (atomic + human-readable). The recommended first call in a new session.",
|
|
4675
5033
|
selectionGuidance: "Use this as the session bootstrap, or to confirm identity together with whether the agent has spend authority right now. For per-token detail (configured vs spent vs reset window) use haven_get_allowances.",
|
|
4676
|
-
behavior: `Reads identity plus the live spend-authority snapshot \u2014 the active on-chain budget delegation. spend_authority_readiness (readiness is a deprecated alias, same value) is "ready" when at least one token has remaining spend authority, "needs_approval" when the agent is active but has none, and "revoked" when the credential is not active. Readiness is AUTHORITY
|
|
5034
|
+
behavior: `Reads identity plus the live spend-authority snapshot \u2014 the active on-chain budget delegation. spend_authority_readiness (readiness is a deprecated alias, same value) is "ready" when at least one token has remaining spend authority, "needs_approval" when the agent is active but has none, and "revoked" when the credential is not active. needs_approval with no allowances[] rows and budgetEndedAt set: the budget ENDED on that date \u2014 ask the owner to set a new one, waiting will not help; with no rows and no budgetEndedAt: nothing approved yet; with rows: spent for this period, refilling at budgetRefillsAt (null: it ends first). Readiness is AUTHORITY \u2014 a budget is live, not that funds are held. Each allowances[] row carries fundsCoverRemaining: false when the account's balance cannot back that row's whole remaining budget \u2014 a heads-up to mention, not a refusal (budgets above the balance are normal; an owner may top up weekly) \u2014 and null when the coverage read failed or the remaining was not read live; the key is absent at remaining 0, and rows for one token are compared alone. Covers hosted identity + on-chain spend authority ONLY \u2014 the hosted server cannot see the LOCAL signer, so "ready" does not mean the signer can start; verify it with a signer tool call or connect --doctor. An over-budget payment is declined before any money moves; there is no approval queue \u2014 ask the owner to grant or raise the budget. allowances[] carries id, tokenAddress, remainingAtomic, remainingDisplay, nextRefillAt per token. taskBudgets[] rows carry maxAtomic/maxDisplay plus spentAtomic/remainingAtomic/remainingDisplay \u2014 what the chain still allows that budget \u2014 and remainingIsFromChain: false marks a failed read (figures null, never the cap); only live rows are listed, each with its status (pending | open | closing) and isExpired. pendingSubBudgetSignatures[] lists sub-budget rows awaiting YOUR signature, with the haven_sign step. Identity fields: id, name, status, accountAddress, delegateAddress, chainId.`,
|
|
4677
5035
|
nextActionGuidance: ""
|
|
4678
5036
|
},
|
|
4679
5037
|
getAllowances: {
|
|
@@ -4687,7 +5045,7 @@ var toolDescriptions = {
|
|
|
4687
5045
|
checkFunds: {
|
|
4688
5046
|
summary: "Check whether the agent's account actually holds at least the given amount of a token \u2014 funds held, not spend permitted.",
|
|
4689
5047
|
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.",
|
|
4690
|
-
behavior: "Returns covered: true (the account holds at least the checked amount), false (a live chain read reports
|
|
5048
|
+
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.",
|
|
4691
5049
|
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."
|
|
4692
5050
|
},
|
|
4693
5051
|
listReceipts: {
|
|
@@ -4715,9 +5073,9 @@ var toolDescriptions = {
|
|
|
4715
5073
|
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."
|
|
4716
5074
|
},
|
|
4717
5075
|
discoverTools: {
|
|
4718
|
-
summary: "Step 1 of a purchase: discover payable services from Haven's
|
|
4719
|
-
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 (
|
|
4720
|
-
behavior: "Use each entry's suggested_tool + suggested_arguments first; an entry without them says why. Read-only lookup against Haven's
|
|
5076
|
+
summary: "Step 1 of a purchase: discover payable services from Haven's merchant catalog \u2014 names, prices, the next call.",
|
|
5077
|
+
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.",
|
|
5078
|
+
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.",
|
|
4721
5079
|
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.`
|
|
4722
5080
|
},
|
|
4723
5081
|
submitCatalogEntry: {
|
|
@@ -4740,8 +5098,8 @@ var toolDescriptions = {
|
|
|
4740
5098
|
},
|
|
4741
5099
|
reportSettlementEvidence: {
|
|
4742
5100
|
summary: "Report a payment's real merchant settlement transaction hash so Haven can verify it on-chain and record it.",
|
|
4743
|
-
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.",
|
|
4744
|
-
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."
|
|
5101
|
+
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.",
|
|
5102
|
+
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."
|
|
4745
5103
|
}
|
|
4746
5104
|
};
|
|
4747
5105
|
|
|
@@ -4995,13 +5353,13 @@ You are an AI agent whose user has no Haven account yet, or has one but has not
|
|
|
4995
5353
|
|
|
4996
5354
|
## What Haven is, in three sentences
|
|
4997
5355
|
|
|
4998
|
-
Your user gives you a **budget on their own account** \u2014 not their wallet, and not a key to their funds. The budget is a delegation they sign, enforced on-chain: a payment over it, to the wrong recipient, or past its expiry is refused at execution time, not by a dashboard promise. Haven constructs and relays the payments; you get an agent credential and a signing key made on your machine, and your user can revoke the budget without you and without Haven.
|
|
5356
|
+
Your user gives you a **budget on their own account** \u2014 not their wallet, and not a key to their funds. The budget is a delegation they sign, enforced on-chain: a payment over it, to the wrong recipient, or past its expiry is refused at execution time, not by a dashboard promise. The budget also ENDS on a date your user chooses \u2014 30, 90 (default), 180 or 365 days out \u2014 and that day is enforced on-chain too. When the budget ends, your authority to pay ends with it; ask your user to renew it (a new approval on the agent's page, or a new \`budget grant\`). Haven constructs and relays the payments; you get an agent credential and a signing key made on your machine, and your user can revoke the budget without you and without Haven.
|
|
4999
5357
|
|
|
5000
5358
|
## The sequence
|
|
5001
5359
|
|
|
5002
5360
|
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.
|
|
5003
5361
|
|
|
5004
|
-
1. **HUMAN \u2014 create the account.** Name, email, password, then a passkey
|
|
5362
|
+
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.
|
|
5005
5363
|
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.
|
|
5006
5364
|
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.
|
|
5007
5365
|
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.
|
|
@@ -5025,7 +5383,7 @@ Send these as your own message, \`<host>\` replaced by the host you fetched this
|
|
|
5025
5383
|
|
|
5026
5384
|
**Before signup** (step 1):
|
|
5027
5385
|
|
|
5028
|
-
> 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
|
|
5386
|
+
> 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\`.
|
|
5029
5387
|
|
|
5030
5388
|
**At the passkey step:**
|
|
5031
5389
|
|
|
@@ -5068,7 +5426,7 @@ If the approval wait times out, nothing is lost \u2014 your agent is registered
|
|
|
5068
5426
|
Call \`haven_get_agent\`, one of the Haven MCP tools the connector wires into your runtime in step 4. It returns identity plus \`spend_authority_readiness\`:
|
|
5069
5427
|
|
|
5070
5428
|
- \`ready\` \u2014 a budget is live: you have the authority to pay. It does not say the account holds funds \u2014 the \`allowances[]\` rows carry \`funds_cover_remaining\`, and \`false\` there is a heads-up to mention to your user, not a refusal.
|
|
5071
|
-
- \`needs_approval\` \u2014
|
|
5429
|
+
- \`needs_approval\` \u2014 no budget can pay. \`allowances[]\` empty with \`budgetEndedAt\` set: your budget ENDED on that date; waiting will not help \u2014 ask your user to set a new one in their Haven tab. \`allowances[]\` empty with \`budgetEndedAt\` null: nobody approved one yet; ask your user again \u2014 there is no queue. Rows, all spent: it refills at \`budgetRefillsAt\`; tell your user, then wait or ask them to raise it (\`null\`: it ends first; ask them to renew it).
|
|
5072
5430
|
- \`revoked\` \u2014 the credential is not active; ask your user to create a new agent.
|
|
5073
5431
|
|
|
5074
5432
|
\`ready\` covers hosted identity and the budget only, not your local signer. Check that with \`npx -y @haven_ai/connect@<channel> --doctor\`, the same tag your prompt named \u2014 a separate command, so the command-modification rule does not bind it.
|
|
@@ -5104,7 +5462,7 @@ Then:
|
|
|
5104
5462
|
1. Run \`<packages.cli.one_liner> login\`. 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. It prints a link and a code and does not need my password \u2014 it must never ask for it. Give me the link straight away and wait for me to approve it in my browser.
|
|
5105
5463
|
2. Once I have approved, run \`haven agents connect --name <a name you choose> --budget <amount> --token USDC --period <minutes>\` with the budget I tell you. If I have not given you one, ask me before running it. Add \`--run\` to complete the connection in the same step.
|
|
5106
5464
|
3. ${AGENT_APPROVAL_RELAY_JSON_SENTENCE}
|
|
5107
|
-
4. Once I have approved the budget, verify with the \`haven_get_agent\` tool: \`ready\` means I have given you the authority to pay \u2014 it does not confirm the account holds funds, so if its allowances rows carry \`funds_cover_remaining: false\`, tell me and still try the payment; \`needs_approval\` means my approval has not landed yet.
|
|
5465
|
+
4. Once I have approved the budget, verify with the \`haven_get_agent\` tool: \`ready\` means I have given you the authority to pay \u2014 it does not confirm the account holds funds, so if its allowances rows carry \`funds_cover_remaining: false\`, tell me and still try the payment; \`needs_approval\` with no allowances rows and \`budgetEndedAt\` set means my budget ended on that date \u2014 tell me, and I will set a new one; with no rows and no \`budgetEndedAt\`, my approval has not landed yet; with rows, the budget is spent \u2014 it refills at \`budgetRefillsAt\` (\`null\`: it ends first), so tell me, and I can raise or renew it.
|
|
5108
5466
|
|
|
5109
5467
|
Two things only I can do: approving that budget with my passkey, and funding the account with USDC \u2014 no ETH, Haven sponsors the gas. Tell me if either is missing rather than working around it.
|
|
5110
5468
|
|
|
@@ -5224,8 +5582,10 @@ Do not guess the wallet address, network, or budget.
|
|
|
5224
5582
|
|
|
5225
5583
|
For instant orientation at the start of a session, read the non-secret
|
|
5226
5584
|
\`agent.json\` the connector wrote to your Haven credential directory (typically
|
|
5227
|
-
\`~/.haven/agents/<
|
|
5228
|
-
|
|
5585
|
+
\`~/.haven/agents/<slug>/agent.json\`, where \`<slug>\` is the wiring name of the
|
|
5586
|
+
\`haven-<slug>\` pair \u2014 only a \`--bare\` run, or a \`--replace\` without \`--name\`,
|
|
5587
|
+
names the directory by the agent id instead; if you don't know the folder, list
|
|
5588
|
+
\`~/.haven/agents/\` to find it). It
|
|
5229
5589
|
holds your agent id, Haven wallet address, network, and *configured* per-token
|
|
5230
5590
|
budget, and contains no keys \u2014 the fastest way to answer "who am I and what may
|
|
5231
5591
|
I spend" with no round trip. If that file is absent (some setups don't write
|
|
@@ -5246,7 +5606,13 @@ spending:
|
|
|
5246
5606
|
the user, not a refusal \u2014 a budget above the balance is a normal setup, so
|
|
5247
5607
|
still try the payment; \`null\` means the coverage read failed or the remaining
|
|
5248
5608
|
figure was not read live; the key is absent when the remaining is 0. Rows for
|
|
5249
|
-
one token are compared alone.
|
|
5609
|
+
one token are compared alone. \`needs_approval\` with no \`allowances[]\`
|
|
5610
|
+
rows and \`budgetEndedAt\` set means the budget ENDED on that date \u2014 waiting
|
|
5611
|
+
will not help, ask the owner to set a new one; with no rows and no
|
|
5612
|
+
\`budgetEndedAt\`, nobody approved a budget yet; with rows (all at remaining 0) the
|
|
5613
|
+
budget is spent for this period, and \`budgetRefillsAt\` says when it refills
|
|
5614
|
+
(\`null\`: it ends before it refills) \u2014 tell the user, then wait or ask them
|
|
5615
|
+
to raise it.
|
|
5250
5616
|
- \`mcp__haven__haven_get_allowances\` \u2014 detailed per-token breakdown
|
|
5251
5617
|
(configured, spent, reset window) when you need more than the summary.
|
|
5252
5618
|
- \`mcp__haven__haven_check_funds\` \u2014 whether the account actually HOLDS at
|
|
@@ -5393,10 +5759,13 @@ request, this is the only way it can learn the purchase failed \u2014 without it
|
|
|
5393
5759
|
failed purchase reads as complete for fifteen minutes. If the merchant's
|
|
5394
5760
|
\`PAYMENT-RESPONSE\` header names a \`transaction\`, pass that raw header as
|
|
5395
5761
|
\`payment_response\` on the SAME \`mcp__haven__haven_report_x402_outcome\`
|
|
5396
|
-
call
|
|
5397
|
-
|
|
5762
|
+
call, together with \`payment_header\`: the exact header you retried the
|
|
5763
|
+
merchant with. Haven records a reported settlement only with that header,
|
|
5764
|
+
which proves the settlement is this payment's. It decodes the response,
|
|
5765
|
+
verifies the settlement on-chain, and the receipt then shows the merchant's
|
|
5766
|
+
settlement, not only the funding transaction. Call
|
|
5398
5767
|
\`mcp__haven__haven_report_settlement_evidence\` only when the outcome answer
|
|
5399
|
-
names it as the next step. On the **erc7710** scheme (the pay result says
|
|
5768
|
+
names it as the next step, and pass the same \`payment_header\` there too. On the **erc7710** scheme (the pay result says
|
|
5400
5769
|
\`settlement_scheme: "erc7710"\`), sign with \`mcp__haven-signer__haven_sign\`,
|
|
5401
5770
|
then \`mcp__haven__haven_submit\` with \`settlement_scheme: "erc7710"\`
|
|
5402
5771
|
returns the \`payment_header\`; retry the merchant yourself with it as
|
|
@@ -5426,7 +5795,9 @@ for example, an invoice carrying an \`x402_payment_url\` to POST with its
|
|
|
5426
5795
|
\`invoice_id\`, beside a raw deposit address and a web payment link.
|
|
5427
5796
|
- **Quote the exact request:** \`mcp__haven__haven_quote_x402\` with \`url\`,
|
|
5428
5797
|
\`method\`, \`headers\` and \`body\`, exactly as the merchant described it.
|
|
5429
|
-
\`body\` is a JSON **string**, not an object.
|
|
5798
|
+
\`body\` is a JSON **string**, not an object. When the price is stated up
|
|
5799
|
+
front (an invoice total, say), also pass \`expected_amount\` \u2014 the price you
|
|
5800
|
+
expect, in whole tokens (\`"0.10"\`). On a JSON POST always pass
|
|
5430
5801
|
\`headers: {"Content-Type": "application/json"}\` \u2014 the tool does not infer
|
|
5431
5802
|
it, and a merchant may answer a request without it with a generic challenge
|
|
5432
5803
|
Haven cannot pay (for example, only the \`upto\` scheme).
|
|
@@ -5455,6 +5826,18 @@ for example, an invoice carrying an \`x402_payment_url\` to POST with its
|
|
|
5455
5826
|
report it, the merchant's settlement evidence. (A deposit transfer is bound
|
|
5456
5827
|
to its payee and amount on-chain too; the difference is the record, not
|
|
5457
5828
|
the binding.)
|
|
5829
|
+
- **If the quote says stop, stop.** The hosted quote checks the agent's
|
|
5830
|
+
remaining budget at quote time, and it can check a price you state
|
|
5831
|
+
(\`expected_amount\`). On the local runtime (\`@haven_ai/mcp\`) the quote
|
|
5832
|
+
checks only a price you state; the budget is checked when you pay.
|
|
5833
|
+
When it returns \`safe_to_continue: false\` \u2014 the amount exceeds the budget, or
|
|
5834
|
+
the price does not match what you expected \u2014 it prefills no cap and names no
|
|
5835
|
+
next tool: stop and tell the user. If the x402 challenge itself is wrong (a
|
|
5836
|
+
price wildly off the invoice) and NOTHING has been paid via x402, the
|
|
5837
|
+
invoice's own deposit address MAY be an alternative, but only with the
|
|
5838
|
+
user's explicit go-ahead \u2014 never automatically. Once an x402 payment has
|
|
5839
|
+
been attempted or refused, never pay the deposit address: it can pay the
|
|
5840
|
+
invoice twice.
|
|
5458
5841
|
- **Pay exactly one route, and never fall back silently.** If the x402 route
|
|
5459
5842
|
is refused or fails, do not then pay the deposit address \u2014 that pays the
|
|
5460
5843
|
invoice twice. Follow the result's guidance fields instead: on EIP-3009, a
|
|
@@ -5591,8 +5974,8 @@ only part of it was usable), and an optional \`note\` (max 2000 characters)
|
|
|
5591
5974
|
saying what was wrong. It is evidence only: it moves no money, never changes
|
|
5592
5975
|
\`settled\` or any money field, and works only on your own settled
|
|
5593
5976
|
payments \u2014 another agent's payment is refused. A re-report replaces your
|
|
5594
|
-
earlier verdict; the receipt then carries it beside the payment, so
|
|
5595
|
-
|
|
5977
|
+
earlier verdict; the receipt then carries it beside the payment, so a junk
|
|
5978
|
+
delivery does not read as a success.
|
|
5596
5979
|
### Relay a delivered code or credential to the owner \u2014 immediately, verbatim
|
|
5597
5980
|
|
|
5598
5981
|
If a merchant response carries what the user PAID FOR \u2014 a redemption code, gift
|
|
@@ -5664,7 +6047,7 @@ async function discoverMerchantMcpUrl(inputUrl, egress) {
|
|
|
5664
6047
|
} catch (err) {
|
|
5665
6048
|
if (err instanceof MerchantEgressRefusedError || err instanceof MerchantEgressResponseCapError) throw err;
|
|
5666
6049
|
if (isBodyPhaseTimeout(err)) {
|
|
5667
|
-
throw new
|
|
6050
|
+
throw new chunkZA3NOSO2_cjs.MerchantTimeoutError(`Merchant discovery document read timed out after ${timeoutMs}ms.`);
|
|
5668
6051
|
}
|
|
5669
6052
|
continue;
|
|
5670
6053
|
}
|
|
@@ -5683,499 +6066,507 @@ function sameUrl(a, b) {
|
|
|
5683
6066
|
|
|
5684
6067
|
Object.defineProperty(exports, "DEFAULT_NEXT_TOOL_BY_ACTION", {
|
|
5685
6068
|
enumerable: true,
|
|
5686
|
-
get: function () { return
|
|
6069
|
+
get: function () { return chunkV2ODMLDD_cjs.DEFAULT_NEXT_TOOL_BY_ACTION; }
|
|
5687
6070
|
});
|
|
5688
6071
|
Object.defineProperty(exports, "ERC7710_ASSET_TRANSFER_METHOD", {
|
|
5689
6072
|
enumerable: true,
|
|
5690
|
-
get: function () { return
|
|
6073
|
+
get: function () { return chunkV2ODMLDD_cjs.ERC7710_ASSET_TRANSFER_METHOD; }
|
|
5691
6074
|
});
|
|
5692
6075
|
Object.defineProperty(exports, "HAVEN_CLIENT_HEADER", {
|
|
5693
6076
|
enumerable: true,
|
|
5694
|
-
get: function () { return
|
|
6077
|
+
get: function () { return chunkV2ODMLDD_cjs.HAVEN_CLIENT_HEADER; }
|
|
5695
6078
|
});
|
|
5696
6079
|
Object.defineProperty(exports, "HAVEN_MINIMUM_NODE_VERSION", {
|
|
5697
6080
|
enumerable: true,
|
|
5698
|
-
get: function () { return
|
|
6081
|
+
get: function () { return chunkV2ODMLDD_cjs.HAVEN_MINIMUM_NODE_VERSION; }
|
|
5699
6082
|
});
|
|
5700
6083
|
Object.defineProperty(exports, "HavenTypedDataRefusedError", {
|
|
5701
6084
|
enumerable: true,
|
|
5702
|
-
get: function () { return
|
|
6085
|
+
get: function () { return chunkV2ODMLDD_cjs.HavenTypedDataRefusedError; }
|
|
5703
6086
|
});
|
|
5704
6087
|
Object.defineProperty(exports, "MAX_TASK_BUDGET_TTL_SECONDS", {
|
|
5705
6088
|
enumerable: true,
|
|
5706
|
-
get: function () { return
|
|
6089
|
+
get: function () { return chunkV2ODMLDD_cjs.MAX_TASK_BUDGET_TTL_SECONDS; }
|
|
5707
6090
|
});
|
|
5708
6091
|
Object.defineProperty(exports, "NEXT_TOOL_SERVER_NAMES", {
|
|
5709
6092
|
enumerable: true,
|
|
5710
|
-
get: function () { return
|
|
6093
|
+
get: function () { return chunkV2ODMLDD_cjs.NEXT_TOOL_SERVER_NAMES; }
|
|
5711
6094
|
});
|
|
5712
6095
|
Object.defineProperty(exports, "NEXT_TOOL_SERVER_ROLES", {
|
|
5713
6096
|
enumerable: true,
|
|
5714
|
-
get: function () { return
|
|
6097
|
+
get: function () { return chunkV2ODMLDD_cjs.NEXT_TOOL_SERVER_ROLES; }
|
|
5715
6098
|
});
|
|
5716
6099
|
Object.defineProperty(exports, "SDK_CLIENT_IDENTITY", {
|
|
5717
6100
|
enumerable: true,
|
|
5718
|
-
get: function () { return
|
|
6101
|
+
get: function () { return chunkV2ODMLDD_cjs.SDK_CLIENT_IDENTITY; }
|
|
5719
6102
|
});
|
|
5720
6103
|
Object.defineProperty(exports, "SDK_VERSION", {
|
|
5721
6104
|
enumerable: true,
|
|
5722
|
-
get: function () { return
|
|
6105
|
+
get: function () { return chunkV2ODMLDD_cjs.SDK_VERSION; }
|
|
5723
6106
|
});
|
|
5724
6107
|
Object.defineProperty(exports, "SWEEP_BASE_CHAIN_ID", {
|
|
5725
6108
|
enumerable: true,
|
|
5726
|
-
get: function () { return
|
|
6109
|
+
get: function () { return chunkV2ODMLDD_cjs.SWEEP_BASE_CHAIN_ID; }
|
|
5727
6110
|
});
|
|
5728
6111
|
Object.defineProperty(exports, "SWEEP_BASE_SEPOLIA_CHAIN_ID", {
|
|
5729
6112
|
enumerable: true,
|
|
5730
|
-
get: function () { return
|
|
6113
|
+
get: function () { return chunkV2ODMLDD_cjs.SWEEP_BASE_SEPOLIA_CHAIN_ID; }
|
|
5731
6114
|
});
|
|
5732
6115
|
Object.defineProperty(exports, "SWEEP_BASE_SEPOLIA_USDC_ADDRESS", {
|
|
5733
6116
|
enumerable: true,
|
|
5734
|
-
get: function () { return
|
|
6117
|
+
get: function () { return chunkV2ODMLDD_cjs.SWEEP_BASE_SEPOLIA_USDC_ADDRESS; }
|
|
5735
6118
|
});
|
|
5736
6119
|
Object.defineProperty(exports, "SWEEP_BASE_USDC_ADDRESS", {
|
|
5737
6120
|
enumerable: true,
|
|
5738
|
-
get: function () { return
|
|
6121
|
+
get: function () { return chunkV2ODMLDD_cjs.SWEEP_BASE_USDC_ADDRESS; }
|
|
5739
6122
|
});
|
|
5740
6123
|
Object.defineProperty(exports, "TRANSFER_WITH_AUTHORIZATION_TYPES", {
|
|
5741
6124
|
enumerable: true,
|
|
5742
|
-
get: function () { return
|
|
6125
|
+
get: function () { return chunkV2ODMLDD_cjs.TRANSFER_WITH_AUTHORIZATION_TYPES; }
|
|
5743
6126
|
});
|
|
5744
6127
|
Object.defineProperty(exports, "TYPED_DATA_NOT_ALLOWED", {
|
|
5745
6128
|
enumerable: true,
|
|
5746
|
-
get: function () { return
|
|
6129
|
+
get: function () { return chunkV2ODMLDD_cjs.TYPED_DATA_NOT_ALLOWED; }
|
|
5747
6130
|
});
|
|
5748
6131
|
Object.defineProperty(exports, "X402PaymentHeaderValidationError", {
|
|
5749
6132
|
enumerable: true,
|
|
5750
|
-
get: function () { return
|
|
6133
|
+
get: function () { return chunkV2ODMLDD_cjs.X402PaymentHeaderValidationError; }
|
|
5751
6134
|
});
|
|
5752
6135
|
Object.defineProperty(exports, "X402_LEGACY_PAYMENT_HEADER_NAME", {
|
|
5753
6136
|
enumerable: true,
|
|
5754
|
-
get: function () { return
|
|
6137
|
+
get: function () { return chunkV2ODMLDD_cjs.X402_LEGACY_PAYMENT_HEADER_NAME; }
|
|
5755
6138
|
});
|
|
5756
6139
|
Object.defineProperty(exports, "X402_MAX_AUTHORIZATION_WINDOW_SECONDS", {
|
|
5757
6140
|
enumerable: true,
|
|
5758
|
-
get: function () { return
|
|
6141
|
+
get: function () { return chunkV2ODMLDD_cjs.X402_MAX_AUTHORIZATION_WINDOW_SECONDS; }
|
|
5759
6142
|
});
|
|
5760
6143
|
Object.defineProperty(exports, "X402_PAYMENT_HEADER_NAME", {
|
|
5761
6144
|
enumerable: true,
|
|
5762
|
-
get: function () { return
|
|
6145
|
+
get: function () { return chunkV2ODMLDD_cjs.X402_PAYMENT_HEADER_NAME; }
|
|
5763
6146
|
});
|
|
5764
6147
|
Object.defineProperty(exports, "X402_PAYMENT_HEADER_NAMES_SENT", {
|
|
5765
6148
|
enumerable: true,
|
|
5766
|
-
get: function () { return
|
|
6149
|
+
get: function () { return chunkV2ODMLDD_cjs.X402_PAYMENT_HEADER_NAMES_SENT; }
|
|
5767
6150
|
});
|
|
5768
6151
|
Object.defineProperty(exports, "X402_PAYMENT_NONCE_TAG", {
|
|
5769
6152
|
enumerable: true,
|
|
5770
|
-
get: function () { return
|
|
6153
|
+
get: function () { return chunkV2ODMLDD_cjs.X402_PAYMENT_NONCE_TAG; }
|
|
5771
6154
|
});
|
|
5772
6155
|
Object.defineProperty(exports, "X402_PAYMENT_REQUIRED_HEADER_NAME", {
|
|
5773
6156
|
enumerable: true,
|
|
5774
|
-
get: function () { return
|
|
6157
|
+
get: function () { return chunkV2ODMLDD_cjs.X402_PAYMENT_REQUIRED_HEADER_NAME; }
|
|
5775
6158
|
});
|
|
5776
6159
|
Object.defineProperty(exports, "X402_PAYMENT_RESPONSE_HEADER_NAME", {
|
|
5777
6160
|
enumerable: true,
|
|
5778
|
-
get: function () { return
|
|
6161
|
+
get: function () { return chunkV2ODMLDD_cjs.X402_PAYMENT_RESPONSE_HEADER_NAME; }
|
|
5779
6162
|
});
|
|
5780
6163
|
Object.defineProperty(exports, "X402_SETTLEMENT_FORWARD_MARGIN_SECONDS", {
|
|
5781
6164
|
enumerable: true,
|
|
5782
|
-
get: function () { return
|
|
6165
|
+
get: function () { return chunkV2ODMLDD_cjs.X402_SETTLEMENT_FORWARD_MARGIN_SECONDS; }
|
|
5783
6166
|
});
|
|
5784
6167
|
Object.defineProperty(exports, "assertBoundDirectPaymentUserOp", {
|
|
5785
6168
|
enumerable: true,
|
|
5786
|
-
get: function () { return
|
|
6169
|
+
get: function () { return chunkV2ODMLDD_cjs.assertBoundDirectPaymentUserOp; }
|
|
5787
6170
|
});
|
|
5788
6171
|
Object.defineProperty(exports, "assertOwnTaskBudgetCloseUserOp", {
|
|
5789
6172
|
enumerable: true,
|
|
5790
|
-
get: function () { return
|
|
6173
|
+
get: function () { return chunkV2ODMLDD_cjs.assertOwnTaskBudgetCloseUserOp; }
|
|
5791
6174
|
});
|
|
5792
6175
|
Object.defineProperty(exports, "assertOwnTaskChild", {
|
|
5793
6176
|
enumerable: true,
|
|
5794
|
-
get: function () { return
|
|
6177
|
+
get: function () { return chunkV2ODMLDD_cjs.assertOwnTaskChild; }
|
|
5795
6178
|
});
|
|
5796
6179
|
Object.defineProperty(exports, "buildSweepAuthorizationMessage", {
|
|
5797
6180
|
enumerable: true,
|
|
5798
|
-
get: function () { return
|
|
6181
|
+
get: function () { return chunkV2ODMLDD_cjs.buildSweepAuthorizationMessage; }
|
|
5799
6182
|
});
|
|
5800
6183
|
Object.defineProperty(exports, "buildSweepTypedData", {
|
|
5801
6184
|
enumerable: true,
|
|
5802
|
-
get: function () { return
|
|
6185
|
+
get: function () { return chunkV2ODMLDD_cjs.buildSweepTypedData; }
|
|
5803
6186
|
});
|
|
5804
6187
|
Object.defineProperty(exports, "buildX402ExpectedMessage", {
|
|
5805
6188
|
enumerable: true,
|
|
5806
|
-
get: function () { return
|
|
6189
|
+
get: function () { return chunkV2ODMLDD_cjs.buildX402ExpectedMessage; }
|
|
5807
6190
|
});
|
|
5808
6191
|
Object.defineProperty(exports, "compareNodeVersions", {
|
|
5809
6192
|
enumerable: true,
|
|
5810
|
-
get: function () { return
|
|
6193
|
+
get: function () { return chunkV2ODMLDD_cjs.compareNodeVersions; }
|
|
5811
6194
|
});
|
|
5812
6195
|
Object.defineProperty(exports, "createNextStepBuilder", {
|
|
5813
6196
|
enumerable: true,
|
|
5814
|
-
get: function () { return
|
|
6197
|
+
get: function () { return chunkV2ODMLDD_cjs.createNextStepBuilder; }
|
|
5815
6198
|
});
|
|
5816
6199
|
Object.defineProperty(exports, "decodeBase64Json", {
|
|
5817
6200
|
enumerable: true,
|
|
5818
|
-
get: function () { return
|
|
6201
|
+
get: function () { return chunkV2ODMLDD_cjs.decodeBase64Json; }
|
|
5819
6202
|
});
|
|
5820
6203
|
Object.defineProperty(exports, "decodeBase64Utf8", {
|
|
5821
6204
|
enumerable: true,
|
|
5822
|
-
get: function () { return
|
|
6205
|
+
get: function () { return chunkV2ODMLDD_cjs.decodeBase64Utf8; }
|
|
5823
6206
|
});
|
|
5824
6207
|
Object.defineProperty(exports, "defaultNextToolFor", {
|
|
5825
6208
|
enumerable: true,
|
|
5826
|
-
get: function () { return
|
|
6209
|
+
get: function () { return chunkV2ODMLDD_cjs.defaultNextToolFor; }
|
|
5827
6210
|
});
|
|
5828
6211
|
Object.defineProperty(exports, "deriveX402PaymentNonce", {
|
|
5829
6212
|
enumerable: true,
|
|
5830
|
-
get: function () { return
|
|
6213
|
+
get: function () { return chunkV2ODMLDD_cjs.deriveX402PaymentNonce; }
|
|
5831
6214
|
});
|
|
5832
6215
|
Object.defineProperty(exports, "encodeBase64Json", {
|
|
5833
6216
|
enumerable: true,
|
|
5834
|
-
get: function () { return
|
|
6217
|
+
get: function () { return chunkV2ODMLDD_cjs.encodeBase64Json; }
|
|
5835
6218
|
});
|
|
5836
6219
|
Object.defineProperty(exports, "encodeBase64Utf8", {
|
|
5837
6220
|
enumerable: true,
|
|
5838
|
-
get: function () { return
|
|
6221
|
+
get: function () { return chunkV2ODMLDD_cjs.encodeBase64Utf8; }
|
|
5839
6222
|
});
|
|
5840
6223
|
Object.defineProperty(exports, "encodePaymentProof", {
|
|
5841
6224
|
enumerable: true,
|
|
5842
|
-
get: function () { return
|
|
6225
|
+
get: function () { return chunkV2ODMLDD_cjs.encodePaymentProof; }
|
|
5843
6226
|
});
|
|
5844
6227
|
Object.defineProperty(exports, "hashDelegation", {
|
|
5845
6228
|
enumerable: true,
|
|
5846
|
-
get: function () { return
|
|
6229
|
+
get: function () { return chunkV2ODMLDD_cjs.hashDelegation; }
|
|
5847
6230
|
});
|
|
5848
6231
|
Object.defineProperty(exports, "havenClientIdentity", {
|
|
5849
6232
|
enumerable: true,
|
|
5850
|
-
get: function () { return
|
|
6233
|
+
get: function () { return chunkV2ODMLDD_cjs.havenClientIdentity; }
|
|
5851
6234
|
});
|
|
5852
6235
|
Object.defineProperty(exports, "isErc7710Option", {
|
|
5853
6236
|
enumerable: true,
|
|
5854
|
-
get: function () { return
|
|
6237
|
+
get: function () { return chunkV2ODMLDD_cjs.isErc7710Option; }
|
|
5855
6238
|
});
|
|
5856
6239
|
Object.defineProperty(exports, "isSupportedNodeVersion", {
|
|
5857
6240
|
enumerable: true,
|
|
5858
|
-
get: function () { return
|
|
6241
|
+
get: function () { return chunkV2ODMLDD_cjs.isSupportedNodeVersion; }
|
|
5859
6242
|
});
|
|
5860
6243
|
Object.defineProperty(exports, "isSweepableChain", {
|
|
5861
6244
|
enumerable: true,
|
|
5862
|
-
get: function () { return
|
|
6245
|
+
get: function () { return chunkV2ODMLDD_cjs.isSweepableChain; }
|
|
5863
6246
|
});
|
|
5864
6247
|
Object.defineProperty(exports, "isTaskChildTypedData", {
|
|
5865
6248
|
enumerable: true,
|
|
5866
|
-
get: function () { return
|
|
6249
|
+
get: function () { return chunkV2ODMLDD_cjs.isTaskChildTypedData; }
|
|
5867
6250
|
});
|
|
5868
6251
|
Object.defineProperty(exports, "normalizePaymentRequired", {
|
|
5869
6252
|
enumerable: true,
|
|
5870
|
-
get: function () { return
|
|
6253
|
+
get: function () { return chunkV2ODMLDD_cjs.normalizePaymentRequired; }
|
|
5871
6254
|
});
|
|
5872
6255
|
Object.defineProperty(exports, "parseNextTool", {
|
|
5873
6256
|
enumerable: true,
|
|
5874
|
-
get: function () { return
|
|
6257
|
+
get: function () { return chunkV2ODMLDD_cjs.parseNextTool; }
|
|
5875
6258
|
});
|
|
5876
6259
|
Object.defineProperty(exports, "parsePaymentRequired", {
|
|
5877
6260
|
enumerable: true,
|
|
5878
|
-
get: function () { return
|
|
6261
|
+
get: function () { return chunkV2ODMLDD_cjs.parsePaymentRequired; }
|
|
5879
6262
|
});
|
|
5880
6263
|
Object.defineProperty(exports, "parsePaymentRequiredResponse", {
|
|
5881
6264
|
enumerable: true,
|
|
5882
|
-
get: function () { return
|
|
6265
|
+
get: function () { return chunkV2ODMLDD_cjs.parsePaymentRequiredResponse; }
|
|
5883
6266
|
});
|
|
5884
6267
|
Object.defineProperty(exports, "readClientUpdate", {
|
|
5885
6268
|
enumerable: true,
|
|
5886
|
-
get: function () { return
|
|
6269
|
+
get: function () { return chunkV2ODMLDD_cjs.readClientUpdate; }
|
|
5887
6270
|
});
|
|
5888
6271
|
Object.defineProperty(exports, "renderNextTool", {
|
|
5889
6272
|
enumerable: true,
|
|
5890
|
-
get: function () { return
|
|
6273
|
+
get: function () { return chunkV2ODMLDD_cjs.renderNextTool; }
|
|
5891
6274
|
});
|
|
5892
6275
|
Object.defineProperty(exports, "resolveTokenBySymbol", {
|
|
5893
6276
|
enumerable: true,
|
|
5894
|
-
get: function () { return
|
|
6277
|
+
get: function () { return chunkV2ODMLDD_cjs.resolveTokenBySymbol; }
|
|
5895
6278
|
});
|
|
5896
6279
|
Object.defineProperty(exports, "resolveTokenFromAddress", {
|
|
5897
6280
|
enumerable: true,
|
|
5898
|
-
get: function () { return
|
|
6281
|
+
get: function () { return chunkV2ODMLDD_cjs.resolveTokenFromAddress; }
|
|
5899
6282
|
});
|
|
5900
6283
|
Object.defineProperty(exports, "selectErc7710PaymentOption", {
|
|
5901
6284
|
enumerable: true,
|
|
5902
|
-
get: function () { return
|
|
6285
|
+
get: function () { return chunkV2ODMLDD_cjs.selectErc7710PaymentOption; }
|
|
5903
6286
|
});
|
|
5904
6287
|
Object.defineProperty(exports, "selectPaymentOption", {
|
|
5905
6288
|
enumerable: true,
|
|
5906
|
-
get: function () { return
|
|
6289
|
+
get: function () { return chunkV2ODMLDD_cjs.selectPaymentOption; }
|
|
5907
6290
|
});
|
|
5908
6291
|
Object.defineProperty(exports, "selectStandardPaymentOption", {
|
|
5909
6292
|
enumerable: true,
|
|
5910
|
-
get: function () { return
|
|
6293
|
+
get: function () { return chunkV2ODMLDD_cjs.selectStandardPaymentOption; }
|
|
5911
6294
|
});
|
|
5912
6295
|
Object.defineProperty(exports, "selectX402SettlementScheme", {
|
|
5913
6296
|
enumerable: true,
|
|
5914
|
-
get: function () { return
|
|
6297
|
+
get: function () { return chunkV2ODMLDD_cjs.selectX402SettlementScheme; }
|
|
5915
6298
|
});
|
|
5916
6299
|
Object.defineProperty(exports, "sweepUsdcAddress", {
|
|
5917
6300
|
enumerable: true,
|
|
5918
|
-
get: function () { return
|
|
6301
|
+
get: function () { return chunkV2ODMLDD_cjs.sweepUsdcAddress; }
|
|
5919
6302
|
});
|
|
5920
6303
|
Object.defineProperty(exports, "sweepUsdcDomain", {
|
|
5921
6304
|
enumerable: true,
|
|
5922
|
-
get: function () { return
|
|
6305
|
+
get: function () { return chunkV2ODMLDD_cjs.sweepUsdcDomain; }
|
|
5923
6306
|
});
|
|
5924
6307
|
Object.defineProperty(exports, "toStandardPaymentRequirements", {
|
|
5925
6308
|
enumerable: true,
|
|
5926
|
-
get: function () { return
|
|
6309
|
+
get: function () { return chunkV2ODMLDD_cjs.toStandardPaymentRequirements; }
|
|
5927
6310
|
});
|
|
5928
6311
|
Object.defineProperty(exports, "unsupportedNodeVersionMessage", {
|
|
5929
6312
|
enumerable: true,
|
|
5930
|
-
get: function () { return
|
|
6313
|
+
get: function () { return chunkV2ODMLDD_cjs.unsupportedNodeVersionMessage; }
|
|
5931
6314
|
});
|
|
5932
6315
|
Object.defineProperty(exports, "validateStandardX402PaymentHeader", {
|
|
5933
6316
|
enumerable: true,
|
|
5934
|
-
get: function () { return
|
|
6317
|
+
get: function () { return chunkV2ODMLDD_cjs.validateStandardX402PaymentHeader; }
|
|
5935
6318
|
});
|
|
5936
6319
|
Object.defineProperty(exports, "x402AssetTransferMethod", {
|
|
5937
6320
|
enumerable: true,
|
|
5938
|
-
get: function () { return
|
|
6321
|
+
get: function () { return chunkV2ODMLDD_cjs.x402AssetTransferMethod; }
|
|
5939
6322
|
});
|
|
5940
6323
|
Object.defineProperty(exports, "x402AuthorizationAmount", {
|
|
5941
6324
|
enumerable: true,
|
|
5942
|
-
get: function () { return
|
|
6325
|
+
get: function () { return chunkV2ODMLDD_cjs.x402AuthorizationAmount; }
|
|
5943
6326
|
});
|
|
5944
6327
|
Object.defineProperty(exports, "x402FacilitatorAddresses", {
|
|
5945
6328
|
enumerable: true,
|
|
5946
|
-
get: function () { return
|
|
6329
|
+
get: function () { return chunkV2ODMLDD_cjs.x402FacilitatorAddresses; }
|
|
5947
6330
|
});
|
|
5948
6331
|
Object.defineProperty(exports, "x402PaymentHeaderNamesFor", {
|
|
5949
6332
|
enumerable: true,
|
|
5950
|
-
get: function () { return
|
|
6333
|
+
get: function () { return chunkV2ODMLDD_cjs.x402PaymentHeaderNamesFor; }
|
|
5951
6334
|
});
|
|
5952
6335
|
Object.defineProperty(exports, "x402RetryHeadersFor", {
|
|
5953
6336
|
enumerable: true,
|
|
5954
|
-
get: function () { return
|
|
6337
|
+
get: function () { return chunkV2ODMLDD_cjs.x402RetryHeadersFor; }
|
|
5955
6338
|
});
|
|
5956
6339
|
Object.defineProperty(exports, "x402V2PaymentEnvelope", {
|
|
5957
6340
|
enumerable: true,
|
|
5958
|
-
get: function () { return
|
|
6341
|
+
get: function () { return chunkV2ODMLDD_cjs.x402V2PaymentEnvelope; }
|
|
5959
6342
|
});
|
|
5960
6343
|
Object.defineProperty(exports, "RECEIPT_VERSION", {
|
|
5961
6344
|
enumerable: true,
|
|
5962
|
-
get: function () { return
|
|
6345
|
+
get: function () { return chunk4JTLJVBS_cjs.RECEIPT_VERSION; }
|
|
5963
6346
|
});
|
|
5964
6347
|
Object.defineProperty(exports, "verifyPaymentReceipt", {
|
|
5965
6348
|
enumerable: true,
|
|
5966
|
-
get: function () { return
|
|
6349
|
+
get: function () { return chunk4JTLJVBS_cjs.verifyPaymentReceipt; }
|
|
5967
6350
|
});
|
|
5968
6351
|
Object.defineProperty(exports, "AGENT_PAYMENT_FAILURE_CODE_VALUES", {
|
|
5969
6352
|
enumerable: true,
|
|
5970
|
-
get: function () { return
|
|
6353
|
+
get: function () { return chunkZA3NOSO2_cjs.AGENT_PAYMENT_FAILURE_CODE_VALUES; }
|
|
5971
6354
|
});
|
|
5972
6355
|
Object.defineProperty(exports, "AGENT_PAYMENT_NEXT_ACTION_VALUES", {
|
|
5973
6356
|
enumerable: true,
|
|
5974
|
-
get: function () { return
|
|
6357
|
+
get: function () { return chunkZA3NOSO2_cjs.AGENT_PAYMENT_NEXT_ACTION_VALUES; }
|
|
5975
6358
|
});
|
|
5976
6359
|
Object.defineProperty(exports, "AGENT_PAYMENT_PHASE_VALUES", {
|
|
5977
6360
|
enumerable: true,
|
|
5978
|
-
get: function () { return
|
|
6361
|
+
get: function () { return chunkZA3NOSO2_cjs.AGENT_PAYMENT_PHASE_VALUES; }
|
|
5979
6362
|
});
|
|
5980
6363
|
Object.defineProperty(exports, "AGENT_PAYMENT_RAIL_VALUES", {
|
|
5981
6364
|
enumerable: true,
|
|
5982
|
-
get: function () { return
|
|
6365
|
+
get: function () { return chunkZA3NOSO2_cjs.AGENT_PAYMENT_RAIL_VALUES; }
|
|
5983
6366
|
});
|
|
5984
6367
|
Object.defineProperty(exports, "AgentPaymentFailureCode", {
|
|
5985
6368
|
enumerable: true,
|
|
5986
|
-
get: function () { return
|
|
6369
|
+
get: function () { return chunkZA3NOSO2_cjs.AgentPaymentFailureCode; }
|
|
5987
6370
|
});
|
|
5988
6371
|
Object.defineProperty(exports, "AgentPaymentFailureCodeDescriptions", {
|
|
5989
6372
|
enumerable: true,
|
|
5990
|
-
get: function () { return
|
|
6373
|
+
get: function () { return chunkZA3NOSO2_cjs.AgentPaymentFailureCodeDescriptions; }
|
|
5991
6374
|
});
|
|
5992
6375
|
Object.defineProperty(exports, "AgentPaymentFailureCodeSchema", {
|
|
5993
6376
|
enumerable: true,
|
|
5994
|
-
get: function () { return
|
|
6377
|
+
get: function () { return chunkZA3NOSO2_cjs.AgentPaymentFailureCodeSchema; }
|
|
5995
6378
|
});
|
|
5996
6379
|
Object.defineProperty(exports, "AgentPaymentNextAction", {
|
|
5997
6380
|
enumerable: true,
|
|
5998
|
-
get: function () { return
|
|
6381
|
+
get: function () { return chunkZA3NOSO2_cjs.AgentPaymentNextAction; }
|
|
5999
6382
|
});
|
|
6000
6383
|
Object.defineProperty(exports, "AgentPaymentNextActionDescriptions", {
|
|
6001
6384
|
enumerable: true,
|
|
6002
|
-
get: function () { return
|
|
6385
|
+
get: function () { return chunkZA3NOSO2_cjs.AgentPaymentNextActionDescriptions; }
|
|
6003
6386
|
});
|
|
6004
6387
|
Object.defineProperty(exports, "AgentPaymentNextActionSchema", {
|
|
6005
6388
|
enumerable: true,
|
|
6006
|
-
get: function () { return
|
|
6389
|
+
get: function () { return chunkZA3NOSO2_cjs.AgentPaymentNextActionSchema; }
|
|
6007
6390
|
});
|
|
6008
6391
|
Object.defineProperty(exports, "AgentPaymentPhase", {
|
|
6009
6392
|
enumerable: true,
|
|
6010
|
-
get: function () { return
|
|
6393
|
+
get: function () { return chunkZA3NOSO2_cjs.AgentPaymentPhase; }
|
|
6011
6394
|
});
|
|
6012
6395
|
Object.defineProperty(exports, "AgentPaymentPhaseDescriptions", {
|
|
6013
6396
|
enumerable: true,
|
|
6014
|
-
get: function () { return
|
|
6397
|
+
get: function () { return chunkZA3NOSO2_cjs.AgentPaymentPhaseDescriptions; }
|
|
6015
6398
|
});
|
|
6016
6399
|
Object.defineProperty(exports, "AgentPaymentPhaseSchema", {
|
|
6017
6400
|
enumerable: true,
|
|
6018
|
-
get: function () { return
|
|
6401
|
+
get: function () { return chunkZA3NOSO2_cjs.AgentPaymentPhaseSchema; }
|
|
6019
6402
|
});
|
|
6020
6403
|
Object.defineProperty(exports, "AgentPaymentRail", {
|
|
6021
6404
|
enumerable: true,
|
|
6022
|
-
get: function () { return
|
|
6405
|
+
get: function () { return chunkZA3NOSO2_cjs.AgentPaymentRail; }
|
|
6023
6406
|
});
|
|
6024
6407
|
Object.defineProperty(exports, "AgentPaymentRailDescriptions", {
|
|
6025
6408
|
enumerable: true,
|
|
6026
|
-
get: function () { return
|
|
6409
|
+
get: function () { return chunkZA3NOSO2_cjs.AgentPaymentRailDescriptions; }
|
|
6027
6410
|
});
|
|
6028
6411
|
Object.defineProperty(exports, "AgentPaymentRailSchema", {
|
|
6029
6412
|
enumerable: true,
|
|
6030
|
-
get: function () { return
|
|
6413
|
+
get: function () { return chunkZA3NOSO2_cjs.AgentPaymentRailSchema; }
|
|
6031
6414
|
});
|
|
6032
6415
|
Object.defineProperty(exports, "AgentPaymentWarningCode", {
|
|
6033
6416
|
enumerable: true,
|
|
6034
|
-
get: function () { return
|
|
6417
|
+
get: function () { return chunkZA3NOSO2_cjs.AgentPaymentWarningCode; }
|
|
6035
6418
|
});
|
|
6036
6419
|
Object.defineProperty(exports, "CONNECTOR_PACKAGE_NAME", {
|
|
6037
6420
|
enumerable: true,
|
|
6038
|
-
get: function () { return
|
|
6421
|
+
get: function () { return chunkZA3NOSO2_cjs.CONNECTOR_PACKAGE_NAME; }
|
|
6039
6422
|
});
|
|
6040
6423
|
Object.defineProperty(exports, "DEFAULT_CONFIRMATION_TIMEOUT_MS", {
|
|
6041
6424
|
enumerable: true,
|
|
6042
|
-
get: function () { return
|
|
6425
|
+
get: function () { return chunkZA3NOSO2_cjs.DEFAULT_CONFIRMATION_TIMEOUT_MS; }
|
|
6043
6426
|
});
|
|
6044
6427
|
Object.defineProperty(exports, "DIRECT_SIGN_CONTEXT_VERSION", {
|
|
6045
6428
|
enumerable: true,
|
|
6046
|
-
get: function () { return
|
|
6429
|
+
get: function () { return chunkZA3NOSO2_cjs.DIRECT_SIGN_CONTEXT_VERSION; }
|
|
6047
6430
|
});
|
|
6048
6431
|
Object.defineProperty(exports, "ENTRY_POINT_V07", {
|
|
6049
6432
|
enumerable: true,
|
|
6050
|
-
get: function () { return
|
|
6433
|
+
get: function () { return chunkZA3NOSO2_cjs.ENTRY_POINT_V07; }
|
|
6434
|
+
});
|
|
6435
|
+
Object.defineProperty(exports, "FundingConfirmationUnknownError", {
|
|
6436
|
+
enumerable: true,
|
|
6437
|
+
get: function () { return chunkZA3NOSO2_cjs.FundingConfirmationUnknownError; }
|
|
6438
|
+
});
|
|
6439
|
+
Object.defineProperty(exports, "FundingRevertedError", {
|
|
6440
|
+
enumerable: true,
|
|
6441
|
+
get: function () { return chunkZA3NOSO2_cjs.FundingRevertedError; }
|
|
6051
6442
|
});
|
|
6052
6443
|
Object.defineProperty(exports, "HAVEN_CONNECTOR_CHANNEL", {
|
|
6053
6444
|
enumerable: true,
|
|
6054
|
-
get: function () { return
|
|
6445
|
+
get: function () { return chunkZA3NOSO2_cjs.HAVEN_CONNECTOR_CHANNEL; }
|
|
6055
6446
|
});
|
|
6056
6447
|
Object.defineProperty(exports, "HYBRID_DELEGATOR_DOMAIN_NAME", {
|
|
6057
6448
|
enumerable: true,
|
|
6058
|
-
get: function () { return
|
|
6449
|
+
get: function () { return chunkZA3NOSO2_cjs.HYBRID_DELEGATOR_DOMAIN_NAME; }
|
|
6059
6450
|
});
|
|
6060
6451
|
Object.defineProperty(exports, "HYBRID_DELEGATOR_DOMAIN_VERSION", {
|
|
6061
6452
|
enumerable: true,
|
|
6062
|
-
get: function () { return
|
|
6453
|
+
get: function () { return chunkZA3NOSO2_cjs.HYBRID_DELEGATOR_DOMAIN_VERSION; }
|
|
6063
6454
|
});
|
|
6064
6455
|
Object.defineProperty(exports, "HavenApiError", {
|
|
6065
6456
|
enumerable: true,
|
|
6066
|
-
get: function () { return
|
|
6457
|
+
get: function () { return chunkZA3NOSO2_cjs.HavenApiError; }
|
|
6067
6458
|
});
|
|
6068
6459
|
Object.defineProperty(exports, "HavenError", {
|
|
6069
6460
|
enumerable: true,
|
|
6070
|
-
get: function () { return
|
|
6461
|
+
get: function () { return chunkZA3NOSO2_cjs.HavenError; }
|
|
6071
6462
|
});
|
|
6072
6463
|
Object.defineProperty(exports, "HavenPaymentStateError", {
|
|
6073
6464
|
enumerable: true,
|
|
6074
|
-
get: function () { return
|
|
6465
|
+
get: function () { return chunkZA3NOSO2_cjs.HavenPaymentStateError; }
|
|
6075
6466
|
});
|
|
6076
6467
|
Object.defineProperty(exports, "HavenSigningError", {
|
|
6077
6468
|
enumerable: true,
|
|
6078
|
-
get: function () { return
|
|
6469
|
+
get: function () { return chunkZA3NOSO2_cjs.HavenSigningError; }
|
|
6079
6470
|
});
|
|
6080
6471
|
Object.defineProperty(exports, "HavenTimeoutError", {
|
|
6081
6472
|
enumerable: true,
|
|
6082
|
-
get: function () { return
|
|
6473
|
+
get: function () { return chunkZA3NOSO2_cjs.HavenTimeoutError; }
|
|
6083
6474
|
});
|
|
6084
6475
|
Object.defineProperty(exports, "HavenUnsupportedSignerVersionError", {
|
|
6085
6476
|
enumerable: true,
|
|
6086
|
-
get: function () { return
|
|
6477
|
+
get: function () { return chunkZA3NOSO2_cjs.HavenUnsupportedSignerVersionError; }
|
|
6087
6478
|
});
|
|
6088
6479
|
Object.defineProperty(exports, "HavenUserOpBindingError", {
|
|
6089
6480
|
enumerable: true,
|
|
6090
|
-
get: function () { return
|
|
6481
|
+
get: function () { return chunkZA3NOSO2_cjs.HavenUserOpBindingError; }
|
|
6091
6482
|
});
|
|
6092
6483
|
Object.defineProperty(exports, "HavenZeroSettlementHashError", {
|
|
6093
6484
|
enumerable: true,
|
|
6094
|
-
get: function () { return
|
|
6485
|
+
get: function () { return chunkZA3NOSO2_cjs.HavenZeroSettlementHashError; }
|
|
6095
6486
|
});
|
|
6096
6487
|
Object.defineProperty(exports, "MerchantTimeoutError", {
|
|
6097
6488
|
enumerable: true,
|
|
6098
|
-
get: function () { return
|
|
6489
|
+
get: function () { return chunkZA3NOSO2_cjs.MerchantTimeoutError; }
|
|
6099
6490
|
});
|
|
6100
6491
|
Object.defineProperty(exports, "PACKED_USER_OPERATION_FIELDS", {
|
|
6101
6492
|
enumerable: true,
|
|
6102
|
-
get: function () { return
|
|
6493
|
+
get: function () { return chunkZA3NOSO2_cjs.PACKED_USER_OPERATION_FIELDS; }
|
|
6103
6494
|
});
|
|
6104
6495
|
Object.defineProperty(exports, "ROOT_AUTHORITY", {
|
|
6105
6496
|
enumerable: true,
|
|
6106
|
-
get: function () { return
|
|
6497
|
+
get: function () { return chunkZA3NOSO2_cjs.ROOT_AUTHORITY; }
|
|
6107
6498
|
});
|
|
6108
6499
|
Object.defineProperty(exports, "SIGNER_UPDATE_FALLBACK", {
|
|
6109
6500
|
enumerable: true,
|
|
6110
|
-
get: function () { return
|
|
6501
|
+
get: function () { return chunkZA3NOSO2_cjs.SIGNER_UPDATE_FALLBACK; }
|
|
6111
6502
|
});
|
|
6112
6503
|
Object.defineProperty(exports, "SignerRefusalCode", {
|
|
6113
6504
|
enumerable: true,
|
|
6114
|
-
get: function () { return
|
|
6505
|
+
get: function () { return chunkZA3NOSO2_cjs.SignerRefusalCode; }
|
|
6115
6506
|
});
|
|
6116
6507
|
Object.defineProperty(exports, "TASK_SIGN_CONTEXT_VERSION", {
|
|
6117
6508
|
enumerable: true,
|
|
6118
|
-
get: function () { return
|
|
6509
|
+
get: function () { return chunkZA3NOSO2_cjs.TASK_SIGN_CONTEXT_VERSION; }
|
|
6119
6510
|
});
|
|
6120
6511
|
Object.defineProperty(exports, "X402AlreadySettledError", {
|
|
6121
6512
|
enumerable: true,
|
|
6122
|
-
get: function () { return
|
|
6513
|
+
get: function () { return chunkZA3NOSO2_cjs.X402AlreadySettledError; }
|
|
6123
6514
|
});
|
|
6124
6515
|
Object.defineProperty(exports, "X402Erc7710AlreadySettledError", {
|
|
6125
6516
|
enumerable: true,
|
|
6126
|
-
get: function () { return
|
|
6517
|
+
get: function () { return chunkZA3NOSO2_cjs.X402Erc7710AlreadySettledError; }
|
|
6127
6518
|
});
|
|
6128
6519
|
Object.defineProperty(exports, "X402TaskBudgetMismatchError", {
|
|
6129
6520
|
enumerable: true,
|
|
6130
|
-
get: function () { return
|
|
6521
|
+
get: function () { return chunkZA3NOSO2_cjs.X402TaskBudgetMismatchError; }
|
|
6131
6522
|
});
|
|
6132
6523
|
Object.defineProperty(exports, "X402UnexpectedStatusError", {
|
|
6133
6524
|
enumerable: true,
|
|
6134
|
-
get: function () { return
|
|
6525
|
+
get: function () { return chunkZA3NOSO2_cjs.X402UnexpectedStatusError; }
|
|
6135
6526
|
});
|
|
6136
6527
|
Object.defineProperty(exports, "assertUserOpTypedDataBinding", {
|
|
6137
6528
|
enumerable: true,
|
|
6138
|
-
get: function () { return
|
|
6529
|
+
get: function () { return chunkZA3NOSO2_cjs.assertUserOpTypedDataBinding; }
|
|
6139
6530
|
});
|
|
6140
6531
|
Object.defineProperty(exports, "connectorRerunCommand", {
|
|
6141
6532
|
enumerable: true,
|
|
6142
|
-
get: function () { return
|
|
6533
|
+
get: function () { return chunkZA3NOSO2_cjs.connectorRerunCommand; }
|
|
6143
6534
|
});
|
|
6144
6535
|
Object.defineProperty(exports, "connectorSpec", {
|
|
6145
6536
|
enumerable: true,
|
|
6146
|
-
get: function () { return
|
|
6537
|
+
get: function () { return chunkZA3NOSO2_cjs.connectorSpec; }
|
|
6147
6538
|
});
|
|
6148
6539
|
Object.defineProperty(exports, "connectorUpgradeCommand", {
|
|
6149
6540
|
enumerable: true,
|
|
6150
|
-
get: function () { return
|
|
6541
|
+
get: function () { return chunkZA3NOSO2_cjs.connectorUpgradeCommand; }
|
|
6151
6542
|
});
|
|
6152
6543
|
Object.defineProperty(exports, "deriveDelegateAccountAddress", {
|
|
6153
6544
|
enumerable: true,
|
|
6154
|
-
get: function () { return
|
|
6545
|
+
get: function () { return chunkZA3NOSO2_cjs.deriveDelegateAccountAddress; }
|
|
6155
6546
|
});
|
|
6156
6547
|
Object.defineProperty(exports, "isConnectorChannel", {
|
|
6157
6548
|
enumerable: true,
|
|
6158
|
-
get: function () { return
|
|
6549
|
+
get: function () { return chunkZA3NOSO2_cjs.isConnectorChannel; }
|
|
6159
6550
|
});
|
|
6160
6551
|
Object.defineProperty(exports, "isPackedUserOperationTypedData", {
|
|
6161
6552
|
enumerable: true,
|
|
6162
|
-
get: function () { return
|
|
6553
|
+
get: function () { return chunkZA3NOSO2_cjs.isPackedUserOperationTypedData; }
|
|
6163
6554
|
});
|
|
6164
6555
|
Object.defineProperty(exports, "packedUserOperationHash", {
|
|
6165
6556
|
enumerable: true,
|
|
6166
|
-
get: function () { return
|
|
6557
|
+
get: function () { return chunkZA3NOSO2_cjs.packedUserOperationHash; }
|
|
6167
6558
|
});
|
|
6168
6559
|
Object.defineProperty(exports, "resolveConnectorChannel", {
|
|
6169
6560
|
enumerable: true,
|
|
6170
|
-
get: function () { return
|
|
6561
|
+
get: function () { return chunkZA3NOSO2_cjs.resolveConnectorChannel; }
|
|
6171
6562
|
});
|
|
6172
6563
|
Object.defineProperty(exports, "signerUpdateFallback", {
|
|
6173
6564
|
enumerable: true,
|
|
6174
|
-
get: function () { return
|
|
6565
|
+
get: function () { return chunkZA3NOSO2_cjs.signerUpdateFallback; }
|
|
6175
6566
|
});
|
|
6176
6567
|
Object.defineProperty(exports, "verifySettlementChild", {
|
|
6177
6568
|
enumerable: true,
|
|
6178
|
-
get: function () { return
|
|
6569
|
+
get: function () { return chunkZA3NOSO2_cjs.verifySettlementChild; }
|
|
6179
6570
|
});
|
|
6180
6571
|
exports.AGENT_APPROVAL_RELAY_JSON_SENTENCE = AGENT_APPROVAL_RELAY_JSON_SENTENCE;
|
|
6181
6572
|
exports.AGENT_APPROVAL_RELAY_PROSE_SENTENCE = AGENT_APPROVAL_RELAY_PROSE_SENTENCE;
|