uvd-x402-sdk 2.99.1 → 2.100.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.
Files changed (58) hide show
  1. package/README.md +10 -0
  2. package/dist/adapters/index.d.mts +1 -1
  3. package/dist/adapters/index.d.ts +1 -1
  4. package/dist/backend/index.d.mts +3 -3
  5. package/dist/backend/index.d.ts +3 -3
  6. package/dist/backend/index.js +177 -42
  7. package/dist/backend/index.js.map +1 -1
  8. package/dist/backend/index.mjs +176 -43
  9. package/dist/backend/index.mjs.map +1 -1
  10. package/dist/{index-Bu8DosJ4.d.mts → index-CS4qStqy.d.mts} +2 -2
  11. package/dist/{index-vMFUhX5W.d.ts → index-CYMXb5eC.d.ts} +27 -10
  12. package/dist/{index-D8JpL_D5.d.ts → index-DagQ74ZQ.d.mts} +1 -1
  13. package/dist/{index-D8JpL_D5.d.mts → index-DagQ74ZQ.d.ts} +1 -1
  14. package/dist/{index-Cp01jrhF.d.ts → index-QswKm6BF.d.ts} +2 -2
  15. package/dist/{index-CnHVH3uK.d.mts → index-prkNXpLX.d.mts} +27 -10
  16. package/dist/index.d.mts +24 -10
  17. package/dist/index.d.ts +24 -10
  18. package/dist/index.js +155 -19
  19. package/dist/index.js.map +1 -1
  20. package/dist/index.mjs +154 -20
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/providers/algorand/index.d.mts +1 -1
  23. package/dist/providers/algorand/index.d.ts +1 -1
  24. package/dist/providers/evm/index.d.mts +1 -1
  25. package/dist/providers/evm/index.d.ts +1 -1
  26. package/dist/providers/hedera/index.d.mts +1 -1
  27. package/dist/providers/hedera/index.d.ts +1 -1
  28. package/dist/providers/near/index.d.mts +1 -1
  29. package/dist/providers/near/index.d.ts +1 -1
  30. package/dist/providers/solana/index.d.mts +1 -1
  31. package/dist/providers/solana/index.d.ts +1 -1
  32. package/dist/providers/stellar/index.d.mts +1 -1
  33. package/dist/providers/stellar/index.d.ts +1 -1
  34. package/dist/providers/sui/index.d.mts +1 -1
  35. package/dist/providers/sui/index.d.ts +1 -1
  36. package/dist/providers/xrpl/index.d.mts +1 -1
  37. package/dist/providers/xrpl/index.d.ts +1 -1
  38. package/dist/react/index.d.mts +4 -4
  39. package/dist/react/index.d.ts +4 -4
  40. package/dist/react/index.js.map +1 -1
  41. package/dist/react/index.mjs.map +1 -1
  42. package/dist/react/picker/index.d.mts +1 -1
  43. package/dist/react/picker/index.d.ts +1 -1
  44. package/dist/receipts-8XsMeo1y.d.ts +191 -0
  45. package/dist/receipts-COPJ_BY9.d.mts +191 -0
  46. package/dist/utils/index.d.mts +2 -2
  47. package/dist/utils/index.d.ts +2 -2
  48. package/dist/{validity-BPV_IcqI.d.ts → validity-BpwXbfdj.d.ts} +1 -1
  49. package/dist/{validity-B6CmORz0.d.mts → validity-eGGXxzpi.d.mts} +1 -1
  50. package/package.json +1 -1
  51. package/src/backend/index.ts +79 -47
  52. package/src/backend/stack-key.ts +263 -0
  53. package/src/dx402.ts +26 -9
  54. package/src/events.ts +12 -2
  55. package/src/index.ts +4 -0
  56. package/src/receipts.ts +12 -2
  57. package/dist/receipts-cLnL2c1l.d.ts +0 -111
  58. package/dist/receipts-hnXkpEYi.d.mts +0 -111
package/README.md CHANGED
@@ -861,6 +861,16 @@ app.post('/api/premium', async (req, res) => {
861
861
 
862
862
  `createPaymentMiddleware()` and `createHonoMiddleware()` verify and settle automatically by default (`before-handler`). Use `settlementStrategy: 'manual'` if you need to control when settlement happens (e.g., settle only after confirming you can fulfill the request).
863
863
 
864
+ ### Stack key (services run by Ultravioleta DAO)
865
+
866
+ Services run by Ultravioleta DAO carry a per-service credential, the stack key, so that the facilitator's rate-limit policy does not answer them `429`. Everything in this SDK that calls the facilitator sends it as `X-UVD-Stack-Key`: the clients `FacilitatorClient` (and the two middlewares), `Erc8004Client`, `BazaarClient`, `EscrowClient` and `AdvancedEscrowClient`, and the functions `anchorEvidence`, `availableBackends`, `streamTrafficEvents` and `getFacilitatorReceipt`, which take the same `stackKey` / `stackKeyHosts` options. It changes nothing else about a payment, and a facilitator that does not know the header ignores it.
867
+
868
+ - **Where it comes from:** the facilitator's operator issues one per service: `uvdsk_` followed by 43-128 base64url characters. The process receives it as `UVD_STACK_KEY` (read by default) or as the `stackKey` option, from a secret store, never from code.
869
+ - **Not for third parties:** if you integrate this SDK in your own product you have no key and need none. Leave both unset and no header is sent.
870
+ - **Only to a house facilitator:** the key goes over `https://` to `facilitator.ultravioletadao.xyz` and nowhere else, checked on the URL of every request. A request to any other host, or over plain `http://`, carries no header, whether the key came from the option or from `UVD_STACK_KEY`, and warns once, naming the host and never the key. `stackKeyHosts: ['facilitator-staging.example']` ADDS hosts (hostnames only, matched exactly); `facilitator.ultravioletadao.xyz` stays in. Plain `http://` is accepted only for `127.0.0.1` or `localhost`, and only when listed there. `EscrowClient`'s default base URL, `escrow.ultravioletadao.xyz`, is not the facilitator and gets the key only if listed.
871
+ - **The key does not follow redirects:** a redirect answered to a request that carries it fails with `StackKeyRedirectError` (exported), and the key is not sent again. Point the client at the facilitator's final URL.
872
+ - **A bad key never breaks a payment:** one leading BOM (U+FEFF), then spaces, tabs, CR and LF at both ends, are removed, and nothing else. A value that still does not match is not sent: the client warns once, without the value, and pays like any other client. The key never appears in a result, an error, a log line or a printed client.
873
+
864
874
  ## React
865
875
 
866
876
  ```tsx
@@ -1,4 +1,4 @@
1
- import { X as X402Version, a as PaymentResult } from '../index-D8JpL_D5.mjs';
1
+ import { X as X402Version, a as PaymentResult } from '../index-DagQ74ZQ.mjs';
2
2
  export { E as EnvKeyAdapter, O as OWSWallet, a as OWSWalletAdapter } from '../ows-Z9v4GxOZ.mjs';
3
3
  import '../wallet-w7BnImDG.mjs';
4
4
 
@@ -1,4 +1,4 @@
1
- import { X as X402Version, a as PaymentResult } from '../index-D8JpL_D5.js';
1
+ import { X as X402Version, a as PaymentResult } from '../index-DagQ74ZQ.js';
2
2
  export { E as EnvKeyAdapter, O as OWSWallet, a as OWSWalletAdapter } from '../ows-C-KmORG9.js';
3
3
  import '../wallet-w7BnImDG.js';
4
4
 
@@ -1,4 +1,4 @@
1
1
  import '../wallet-w7BnImDG.mjs';
2
- export { a as FacilitatorReceipt, F as FetchReceiptResult, P as PaymentState, b as PurchaseContext, c as RECEIPT_ISSUER, R as ReceiptFetchOptions, d as ReceiptKeys, e as canonicalReceiptJson, f as createPurchaseContext, g as fetchWithReceipt, h as getFacilitatorReceipt, m as mergeHeaderList, i as mergePaymentResponseHeaders, p as parseFacilitatorReceipt, j as paymentResponseHeaders, k as purchaseContextHeader, r as receiptCommitment, l as receiptFromErrorBody, n as receiptFromResponse, v as validatePurchaseContext, o as verifyFacilitatorReceipt } from '../receipts-hnXkpEYi.mjs';
3
- import '../index-D8JpL_D5.mjs';
4
- export { A as AMBIGUOUS_LEASE_REASONS, a as AUTHORIZATION_ALREADY_SETTLED, b as AUTHORIZATION_IN_FLIGHT, c as AdmittedAuthorizationCode, ap as AdvancedAuthorizationResult, aq as AdvancedEscrowClient, ar as AdvancedEscrowClientOptions, as as AdvancedEscrowContracts, at as AdvancedEscrowTaskTier, au as AdvancedPaymentInfo, av as AdvancedTransactionResult, aw as AgentId, ax as AgentIdentity, ay as AgentRegistration, az as AgentRegistrationFile, aA as AgentService, aB as AtomStats, aC as BASE_MAINNET_CONTRACTS, aD as BazaarClient, aE as BazaarClientOptions, aF as BazaarDiscoverOptions, aG as BazaarDiscoverResponse, aH as BazaarRegisterOptions, aI as BazaarResource, aJ as CreateEscrowOptions, D as DEFAULT_FACILITATOR_RETRIES, d as DEFAULT_RETRY_AFTER_SECONDS, aK as DEPOSIT_LIMIT_USDC, aL as DiscoveryAccepts, aM as DiscoveryCuration, aN as DiscoveryHealth, aO as DiscoveryHealthStatus, aP as DiscoveryListOptions, aQ as DiscoveryPagination, aR as DiscoveryRegisterOptions, aS as DiscoveryResource, aT as DiscoveryResponse, aU as DiscoverySource, aV as DiscoveryStats, aW as DiscoveryTier, aX as Dispute, aY as DisputeOutcome, aZ as ERC8004_CONTRACTS, a_ as ERC8004_EXTENSION_ID, a$ as ESCROW_CONTRACTS, b0 as ESCROW_NOTHING_TO_VOID, b1 as ESCROW_OPERATOR_GENERATION, b2 as ESCROW_OPERATOR_NOT_DEPLOYED, b3 as ESCROW_TIMEOUT_MS, b4 as ESCROW_UNSUPPORTED_ON_GENERATION, b5 as ESCROW_VOID_AMOUNT_MISMATCH, b6 as Erc8004Client, b7 as Erc8004ClientOptions, b8 as Erc8004LookupError, b9 as Erc8004Network, ba as EscrowClient, bb as EscrowClientOptions, bc as EscrowOperatorGeneration, bd as EscrowPayment, be as EscrowStateResponse, bf as EscrowStatus, F as FacilitatorCallOptions, e as FacilitatorClient, f as FacilitatorClientOptions, g as FacilitatorErrorInfo, h as FacilitatorFailureFields, i as FacilitatorFetchOptions, bg as FeedbackEntry, bh as FeedbackParams, bi as FeedbackRequest, bj as FeedbackResponse, bk as HEALTH_FILTERS, H as HonoMiddlewareOptions, I as IDEMPOTENCY_KEY_HEADER, j as IDEMPOTENT_REPLAYED_HEADER, bl as IdentityByOwnerResponse, bm as IdentityMetadataResponse, bn as IdentityTotalSupplyResponse, bo as LifecycleAuthOptions, M as MAX_RETRY_AFTER_SECONDS, bp as MAX_SEARCH_LEN, bq as MetadataEntryParam, br as OPERATOR_ABI, bs as OPERATOR_ABI_CREATE3, bt as OPERATOR_ABI_V3, bu as PAYMENT_INFO_TYPEHASH, P as ParsedFacilitatorErrorBody, v as PaymentAcceptance, w as PaymentConflictResponse, x as PaymentMiddlewareOptions, y as PaymentPayloadV2, bv as PaymentRequirementResolver, bw as PaymentRequirements, bx as PaymentRequirementsOptions, z as PaymentRequirementsV2, by as PrepareRelayFeedbackRequest, bz as PrepareRelayFeedbackResponse, bA as PrepareRelayResponseRequest, bB as PrepareSolanaFeedbackRequest, bC as PrepareSolanaFeedbackResponse, bD as ProofOfPayment, R as RECEIPT_REQUEST_CONFLICT, bE as RELAYED_FEEDBACK_NETWORKS, C as REPLAYABLE_LEASE_REASONS, bF as RefundRequest, bG as RefundStatus, bH as RegisterAgentRequest, bI as RegisterAgentResponse, bJ as RegisterJobResponse, bK as RegisterJobStatus, bL as RegistrationPendingError, bM as RelayAuthorizationParams, bN as ReputationResponse, bO as ReputationSummary, bP as RequestRefundOptions, E as ResourceInfoV2, S as SETTLEMENT_UNCONFIRMED, bQ as SOLANA_FEEDBACK_NETWORKS, bR as SettleRequest, G as SettleRequestV2, J as SettleResponse, bS as SettleResponseWithProof, bT as SubmitRelayFeedbackRequest, bU as SubmitRelayResponseRequest, bV as SubmitSolanaFeedbackRequest, bW as TIER_FILTERS, bX as TIER_TIMINGS, bY as USDC_DOMAIN_NAME, bZ as UnavailableBody, b_ as UnavailableResponse, V as VerifiedPaymentState, b$ as VerifyRequest, K as VerifyRequestV2, N as VerifyResponse, W as WRITER_LEASE_REASONS, Q as WriterLeaseReason, X as X402_CORS_HEADERS, T as X402_HEADER_NAMES, c0 as ZERO_ADDRESS, c1 as buildErc8004PaymentRequirements, Z as buildPaymentConflictResponse, _ as buildPaymentRequirements, $ as buildSettleRequest, a0 as buildSettleRequestForVersion, a1 as buildSettleRequestV2, c2 as buildUnavailableResponse, a2 as buildVerifyRequest, a3 as buildVerifyRequestForVersion, a4 as buildVerifyRequestV2, c3 as canRefundEscrow, c4 as canReleaseEscrow, c5 as carryFailureFields, a5 as create402Response, a6 as createHonoMiddleware, a7 as createIdempotencyKey, a8 as createPaymentMiddleware, c6 as epochToDate, c7 as escrowTimeRemaining, a9 as extractPaymentFromHeaders, aa as facilitatorFetch, ab as getCorsHeaders, c8 as getEscrowContractsByChainId, c9 as getEscrowOperatorGeneration, ca as getEscrowSupportedChainIds, cb as isAlive, ac as isAmbiguousLeaseReason, ad as isAuthorizationAlreadyUsed, ae as isAuthorizationInFlight, cc as isEscrowExpired, cd as isEscrowSupportedOnChain, ce as isRegisterJobTerminal, af as isReplayableLeaseReason, ag as isSettlementUnconfirmed, ai as parseFacilitatorErrorBody, cf as parsePaymentHeader, aj as parseRetryAfterSeconds, ak as readFacilitatorError, al as resolveEnvelopeVersion, cg as supportsRelayedFeedback, ch as supportsSolanaFeedback, am as toPaymentRequirementsV2, an as toResourceInfoV2, ci as wireNetwork } from '../index-CnHVH3uK.mjs';
2
+ export { a as FacilitatorReceipt, F as FetchReceiptResult, P as PaymentState, b as PurchaseContext, c as RECEIPT_ISSUER, R as ReceiptFetchOptions, d as ReceiptKeys, e as STACK_KEY_HEADER, S as StackKeyOptions, f as StackKeyRedirectError, g as canonicalReceiptJson, h as createPurchaseContext, i as fetchWithReceipt, j as getFacilitatorReceipt, m as mergeHeaderList, k as mergePaymentResponseHeaders, p as parseFacilitatorReceipt, l as paymentResponseHeaders, n as purchaseContextHeader, r as receiptCommitment, o as receiptFromErrorBody, q as receiptFromResponse, v as validatePurchaseContext, s as verifyFacilitatorReceipt } from '../receipts-COPJ_BY9.mjs';
3
+ import '../index-DagQ74ZQ.mjs';
4
+ export { A as AMBIGUOUS_LEASE_REASONS, a as AUTHORIZATION_ALREADY_SETTLED, b as AUTHORIZATION_IN_FLIGHT, c as AdmittedAuthorizationCode, ap as AdvancedAuthorizationResult, aq as AdvancedEscrowClient, ar as AdvancedEscrowClientOptions, as as AdvancedEscrowContracts, at as AdvancedEscrowTaskTier, au as AdvancedPaymentInfo, av as AdvancedTransactionResult, aw as AgentId, ax as AgentIdentity, ay as AgentRegistration, az as AgentRegistrationFile, aA as AgentService, aB as AtomStats, aC as BASE_MAINNET_CONTRACTS, aD as BazaarClient, aE as BazaarClientOptions, aF as BazaarDiscoverOptions, aG as BazaarDiscoverResponse, aH as BazaarRegisterOptions, aI as BazaarResource, aJ as CreateEscrowOptions, D as DEFAULT_FACILITATOR_RETRIES, d as DEFAULT_RETRY_AFTER_SECONDS, aK as DEPOSIT_LIMIT_USDC, aL as DiscoveryAccepts, aM as DiscoveryCuration, aN as DiscoveryHealth, aO as DiscoveryHealthStatus, aP as DiscoveryListOptions, aQ as DiscoveryPagination, aR as DiscoveryRegisterOptions, aS as DiscoveryResource, aT as DiscoveryResponse, aU as DiscoverySource, aV as DiscoveryStats, aW as DiscoveryTier, aX as Dispute, aY as DisputeOutcome, aZ as ERC8004_CONTRACTS, a_ as ERC8004_EXTENSION_ID, a$ as ESCROW_CONTRACTS, b0 as ESCROW_NOTHING_TO_VOID, b1 as ESCROW_OPERATOR_GENERATION, b2 as ESCROW_OPERATOR_NOT_DEPLOYED, b3 as ESCROW_TIMEOUT_MS, b4 as ESCROW_UNSUPPORTED_ON_GENERATION, b5 as ESCROW_VOID_AMOUNT_MISMATCH, b6 as Erc8004Client, b7 as Erc8004ClientOptions, b8 as Erc8004LookupError, b9 as Erc8004Network, ba as EscrowClient, bb as EscrowClientOptions, bc as EscrowOperatorGeneration, bd as EscrowPayment, be as EscrowStateResponse, bf as EscrowStatus, F as FacilitatorCallOptions, e as FacilitatorClient, f as FacilitatorClientOptions, g as FacilitatorErrorInfo, h as FacilitatorFailureFields, i as FacilitatorFetchOptions, bg as FeedbackEntry, bh as FeedbackParams, bi as FeedbackRequest, bj as FeedbackResponse, bk as HEALTH_FILTERS, H as HonoMiddlewareOptions, I as IDEMPOTENCY_KEY_HEADER, j as IDEMPOTENT_REPLAYED_HEADER, bl as IdentityByOwnerResponse, bm as IdentityMetadataResponse, bn as IdentityTotalSupplyResponse, bo as LifecycleAuthOptions, M as MAX_RETRY_AFTER_SECONDS, bp as MAX_SEARCH_LEN, bq as MetadataEntryParam, br as OPERATOR_ABI, bs as OPERATOR_ABI_CREATE3, bt as OPERATOR_ABI_V3, bu as PAYMENT_INFO_TYPEHASH, P as ParsedFacilitatorErrorBody, v as PaymentAcceptance, w as PaymentConflictResponse, x as PaymentMiddlewareOptions, y as PaymentPayloadV2, bv as PaymentRequirementResolver, bw as PaymentRequirements, bx as PaymentRequirementsOptions, z as PaymentRequirementsV2, by as PrepareRelayFeedbackRequest, bz as PrepareRelayFeedbackResponse, bA as PrepareRelayResponseRequest, bB as PrepareSolanaFeedbackRequest, bC as PrepareSolanaFeedbackResponse, bD as ProofOfPayment, R as RECEIPT_REQUEST_CONFLICT, bE as RELAYED_FEEDBACK_NETWORKS, C as REPLAYABLE_LEASE_REASONS, bF as RefundRequest, bG as RefundStatus, bH as RegisterAgentRequest, bI as RegisterAgentResponse, bJ as RegisterJobResponse, bK as RegisterJobStatus, bL as RegistrationPendingError, bM as RelayAuthorizationParams, bN as ReputationResponse, bO as ReputationSummary, bP as RequestRefundOptions, E as ResourceInfoV2, S as SETTLEMENT_UNCONFIRMED, bQ as SOLANA_FEEDBACK_NETWORKS, bR as SettleRequest, G as SettleRequestV2, J as SettleResponse, bS as SettleResponseWithProof, bT as SubmitRelayFeedbackRequest, bU as SubmitRelayResponseRequest, bV as SubmitSolanaFeedbackRequest, bW as TIER_FILTERS, bX as TIER_TIMINGS, bY as USDC_DOMAIN_NAME, bZ as UnavailableBody, b_ as UnavailableResponse, V as VerifiedPaymentState, b$ as VerifyRequest, K as VerifyRequestV2, N as VerifyResponse, W as WRITER_LEASE_REASONS, Q as WriterLeaseReason, X as X402_CORS_HEADERS, T as X402_HEADER_NAMES, c0 as ZERO_ADDRESS, c1 as buildErc8004PaymentRequirements, Z as buildPaymentConflictResponse, _ as buildPaymentRequirements, $ as buildSettleRequest, a0 as buildSettleRequestForVersion, a1 as buildSettleRequestV2, c2 as buildUnavailableResponse, a2 as buildVerifyRequest, a3 as buildVerifyRequestForVersion, a4 as buildVerifyRequestV2, c3 as canRefundEscrow, c4 as canReleaseEscrow, c5 as carryFailureFields, a5 as create402Response, a6 as createHonoMiddleware, a7 as createIdempotencyKey, a8 as createPaymentMiddleware, c6 as epochToDate, c7 as escrowTimeRemaining, a9 as extractPaymentFromHeaders, aa as facilitatorFetch, ab as getCorsHeaders, c8 as getEscrowContractsByChainId, c9 as getEscrowOperatorGeneration, ca as getEscrowSupportedChainIds, cb as isAlive, ac as isAmbiguousLeaseReason, ad as isAuthorizationAlreadyUsed, ae as isAuthorizationInFlight, cc as isEscrowExpired, cd as isEscrowSupportedOnChain, ce as isRegisterJobTerminal, af as isReplayableLeaseReason, ag as isSettlementUnconfirmed, ai as parseFacilitatorErrorBody, cf as parsePaymentHeader, aj as parseRetryAfterSeconds, ak as readFacilitatorError, al as resolveEnvelopeVersion, cg as supportsRelayedFeedback, ch as supportsSolanaFeedback, am as toPaymentRequirementsV2, an as toResourceInfoV2, ci as wireNetwork } from '../index-prkNXpLX.mjs';
@@ -1,4 +1,4 @@
1
1
  import '../wallet-w7BnImDG.js';
2
- export { a as FacilitatorReceipt, F as FetchReceiptResult, P as PaymentState, b as PurchaseContext, c as RECEIPT_ISSUER, R as ReceiptFetchOptions, d as ReceiptKeys, e as canonicalReceiptJson, f as createPurchaseContext, g as fetchWithReceipt, h as getFacilitatorReceipt, m as mergeHeaderList, i as mergePaymentResponseHeaders, p as parseFacilitatorReceipt, j as paymentResponseHeaders, k as purchaseContextHeader, r as receiptCommitment, l as receiptFromErrorBody, n as receiptFromResponse, v as validatePurchaseContext, o as verifyFacilitatorReceipt } from '../receipts-cLnL2c1l.js';
3
- import '../index-D8JpL_D5.js';
4
- export { A as AMBIGUOUS_LEASE_REASONS, a as AUTHORIZATION_ALREADY_SETTLED, b as AUTHORIZATION_IN_FLIGHT, c as AdmittedAuthorizationCode, ap as AdvancedAuthorizationResult, aq as AdvancedEscrowClient, ar as AdvancedEscrowClientOptions, as as AdvancedEscrowContracts, at as AdvancedEscrowTaskTier, au as AdvancedPaymentInfo, av as AdvancedTransactionResult, aw as AgentId, ax as AgentIdentity, ay as AgentRegistration, az as AgentRegistrationFile, aA as AgentService, aB as AtomStats, aC as BASE_MAINNET_CONTRACTS, aD as BazaarClient, aE as BazaarClientOptions, aF as BazaarDiscoverOptions, aG as BazaarDiscoverResponse, aH as BazaarRegisterOptions, aI as BazaarResource, aJ as CreateEscrowOptions, D as DEFAULT_FACILITATOR_RETRIES, d as DEFAULT_RETRY_AFTER_SECONDS, aK as DEPOSIT_LIMIT_USDC, aL as DiscoveryAccepts, aM as DiscoveryCuration, aN as DiscoveryHealth, aO as DiscoveryHealthStatus, aP as DiscoveryListOptions, aQ as DiscoveryPagination, aR as DiscoveryRegisterOptions, aS as DiscoveryResource, aT as DiscoveryResponse, aU as DiscoverySource, aV as DiscoveryStats, aW as DiscoveryTier, aX as Dispute, aY as DisputeOutcome, aZ as ERC8004_CONTRACTS, a_ as ERC8004_EXTENSION_ID, a$ as ESCROW_CONTRACTS, b0 as ESCROW_NOTHING_TO_VOID, b1 as ESCROW_OPERATOR_GENERATION, b2 as ESCROW_OPERATOR_NOT_DEPLOYED, b3 as ESCROW_TIMEOUT_MS, b4 as ESCROW_UNSUPPORTED_ON_GENERATION, b5 as ESCROW_VOID_AMOUNT_MISMATCH, b6 as Erc8004Client, b7 as Erc8004ClientOptions, b8 as Erc8004LookupError, b9 as Erc8004Network, ba as EscrowClient, bb as EscrowClientOptions, bc as EscrowOperatorGeneration, bd as EscrowPayment, be as EscrowStateResponse, bf as EscrowStatus, F as FacilitatorCallOptions, e as FacilitatorClient, f as FacilitatorClientOptions, g as FacilitatorErrorInfo, h as FacilitatorFailureFields, i as FacilitatorFetchOptions, bg as FeedbackEntry, bh as FeedbackParams, bi as FeedbackRequest, bj as FeedbackResponse, bk as HEALTH_FILTERS, H as HonoMiddlewareOptions, I as IDEMPOTENCY_KEY_HEADER, j as IDEMPOTENT_REPLAYED_HEADER, bl as IdentityByOwnerResponse, bm as IdentityMetadataResponse, bn as IdentityTotalSupplyResponse, bo as LifecycleAuthOptions, M as MAX_RETRY_AFTER_SECONDS, bp as MAX_SEARCH_LEN, bq as MetadataEntryParam, br as OPERATOR_ABI, bs as OPERATOR_ABI_CREATE3, bt as OPERATOR_ABI_V3, bu as PAYMENT_INFO_TYPEHASH, P as ParsedFacilitatorErrorBody, v as PaymentAcceptance, w as PaymentConflictResponse, x as PaymentMiddlewareOptions, y as PaymentPayloadV2, bv as PaymentRequirementResolver, bw as PaymentRequirements, bx as PaymentRequirementsOptions, z as PaymentRequirementsV2, by as PrepareRelayFeedbackRequest, bz as PrepareRelayFeedbackResponse, bA as PrepareRelayResponseRequest, bB as PrepareSolanaFeedbackRequest, bC as PrepareSolanaFeedbackResponse, bD as ProofOfPayment, R as RECEIPT_REQUEST_CONFLICT, bE as RELAYED_FEEDBACK_NETWORKS, C as REPLAYABLE_LEASE_REASONS, bF as RefundRequest, bG as RefundStatus, bH as RegisterAgentRequest, bI as RegisterAgentResponse, bJ as RegisterJobResponse, bK as RegisterJobStatus, bL as RegistrationPendingError, bM as RelayAuthorizationParams, bN as ReputationResponse, bO as ReputationSummary, bP as RequestRefundOptions, E as ResourceInfoV2, S as SETTLEMENT_UNCONFIRMED, bQ as SOLANA_FEEDBACK_NETWORKS, bR as SettleRequest, G as SettleRequestV2, J as SettleResponse, bS as SettleResponseWithProof, bT as SubmitRelayFeedbackRequest, bU as SubmitRelayResponseRequest, bV as SubmitSolanaFeedbackRequest, bW as TIER_FILTERS, bX as TIER_TIMINGS, bY as USDC_DOMAIN_NAME, bZ as UnavailableBody, b_ as UnavailableResponse, V as VerifiedPaymentState, b$ as VerifyRequest, K as VerifyRequestV2, N as VerifyResponse, W as WRITER_LEASE_REASONS, Q as WriterLeaseReason, X as X402_CORS_HEADERS, T as X402_HEADER_NAMES, c0 as ZERO_ADDRESS, c1 as buildErc8004PaymentRequirements, Z as buildPaymentConflictResponse, _ as buildPaymentRequirements, $ as buildSettleRequest, a0 as buildSettleRequestForVersion, a1 as buildSettleRequestV2, c2 as buildUnavailableResponse, a2 as buildVerifyRequest, a3 as buildVerifyRequestForVersion, a4 as buildVerifyRequestV2, c3 as canRefundEscrow, c4 as canReleaseEscrow, c5 as carryFailureFields, a5 as create402Response, a6 as createHonoMiddleware, a7 as createIdempotencyKey, a8 as createPaymentMiddleware, c6 as epochToDate, c7 as escrowTimeRemaining, a9 as extractPaymentFromHeaders, aa as facilitatorFetch, ab as getCorsHeaders, c8 as getEscrowContractsByChainId, c9 as getEscrowOperatorGeneration, ca as getEscrowSupportedChainIds, cb as isAlive, ac as isAmbiguousLeaseReason, ad as isAuthorizationAlreadyUsed, ae as isAuthorizationInFlight, cc as isEscrowExpired, cd as isEscrowSupportedOnChain, ce as isRegisterJobTerminal, af as isReplayableLeaseReason, ag as isSettlementUnconfirmed, ai as parseFacilitatorErrorBody, cf as parsePaymentHeader, aj as parseRetryAfterSeconds, ak as readFacilitatorError, al as resolveEnvelopeVersion, cg as supportsRelayedFeedback, ch as supportsSolanaFeedback, am as toPaymentRequirementsV2, an as toResourceInfoV2, ci as wireNetwork } from '../index-vMFUhX5W.js';
2
+ export { a as FacilitatorReceipt, F as FetchReceiptResult, P as PaymentState, b as PurchaseContext, c as RECEIPT_ISSUER, R as ReceiptFetchOptions, d as ReceiptKeys, e as STACK_KEY_HEADER, S as StackKeyOptions, f as StackKeyRedirectError, g as canonicalReceiptJson, h as createPurchaseContext, i as fetchWithReceipt, j as getFacilitatorReceipt, m as mergeHeaderList, k as mergePaymentResponseHeaders, p as parseFacilitatorReceipt, l as paymentResponseHeaders, n as purchaseContextHeader, r as receiptCommitment, o as receiptFromErrorBody, q as receiptFromResponse, v as validatePurchaseContext, s as verifyFacilitatorReceipt } from '../receipts-8XsMeo1y.js';
3
+ import '../index-DagQ74ZQ.js';
4
+ export { A as AMBIGUOUS_LEASE_REASONS, a as AUTHORIZATION_ALREADY_SETTLED, b as AUTHORIZATION_IN_FLIGHT, c as AdmittedAuthorizationCode, ap as AdvancedAuthorizationResult, aq as AdvancedEscrowClient, ar as AdvancedEscrowClientOptions, as as AdvancedEscrowContracts, at as AdvancedEscrowTaskTier, au as AdvancedPaymentInfo, av as AdvancedTransactionResult, aw as AgentId, ax as AgentIdentity, ay as AgentRegistration, az as AgentRegistrationFile, aA as AgentService, aB as AtomStats, aC as BASE_MAINNET_CONTRACTS, aD as BazaarClient, aE as BazaarClientOptions, aF as BazaarDiscoverOptions, aG as BazaarDiscoverResponse, aH as BazaarRegisterOptions, aI as BazaarResource, aJ as CreateEscrowOptions, D as DEFAULT_FACILITATOR_RETRIES, d as DEFAULT_RETRY_AFTER_SECONDS, aK as DEPOSIT_LIMIT_USDC, aL as DiscoveryAccepts, aM as DiscoveryCuration, aN as DiscoveryHealth, aO as DiscoveryHealthStatus, aP as DiscoveryListOptions, aQ as DiscoveryPagination, aR as DiscoveryRegisterOptions, aS as DiscoveryResource, aT as DiscoveryResponse, aU as DiscoverySource, aV as DiscoveryStats, aW as DiscoveryTier, aX as Dispute, aY as DisputeOutcome, aZ as ERC8004_CONTRACTS, a_ as ERC8004_EXTENSION_ID, a$ as ESCROW_CONTRACTS, b0 as ESCROW_NOTHING_TO_VOID, b1 as ESCROW_OPERATOR_GENERATION, b2 as ESCROW_OPERATOR_NOT_DEPLOYED, b3 as ESCROW_TIMEOUT_MS, b4 as ESCROW_UNSUPPORTED_ON_GENERATION, b5 as ESCROW_VOID_AMOUNT_MISMATCH, b6 as Erc8004Client, b7 as Erc8004ClientOptions, b8 as Erc8004LookupError, b9 as Erc8004Network, ba as EscrowClient, bb as EscrowClientOptions, bc as EscrowOperatorGeneration, bd as EscrowPayment, be as EscrowStateResponse, bf as EscrowStatus, F as FacilitatorCallOptions, e as FacilitatorClient, f as FacilitatorClientOptions, g as FacilitatorErrorInfo, h as FacilitatorFailureFields, i as FacilitatorFetchOptions, bg as FeedbackEntry, bh as FeedbackParams, bi as FeedbackRequest, bj as FeedbackResponse, bk as HEALTH_FILTERS, H as HonoMiddlewareOptions, I as IDEMPOTENCY_KEY_HEADER, j as IDEMPOTENT_REPLAYED_HEADER, bl as IdentityByOwnerResponse, bm as IdentityMetadataResponse, bn as IdentityTotalSupplyResponse, bo as LifecycleAuthOptions, M as MAX_RETRY_AFTER_SECONDS, bp as MAX_SEARCH_LEN, bq as MetadataEntryParam, br as OPERATOR_ABI, bs as OPERATOR_ABI_CREATE3, bt as OPERATOR_ABI_V3, bu as PAYMENT_INFO_TYPEHASH, P as ParsedFacilitatorErrorBody, v as PaymentAcceptance, w as PaymentConflictResponse, x as PaymentMiddlewareOptions, y as PaymentPayloadV2, bv as PaymentRequirementResolver, bw as PaymentRequirements, bx as PaymentRequirementsOptions, z as PaymentRequirementsV2, by as PrepareRelayFeedbackRequest, bz as PrepareRelayFeedbackResponse, bA as PrepareRelayResponseRequest, bB as PrepareSolanaFeedbackRequest, bC as PrepareSolanaFeedbackResponse, bD as ProofOfPayment, R as RECEIPT_REQUEST_CONFLICT, bE as RELAYED_FEEDBACK_NETWORKS, C as REPLAYABLE_LEASE_REASONS, bF as RefundRequest, bG as RefundStatus, bH as RegisterAgentRequest, bI as RegisterAgentResponse, bJ as RegisterJobResponse, bK as RegisterJobStatus, bL as RegistrationPendingError, bM as RelayAuthorizationParams, bN as ReputationResponse, bO as ReputationSummary, bP as RequestRefundOptions, E as ResourceInfoV2, S as SETTLEMENT_UNCONFIRMED, bQ as SOLANA_FEEDBACK_NETWORKS, bR as SettleRequest, G as SettleRequestV2, J as SettleResponse, bS as SettleResponseWithProof, bT as SubmitRelayFeedbackRequest, bU as SubmitRelayResponseRequest, bV as SubmitSolanaFeedbackRequest, bW as TIER_FILTERS, bX as TIER_TIMINGS, bY as USDC_DOMAIN_NAME, bZ as UnavailableBody, b_ as UnavailableResponse, V as VerifiedPaymentState, b$ as VerifyRequest, K as VerifyRequestV2, N as VerifyResponse, W as WRITER_LEASE_REASONS, Q as WriterLeaseReason, X as X402_CORS_HEADERS, T as X402_HEADER_NAMES, c0 as ZERO_ADDRESS, c1 as buildErc8004PaymentRequirements, Z as buildPaymentConflictResponse, _ as buildPaymentRequirements, $ as buildSettleRequest, a0 as buildSettleRequestForVersion, a1 as buildSettleRequestV2, c2 as buildUnavailableResponse, a2 as buildVerifyRequest, a3 as buildVerifyRequestForVersion, a4 as buildVerifyRequestV2, c3 as canRefundEscrow, c4 as canReleaseEscrow, c5 as carryFailureFields, a5 as create402Response, a6 as createHonoMiddleware, a7 as createIdempotencyKey, a8 as createPaymentMiddleware, c6 as epochToDate, c7 as escrowTimeRemaining, a9 as extractPaymentFromHeaders, aa as facilitatorFetch, ab as getCorsHeaders, c8 as getEscrowContractsByChainId, c9 as getEscrowOperatorGeneration, ca as getEscrowSupportedChainIds, cb as isAlive, ac as isAmbiguousLeaseReason, ad as isAuthorizationAlreadyUsed, ae as isAuthorizationInFlight, cc as isEscrowExpired, cd as isEscrowSupportedOnChain, ce as isRegisterJobTerminal, af as isReplayableLeaseReason, ag as isSettlementUnconfirmed, ai as parseFacilitatorErrorBody, cf as parsePaymentHeader, aj as parseRetryAfterSeconds, ak as readFacilitatorError, al as resolveEnvelopeVersion, cg as supportsRelayedFeedback, ch as supportsSolanaFeedback, am as toPaymentRequirementsV2, an as toResourceInfoV2, ci as wireNetwork } from '../index-CYMXb5eC.js';
@@ -11,6 +11,127 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
11
11
  if (typeof require !== "undefined") return require.apply(this, arguments);
12
12
  throw Error('Dynamic require of "' + x + '" is not supported');
13
13
  });
14
+
15
+ // src/backend/stack-key.ts
16
+ var STACK_KEY_HEADER = "X-UVD-Stack-Key";
17
+ var STACK_KEY_FORMAT = /^uvdsk_[A-Za-z0-9_-]{43,128}$/;
18
+ var LEADING_BOM = /^\uFEFF/;
19
+ var EDGE_WHITESPACE = /^[ \t\r\n]+|[ \t\r\n]+$/g;
20
+ var HOUSE_FACILITATOR_HOSTS = ["facilitator.ultravioletadao.xyz"];
21
+ var LOOPBACK_HOSTS = ["127.0.0.1", "localhost"];
22
+ var StackKeyRedirectError = class extends Error {
23
+ /** The redirect status, or `0` for an opaque redirect (browsers). */
24
+ status;
25
+ constructor(status) {
26
+ super(
27
+ `[x402] the facilitator answered a redirect (${status || "opaque"}) to a request carrying ${STACK_KEY_HEADER}; the stack key does not follow redirects. Point the client at the facilitator's final URL.`
28
+ );
29
+ this.name = "StackKeyRedirectError";
30
+ this.status = status;
31
+ }
32
+ };
33
+ var bindings = /* @__PURE__ */ new WeakMap();
34
+ var warnedFormat = false;
35
+ var warnedHost = false;
36
+ function readEnv() {
37
+ try {
38
+ return typeof process !== "undefined" ? process.env?.UVD_STACK_KEY : void 0;
39
+ } catch {
40
+ return void 0;
41
+ }
42
+ }
43
+ function resolveKey(option) {
44
+ const fromOption = option !== void 0 && option !== null;
45
+ const raw = fromOption ? option : readEnv();
46
+ if (raw === void 0 || raw === null) return void 0;
47
+ const key = typeof raw === "string" ? raw.replace(LEADING_BOM, "").replace(EDGE_WHITESPACE, "") : void 0;
48
+ if (key === "") return void 0;
49
+ if (key !== void 0 && STACK_KEY_FORMAT.test(key)) return key;
50
+ if (!warnedFormat) {
51
+ warnedFormat = true;
52
+ console.warn(
53
+ `[x402] stack key ignored (${fromOption ? "stackKey option" : "UVD_STACK_KEY"}): it is not "uvdsk_" followed by 43-128 base64url characters. Requests go out without ${STACK_KEY_HEADER}.`
54
+ );
55
+ }
56
+ return void 0;
57
+ }
58
+ function listedHosts(option) {
59
+ if (!Array.isArray(option)) return [];
60
+ return option.filter((host) => typeof host === "string").map((host) => host.trim().toLowerCase()).filter((host) => host !== "");
61
+ }
62
+ function isHouseFacilitator(url, listed) {
63
+ const host = url.hostname.toLowerCase();
64
+ if (url.protocol === "https:") return HOUSE_FACILITATOR_HOSTS.includes(host) || listed.includes(host);
65
+ if (url.protocol === "http:") return LOOPBACK_HOSTS.includes(host) && listed.includes(host);
66
+ return false;
67
+ }
68
+ function bindStackKey(owner, options) {
69
+ const key = resolveKey(options?.stackKey);
70
+ if (key !== void 0) bindings.set(owner, { key, hosts: listedHosts(options?.stackKeyHosts) });
71
+ }
72
+ function keyFor(owner, url) {
73
+ const binding = bindings.get(owner);
74
+ if (binding === void 0) return void 0;
75
+ let parsed;
76
+ try {
77
+ parsed = new URL(url);
78
+ } catch {
79
+ parsed = void 0;
80
+ }
81
+ if (parsed !== void 0 && isHouseFacilitator(parsed, binding.hosts)) return binding.key;
82
+ if (!warnedHost) {
83
+ warnedHost = true;
84
+ const where = parsed !== void 0 ? `${parsed.protocol}//${parsed.host}` : "an unparseable URL";
85
+ console.warn(
86
+ `[x402] stack key not sent: ${where} is not a house facilitator. The key goes only over https to ${HOUSE_FACILITATOR_HOSTS.join(", ")} or to a host in stackKeyHosts (plain http only to 127.0.0.1 or localhost listed there).`
87
+ );
88
+ }
89
+ return void 0;
90
+ }
91
+ function headersWithKey(headers, key) {
92
+ const out = {};
93
+ if (typeof Headers !== "undefined" && headers instanceof Headers) {
94
+ headers.forEach((value, name) => {
95
+ out[name] = value;
96
+ });
97
+ } else if (Array.isArray(headers)) {
98
+ for (const [name, value] of headers) out[name] = value;
99
+ } else if (headers) {
100
+ Object.assign(out, headers);
101
+ }
102
+ for (const name of Object.keys(out)) {
103
+ if (name.toLowerCase() === STACK_KEY_HEADER.toLowerCase()) delete out[name];
104
+ }
105
+ out[STACK_KEY_HEADER] = key;
106
+ return out;
107
+ }
108
+ function isRedirect(response) {
109
+ return response.type === "opaqueredirect" || response.status >= 300 && response.status < 400;
110
+ }
111
+ async function stackKeyFetch(owner, url, init, fetchImpl) {
112
+ const doFetch = fetchImpl ?? fetch;
113
+ const key = keyFor(owner, url);
114
+ if (key === void 0) return doFetch(url, init);
115
+ const response = await doFetch(url, { ...init, headers: headersWithKey(init?.headers, key), redirect: "manual" });
116
+ if (isRedirect(response)) {
117
+ try {
118
+ await response.body?.cancel();
119
+ } catch {
120
+ }
121
+ throw new StackKeyRedirectError(response.status);
122
+ }
123
+ return response;
124
+ }
125
+ function stackKeyFetcher(owner, fetchImpl) {
126
+ return (input, init) => stackKeyFetch(
127
+ owner,
128
+ typeof input === "string" ? input : input instanceof URL ? input.href : input.url,
129
+ init,
130
+ fetchImpl
131
+ );
132
+ }
133
+
134
+ // src/receipts.ts
14
135
  var RECEIPT_ISSUER = "https://facilitator.ultravioletadao.xyz";
15
136
  var encoder = new TextEncoder();
16
137
  var decoder = new TextDecoder("utf-8", { fatal: true });
@@ -204,7 +325,9 @@ async function fetchWithReceipt(fetchClient, url, options) {
204
325
  async function getFacilitatorReceipt(receiptId, context, options = {}) {
205
326
  if (!/^[0-9a-f-]{36}$/.test(receiptId)) throw new Error("invalid receipt ID");
206
327
  const issuer = options.issuer || RECEIPT_ISSUER;
207
- const response = await (options.fetchImpl || globalThis.fetch)(`${issuer}/receipts/${receiptId}`, { headers: { Authorization: `Bearer ${context.accessToken}` } });
328
+ const owner = {};
329
+ bindStackKey(owner, options);
330
+ const response = await stackKeyFetch(owner, `${issuer}/receipts/${receiptId}`, { headers: { Authorization: `Bearer ${context.accessToken}` } }, options.fetchImpl || globalThis.fetch);
208
331
  if (!response.ok) throw new Error(`receipt lookup failed: ${response.status}`);
209
332
  const receipt = parseFacilitatorReceipt((await response.json()).receipt);
210
333
  if (!receipt || receipt.issuer !== issuer || receipt.purchaseId !== context.purchaseId) throw new Error("receipt lookup mismatch");
@@ -2194,6 +2317,7 @@ var FacilitatorClient = class {
2194
2317
  this.timeout = options.timeout || 3e4;
2195
2318
  this.retries = options.retries;
2196
2319
  this.x402Version = options.x402Version ?? "auto";
2320
+ bindStackKey(this, options);
2197
2321
  }
2198
2322
  /**
2199
2323
  * Get timeout for a specific network, using per-chain defaults when no explicit timeout was set.
@@ -2240,7 +2364,7 @@ var FacilitatorClient = class {
2240
2364
  headers: facilitatorHeaders(idempotencyKey, options.receiptContext),
2241
2365
  body: JSON.stringify(body)
2242
2366
  },
2243
- { timeoutMs: this.timeout, retries: this.retries }
2367
+ { timeoutMs: this.timeout, retries: this.retries, fetchImpl: stackKeyFetcher(this) }
2244
2368
  );
2245
2369
  if (error) {
2246
2370
  return {
@@ -2301,7 +2425,7 @@ var FacilitatorClient = class {
2301
2425
  headers: facilitatorHeaders(idempotencyKey, options.receiptContext),
2302
2426
  body: JSON.stringify(body)
2303
2427
  },
2304
- { timeoutMs: settleTimeout, retries: this.retries }
2428
+ { timeoutMs: settleTimeout, retries: this.retries, fetchImpl: stackKeyFetcher(this) }
2305
2429
  );
2306
2430
  if (error) {
2307
2431
  return {
@@ -2418,7 +2542,7 @@ var FacilitatorClient = class {
2418
2542
  */
2419
2543
  async healthCheck() {
2420
2544
  try {
2421
- const response = await fetch(`${this.baseUrl}/health`, {
2545
+ const response = await stackKeyFetch(this, `${this.baseUrl}/health`, {
2422
2546
  method: "GET"
2423
2547
  });
2424
2548
  return response.ok;
@@ -2432,7 +2556,7 @@ var FacilitatorClient = class {
2432
2556
  * @returns Version info (e.g., { version: "1.37.0" })
2433
2557
  */
2434
2558
  async getVersion() {
2435
- const response = await fetch(`${this.baseUrl}/version`, {
2559
+ const response = await stackKeyFetch(this, `${this.baseUrl}/version`, {
2436
2560
  method: "GET"
2437
2561
  });
2438
2562
  if (!response.ok) {
@@ -2455,7 +2579,7 @@ var FacilitatorClient = class {
2455
2579
  * ```
2456
2580
  */
2457
2581
  async getSupported() {
2458
- const response = await fetch(`${this.baseUrl}/supported`, {
2582
+ const response = await stackKeyFetch(this, `${this.baseUrl}/supported`, {
2459
2583
  method: "GET"
2460
2584
  });
2461
2585
  if (!response.ok) {
@@ -2482,7 +2606,7 @@ var FacilitatorClient = class {
2482
2606
  * unrecognised; render the atomic value rather than guessing a scale.
2483
2607
  */
2484
2608
  async getStats() {
2485
- const response = await fetch(`${this.baseUrl}/api/stats`, { method: "GET" });
2609
+ const response = await stackKeyFetch(this, `${this.baseUrl}/api/stats`, { method: "GET" });
2486
2610
  if (!response.ok) {
2487
2611
  const errorText = await response.text();
2488
2612
  throw new Error(`GET /api/stats failed: ${response.status} - ${errorText}`);
@@ -2505,7 +2629,8 @@ var FacilitatorClient = class {
2505
2629
  if (options.limit !== void 0) params.set("limit", String(options.limit));
2506
2630
  if (options.network) params.set("network", options.network);
2507
2631
  const query = params.toString();
2508
- const response = await fetch(
2632
+ const response = await stackKeyFetch(
2633
+ this,
2509
2634
  `${this.baseUrl}/transactions${query ? `?${query}` : ""}`,
2510
2635
  { method: "GET" }
2511
2636
  );
@@ -2527,7 +2652,7 @@ var FacilitatorClient = class {
2527
2652
  * ```
2528
2653
  */
2529
2654
  async getBlacklist() {
2530
- const response = await fetch(`${this.baseUrl}/blacklist`, {
2655
+ const response = await stackKeyFetch(this, `${this.baseUrl}/blacklist`, {
2531
2656
  method: "GET"
2532
2657
  });
2533
2658
  if (!response.ok) {
@@ -2568,7 +2693,7 @@ var FacilitatorClient = class {
2568
2693
  const controller = new AbortController();
2569
2694
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
2570
2695
  try {
2571
- const response = await fetch(`${this.baseUrl}/accepts`, {
2696
+ const response = await stackKeyFetch(this, `${this.baseUrl}/accepts`, {
2572
2697
  method: "POST",
2573
2698
  headers: { "Content-Type": "application/json" },
2574
2699
  body: JSON.stringify({
@@ -2880,7 +3005,9 @@ function createPaymentMiddleware(getRequirements, options = {}) {
2880
3005
  const client = new FacilitatorClient({
2881
3006
  baseUrl: options.facilitatorUrl || options.baseUrl,
2882
3007
  timeout: options.timeout,
2883
- retries: options.retries
3008
+ retries: options.retries,
3009
+ stackKey: options.stackKey,
3010
+ stackKeyHosts: options.stackKeyHosts
2884
3011
  });
2885
3012
  const settlementStrategy = options.settlementStrategy || "before-handler";
2886
3013
  return async (req, res, next) => {
@@ -2982,7 +3109,9 @@ function createHonoMiddleware(options) {
2982
3109
  const client = new FacilitatorClient({
2983
3110
  baseUrl: options.facilitatorUrl || options.baseUrl,
2984
3111
  timeout: options.timeout,
2985
- retries: options.retries
3112
+ retries: options.retries,
3113
+ stackKey: options.stackKey,
3114
+ stackKeyHosts: options.stackKeyHosts
2986
3115
  });
2987
3116
  const settlementStrategy = options.settlementStrategy || "before-handler";
2988
3117
  if (!options.accepts[0]) {
@@ -3097,6 +3226,7 @@ var BazaarClient = class {
3097
3226
  constructor(options = {}) {
3098
3227
  this.baseUrl = (options.baseUrl || "https://facilitator.ultravioletadao.xyz").replace(/\/+$/, "");
3099
3228
  this.timeout = options.timeout || 3e4;
3229
+ bindStackKey(this, options);
3100
3230
  }
3101
3231
  /**
3102
3232
  * Issue a request against the facilitator with the configured timeout.
@@ -3105,7 +3235,7 @@ var BazaarClient = class {
3105
3235
  const controller = new AbortController();
3106
3236
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3107
3237
  try {
3108
- const response = await fetch(`${this.baseUrl}${path}`, {
3238
+ const response = await stackKeyFetch(this, `${this.baseUrl}${path}`, {
3109
3239
  ...init,
3110
3240
  headers: { Accept: "application/json", ...init?.headers || {} },
3111
3241
  signal: controller.signal
@@ -3241,7 +3371,7 @@ var BazaarClient = class {
3241
3371
  const controller = new AbortController();
3242
3372
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3243
3373
  try {
3244
- const response = await fetch(`${this.baseUrl}/health`, {
3374
+ const response = await stackKeyFetch(this, `${this.baseUrl}/health`, {
3245
3375
  method: "GET",
3246
3376
  signal: controller.signal
3247
3377
  });
@@ -3269,6 +3399,7 @@ var EscrowClient = class {
3269
3399
  this.baseUrl = options.baseUrl || "https://escrow.ultravioletadao.xyz";
3270
3400
  this.apiKey = options.apiKey;
3271
3401
  this.timeout = options.timeout || 3e4;
3402
+ bindStackKey(this, options);
3272
3403
  }
3273
3404
  getHeaders(authenticated = false) {
3274
3405
  const headers = {
@@ -3293,7 +3424,7 @@ var EscrowClient = class {
3293
3424
  const controller = new AbortController();
3294
3425
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3295
3426
  try {
3296
- const response = await fetch(url, {
3427
+ const response = await stackKeyFetch(this, url, {
3297
3428
  method: "POST",
3298
3429
  headers: this.getHeaders(true),
3299
3430
  body: JSON.stringify({
@@ -3326,7 +3457,7 @@ var EscrowClient = class {
3326
3457
  const controller = new AbortController();
3327
3458
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3328
3459
  try {
3329
- const response = await fetch(url, {
3460
+ const response = await stackKeyFetch(this, url, {
3330
3461
  method: "GET",
3331
3462
  headers: this.getHeaders(),
3332
3463
  signal: controller.signal
@@ -3355,7 +3486,7 @@ var EscrowClient = class {
3355
3486
  const controller = new AbortController();
3356
3487
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3357
3488
  try {
3358
- const response = await fetch(url, {
3489
+ const response = await stackKeyFetch(this, url, {
3359
3490
  method: "POST",
3360
3491
  headers: this.getHeaders(true),
3361
3492
  signal: controller.signal
@@ -3384,7 +3515,7 @@ var EscrowClient = class {
3384
3515
  const controller = new AbortController();
3385
3516
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3386
3517
  try {
3387
- const response = await fetch(url, {
3518
+ const response = await stackKeyFetch(this, url, {
3388
3519
  method: "POST",
3389
3520
  headers: this.getHeaders(true),
3390
3521
  body: JSON.stringify({
@@ -3417,7 +3548,7 @@ var EscrowClient = class {
3417
3548
  const controller = new AbortController();
3418
3549
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3419
3550
  try {
3420
- const response = await fetch(url, {
3551
+ const response = await stackKeyFetch(this, url, {
3421
3552
  method: "POST",
3422
3553
  headers: this.getHeaders(true),
3423
3554
  body: JSON.stringify({ amount }),
@@ -3446,7 +3577,7 @@ var EscrowClient = class {
3446
3577
  const controller = new AbortController();
3447
3578
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3448
3579
  try {
3449
- const response = await fetch(url, {
3580
+ const response = await stackKeyFetch(this, url, {
3450
3581
  method: "POST",
3451
3582
  headers: this.getHeaders(true),
3452
3583
  body: JSON.stringify({ reason }),
@@ -3474,7 +3605,7 @@ var EscrowClient = class {
3474
3605
  const controller = new AbortController();
3475
3606
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3476
3607
  try {
3477
- const response = await fetch(url, {
3608
+ const response = await stackKeyFetch(this, url, {
3478
3609
  method: "GET",
3479
3610
  headers: this.getHeaders(),
3480
3611
  signal: controller.signal
@@ -3505,7 +3636,7 @@ var EscrowClient = class {
3505
3636
  const controller = new AbortController();
3506
3637
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3507
3638
  try {
3508
- const response = await fetch(url, {
3639
+ const response = await stackKeyFetch(this, url, {
3509
3640
  method: "POST",
3510
3641
  headers: this.getHeaders(true),
3511
3642
  body: JSON.stringify({ reason, evidence }),
@@ -3534,7 +3665,7 @@ var EscrowClient = class {
3534
3665
  const controller = new AbortController();
3535
3666
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3536
3667
  try {
3537
- const response = await fetch(url, {
3668
+ const response = await stackKeyFetch(this, url, {
3538
3669
  method: "POST",
3539
3670
  headers: this.getHeaders(true),
3540
3671
  body: JSON.stringify({ evidence }),
@@ -3562,7 +3693,7 @@ var EscrowClient = class {
3562
3693
  const controller = new AbortController();
3563
3694
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3564
3695
  try {
3565
- const response = await fetch(url, {
3696
+ const response = await stackKeyFetch(this, url, {
3566
3697
  method: "GET",
3567
3698
  headers: this.getHeaders(),
3568
3699
  signal: controller.signal
@@ -3595,7 +3726,7 @@ var EscrowClient = class {
3595
3726
  const controller = new AbortController();
3596
3727
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3597
3728
  try {
3598
- const response = await fetch(url, {
3729
+ const response = await stackKeyFetch(this, url, {
3599
3730
  method: "GET",
3600
3731
  headers: this.getHeaders(true),
3601
3732
  signal: controller.signal
@@ -3635,7 +3766,7 @@ var EscrowClient = class {
3635
3766
  const controller = new AbortController();
3636
3767
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3637
3768
  try {
3638
- const response = await fetch(url, {
3769
+ const response = await stackKeyFetch(this, url, {
3639
3770
  method: "POST",
3640
3771
  headers: this.getHeaders(),
3641
3772
  body: JSON.stringify(options),
@@ -3659,7 +3790,7 @@ var EscrowClient = class {
3659
3790
  */
3660
3791
  async healthCheck() {
3661
3792
  try {
3662
- const response = await fetch(`${this.baseUrl}/health`, {
3793
+ const response = await stackKeyFetch(this, `${this.baseUrl}/health`, {
3663
3794
  method: "GET"
3664
3795
  });
3665
3796
  return response.ok;
@@ -3989,6 +4120,7 @@ var Erc8004Client = class {
3989
4120
  this.baseUrl = options.baseUrl || "https://facilitator.ultravioletadao.xyz";
3990
4121
  this.timeout = options.timeout || 3e4;
3991
4122
  this.retries = options.retries;
4123
+ bindStackKey(this, options);
3992
4124
  }
3993
4125
  /**
3994
4126
  * POST a write route, keeping a refusal readable.
@@ -4014,7 +4146,7 @@ var Erc8004Client = class {
4014
4146
  },
4015
4147
  body: JSON.stringify(body)
4016
4148
  },
4017
- { timeoutMs: this.timeout, retries: this.retries }
4149
+ { timeoutMs: this.timeout, retries: this.retries, fetchImpl: stackKeyFetcher(this) }
4018
4150
  );
4019
4151
  }
4020
4152
  /**
@@ -4029,7 +4161,7 @@ var Erc8004Client = class {
4029
4161
  const controller = new AbortController();
4030
4162
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
4031
4163
  try {
4032
- const response = await fetch(url, {
4164
+ const response = await stackKeyFetch(this, url, {
4033
4165
  method: "GET",
4034
4166
  headers: { "Accept": "application/json" },
4035
4167
  signal: controller.signal
@@ -4064,7 +4196,7 @@ var Erc8004Client = class {
4064
4196
  const url = `${this.baseUrl}/identity/${wireNetwork(network)}/owner/${address}`;
4065
4197
  const controller = new AbortController();
4066
4198
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
4067
- const response = await fetch(url, {
4199
+ const response = await stackKeyFetch(this, url, {
4068
4200
  method: "GET",
4069
4201
  headers: { Accept: "application/json" },
4070
4202
  signal: controller.signal
@@ -4130,7 +4262,7 @@ var Erc8004Client = class {
4130
4262
  const controller = new AbortController();
4131
4263
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
4132
4264
  try {
4133
- const response = await fetch(url, {
4265
+ const response = await stackKeyFetch(this, url, {
4134
4266
  method: "GET",
4135
4267
  headers: { "Accept": "application/json" },
4136
4268
  signal: controller.signal
@@ -4264,7 +4396,7 @@ var Erc8004Client = class {
4264
4396
  const controller = new AbortController();
4265
4397
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
4266
4398
  try {
4267
- const response = await fetch(url, {
4399
+ const response = await stackKeyFetch(this, url, {
4268
4400
  method: "POST",
4269
4401
  headers: {
4270
4402
  "Content-Type": "application/json",
@@ -4398,7 +4530,7 @@ var Erc8004Client = class {
4398
4530
  const controller = new AbortController();
4399
4531
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
4400
4532
  try {
4401
- const response = await fetch(url, {
4533
+ const response = await stackKeyFetch(this, url, {
4402
4534
  method: "POST",
4403
4535
  headers: {
4404
4536
  "Content-Type": "application/json",
@@ -4544,7 +4676,7 @@ var Erc8004Client = class {
4544
4676
  const controller = new AbortController();
4545
4677
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
4546
4678
  try {
4547
- const response = await fetch(url, {
4679
+ const response = await stackKeyFetch(this, url, {
4548
4680
  method: "GET",
4549
4681
  headers: { "Accept": "application/json" },
4550
4682
  signal: controller.signal
@@ -4808,7 +4940,7 @@ var Erc8004Client = class {
4808
4940
  const url = `${this.baseUrl}/register/status/${encodeURIComponent(jobId)}`;
4809
4941
  const controller = new AbortController();
4810
4942
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
4811
- const response = await fetch(url, {
4943
+ const response = await stackKeyFetch(this, url, {
4812
4944
  method: "GET",
4813
4945
  headers: { Accept: "application/json" },
4814
4946
  signal: controller.signal
@@ -4858,7 +4990,7 @@ var Erc8004Client = class {
4858
4990
  const controller = new AbortController();
4859
4991
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
4860
4992
  try {
4861
- const response = await fetch(url, {
4993
+ const response = await stackKeyFetch(this, url, {
4862
4994
  method: "GET",
4863
4995
  headers: { "Accept": "application/json" },
4864
4996
  signal: controller.signal
@@ -4887,7 +5019,7 @@ var Erc8004Client = class {
4887
5019
  const controller = new AbortController();
4888
5020
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
4889
5021
  try {
4890
- const response = await fetch(url, {
5022
+ const response = await stackKeyFetch(this, url, {
4891
5023
  method: "GET",
4892
5024
  headers: { "Accept": "application/json" },
4893
5025
  signal: controller.signal
@@ -4914,7 +5046,7 @@ var Erc8004Client = class {
4914
5046
  const controller = new AbortController();
4915
5047
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
4916
5048
  try {
4917
- const response = await fetch(url, {
5049
+ const response = await stackKeyFetch(this, url, {
4918
5050
  method: "GET",
4919
5051
  headers: { "Accept": "application/json" },
4920
5052
  signal: controller.signal
@@ -5256,6 +5388,7 @@ var AdvancedEscrowClient = class {
5256
5388
  this.gasLimit = options.gasLimit || 3e5;
5257
5389
  this.timeout = options.timeout || ESCROW_TIMEOUT_MS[this.chainId] || DEFAULT_ESCROW_TIMEOUT_MS;
5258
5390
  this.retries = options.retries;
5391
+ bindStackKey(this, options);
5259
5392
  if (this.walletAdapter && !this.rpcUrl) {
5260
5393
  throw new Error(
5261
5394
  "AdvancedEscrowClient: rpcUrl is required when using a SigningWalletAdapter. The adapter signs transactions offline; an RPC provider is needed to build and broadcast them."
@@ -5474,7 +5607,7 @@ var AdvancedEscrowClient = class {
5474
5607
  const controller = new AbortController();
5475
5608
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
5476
5609
  try {
5477
- const response = await fetch(`${this.facilitatorUrl}/settle`, {
5610
+ const response = await stackKeyFetch(this, `${this.facilitatorUrl}/settle`, {
5478
5611
  method: "POST",
5479
5612
  headers: { "Content-Type": "application/json" },
5480
5613
  body: JSON.stringify(payload),
@@ -5691,7 +5824,7 @@ var AdvancedEscrowClient = class {
5691
5824
  headers: { "Content-Type": "application/json" },
5692
5825
  body: JSON.stringify(payload)
5693
5826
  },
5694
- { timeoutMs: this.timeout, retries: this.retries }
5827
+ { timeoutMs: this.timeout, retries: this.retries, fetchImpl: stackKeyFetcher(this) }
5695
5828
  );
5696
5829
  if (error) {
5697
5830
  return { success: false, error: error.error, ...failureFields(error) };
@@ -5825,7 +5958,7 @@ var AdvancedEscrowClient = class {
5825
5958
  headers: { "Content-Type": "application/json" },
5826
5959
  body: JSON.stringify(payload)
5827
5960
  },
5828
- { timeoutMs: this.timeout, retries: this.retries }
5961
+ { timeoutMs: this.timeout, retries: this.retries, fetchImpl: stackKeyFetcher(this) }
5829
5962
  );
5830
5963
  if (error) {
5831
5964
  return { success: false, error: error.error, ...failureFields(error) };
@@ -5902,7 +6035,7 @@ var AdvancedEscrowClient = class {
5902
6035
  tokenCollector: this.contracts.tokenCollector
5903
6036
  }
5904
6037
  };
5905
- const response = await fetch(`${this.facilitatorUrl}/escrow/state`, {
6038
+ const response = await stackKeyFetch(this, `${this.facilitatorUrl}/escrow/state`, {
5906
6039
  method: "POST",
5907
6040
  headers: { "Content-Type": "application/json" },
5908
6041
  body: JSON.stringify(payload)
@@ -6206,6 +6339,8 @@ exports.REPLAYABLE_LEASE_REASONS = REPLAYABLE_LEASE_REASONS;
6206
6339
  exports.RegistrationPendingError = RegistrationPendingError;
6207
6340
  exports.SETTLEMENT_UNCONFIRMED = SETTLEMENT_UNCONFIRMED;
6208
6341
  exports.SOLANA_FEEDBACK_NETWORKS = SOLANA_FEEDBACK_NETWORKS;
6342
+ exports.STACK_KEY_HEADER = STACK_KEY_HEADER;
6343
+ exports.StackKeyRedirectError = StackKeyRedirectError;
6209
6344
  exports.TIER_FILTERS = TIER_FILTERS;
6210
6345
  exports.TIER_TIMINGS = TIER_TIMINGS;
6211
6346
  exports.USDC_DOMAIN_NAME = USDC_DOMAIN_NAME;