@haven_ai/sdk 0.0.0-dev.202609232125.72f3d20 → 0.0.0-dev.202609241802.ea320de
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/dist/{base64-CNakwKE8.d.cts → base64-CPxbmyU9.d.cts} +80 -17
- package/dist/{base64-CNakwKE8.d.ts → base64-CPxbmyU9.d.ts} +80 -17
- package/dist/{chunk-7FXW3IKZ.js → chunk-FR5R26V3.js} +139 -8
- package/dist/chunk-FR5R26V3.js.map +1 -0
- package/dist/{chunk-AS6BCA42.cjs → chunk-M57KOLAN.cjs} +147 -7
- package/dist/chunk-M57KOLAN.cjs.map +1 -0
- package/dist/edge.cjs +50 -26
- package/dist/edge.d.cts +2 -1
- package/dist/edge.d.ts +2 -1
- package/dist/edge.js +2 -2
- package/dist/index.cjs +291 -252
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -7
- package/dist/index.d.ts +10 -7
- package/dist/index.js +11 -8
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/chunk-7FXW3IKZ.js.map +0 -1
- package/dist/chunk-AS6BCA42.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -112,8 +112,14 @@ const intent = await haven.createIntent({
|
|
|
112
112
|
to: '0xabc...',
|
|
113
113
|
})
|
|
114
114
|
|
|
115
|
-
// Step 2: Sign the
|
|
116
|
-
|
|
115
|
+
// Step 2: Sign externally. On the delegation rail (the only rail that pays)
|
|
116
|
+
// the account validates the EIP-712 typed data in intent.signData.typed_data,
|
|
117
|
+
// never the bare hash — a signature over signData.hash is rejected on-chain
|
|
118
|
+
// (AA24). Sign that typed data with your delegate key (viem signTypedData),
|
|
119
|
+
// after checking it with assertUserOpTypedDataBinding(typed_data, hash).
|
|
120
|
+
// There is no public HavenClient method for this step yet; pay() does it
|
|
121
|
+
// for you.
|
|
122
|
+
const signature = await signTypedDataWithYourDelegateKey(intent.signData.typed_data)
|
|
117
123
|
|
|
118
124
|
// Step 3: Submit the signature
|
|
119
125
|
await haven.submitSignature(intent.paymentId, signature)
|
|
@@ -251,7 +257,7 @@ const data = await response.json()
|
|
|
251
257
|
|
|
252
258
|
Merchant-verified x402 retries use the official EIP-3009 `exact` scheme on Base USDC (`base` / `eip155:8453`). `haven.fetch()` sends the payment under `PAYMENT-SIGNATURE` (the x402 v2 name), and on the EIP-3009 bridge also under `X-PAYMENT` (v1), so a merchant on either version reads it. **On erc7710 it sends the v2 name ALONE**: that payload is always x402 v2, and its header carries a whole delegation chain, so duplicating it overflows the merchant's header limit and the request is refused with HTTP 431. If you build the retry yourself, follow the same rule. Haven's older tx-hash proof helper remains exported for Haven-native integrations; it is a different payload that happens to have shared the v2 name, and it is not what `haven.fetch()` sends.
|
|
253
259
|
|
|
254
|
-
For standard x402, the `x402-wallet` identity is the agent delegate wallet, because that is the wallet that signs and settles the merchant payment. Integrations that scope access by Haven wallet
|
|
260
|
+
For standard x402, the `x402-wallet` identity is the agent delegate wallet, because that is the wallet that signs and settles the merchant payment. Integrations that scope access by Haven wallet address should use a Haven-native flow instead of standard merchant x402.
|
|
255
261
|
|
|
256
262
|
## AI Agent Integration
|
|
257
263
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PaymentRequirements } from 'x402/types';
|
|
2
|
+
import { Hex } from 'viem';
|
|
2
3
|
|
|
3
4
|
interface HavenClientConfig {
|
|
4
5
|
/** Haven API key (sk_agent_xxx) */
|
|
@@ -33,7 +34,7 @@ interface HavenClientConfig {
|
|
|
33
34
|
* JSON-RPC RPC URLs keyed by EIP-155 chain ID.
|
|
34
35
|
*
|
|
35
36
|
* When provided for a chain, the SDK waits for ≥1 on-chain confirmation of
|
|
36
|
-
* the
|
|
37
|
+
* the funding tx (account → delegate EOA) before retrying the merchant. This prevents
|
|
37
38
|
* the race where the merchant's `balanceOf(delegate)` call runs before the
|
|
38
39
|
* funding block has propagated to the merchant's RPC node.
|
|
39
40
|
*
|
|
@@ -258,10 +259,10 @@ interface X402AuthorizationOptions {
|
|
|
258
259
|
* Keyless x402 construct result.
|
|
259
260
|
*
|
|
260
261
|
* Returned by `createX402Intent` — the non-custodial half of an x402 payment.
|
|
261
|
-
* It carries the unsigned funding
|
|
262
|
+
* It carries the unsigned funding payload (`signData`, account → delegate EOA)
|
|
262
263
|
* plus everything the *edge* needs to build and sign the EIP-3009 merchant
|
|
263
264
|
* header itself. The construct path never signs; both delegate signatures
|
|
264
|
-
* (funding
|
|
265
|
+
* (funding payload + merchant header) happen on the machine that holds the key.
|
|
265
266
|
*/
|
|
266
267
|
interface X402Intent {
|
|
267
268
|
/** Haven payment id for the funding transfer. */
|
|
@@ -271,7 +272,7 @@ interface X402Intent {
|
|
|
271
272
|
status: 'pending_signature';
|
|
272
273
|
/** ISO 8601 expiry of the funding intent, if returned. */
|
|
273
274
|
expiresAt?: string;
|
|
274
|
-
/** The unsigned funding
|
|
275
|
+
/** The unsigned funding payload to sign with the delegate key (account → delegate EOA). */
|
|
275
276
|
signData: SignData;
|
|
276
277
|
/** The selected x402 option — the edge needs this to build the EIP-3009 header. */
|
|
277
278
|
accepted: X402PaymentOption;
|
|
@@ -618,12 +619,12 @@ interface HavenBalanceCoverage {
|
|
|
618
619
|
/**
|
|
619
620
|
* Affirmative spend-readiness for the authenticated agent, derived from the raw
|
|
620
621
|
* agent status plus the remaining spend authority the backend reports per rail
|
|
621
|
-
* (the
|
|
622
|
-
*
|
|
622
|
+
* (the active budget delegation on the delegation rail — #1135; the retired
|
|
623
|
+
* AllowanceModule rail used an on-chain allowance instead):
|
|
623
624
|
* - `ready` — active and at least one token has remaining spend authority.
|
|
624
625
|
* - `needs_approval`— active but no remaining spend authority to auto-spend.
|
|
625
|
-
* The over-budget outcome differs by rail: on the
|
|
626
|
-
* AllowanceModule rail the payment
|
|
626
|
+
* The over-budget outcome differs by rail: on the retired
|
|
627
|
+
* AllowanceModule rail the payment was queued for the wallet
|
|
627
628
|
* owner to approve in Haven; on the delegation rail there is
|
|
628
629
|
* NO approval queue — an over-budget redemption reverts
|
|
629
630
|
* on-chain, so the owner must grant or raise the budget in
|
|
@@ -835,7 +836,7 @@ declare const DEFAULT_CONFIRMATION_TIMEOUT_MS = 90000;
|
|
|
835
836
|
* done, or as failed, are the same defect in opposite directions.
|
|
836
837
|
*/
|
|
837
838
|
type SweepConfirmation =
|
|
838
|
-
/** A receipt was observed. The funds are in the
|
|
839
|
+
/** A receipt was observed. The funds are in the agent's Haven account. */
|
|
839
840
|
'confirmed'
|
|
840
841
|
/**
|
|
841
842
|
* Broadcast, but no receipt within `DEFAULT_CONFIRMATION_TIMEOUT_MS` (or the
|
|
@@ -876,7 +877,7 @@ interface SweepEntry {
|
|
|
876
877
|
interface SweepResult {
|
|
877
878
|
/** Address funds were swept FROM */
|
|
878
879
|
fromAddress: string;
|
|
879
|
-
/** Address funds were swept TO (always the
|
|
880
|
+
/** Address funds were swept TO (always the agent's Haven account) */
|
|
880
881
|
toAddress: string;
|
|
881
882
|
/** Chain the sweep occurred on */
|
|
882
883
|
chainId: number;
|
|
@@ -984,9 +985,9 @@ declare const AgentPaymentNextAction: {
|
|
|
984
985
|
*/
|
|
985
986
|
readonly FundAccountOrRaiseAllowance: "fund_account_or_raise_allowance";
|
|
986
987
|
/**
|
|
987
|
-
* The delegate wallet may hold funds that were sent from the
|
|
988
|
-
* settled to the merchant. The wallet owner should initiate
|
|
989
|
-
* return those funds to
|
|
988
|
+
* The delegate wallet may hold funds that were sent from the agent's Haven
|
|
989
|
+
* account but never settled to the merchant. The wallet owner should initiate
|
|
990
|
+
* a sweep to return those funds to that account.
|
|
990
991
|
*/
|
|
991
992
|
readonly SweepStrandedFunds: "sweep_stranded_funds";
|
|
992
993
|
/**
|
|
@@ -1082,7 +1083,7 @@ type AgentPaymentFailureCode = (typeof AgentPaymentFailureCode)[keyof typeof Age
|
|
|
1082
1083
|
* historical `mpp_demo` rows, which remain readable.
|
|
1083
1084
|
*/
|
|
1084
1085
|
declare const AgentPaymentRail: {
|
|
1085
|
-
/** Standard Haven payment from the user's
|
|
1086
|
+
/** Standard Haven payment from the user's account, redeemed through the agent's budget delegation. */
|
|
1086
1087
|
readonly Direct: "direct";
|
|
1087
1088
|
/** x402 HTTP 402 payment flow with a Haven funding leg and merchant retry leg. */
|
|
1088
1089
|
readonly X402: "x402";
|
|
@@ -1644,7 +1645,7 @@ interface SweepEip712Domain {
|
|
|
1644
1645
|
interface SweepAuthorization {
|
|
1645
1646
|
/** Delegate EOA the funds are swept FROM. */
|
|
1646
1647
|
from: string;
|
|
1647
|
-
/**
|
|
1648
|
+
/** The agent's Haven account the funds are swept TO. */
|
|
1648
1649
|
to: string;
|
|
1649
1650
|
/** Atomic USDC amount (decimal string). */
|
|
1650
1651
|
value: string;
|
|
@@ -2213,7 +2214,7 @@ declare function x402FacilitatorAddresses(option: X402PaymentOption): string[] |
|
|
|
2213
2214
|
* positional match and never look at `extra.assetTransferMethod`, so a merchant
|
|
2214
2215
|
* that listed its erc7710 entry first made a Haven client echo that option
|
|
2215
2216
|
* while signing a standard EIP-3009 authorization. The merchant rejects the
|
|
2216
|
-
* mismatch cleanly — but on the
|
|
2217
|
+
* mismatch cleanly — but on the two-leg bridge the account→delegate funding
|
|
2217
2218
|
* transfer has already executed, so the visible result is a stranded delegate
|
|
2218
2219
|
* balance for the sweep to reclaim. Only our own demo merchant's ordering was
|
|
2219
2220
|
* holding that shut, and that pin binds our merchant, not the ones we do not
|
|
@@ -2309,6 +2310,68 @@ declare function resolveTokenFromAddress(address: string, network?: string): {
|
|
|
2309
2310
|
decimals: number;
|
|
2310
2311
|
} | null;
|
|
2311
2312
|
|
|
2313
|
+
/**
|
|
2314
|
+
* #3271: the integrity check every client runs before signing a direct
|
|
2315
|
+
* delegation-rail payment's typed data.
|
|
2316
|
+
*
|
|
2317
|
+
* A direct payment (`POST /payments`, surfaced as `haven_send` / `haven_pay`)
|
|
2318
|
+
* is signed as the HybridDeleGator's EIP-712 `PackedUserOperation`, and Haven
|
|
2319
|
+
* returns two things for it: that typed data, and `payload_hash` — the
|
|
2320
|
+
* ERC-4337 v0.7 UserOperation hash of the same operation. Nothing used to tie
|
|
2321
|
+
* the two together at signing time. The typed data is multi-KB and reaches the
|
|
2322
|
+
* signer through a language model when it is relayed by hand, so one corrupted
|
|
2323
|
+
* character produced a valid-looking signature over the wrong digest, and the
|
|
2324
|
+
* first sign of it was `AA24 signature error` from the bundler (#3271,
|
|
2325
|
+
* reproduced on dev 2026-09-24).
|
|
2326
|
+
*
|
|
2327
|
+
* This recomputes the v0.7 hash from the typed data's own message and domain
|
|
2328
|
+
* and refuses unless it equals `payload_hash`, and it pins the parts of the
|
|
2329
|
+
* typed data the hash does NOT cover (domain name/version/verifyingContract,
|
|
2330
|
+
* the field list, the EntryPoint). It is a CORRUPTION check: the caller supplies
|
|
2331
|
+
* both values, so it proves they describe the same operation, never that Haven
|
|
2332
|
+
* prepared it. Provenance is the byte-free sign context (`payment_id`); what the
|
|
2333
|
+
* signer will sign at all is #3272.
|
|
2334
|
+
*
|
|
2335
|
+
* Pure viem, no ethers: `@haven_ai/sdk/edge` re-exports it for the edge signer,
|
|
2336
|
+
* and `edge-imports.test.ts` pins that graph.
|
|
2337
|
+
*/
|
|
2338
|
+
/** Version of the direct-payment sign context (`GET /payments/:id/sign-context`). */
|
|
2339
|
+
declare const DIRECT_SIGN_CONTEXT_VERSION = 1;
|
|
2340
|
+
/** The ERC-4337 v0.7 EntryPoint — the only one the delegation rail submits to. */
|
|
2341
|
+
declare const ENTRY_POINT_V07 = "0x0000000071727De22E5E9d8BAf0edAc6f37da032";
|
|
2342
|
+
/**
|
|
2343
|
+
* The HybridDeleGator EIP-712 domain constants and the `PackedUserOperation`
|
|
2344
|
+
* field list, vendored from `@metamask/smart-accounts-kit`
|
|
2345
|
+
* (`contracts.HybridDeleGator.constants`, `SIGNABLE_USER_OP_TYPED_DATA`) so the
|
|
2346
|
+
* published packages need no runtime dependency on the kit. Pinned equal to the
|
|
2347
|
+
* kit's values by `userop-binding.test.ts`.
|
|
2348
|
+
*/
|
|
2349
|
+
declare const HYBRID_DELEGATOR_DOMAIN_NAME = "HybridDeleGator";
|
|
2350
|
+
declare const HYBRID_DELEGATOR_DOMAIN_VERSION = "1";
|
|
2351
|
+
declare const PACKED_USER_OPERATION_FIELDS: ReadonlyArray<{
|
|
2352
|
+
name: string;
|
|
2353
|
+
type: string;
|
|
2354
|
+
}>;
|
|
2355
|
+
/** Refusal raised when UserOperation typed data (a direct payment, or the SDK's x402 funding leg) does not match its `payload_hash`. */
|
|
2356
|
+
declare class HavenUserOpBindingError extends HavenError {
|
|
2357
|
+
constructor(message: string);
|
|
2358
|
+
}
|
|
2359
|
+
/** True when the typed data is a `PackedUserOperation` (the direct-payment shape). */
|
|
2360
|
+
declare function isPackedUserOperationTypedData(value: unknown): boolean;
|
|
2361
|
+
/**
|
|
2362
|
+
* Compute the ERC-4337 v0.7 UserOperation hash from a HybridDeleGator
|
|
2363
|
+
* `PackedUserOperation` typed-data object — the value Haven returns as
|
|
2364
|
+
* `payload_hash` for a direct payment (`getUserOperationHash`, entryPoint 0.7).
|
|
2365
|
+
*/
|
|
2366
|
+
declare function packedUserOperationHash(typedData: unknown): Hex;
|
|
2367
|
+
/**
|
|
2368
|
+
* Refuse (throw `HavenUserOpBindingError`) unless this `PackedUserOperation`
|
|
2369
|
+
* typed data is the operation `payloadHash` names, in the HybridDeleGator
|
|
2370
|
+
* domain of its own sender, against the v0.7 EntryPoint. Returns the
|
|
2371
|
+
* recomputed hash.
|
|
2372
|
+
*/
|
|
2373
|
+
declare function assertUserOpTypedDataBinding(typedData: unknown, payloadHash: string): Hex;
|
|
2374
|
+
|
|
2312
2375
|
/**
|
|
2313
2376
|
* Runtime-agnostic base64 helpers — the single source of truth for the wire
|
|
2314
2377
|
* encoding shared by the SDK and the edge signer (#325).
|
|
@@ -2347,4 +2410,4 @@ declare function encodeBase64Json(value: unknown): string;
|
|
|
2347
2410
|
*/
|
|
2348
2411
|
declare function decodeBase64Json<T>(value: string, label?: string): T;
|
|
2349
2412
|
|
|
2350
|
-
export { type AgentPaymentSummary as $, type AgentPaymentWarning as A, type X402McpTransport as B, type X402MerchantCallContext as C, HavenError as D, AGENT_PAYMENT_FAILURE_CODE_VALUES as E, AGENT_PAYMENT_NEXT_ACTION_VALUES as F, AGENT_PAYMENT_PHASE_VALUES as G, type HavenClientConfig as H, AGENT_PAYMENT_RAIL_VALUES as I, type AgentNextStep as J, type AgentPaymentEnumSchema as K, AgentPaymentFailureCode as L, AgentPaymentFailureCodeDescriptions as M, AgentPaymentFailureCodeSchema as N, AgentPaymentNextAction as O, type PaymentRequest as P, AgentPaymentNextActionDescriptions as Q, type RawPaymentParties as R, type SweepResult as S, AgentPaymentNextActionSchema as T, AgentPaymentPhase as U, AgentPaymentPhaseDescriptions as V, AgentPaymentPhaseSchema as W, type X402PaymentRequired as X, AgentPaymentRail as Y, AgentPaymentRailDescriptions as Z, AgentPaymentRailSchema as _, type PaymentResult as a,
|
|
2413
|
+
export { type AgentPaymentSummary as $, type AgentPaymentWarning as A, type X402McpTransport as B, type X402MerchantCallContext as C, HavenError as D, AGENT_PAYMENT_FAILURE_CODE_VALUES as E, AGENT_PAYMENT_NEXT_ACTION_VALUES as F, AGENT_PAYMENT_PHASE_VALUES as G, type HavenClientConfig as H, AGENT_PAYMENT_RAIL_VALUES as I, type AgentNextStep as J, type AgentPaymentEnumSchema as K, AgentPaymentFailureCode as L, AgentPaymentFailureCodeDescriptions as M, AgentPaymentFailureCodeSchema as N, AgentPaymentNextAction as O, type PaymentRequest as P, AgentPaymentNextActionDescriptions as Q, type RawPaymentParties as R, type SweepResult as S, AgentPaymentNextActionSchema as T, AgentPaymentPhase as U, AgentPaymentPhaseDescriptions as V, AgentPaymentPhaseSchema as W, type X402PaymentRequired as X, AgentPaymentRail as Y, AgentPaymentRailDescriptions as Z, AgentPaymentRailSchema as _, type PaymentResult as a, type X402SchemeSelection as a$, AgentPaymentWarningCode as a0, type AgentPurchaseSummary as a1, CONNECTOR_PACKAGE_NAME as a2, type CatalogSubmissionAccepted as a3, DEFAULT_CONFIRMATION_TIMEOUT_MS as a4, DEFAULT_NEXT_TOOL_BY_ACTION as a5, DIRECT_SIGN_CONTEXT_VERSION as a6, ENTRY_POINT_V07 as a7, ERC7710_ASSET_TRANSFER_METHOD as a8, HAVEN_CONNECTOR_CHANNEL as a9, PACKED_USER_OPERATION_FIELDS as aA, type PaymentFee as aB, type PaymentNextAction as aC, type PaymentPhase as aD, type PaymentStatus as aE, SIGNER_UPDATE_FALLBACK as aF, SWEEP_BASE_CHAIN_ID as aG, SWEEP_BASE_SEPOLIA_CHAIN_ID as aH, SWEEP_BASE_SEPOLIA_USDC_ADDRESS as aI, SWEEP_BASE_USDC_ADDRESS as aJ, SignerRefusalCode as aK, type SweepConfirmation as aL, type SweepEip712Domain as aM, type SweepEntry as aN, type SweepExpectedAuth as aO, type SweepPreparation as aP, type SweepSubmitResult as aQ, type SweepTypedData as aR, TRANSFER_WITH_AUTHORIZATION_TYPES as aS, type UnsupportedNodeVersionMessageOptions as aT, X402AlreadySettledError as aU, type X402ExpectedAuth as aV, type X402ExpectedContext as aW, type X402PaymentHeaderContext as aX, X402PaymentHeaderValidationError as aY, type X402PaymentOption as aZ, type X402RequestSnapshot as a_, HAVEN_MINIMUM_NODE_VERSION as aa, HYBRID_DELEGATOR_DOMAIN_NAME as ab, HYBRID_DELEGATOR_DOMAIN_VERSION as ac, type HavenAgentAllowanceSummary as ad, type HavenAgentReadiness as ae, type HavenAllowance as af, HavenApiError as ag, type HavenCatalogMerchant as ah, type HavenListScope as ai, HavenPaymentStateError as aj, HavenSigningError as ak, HavenTimeoutError as al, HavenUnsupportedSignerVersionError as am, HavenUserOpBindingError as an, HavenZeroSettlementHashError as ao, type MachinePaymentRail as ap, MerchantTimeoutError as aq, NEXT_TOOL_SERVER_NAMES as ar, NEXT_TOOL_SERVER_ROLES as as, type NextStep as at, type NextStepArguments as au, type NextStepHandoff as av, type NextStepInput as aw, type NextStepTarget as ax, type NextStepTargets as ay, type NextToolServerRole as az, type PaymentIntent as b, X402UnexpectedStatusError as b0, X402_LEGACY_PAYMENT_HEADER_NAME as b1, X402_MAX_AUTHORIZATION_WINDOW_SECONDS as b2, X402_PAYMENT_HEADER_NAME as b3, X402_PAYMENT_HEADER_NAMES_SENT as b4, X402_PAYMENT_REQUIRED_HEADER_NAME as b5, X402_PAYMENT_RESPONSE_HEADER_NAME as b6, X402_SETTLEMENT_FORWARD_MARGIN_SECONDS as b7, assertUserOpTypedDataBinding as b8, buildSweepAuthorizationMessage as b9, selectPaymentOption as bA, selectStandardPaymentOption as bB, selectX402SettlementScheme as bC, signerUpdateFallback as bD, sweepUsdcAddress as bE, sweepUsdcDomain as bF, toStandardPaymentRequirements as bG, unsupportedNodeVersionMessage as bH, validateStandardX402PaymentHeader as bI, x402AssetTransferMethod as bJ, x402AuthorizationAmount as bK, x402FacilitatorAddresses as bL, x402V2PaymentEnvelope as bM, buildSweepTypedData as ba, buildX402ExpectedMessage as bb, compareNodeVersions as bc, connectorRerunCommand as bd, connectorSpec as be, createNextStepBuilder as bf, decodeBase64Json as bg, decodeBase64Utf8 as bh, defaultNextToolFor as bi, encodeBase64Json as bj, encodeBase64Utf8 as bk, encodePaymentProof as bl, isConnectorChannel as bm, isErc7710Option as bn, isPackedUserOperationTypedData as bo, isSupportedNodeVersion as bp, isSweepableChain as bq, normalizePaymentRequired as br, packedUserOperationHash as bs, parseNextTool as bt, parsePaymentRequired as bu, parsePaymentRequiredResponse as bv, renderNextTool as bw, resolveConnectorChannel as bx, resolveTokenFromAddress as by, selectErc7710PaymentOption as bz, type X402AuthorizationOptions as c, type X402Intent as d, type PaymentStatusResult as e, type HavenAgent as f, type HavenAgentSummary as g, type SweepPrepareResponse as h, type SweepAuthorization as i, type SweepSubmitResponse as j, type HavenAllowanceSummary as k, type HavenBalanceCoverage as l, type PostPurchaseAllowanceSummary as m, type HavenCatalogEntry as n, type HavenCatalogSubmission as o, type HavenPaymentReceipt as p, type HavenPaymentReceiptsPage as q, type PaymentResumeState as r, type X402Receipt as s, type X402Quote as t, type X402Erc7710Settlement as u, type X402McpCallContext as v, type SignData as w, type ResumeAuthorizedX402Input as x, type ResumeX402PaymentInput as y, type X402ResumeState as z };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PaymentRequirements } from 'x402/types';
|
|
2
|
+
import { Hex } from 'viem';
|
|
2
3
|
|
|
3
4
|
interface HavenClientConfig {
|
|
4
5
|
/** Haven API key (sk_agent_xxx) */
|
|
@@ -33,7 +34,7 @@ interface HavenClientConfig {
|
|
|
33
34
|
* JSON-RPC RPC URLs keyed by EIP-155 chain ID.
|
|
34
35
|
*
|
|
35
36
|
* When provided for a chain, the SDK waits for ≥1 on-chain confirmation of
|
|
36
|
-
* the
|
|
37
|
+
* the funding tx (account → delegate EOA) before retrying the merchant. This prevents
|
|
37
38
|
* the race where the merchant's `balanceOf(delegate)` call runs before the
|
|
38
39
|
* funding block has propagated to the merchant's RPC node.
|
|
39
40
|
*
|
|
@@ -258,10 +259,10 @@ interface X402AuthorizationOptions {
|
|
|
258
259
|
* Keyless x402 construct result.
|
|
259
260
|
*
|
|
260
261
|
* Returned by `createX402Intent` — the non-custodial half of an x402 payment.
|
|
261
|
-
* It carries the unsigned funding
|
|
262
|
+
* It carries the unsigned funding payload (`signData`, account → delegate EOA)
|
|
262
263
|
* plus everything the *edge* needs to build and sign the EIP-3009 merchant
|
|
263
264
|
* header itself. The construct path never signs; both delegate signatures
|
|
264
|
-
* (funding
|
|
265
|
+
* (funding payload + merchant header) happen on the machine that holds the key.
|
|
265
266
|
*/
|
|
266
267
|
interface X402Intent {
|
|
267
268
|
/** Haven payment id for the funding transfer. */
|
|
@@ -271,7 +272,7 @@ interface X402Intent {
|
|
|
271
272
|
status: 'pending_signature';
|
|
272
273
|
/** ISO 8601 expiry of the funding intent, if returned. */
|
|
273
274
|
expiresAt?: string;
|
|
274
|
-
/** The unsigned funding
|
|
275
|
+
/** The unsigned funding payload to sign with the delegate key (account → delegate EOA). */
|
|
275
276
|
signData: SignData;
|
|
276
277
|
/** The selected x402 option — the edge needs this to build the EIP-3009 header. */
|
|
277
278
|
accepted: X402PaymentOption;
|
|
@@ -618,12 +619,12 @@ interface HavenBalanceCoverage {
|
|
|
618
619
|
/**
|
|
619
620
|
* Affirmative spend-readiness for the authenticated agent, derived from the raw
|
|
620
621
|
* agent status plus the remaining spend authority the backend reports per rail
|
|
621
|
-
* (the
|
|
622
|
-
*
|
|
622
|
+
* (the active budget delegation on the delegation rail — #1135; the retired
|
|
623
|
+
* AllowanceModule rail used an on-chain allowance instead):
|
|
623
624
|
* - `ready` — active and at least one token has remaining spend authority.
|
|
624
625
|
* - `needs_approval`— active but no remaining spend authority to auto-spend.
|
|
625
|
-
* The over-budget outcome differs by rail: on the
|
|
626
|
-
* AllowanceModule rail the payment
|
|
626
|
+
* The over-budget outcome differs by rail: on the retired
|
|
627
|
+
* AllowanceModule rail the payment was queued for the wallet
|
|
627
628
|
* owner to approve in Haven; on the delegation rail there is
|
|
628
629
|
* NO approval queue — an over-budget redemption reverts
|
|
629
630
|
* on-chain, so the owner must grant or raise the budget in
|
|
@@ -835,7 +836,7 @@ declare const DEFAULT_CONFIRMATION_TIMEOUT_MS = 90000;
|
|
|
835
836
|
* done, or as failed, are the same defect in opposite directions.
|
|
836
837
|
*/
|
|
837
838
|
type SweepConfirmation =
|
|
838
|
-
/** A receipt was observed. The funds are in the
|
|
839
|
+
/** A receipt was observed. The funds are in the agent's Haven account. */
|
|
839
840
|
'confirmed'
|
|
840
841
|
/**
|
|
841
842
|
* Broadcast, but no receipt within `DEFAULT_CONFIRMATION_TIMEOUT_MS` (or the
|
|
@@ -876,7 +877,7 @@ interface SweepEntry {
|
|
|
876
877
|
interface SweepResult {
|
|
877
878
|
/** Address funds were swept FROM */
|
|
878
879
|
fromAddress: string;
|
|
879
|
-
/** Address funds were swept TO (always the
|
|
880
|
+
/** Address funds were swept TO (always the agent's Haven account) */
|
|
880
881
|
toAddress: string;
|
|
881
882
|
/** Chain the sweep occurred on */
|
|
882
883
|
chainId: number;
|
|
@@ -984,9 +985,9 @@ declare const AgentPaymentNextAction: {
|
|
|
984
985
|
*/
|
|
985
986
|
readonly FundAccountOrRaiseAllowance: "fund_account_or_raise_allowance";
|
|
986
987
|
/**
|
|
987
|
-
* The delegate wallet may hold funds that were sent from the
|
|
988
|
-
* settled to the merchant. The wallet owner should initiate
|
|
989
|
-
* return those funds to
|
|
988
|
+
* The delegate wallet may hold funds that were sent from the agent's Haven
|
|
989
|
+
* account but never settled to the merchant. The wallet owner should initiate
|
|
990
|
+
* a sweep to return those funds to that account.
|
|
990
991
|
*/
|
|
991
992
|
readonly SweepStrandedFunds: "sweep_stranded_funds";
|
|
992
993
|
/**
|
|
@@ -1082,7 +1083,7 @@ type AgentPaymentFailureCode = (typeof AgentPaymentFailureCode)[keyof typeof Age
|
|
|
1082
1083
|
* historical `mpp_demo` rows, which remain readable.
|
|
1083
1084
|
*/
|
|
1084
1085
|
declare const AgentPaymentRail: {
|
|
1085
|
-
/** Standard Haven payment from the user's
|
|
1086
|
+
/** Standard Haven payment from the user's account, redeemed through the agent's budget delegation. */
|
|
1086
1087
|
readonly Direct: "direct";
|
|
1087
1088
|
/** x402 HTTP 402 payment flow with a Haven funding leg and merchant retry leg. */
|
|
1088
1089
|
readonly X402: "x402";
|
|
@@ -1644,7 +1645,7 @@ interface SweepEip712Domain {
|
|
|
1644
1645
|
interface SweepAuthorization {
|
|
1645
1646
|
/** Delegate EOA the funds are swept FROM. */
|
|
1646
1647
|
from: string;
|
|
1647
|
-
/**
|
|
1648
|
+
/** The agent's Haven account the funds are swept TO. */
|
|
1648
1649
|
to: string;
|
|
1649
1650
|
/** Atomic USDC amount (decimal string). */
|
|
1650
1651
|
value: string;
|
|
@@ -2213,7 +2214,7 @@ declare function x402FacilitatorAddresses(option: X402PaymentOption): string[] |
|
|
|
2213
2214
|
* positional match and never look at `extra.assetTransferMethod`, so a merchant
|
|
2214
2215
|
* that listed its erc7710 entry first made a Haven client echo that option
|
|
2215
2216
|
* while signing a standard EIP-3009 authorization. The merchant rejects the
|
|
2216
|
-
* mismatch cleanly — but on the
|
|
2217
|
+
* mismatch cleanly — but on the two-leg bridge the account→delegate funding
|
|
2217
2218
|
* transfer has already executed, so the visible result is a stranded delegate
|
|
2218
2219
|
* balance for the sweep to reclaim. Only our own demo merchant's ordering was
|
|
2219
2220
|
* holding that shut, and that pin binds our merchant, not the ones we do not
|
|
@@ -2309,6 +2310,68 @@ declare function resolveTokenFromAddress(address: string, network?: string): {
|
|
|
2309
2310
|
decimals: number;
|
|
2310
2311
|
} | null;
|
|
2311
2312
|
|
|
2313
|
+
/**
|
|
2314
|
+
* #3271: the integrity check every client runs before signing a direct
|
|
2315
|
+
* delegation-rail payment's typed data.
|
|
2316
|
+
*
|
|
2317
|
+
* A direct payment (`POST /payments`, surfaced as `haven_send` / `haven_pay`)
|
|
2318
|
+
* is signed as the HybridDeleGator's EIP-712 `PackedUserOperation`, and Haven
|
|
2319
|
+
* returns two things for it: that typed data, and `payload_hash` — the
|
|
2320
|
+
* ERC-4337 v0.7 UserOperation hash of the same operation. Nothing used to tie
|
|
2321
|
+
* the two together at signing time. The typed data is multi-KB and reaches the
|
|
2322
|
+
* signer through a language model when it is relayed by hand, so one corrupted
|
|
2323
|
+
* character produced a valid-looking signature over the wrong digest, and the
|
|
2324
|
+
* first sign of it was `AA24 signature error` from the bundler (#3271,
|
|
2325
|
+
* reproduced on dev 2026-09-24).
|
|
2326
|
+
*
|
|
2327
|
+
* This recomputes the v0.7 hash from the typed data's own message and domain
|
|
2328
|
+
* and refuses unless it equals `payload_hash`, and it pins the parts of the
|
|
2329
|
+
* typed data the hash does NOT cover (domain name/version/verifyingContract,
|
|
2330
|
+
* the field list, the EntryPoint). It is a CORRUPTION check: the caller supplies
|
|
2331
|
+
* both values, so it proves they describe the same operation, never that Haven
|
|
2332
|
+
* prepared it. Provenance is the byte-free sign context (`payment_id`); what the
|
|
2333
|
+
* signer will sign at all is #3272.
|
|
2334
|
+
*
|
|
2335
|
+
* Pure viem, no ethers: `@haven_ai/sdk/edge` re-exports it for the edge signer,
|
|
2336
|
+
* and `edge-imports.test.ts` pins that graph.
|
|
2337
|
+
*/
|
|
2338
|
+
/** Version of the direct-payment sign context (`GET /payments/:id/sign-context`). */
|
|
2339
|
+
declare const DIRECT_SIGN_CONTEXT_VERSION = 1;
|
|
2340
|
+
/** The ERC-4337 v0.7 EntryPoint — the only one the delegation rail submits to. */
|
|
2341
|
+
declare const ENTRY_POINT_V07 = "0x0000000071727De22E5E9d8BAf0edAc6f37da032";
|
|
2342
|
+
/**
|
|
2343
|
+
* The HybridDeleGator EIP-712 domain constants and the `PackedUserOperation`
|
|
2344
|
+
* field list, vendored from `@metamask/smart-accounts-kit`
|
|
2345
|
+
* (`contracts.HybridDeleGator.constants`, `SIGNABLE_USER_OP_TYPED_DATA`) so the
|
|
2346
|
+
* published packages need no runtime dependency on the kit. Pinned equal to the
|
|
2347
|
+
* kit's values by `userop-binding.test.ts`.
|
|
2348
|
+
*/
|
|
2349
|
+
declare const HYBRID_DELEGATOR_DOMAIN_NAME = "HybridDeleGator";
|
|
2350
|
+
declare const HYBRID_DELEGATOR_DOMAIN_VERSION = "1";
|
|
2351
|
+
declare const PACKED_USER_OPERATION_FIELDS: ReadonlyArray<{
|
|
2352
|
+
name: string;
|
|
2353
|
+
type: string;
|
|
2354
|
+
}>;
|
|
2355
|
+
/** Refusal raised when UserOperation typed data (a direct payment, or the SDK's x402 funding leg) does not match its `payload_hash`. */
|
|
2356
|
+
declare class HavenUserOpBindingError extends HavenError {
|
|
2357
|
+
constructor(message: string);
|
|
2358
|
+
}
|
|
2359
|
+
/** True when the typed data is a `PackedUserOperation` (the direct-payment shape). */
|
|
2360
|
+
declare function isPackedUserOperationTypedData(value: unknown): boolean;
|
|
2361
|
+
/**
|
|
2362
|
+
* Compute the ERC-4337 v0.7 UserOperation hash from a HybridDeleGator
|
|
2363
|
+
* `PackedUserOperation` typed-data object — the value Haven returns as
|
|
2364
|
+
* `payload_hash` for a direct payment (`getUserOperationHash`, entryPoint 0.7).
|
|
2365
|
+
*/
|
|
2366
|
+
declare function packedUserOperationHash(typedData: unknown): Hex;
|
|
2367
|
+
/**
|
|
2368
|
+
* Refuse (throw `HavenUserOpBindingError`) unless this `PackedUserOperation`
|
|
2369
|
+
* typed data is the operation `payloadHash` names, in the HybridDeleGator
|
|
2370
|
+
* domain of its own sender, against the v0.7 EntryPoint. Returns the
|
|
2371
|
+
* recomputed hash.
|
|
2372
|
+
*/
|
|
2373
|
+
declare function assertUserOpTypedDataBinding(typedData: unknown, payloadHash: string): Hex;
|
|
2374
|
+
|
|
2312
2375
|
/**
|
|
2313
2376
|
* Runtime-agnostic base64 helpers — the single source of truth for the wire
|
|
2314
2377
|
* encoding shared by the SDK and the edge signer (#325).
|
|
@@ -2347,4 +2410,4 @@ declare function encodeBase64Json(value: unknown): string;
|
|
|
2347
2410
|
*/
|
|
2348
2411
|
declare function decodeBase64Json<T>(value: string, label?: string): T;
|
|
2349
2412
|
|
|
2350
|
-
export { type AgentPaymentSummary as $, type AgentPaymentWarning as A, type X402McpTransport as B, type X402MerchantCallContext as C, HavenError as D, AGENT_PAYMENT_FAILURE_CODE_VALUES as E, AGENT_PAYMENT_NEXT_ACTION_VALUES as F, AGENT_PAYMENT_PHASE_VALUES as G, type HavenClientConfig as H, AGENT_PAYMENT_RAIL_VALUES as I, type AgentNextStep as J, type AgentPaymentEnumSchema as K, AgentPaymentFailureCode as L, AgentPaymentFailureCodeDescriptions as M, AgentPaymentFailureCodeSchema as N, AgentPaymentNextAction as O, type PaymentRequest as P, AgentPaymentNextActionDescriptions as Q, type RawPaymentParties as R, type SweepResult as S, AgentPaymentNextActionSchema as T, AgentPaymentPhase as U, AgentPaymentPhaseDescriptions as V, AgentPaymentPhaseSchema as W, type X402PaymentRequired as X, AgentPaymentRail as Y, AgentPaymentRailDescriptions as Z, AgentPaymentRailSchema as _, type PaymentResult as a,
|
|
2413
|
+
export { type AgentPaymentSummary as $, type AgentPaymentWarning as A, type X402McpTransport as B, type X402MerchantCallContext as C, HavenError as D, AGENT_PAYMENT_FAILURE_CODE_VALUES as E, AGENT_PAYMENT_NEXT_ACTION_VALUES as F, AGENT_PAYMENT_PHASE_VALUES as G, type HavenClientConfig as H, AGENT_PAYMENT_RAIL_VALUES as I, type AgentNextStep as J, type AgentPaymentEnumSchema as K, AgentPaymentFailureCode as L, AgentPaymentFailureCodeDescriptions as M, AgentPaymentFailureCodeSchema as N, AgentPaymentNextAction as O, type PaymentRequest as P, AgentPaymentNextActionDescriptions as Q, type RawPaymentParties as R, type SweepResult as S, AgentPaymentNextActionSchema as T, AgentPaymentPhase as U, AgentPaymentPhaseDescriptions as V, AgentPaymentPhaseSchema as W, type X402PaymentRequired as X, AgentPaymentRail as Y, AgentPaymentRailDescriptions as Z, AgentPaymentRailSchema as _, type PaymentResult as a, type X402SchemeSelection as a$, AgentPaymentWarningCode as a0, type AgentPurchaseSummary as a1, CONNECTOR_PACKAGE_NAME as a2, type CatalogSubmissionAccepted as a3, DEFAULT_CONFIRMATION_TIMEOUT_MS as a4, DEFAULT_NEXT_TOOL_BY_ACTION as a5, DIRECT_SIGN_CONTEXT_VERSION as a6, ENTRY_POINT_V07 as a7, ERC7710_ASSET_TRANSFER_METHOD as a8, HAVEN_CONNECTOR_CHANNEL as a9, PACKED_USER_OPERATION_FIELDS as aA, type PaymentFee as aB, type PaymentNextAction as aC, type PaymentPhase as aD, type PaymentStatus as aE, SIGNER_UPDATE_FALLBACK as aF, SWEEP_BASE_CHAIN_ID as aG, SWEEP_BASE_SEPOLIA_CHAIN_ID as aH, SWEEP_BASE_SEPOLIA_USDC_ADDRESS as aI, SWEEP_BASE_USDC_ADDRESS as aJ, SignerRefusalCode as aK, type SweepConfirmation as aL, type SweepEip712Domain as aM, type SweepEntry as aN, type SweepExpectedAuth as aO, type SweepPreparation as aP, type SweepSubmitResult as aQ, type SweepTypedData as aR, TRANSFER_WITH_AUTHORIZATION_TYPES as aS, type UnsupportedNodeVersionMessageOptions as aT, X402AlreadySettledError as aU, type X402ExpectedAuth as aV, type X402ExpectedContext as aW, type X402PaymentHeaderContext as aX, X402PaymentHeaderValidationError as aY, type X402PaymentOption as aZ, type X402RequestSnapshot as a_, HAVEN_MINIMUM_NODE_VERSION as aa, HYBRID_DELEGATOR_DOMAIN_NAME as ab, HYBRID_DELEGATOR_DOMAIN_VERSION as ac, type HavenAgentAllowanceSummary as ad, type HavenAgentReadiness as ae, type HavenAllowance as af, HavenApiError as ag, type HavenCatalogMerchant as ah, type HavenListScope as ai, HavenPaymentStateError as aj, HavenSigningError as ak, HavenTimeoutError as al, HavenUnsupportedSignerVersionError as am, HavenUserOpBindingError as an, HavenZeroSettlementHashError as ao, type MachinePaymentRail as ap, MerchantTimeoutError as aq, NEXT_TOOL_SERVER_NAMES as ar, NEXT_TOOL_SERVER_ROLES as as, type NextStep as at, type NextStepArguments as au, type NextStepHandoff as av, type NextStepInput as aw, type NextStepTarget as ax, type NextStepTargets as ay, type NextToolServerRole as az, type PaymentIntent as b, X402UnexpectedStatusError as b0, X402_LEGACY_PAYMENT_HEADER_NAME as b1, X402_MAX_AUTHORIZATION_WINDOW_SECONDS as b2, X402_PAYMENT_HEADER_NAME as b3, X402_PAYMENT_HEADER_NAMES_SENT as b4, X402_PAYMENT_REQUIRED_HEADER_NAME as b5, X402_PAYMENT_RESPONSE_HEADER_NAME as b6, X402_SETTLEMENT_FORWARD_MARGIN_SECONDS as b7, assertUserOpTypedDataBinding as b8, buildSweepAuthorizationMessage as b9, selectPaymentOption as bA, selectStandardPaymentOption as bB, selectX402SettlementScheme as bC, signerUpdateFallback as bD, sweepUsdcAddress as bE, sweepUsdcDomain as bF, toStandardPaymentRequirements as bG, unsupportedNodeVersionMessage as bH, validateStandardX402PaymentHeader as bI, x402AssetTransferMethod as bJ, x402AuthorizationAmount as bK, x402FacilitatorAddresses as bL, x402V2PaymentEnvelope as bM, buildSweepTypedData as ba, buildX402ExpectedMessage as bb, compareNodeVersions as bc, connectorRerunCommand as bd, connectorSpec as be, createNextStepBuilder as bf, decodeBase64Json as bg, decodeBase64Utf8 as bh, defaultNextToolFor as bi, encodeBase64Json as bj, encodeBase64Utf8 as bk, encodePaymentProof as bl, isConnectorChannel as bm, isErc7710Option as bn, isPackedUserOperationTypedData as bo, isSupportedNodeVersion as bp, isSweepableChain as bq, normalizePaymentRequired as br, packedUserOperationHash as bs, parseNextTool as bt, parsePaymentRequired as bu, parsePaymentRequiredResponse as bv, renderNextTool as bw, resolveConnectorChannel as bx, resolveTokenFromAddress as by, selectErc7710PaymentOption as bz, type X402AuthorizationOptions as c, type X402Intent as d, type PaymentStatusResult as e, type HavenAgent as f, type HavenAgentSummary as g, type SweepPrepareResponse as h, type SweepAuthorization as i, type SweepSubmitResponse as j, type HavenAllowanceSummary as k, type HavenBalanceCoverage as l, type PostPurchaseAllowanceSummary as m, type HavenCatalogEntry as n, type HavenCatalogSubmission as o, type HavenPaymentReceipt as p, type HavenPaymentReceiptsPage as q, type PaymentResumeState as r, type X402Receipt as s, type X402Quote as t, type X402Erc7710Settlement as u, type X402McpCallContext as v, type SignData as w, type ResumeAuthorizedX402Input as x, type ResumeX402PaymentInput as y, type X402ResumeState as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { keccak256, encodeAbiParameters, getAddress, recoverTypedDataAddress, isAddress } from 'viem';
|
|
1
2
|
import { createHash } from 'crypto';
|
|
2
|
-
import { recoverTypedDataAddress } from 'viem';
|
|
3
3
|
|
|
4
4
|
// src/connector-channel.ts
|
|
5
5
|
var CONNECTOR_PACKAGE_NAME = "@haven_ai/connect";
|
|
@@ -113,9 +113,9 @@ var AgentPaymentNextAction = {
|
|
|
113
113
|
*/
|
|
114
114
|
FundAccountOrRaiseAllowance: "fund_account_or_raise_allowance",
|
|
115
115
|
/**
|
|
116
|
-
* The delegate wallet may hold funds that were sent from the
|
|
117
|
-
* settled to the merchant. The wallet owner should initiate
|
|
118
|
-
* return those funds to
|
|
116
|
+
* The delegate wallet may hold funds that were sent from the agent's Haven
|
|
117
|
+
* account but never settled to the merchant. The wallet owner should initiate
|
|
118
|
+
* a sweep to return those funds to that account.
|
|
119
119
|
*/
|
|
120
120
|
SweepStrandedFunds: "sweep_stranded_funds",
|
|
121
121
|
/**
|
|
@@ -189,7 +189,7 @@ var AgentPaymentFailureCode = {
|
|
|
189
189
|
MerchantNotReady: "MERCHANT_NOT_READY"
|
|
190
190
|
};
|
|
191
191
|
var AgentPaymentRail = {
|
|
192
|
-
/** Standard Haven payment from the user's
|
|
192
|
+
/** Standard Haven payment from the user's account, redeemed through the agent's budget delegation. */
|
|
193
193
|
Direct: "direct",
|
|
194
194
|
/** x402 HTTP 402 payment flow with a Haven funding leg and merchant retry leg. */
|
|
195
195
|
X402: "x402",
|
|
@@ -451,6 +451,137 @@ var HavenTimeoutError = class extends HavenError {
|
|
|
451
451
|
this.name = "HavenTimeoutError";
|
|
452
452
|
}
|
|
453
453
|
};
|
|
454
|
+
var DIRECT_SIGN_CONTEXT_VERSION = 1;
|
|
455
|
+
var EIP712_DOMAIN_FIELDS = [
|
|
456
|
+
{ name: "name", type: "string" },
|
|
457
|
+
{ name: "version", type: "string" },
|
|
458
|
+
{ name: "chainId", type: "uint256" },
|
|
459
|
+
{ name: "verifyingContract", type: "address" }
|
|
460
|
+
];
|
|
461
|
+
var ENTRY_POINT_V07 = "0x0000000071727De22E5E9d8BAf0edAc6f37da032";
|
|
462
|
+
var HYBRID_DELEGATOR_DOMAIN_NAME = "HybridDeleGator";
|
|
463
|
+
var HYBRID_DELEGATOR_DOMAIN_VERSION = "1";
|
|
464
|
+
var PACKED_USER_OPERATION_FIELDS = [
|
|
465
|
+
{ name: "sender", type: "address" },
|
|
466
|
+
{ name: "nonce", type: "uint256" },
|
|
467
|
+
{ name: "initCode", type: "bytes" },
|
|
468
|
+
{ name: "callData", type: "bytes" },
|
|
469
|
+
{ name: "accountGasLimits", type: "bytes32" },
|
|
470
|
+
{ name: "preVerificationGas", type: "uint256" },
|
|
471
|
+
{ name: "gasFees", type: "bytes32" },
|
|
472
|
+
{ name: "paymasterAndData", type: "bytes" },
|
|
473
|
+
{ name: "entryPoint", type: "address" }
|
|
474
|
+
];
|
|
475
|
+
var HavenUserOpBindingError = class extends HavenError {
|
|
476
|
+
constructor(message) {
|
|
477
|
+
super(message, "USEROP_BINDING_MISMATCH");
|
|
478
|
+
this.name = "HavenUserOpBindingError";
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
function isPackedUserOperationTypedData(value) {
|
|
482
|
+
return typeof value === "object" && value !== null && value.primaryType === "PackedUserOperation";
|
|
483
|
+
}
|
|
484
|
+
var HEX = /^0x[0-9a-fA-F]*$/;
|
|
485
|
+
var BYTES32 = /^0x[0-9a-fA-F]{64}$/;
|
|
486
|
+
function refuse(detail) {
|
|
487
|
+
throw new HavenUserOpBindingError(
|
|
488
|
+
`Refusing to sign: this UserOperation typed data does not match its payload_hash (${detail}). The payload was altered between the Haven result and this call \u2014 sign by payment_id so the signer fetches the exact bytes, or pass typed_data_b64 from the result unchanged.`
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
function hexField(message, key, pattern) {
|
|
492
|
+
const value = message[key];
|
|
493
|
+
if (typeof value !== "string" || !pattern.test(value)) refuse(`message.${key} is not well-formed`);
|
|
494
|
+
return value;
|
|
495
|
+
}
|
|
496
|
+
function uintField(message, key) {
|
|
497
|
+
const value = message[key];
|
|
498
|
+
try {
|
|
499
|
+
if (typeof value === "bigint") return value;
|
|
500
|
+
if (typeof value === "string" && /^(0x[0-9a-fA-F]+|[0-9]+)$/.test(value) || typeof value === "number") {
|
|
501
|
+
const n = BigInt(value);
|
|
502
|
+
if (n >= 0n) return n;
|
|
503
|
+
}
|
|
504
|
+
} catch {
|
|
505
|
+
}
|
|
506
|
+
return refuse(`message.${key} is not an unsigned integer`);
|
|
507
|
+
}
|
|
508
|
+
function addressField(value, where) {
|
|
509
|
+
if (typeof value !== "string" || !isAddress(value, { strict: false })) refuse(`${where} is not an address`);
|
|
510
|
+
return getAddress(value);
|
|
511
|
+
}
|
|
512
|
+
function packedUserOperationHash(typedData) {
|
|
513
|
+
if (!isPackedUserOperationTypedData(typedData)) refuse("primaryType is not PackedUserOperation");
|
|
514
|
+
const td = typedData;
|
|
515
|
+
const message = td.message;
|
|
516
|
+
if (!message || typeof message !== "object") refuse("message is missing");
|
|
517
|
+
const chainId = uintField({ chainId: td.domain?.chainId }, "chainId");
|
|
518
|
+
const inner = keccak256(
|
|
519
|
+
encodeAbiParameters(
|
|
520
|
+
[
|
|
521
|
+
{ type: "address" },
|
|
522
|
+
{ type: "uint256" },
|
|
523
|
+
{ type: "bytes32" },
|
|
524
|
+
{ type: "bytes32" },
|
|
525
|
+
{ type: "bytes32" },
|
|
526
|
+
{ type: "uint256" },
|
|
527
|
+
{ type: "bytes32" },
|
|
528
|
+
{ type: "bytes32" }
|
|
529
|
+
],
|
|
530
|
+
[
|
|
531
|
+
addressField(message.sender, "message.sender"),
|
|
532
|
+
uintField(message, "nonce"),
|
|
533
|
+
keccak256(hexField(message, "initCode", HEX)),
|
|
534
|
+
keccak256(hexField(message, "callData", HEX)),
|
|
535
|
+
hexField(message, "accountGasLimits", BYTES32),
|
|
536
|
+
uintField(message, "preVerificationGas"),
|
|
537
|
+
hexField(message, "gasFees", BYTES32),
|
|
538
|
+
keccak256(hexField(message, "paymasterAndData", HEX))
|
|
539
|
+
]
|
|
540
|
+
)
|
|
541
|
+
);
|
|
542
|
+
return keccak256(
|
|
543
|
+
encodeAbiParameters(
|
|
544
|
+
[{ type: "bytes32" }, { type: "address" }, { type: "uint256" }],
|
|
545
|
+
[inner, addressField(message.entryPoint, "message.entryPoint"), chainId]
|
|
546
|
+
)
|
|
547
|
+
);
|
|
548
|
+
}
|
|
549
|
+
function assertUserOpTypedDataBinding(typedData, payloadHash) {
|
|
550
|
+
if (typeof payloadHash !== "string" || !BYTES32.test(payloadHash)) refuse("payload_hash is not a 32-byte hex string");
|
|
551
|
+
if (!isPackedUserOperationTypedData(typedData)) refuse("primaryType is not PackedUserOperation");
|
|
552
|
+
const td = typedData;
|
|
553
|
+
const domain = td.domain ?? {};
|
|
554
|
+
const message = td.message ?? {};
|
|
555
|
+
if (domain.name !== HYBRID_DELEGATOR_DOMAIN_NAME) refuse("domain.name is not HybridDeleGator");
|
|
556
|
+
if (domain.version !== HYBRID_DELEGATOR_DOMAIN_VERSION) refuse("domain.version is not 1");
|
|
557
|
+
if (addressField(domain.verifyingContract, "domain.verifyingContract") !== addressField(message.sender, "message.sender")) {
|
|
558
|
+
refuse("domain.verifyingContract is not message.sender");
|
|
559
|
+
}
|
|
560
|
+
if (addressField(message.entryPoint, "message.entryPoint") !== getAddress(ENTRY_POINT_V07)) {
|
|
561
|
+
refuse("message.entryPoint is not the v0.7 EntryPoint");
|
|
562
|
+
}
|
|
563
|
+
const fields = (td.types ?? {}).PackedUserOperation;
|
|
564
|
+
if (!Array.isArray(fields) || fields.length !== PACKED_USER_OPERATION_FIELDS.length || fields.some(
|
|
565
|
+
(f, i) => !f || f.name !== PACKED_USER_OPERATION_FIELDS[i].name || f.type !== PACKED_USER_OPERATION_FIELDS[i].type
|
|
566
|
+
)) {
|
|
567
|
+
refuse("types.PackedUserOperation is not the HybridDeleGator field list");
|
|
568
|
+
}
|
|
569
|
+
const extraTypes = Object.keys(td.types ?? {}).filter((k) => k !== "PackedUserOperation" && k !== "EIP712Domain");
|
|
570
|
+
if (extraTypes.length > 0) refuse(`unexpected types: ${extraTypes.join(", ")}`);
|
|
571
|
+
const domainKeys = Object.keys(domain).sort();
|
|
572
|
+
if (domainKeys.join(",") !== [...EIP712_DOMAIN_FIELDS.map((f) => f.name)].sort().join(",")) {
|
|
573
|
+
refuse(`domain keys are not exactly ${EIP712_DOMAIN_FIELDS.map((f) => f.name).join(", ")}`);
|
|
574
|
+
}
|
|
575
|
+
const declaredDomain = (td.types ?? {}).EIP712Domain;
|
|
576
|
+
if (declaredDomain !== void 0 && (!Array.isArray(declaredDomain) || declaredDomain.length !== EIP712_DOMAIN_FIELDS.length || declaredDomain.some(
|
|
577
|
+
(f, i) => !f || f.name !== EIP712_DOMAIN_FIELDS[i].name || f.type !== EIP712_DOMAIN_FIELDS[i].type
|
|
578
|
+
))) {
|
|
579
|
+
refuse("types.EIP712Domain is not the canonical name/version/chainId/verifyingContract list");
|
|
580
|
+
}
|
|
581
|
+
const recomputed = packedUserOperationHash(typedData);
|
|
582
|
+
if (recomputed.toLowerCase() !== payloadHash.toLowerCase()) refuse("recomputed UserOperation hash differs");
|
|
583
|
+
return recomputed;
|
|
584
|
+
}
|
|
454
585
|
|
|
455
586
|
// src/base64.ts
|
|
456
587
|
function normalizeBase64(value) {
|
|
@@ -1160,6 +1291,6 @@ function major(version) {
|
|
|
1160
1291
|
return String(parseNodeVersion(version)[0]);
|
|
1161
1292
|
}
|
|
1162
1293
|
|
|
1163
|
-
export { AGENT_PAYMENT_FAILURE_CODE_VALUES, AGENT_PAYMENT_NEXT_ACTION_VALUES, AGENT_PAYMENT_PHASE_VALUES, AGENT_PAYMENT_RAIL_VALUES, AgentPaymentFailureCode, AgentPaymentFailureCodeDescriptions, AgentPaymentFailureCodeSchema, AgentPaymentNextAction, AgentPaymentNextActionDescriptions, AgentPaymentNextActionSchema, AgentPaymentPhase, AgentPaymentPhaseDescriptions, AgentPaymentPhaseSchema, AgentPaymentRail, AgentPaymentRailDescriptions, AgentPaymentRailSchema, AgentPaymentWarningCode, CONNECTOR_PACKAGE_NAME, DEFAULT_CONFIRMATION_TIMEOUT_MS, DEFAULT_NEXT_TOOL_BY_ACTION, ERC7710_ASSET_TRANSFER_METHOD, HAVEN_CONNECTOR_CHANNEL, HAVEN_MINIMUM_NODE_VERSION, HavenApiError, HavenError, HavenPaymentStateError, HavenSigningError, HavenTimeoutError, HavenUnsupportedSignerVersionError, HavenZeroSettlementHashError, MerchantTimeoutError, NEXT_TOOL_SERVER_NAMES, NEXT_TOOL_SERVER_ROLES, SIGNER_UPDATE_FALLBACK, SWEEP_BASE_CHAIN_ID, SWEEP_BASE_SEPOLIA_CHAIN_ID, SWEEP_BASE_SEPOLIA_USDC_ADDRESS, SWEEP_BASE_USDC_ADDRESS, SignerRefusalCode, TRANSFER_WITH_AUTHORIZATION_TYPES, X402AlreadySettledError, X402PaymentHeaderValidationError, X402UnexpectedStatusError, X402_LEGACY_PAYMENT_HEADER_NAME, X402_MAX_AUTHORIZATION_WINDOW_SECONDS, X402_PAYMENT_HEADER_NAME, X402_PAYMENT_HEADER_NAMES, X402_PAYMENT_HEADER_NAMES_SENT, X402_PAYMENT_REQUIRED_HEADER_NAME, X402_PAYMENT_RESPONSE_HEADER_NAME, X402_SETTLEMENT_FORWARD_MARGIN_SECONDS, buildSweepAuthorizationMessage, buildSweepTypedData, buildX402ExpectedMessage, buildX402IdempotencyKey, compareNodeVersions, connectorRerunCommand, connectorSpec, createNextStepBuilder, decodeBase64Json, decodeBase64Utf8, defaultNextToolFor, encodeBase64Json, encodeBase64Utf8, encodePaymentProof, isConnectorChannel, isErc7710Option, isSupportedNodeVersion, isSweepableChain, normalizePaymentRequired, parseNextTool, parsePaymentRequired, parsePaymentRequiredResponse, renderNextTool, resolveConnectorChannel, resolveTokenFromAddress, selectErc7710PaymentOption, selectPaymentOption, selectStandardPaymentOption, selectX402SettlementScheme, signerUpdateFallback, sweepUsdcAddress, sweepUsdcDomain, toStandardPaymentRequirements, unsupportedNodeVersionMessage, validateStandardX402PaymentHeader, x402AssetTransferMethod, x402AuthorizationAmount, x402FacilitatorAddresses, x402PaymentHeaderNamesFor, x402PaymentHeaderNamesSent, x402V2PaymentEnvelope };
|
|
1164
|
-
//# sourceMappingURL=chunk-
|
|
1165
|
-
//# sourceMappingURL=chunk-
|
|
1294
|
+
export { AGENT_PAYMENT_FAILURE_CODE_VALUES, AGENT_PAYMENT_NEXT_ACTION_VALUES, AGENT_PAYMENT_PHASE_VALUES, AGENT_PAYMENT_RAIL_VALUES, AgentPaymentFailureCode, AgentPaymentFailureCodeDescriptions, AgentPaymentFailureCodeSchema, AgentPaymentNextAction, AgentPaymentNextActionDescriptions, AgentPaymentNextActionSchema, AgentPaymentPhase, AgentPaymentPhaseDescriptions, AgentPaymentPhaseSchema, AgentPaymentRail, AgentPaymentRailDescriptions, AgentPaymentRailSchema, AgentPaymentWarningCode, CONNECTOR_PACKAGE_NAME, DEFAULT_CONFIRMATION_TIMEOUT_MS, DEFAULT_NEXT_TOOL_BY_ACTION, DIRECT_SIGN_CONTEXT_VERSION, ENTRY_POINT_V07, ERC7710_ASSET_TRANSFER_METHOD, HAVEN_CONNECTOR_CHANNEL, HAVEN_MINIMUM_NODE_VERSION, HYBRID_DELEGATOR_DOMAIN_NAME, HYBRID_DELEGATOR_DOMAIN_VERSION, HavenApiError, HavenError, HavenPaymentStateError, HavenSigningError, HavenTimeoutError, HavenUnsupportedSignerVersionError, HavenUserOpBindingError, HavenZeroSettlementHashError, MerchantTimeoutError, NEXT_TOOL_SERVER_NAMES, NEXT_TOOL_SERVER_ROLES, PACKED_USER_OPERATION_FIELDS, SIGNER_UPDATE_FALLBACK, SWEEP_BASE_CHAIN_ID, SWEEP_BASE_SEPOLIA_CHAIN_ID, SWEEP_BASE_SEPOLIA_USDC_ADDRESS, SWEEP_BASE_USDC_ADDRESS, SignerRefusalCode, TRANSFER_WITH_AUTHORIZATION_TYPES, X402AlreadySettledError, X402PaymentHeaderValidationError, X402UnexpectedStatusError, X402_LEGACY_PAYMENT_HEADER_NAME, X402_MAX_AUTHORIZATION_WINDOW_SECONDS, X402_PAYMENT_HEADER_NAME, X402_PAYMENT_HEADER_NAMES, X402_PAYMENT_HEADER_NAMES_SENT, X402_PAYMENT_REQUIRED_HEADER_NAME, X402_PAYMENT_RESPONSE_HEADER_NAME, X402_SETTLEMENT_FORWARD_MARGIN_SECONDS, assertUserOpTypedDataBinding, buildSweepAuthorizationMessage, buildSweepTypedData, buildX402ExpectedMessage, buildX402IdempotencyKey, compareNodeVersions, connectorRerunCommand, connectorSpec, createNextStepBuilder, decodeBase64Json, decodeBase64Utf8, defaultNextToolFor, encodeBase64Json, encodeBase64Utf8, encodePaymentProof, isConnectorChannel, isErc7710Option, isPackedUserOperationTypedData, isSupportedNodeVersion, isSweepableChain, normalizePaymentRequired, packedUserOperationHash, parseNextTool, parsePaymentRequired, parsePaymentRequiredResponse, renderNextTool, resolveConnectorChannel, resolveTokenFromAddress, selectErc7710PaymentOption, selectPaymentOption, selectStandardPaymentOption, selectX402SettlementScheme, signerUpdateFallback, sweepUsdcAddress, sweepUsdcDomain, toStandardPaymentRequirements, unsupportedNodeVersionMessage, validateStandardX402PaymentHeader, x402AssetTransferMethod, x402AuthorizationAmount, x402FacilitatorAddresses, x402PaymentHeaderNamesFor, x402PaymentHeaderNamesSent, x402V2PaymentEnvelope };
|
|
1295
|
+
//# sourceMappingURL=chunk-FR5R26V3.js.map
|
|
1296
|
+
//# sourceMappingURL=chunk-FR5R26V3.js.map
|