@haven_ai/sdk 0.1.24-alpha.0 → 0.1.25-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +47 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -2
- package/dist/index.d.ts +22 -2
- package/dist/index.js +47 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1758,8 +1758,18 @@ declare class HavenClient {
|
|
|
1758
1758
|
* balance — otherwise it rejects with "Payment verification failed". The
|
|
1759
1759
|
* SDK's local path already does this (see authorizeStandardX402); the hosted
|
|
1760
1760
|
* split flow regressed when the 5→3 collapse removed the incidental
|
|
1761
|
-
* inter-call latency that used to mask it.
|
|
1762
|
-
*
|
|
1761
|
+
* inter-call latency that used to mask it.
|
|
1762
|
+
*
|
|
1763
|
+
* **NOT a no-op when the funding tx hash is absent** (#1508). The WAIT is
|
|
1764
|
+
* skipped without a hash or a chain RPC, but the `GET /payments/:id` read
|
|
1765
|
+
* below runs UNCONDITIONALLY — it is how the fallback hash and the chainId
|
|
1766
|
+
* are obtained. That distinction is load-bearing: this method must never be
|
|
1767
|
+
* called on a scheme with no funding leg, because the read itself fails once
|
|
1768
|
+
* the intent reaches a status the backend maps to a non-2xx (`submitted` is a
|
|
1769
|
+
* 409), turning a settled payment into a reported error. The previous wording
|
|
1770
|
+
* here said "No-op when the funding tx hash ... is unavailable", and the
|
|
1771
|
+
* hosted erc7710 path was written against that promise — see
|
|
1772
|
+
* `deliverMerchantPayment`'s `noFundingLeg` option.
|
|
1763
1773
|
*/
|
|
1764
1774
|
ensureFundingConfirmed(paymentId: string, fundingTxHash?: string): Promise<void>;
|
|
1765
1775
|
completeX402MerchantCall(input: {
|
|
@@ -1768,6 +1778,16 @@ declare class HavenClient {
|
|
|
1768
1778
|
paymentId: string;
|
|
1769
1779
|
paymentHeader: string;
|
|
1770
1780
|
mcpTransport?: X402McpTransport;
|
|
1781
|
+
/**
|
|
1782
|
+
* #1508: the payment settles with NO funding leg (erc7710). This method was
|
|
1783
|
+
* written for EIP-3009 and encodes that lifecycle in two places — the
|
|
1784
|
+
* readiness gate wants `confirmed`, and a Haven funding tx hash is
|
|
1785
|
+
* mandatory. Neither is reachable on a scheme where the MERCHANT redeems
|
|
1786
|
+
* the delegation chain: the intent sits at `submitted` by design, and there
|
|
1787
|
+
* is no Haven-submitted transaction at all. Set this to take the
|
|
1788
|
+
* no-funding-leg path through both.
|
|
1789
|
+
*/
|
|
1790
|
+
noFundingLeg?: boolean;
|
|
1771
1791
|
}): Promise<{
|
|
1772
1792
|
status: number;
|
|
1773
1793
|
ok: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -1758,8 +1758,18 @@ declare class HavenClient {
|
|
|
1758
1758
|
* balance — otherwise it rejects with "Payment verification failed". The
|
|
1759
1759
|
* SDK's local path already does this (see authorizeStandardX402); the hosted
|
|
1760
1760
|
* split flow regressed when the 5→3 collapse removed the incidental
|
|
1761
|
-
* inter-call latency that used to mask it.
|
|
1762
|
-
*
|
|
1761
|
+
* inter-call latency that used to mask it.
|
|
1762
|
+
*
|
|
1763
|
+
* **NOT a no-op when the funding tx hash is absent** (#1508). The WAIT is
|
|
1764
|
+
* skipped without a hash or a chain RPC, but the `GET /payments/:id` read
|
|
1765
|
+
* below runs UNCONDITIONALLY — it is how the fallback hash and the chainId
|
|
1766
|
+
* are obtained. That distinction is load-bearing: this method must never be
|
|
1767
|
+
* called on a scheme with no funding leg, because the read itself fails once
|
|
1768
|
+
* the intent reaches a status the backend maps to a non-2xx (`submitted` is a
|
|
1769
|
+
* 409), turning a settled payment into a reported error. The previous wording
|
|
1770
|
+
* here said "No-op when the funding tx hash ... is unavailable", and the
|
|
1771
|
+
* hosted erc7710 path was written against that promise — see
|
|
1772
|
+
* `deliverMerchantPayment`'s `noFundingLeg` option.
|
|
1763
1773
|
*/
|
|
1764
1774
|
ensureFundingConfirmed(paymentId: string, fundingTxHash?: string): Promise<void>;
|
|
1765
1775
|
completeX402MerchantCall(input: {
|
|
@@ -1768,6 +1778,16 @@ declare class HavenClient {
|
|
|
1768
1778
|
paymentId: string;
|
|
1769
1779
|
paymentHeader: string;
|
|
1770
1780
|
mcpTransport?: X402McpTransport;
|
|
1781
|
+
/**
|
|
1782
|
+
* #1508: the payment settles with NO funding leg (erc7710). This method was
|
|
1783
|
+
* written for EIP-3009 and encodes that lifecycle in two places — the
|
|
1784
|
+
* readiness gate wants `confirmed`, and a Haven funding tx hash is
|
|
1785
|
+
* mandatory. Neither is reachable on a scheme where the MERCHANT redeems
|
|
1786
|
+
* the delegation chain: the intent sits at `submitted` by design, and there
|
|
1787
|
+
* is no Haven-submitted transaction at all. Set this to take the
|
|
1788
|
+
* no-funding-leg path through both.
|
|
1789
|
+
*/
|
|
1790
|
+
noFundingLeg?: boolean;
|
|
1771
1791
|
}): Promise<{
|
|
1772
1792
|
status: number;
|
|
1773
1793
|
ok: boolean;
|
package/dist/index.js
CHANGED
|
@@ -2463,8 +2463,18 @@ var HavenClient = class {
|
|
|
2463
2463
|
* balance — otherwise it rejects with "Payment verification failed". The
|
|
2464
2464
|
* SDK's local path already does this (see authorizeStandardX402); the hosted
|
|
2465
2465
|
* split flow regressed when the 5→3 collapse removed the incidental
|
|
2466
|
-
* inter-call latency that used to mask it.
|
|
2467
|
-
*
|
|
2466
|
+
* inter-call latency that used to mask it.
|
|
2467
|
+
*
|
|
2468
|
+
* **NOT a no-op when the funding tx hash is absent** (#1508). The WAIT is
|
|
2469
|
+
* skipped without a hash or a chain RPC, but the `GET /payments/:id` read
|
|
2470
|
+
* below runs UNCONDITIONALLY — it is how the fallback hash and the chainId
|
|
2471
|
+
* are obtained. That distinction is load-bearing: this method must never be
|
|
2472
|
+
* called on a scheme with no funding leg, because the read itself fails once
|
|
2473
|
+
* the intent reaches a status the backend maps to a non-2xx (`submitted` is a
|
|
2474
|
+
* 409), turning a settled payment into a reported error. The previous wording
|
|
2475
|
+
* here said "No-op when the funding tx hash ... is unavailable", and the
|
|
2476
|
+
* hosted erc7710 path was written against that promise — see
|
|
2477
|
+
* `deliverMerchantPayment`'s `noFundingLeg` option.
|
|
2468
2478
|
*/
|
|
2469
2479
|
async ensureFundingConfirmed(paymentId, fundingTxHash) {
|
|
2470
2480
|
const status = await this.getPaymentStatus(paymentId);
|
|
@@ -2473,8 +2483,10 @@ var HavenClient = class {
|
|
|
2473
2483
|
async completeX402MerchantCall(input) {
|
|
2474
2484
|
const evidenceContext = await this.resolveX402MerchantCompletionContext({
|
|
2475
2485
|
paymentId: input.paymentId,
|
|
2476
|
-
url: input.url
|
|
2486
|
+
url: input.url,
|
|
2487
|
+
noFundingLeg: input.noFundingLeg === true
|
|
2477
2488
|
});
|
|
2489
|
+
const fundingTxHash = evidenceContext.txHash;
|
|
2478
2490
|
const shouldHandshakeMcp = isMcpUrl(input.url) || input.mcpTransport?.handshakeRequired === true;
|
|
2479
2491
|
const x402Wallet = shouldHandshakeMcp ? await this.resolveX402WalletForMerchantCall() : this.x402PayerAddress();
|
|
2480
2492
|
let mcpSessionId;
|
|
@@ -2498,33 +2510,37 @@ var HavenClient = class {
|
|
|
2498
2510
|
body = text;
|
|
2499
2511
|
}
|
|
2500
2512
|
if (!surfaced.ok) {
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2513
|
+
if (!input.noFundingLeg && fundingTxHash) {
|
|
2514
|
+
await this.recordMerchantRetryRejected({
|
|
2515
|
+
rail: "x402",
|
|
2516
|
+
paymentId: evidenceContext.paymentId,
|
|
2517
|
+
txHash: fundingTxHash,
|
|
2518
|
+
resourceUrl: evidenceContext.resourceUrl,
|
|
2519
|
+
merchant: {
|
|
2520
|
+
merchant_status: surfaced.status,
|
|
2521
|
+
merchant_status_text: surfaced.statusText,
|
|
2522
|
+
merchant_headers: Object.fromEntries(surfaced.headers.entries()),
|
|
2523
|
+
merchant_body: text
|
|
2524
|
+
},
|
|
2525
|
+
details: {
|
|
2526
|
+
merchant_to: evidenceContext.merchantAddress
|
|
2527
|
+
}
|
|
2528
|
+
});
|
|
2529
|
+
}
|
|
2516
2530
|
} else {
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2531
|
+
if (!input.noFundingLeg && fundingTxHash) {
|
|
2532
|
+
await this.reportMachinePaymentEvidence({
|
|
2533
|
+
paymentId: evidenceContext.paymentId,
|
|
2534
|
+
rail: "x402",
|
|
2535
|
+
txHash: fundingTxHash,
|
|
2536
|
+
resourceUrl: evidenceContext.resourceUrl,
|
|
2537
|
+
merchantStatus: surfaced.status,
|
|
2538
|
+
paymentProofHeaderName: "X-PAYMENT",
|
|
2539
|
+
paymentProofHeader: input.paymentHeader,
|
|
2540
|
+
protocolReceiptHeaderName: protocolReceiptHeader ? "PAYMENT-RESPONSE" : void 0,
|
|
2541
|
+
protocolReceiptHeader
|
|
2542
|
+
});
|
|
2543
|
+
}
|
|
2528
2544
|
await this.reportMerchantReceipt(evidenceContext.paymentId, surfaced);
|
|
2529
2545
|
}
|
|
2530
2546
|
return {
|
|
@@ -2570,11 +2586,11 @@ var HavenClient = class {
|
|
|
2570
2586
|
status
|
|
2571
2587
|
);
|
|
2572
2588
|
}
|
|
2573
|
-
const readyForMerchantCompletion = status.nextAction === AgentPaymentNextAction.RetryOriginalX402Request || status.kind === "payment_intent" && status.status === "confirmed" && status.phase === AgentPaymentPhase.PaymentConfirmed && status.nextAction === AgentPaymentNextAction.None;
|
|
2589
|
+
const readyForMerchantCompletion = input.noFundingLeg ? status.kind === "payment_intent" && status.status === "submitted" : status.nextAction === AgentPaymentNextAction.RetryOriginalX402Request || status.kind === "payment_intent" && status.status === "confirmed" && status.phase === AgentPaymentPhase.PaymentConfirmed && status.nextAction === AgentPaymentNextAction.None;
|
|
2574
2590
|
if (!readyForMerchantCompletion) {
|
|
2575
2591
|
throw new HavenPaymentStateError(status.message, PAYMENT_STATE_STATUS_CODES[status.status] ?? 409, status);
|
|
2576
2592
|
}
|
|
2577
|
-
if (!status.txHash) {
|
|
2593
|
+
if (!input.noFundingLeg && !status.txHash) {
|
|
2578
2594
|
throw new HavenApiError(
|
|
2579
2595
|
`x402 payment ${status.paymentId} is ready for merchant completion but has no Haven transaction hash.`,
|
|
2580
2596
|
502,
|