{"version":3,"sources":["../../src/offer-receipt/eip712.ts","../../src/offer-receipt/signing.ts","../../src/offer-receipt/server.ts","../../src/offer-receipt/client.ts"],"sourcesContent":["/**\n * EIP-712 type definitions for Offer and Receipt signing.\n *\n * The chainId is fixed at 1 (Ethereum mainnet) for all signatures,\n * as EIP-712 serves as an off-chain format independent of actual payment networks.\n */\n\n/** EIP-712 domain for offer signing */\nexport const OFFER_DOMAIN = {\n  name: \"t402 offer\",\n  version: \"1\",\n  chainId: 1,\n} as const;\n\n/** EIP-712 domain for receipt signing */\nexport const RECEIPT_DOMAIN = {\n  name: \"t402 receipt\",\n  version: \"1\",\n  chainId: 1,\n} as const;\n\n/** EIP-712 typed data types for Offer */\nexport const OFFER_TYPES = {\n  Offer: [\n    { name: \"version\", type: \"uint256\" },\n    { name: \"resourceUrl\", type: \"string\" },\n    { name: \"scheme\", type: \"string\" },\n    { name: \"network\", type: \"string\" },\n    { name: \"asset\", type: \"string\" },\n    { name: \"payTo\", type: \"string\" },\n    { name: \"amount\", type: \"string\" },\n    { name: \"validUntil\", type: \"uint256\" },\n  ],\n} as const;\n\n/** EIP-712 typed data types for Receipt */\nexport const RECEIPT_TYPES = {\n  Receipt: [\n    { name: \"version\", type: \"uint256\" },\n    { name: \"network\", type: \"string\" },\n    { name: \"resourceUrl\", type: \"string\" },\n    { name: \"payer\", type: \"string\" },\n    { name: \"issuedAt\", type: \"uint256\" },\n    { name: \"transaction\", type: \"string\" },\n  ],\n} as const;\n\n/** Primary type name for offers */\nexport const OFFER_PRIMARY_TYPE = \"Offer\" as const;\n\n/** Primary type name for receipts */\nexport const RECEIPT_PRIMARY_TYPE = \"Receipt\" as const;\n\n/**\n * Normalize an OfferPayload for EIP-712 signing.\n * Optional fields use 0 or \"\" when absent.\n */\nexport function normalizeOfferForSigning(payload: {\n  version: number;\n  resourceUrl: string;\n  scheme: string;\n  network: string;\n  asset: string;\n  payTo: string;\n  amount: string;\n  validUntil?: number;\n}): Record<string, unknown> {\n  return {\n    version: payload.version,\n    resourceUrl: payload.resourceUrl,\n    scheme: payload.scheme,\n    network: payload.network,\n    asset: payload.asset,\n    payTo: payload.payTo,\n    amount: payload.amount,\n    validUntil: payload.validUntil ?? 0,\n  };\n}\n\n/**\n * Normalize a ReceiptPayload for EIP-712 signing.\n * Optional fields use \"\" when absent.\n */\nexport function normalizeReceiptForSigning(payload: {\n  version: number;\n  network: string;\n  resourceUrl: string;\n  payer: string;\n  issuedAt: number;\n  transaction?: string;\n}): Record<string, unknown> {\n  return {\n    version: payload.version,\n    network: payload.network,\n    resourceUrl: payload.resourceUrl,\n    payer: payload.payer,\n    issuedAt: payload.issuedAt,\n    transaction: payload.transaction ?? \"\",\n  };\n}\n","/**\n * Offer and Receipt signing and verification logic.\n *\n * Supports EIP-712 format. JWS support can be added later.\n */\n\nimport type {\n  OfferPayload,\n  ReceiptPayload,\n  EIP712Offer,\n  EIP712Receipt,\n  SignedOffer,\n  SignedReceipt,\n  EIP712OfferReceiptSigner,\n  EIP712OfferReceiptVerifier,\n} from \"./types\";\n\n// EIP-712 constants are re-exported at the bottom of this file\n\n/**\n * Create a signed offer from payment requirements.\n */\nexport async function createSignedOffer(\n  signer: EIP712OfferReceiptSigner,\n  payload: OfferPayload,\n  acceptIndex?: number,\n): Promise<EIP712Offer> {\n  const signature = await signer.signOffer(payload);\n  return {\n    format: \"eip712\",\n    payload,\n    signature,\n    ...(acceptIndex !== undefined ? { acceptIndex } : {}),\n  };\n}\n\n/**\n * Create a signed receipt after successful payment.\n */\nexport async function createSignedReceipt(\n  signer: EIP712OfferReceiptSigner,\n  payload: ReceiptPayload,\n): Promise<EIP712Receipt> {\n  const signature = await signer.signReceipt(payload);\n  return {\n    format: \"eip712\",\n    payload,\n    signature,\n  };\n}\n\n/**\n * Verify an EIP-712 signed offer.\n * Returns the recovered signer address, or throws if invalid.\n */\nexport async function verifyOffer(\n  verifier: EIP712OfferReceiptVerifier,\n  offer: SignedOffer,\n): Promise<{ valid: boolean; signer?: string; payload?: OfferPayload }> {\n  if (offer.format === \"jws\") {\n    // JWS verification not yet implemented\n    return { valid: false };\n  }\n\n  try {\n    const signerAddress = await verifier.recoverOfferSigner(\n      offer.payload,\n      offer.signature,\n    );\n    return {\n      valid: true,\n      signer: signerAddress,\n      payload: offer.payload,\n    };\n  } catch {\n    return { valid: false };\n  }\n}\n\n/**\n * Verify an EIP-712 signed receipt.\n * Returns the recovered signer address, or throws if invalid.\n */\nexport async function verifyReceipt(\n  verifier: EIP712OfferReceiptVerifier,\n  receipt: SignedReceipt,\n): Promise<{ valid: boolean; signer?: string; payload?: ReceiptPayload }> {\n  if (receipt.format === \"jws\") {\n    // JWS verification not yet implemented\n    return { valid: false };\n  }\n\n  try {\n    const signerAddress = await verifier.recoverReceiptSigner(\n      receipt.payload,\n      receipt.signature,\n    );\n    return {\n      valid: true,\n      signer: signerAddress,\n      payload: receipt.payload,\n    };\n  } catch {\n    return { valid: false };\n  }\n}\n\n/**\n * Match an offer to payment requirements by comparing key fields.\n */\nexport function matchOfferToRequirements(\n  offer: SignedOffer,\n  requirements: {\n    scheme: string;\n    network: string;\n    asset: string;\n    payTo: string;\n    amount: string;\n  },\n): boolean {\n  const payload = offer.format === \"eip712\" ? offer.payload : null;\n  if (!payload) return false;\n\n  return (\n    payload.scheme === requirements.scheme &&\n    payload.network === requirements.network &&\n    payload.asset.toLowerCase() === requirements.asset.toLowerCase() &&\n    payload.payTo.toLowerCase() === requirements.payTo.toLowerCase() &&\n    payload.amount === requirements.amount\n  );\n}\n\n/**\n * Check if an offer has expired.\n */\nexport function isOfferExpired(offer: SignedOffer, nowSeconds?: number): boolean {\n  const payload = offer.format === \"eip712\" ? offer.payload : null;\n  if (!payload) return true;\n\n  if (!payload.validUntil || payload.validUntil === 0) return false;\n\n  const now = nowSeconds ?? Math.floor(Date.now() / 1000);\n  return now > payload.validUntil;\n}\n\n// Re-export domain and normalization for signer implementations\nexport {\n  OFFER_DOMAIN,\n  RECEIPT_DOMAIN,\n  OFFER_TYPES,\n  RECEIPT_TYPES,\n  OFFER_PRIMARY_TYPE,\n  RECEIPT_PRIMARY_TYPE,\n  normalizeOfferForSigning,\n  normalizeReceiptForSigning,\n} from \"./eip712\";\n","/**\n * Server-side offer-receipt extension.\n *\n * Signs offers when generating 402 responses and\n * signs receipts when payment succeeds.\n */\n\nimport type { ResourceServerExtension } from \"@t402/core/types\";\n\nimport type {\n  OfferPayload,\n  ReceiptPayload,\n  SignedOffer,\n  SignedReceipt,\n  EIP712OfferReceiptSigner,\n} from \"./types\";\n\nimport { createSignedOffer, createSignedReceipt } from \"./signing\";\n\n/** Extension key for offer-receipt */\nexport const OFFER_RECEIPT_KEY = \"offer-receipt\";\n\n/**\n * Configuration for the offer-receipt server extension.\n */\nexport interface OfferReceiptServerConfig {\n  /** EIP-712 signer for creating offers and receipts */\n  signer: EIP712OfferReceiptSigner;\n  /** URL of the protected resource (used in offer/receipt payloads) */\n  resourceUrl: string;\n  /** Optional: default validUntil offset in seconds (0 = no expiry) */\n  offerValiditySeconds?: number;\n}\n\n/**\n * Create signed offers from payment requirements (accepts array).\n *\n * Called by the server when generating a 402 response.\n * Each accepted payment method gets a corresponding signed offer.\n */\nexport async function createOffersFromRequirements(\n  config: OfferReceiptServerConfig,\n  accepts: Array<{\n    scheme: string;\n    network: string;\n    asset: string;\n    payTo: string;\n    amount: string;\n  }>,\n): Promise<SignedOffer[]> {\n  const now = Math.floor(Date.now() / 1000);\n  const validUntil = config.offerValiditySeconds\n    ? now + config.offerValiditySeconds\n    : 0;\n\n  const offers: SignedOffer[] = [];\n\n  for (let i = 0; i < accepts.length; i++) {\n    const req = accepts[i];\n    const payload: OfferPayload = {\n      version: 1,\n      resourceUrl: config.resourceUrl,\n      scheme: req.scheme,\n      network: req.network,\n      asset: req.asset,\n      payTo: req.payTo,\n      amount: req.amount,\n      validUntil,\n    };\n\n    const offer = await createSignedOffer(config.signer, payload, i);\n    offers.push(offer);\n  }\n\n  return offers;\n}\n\n/**\n * Create a signed receipt after successful payment.\n *\n * Called by the server after verifying and settling a payment.\n */\nexport async function createReceiptForPayment(\n  config: OfferReceiptServerConfig,\n  params: {\n    network: string;\n    payer: string;\n    transaction?: string;\n  },\n): Promise<SignedReceipt> {\n  const payload: ReceiptPayload = {\n    version: 1,\n    network: params.network,\n    resourceUrl: config.resourceUrl,\n    payer: params.payer,\n    issuedAt: Math.floor(Date.now() / 1000),\n    transaction: params.transaction,\n  };\n\n  return createSignedReceipt(config.signer, payload);\n}\n\n/**\n * Resource server extension that attaches signed offers to 402 responses.\n *\n * Usage:\n * ```ts\n * const extension = offerReceiptServerExtension({\n *   signer: myEIP712Signer,\n *   resourceUrl: \"https://api.example.com/data\",\n *   offerValiditySeconds: 300,\n * });\n *\n * server.registerExtension(extension);\n * ```\n */\nexport function offerReceiptServerExtension(\n  _config: OfferReceiptServerConfig,\n): ResourceServerExtension {\n  return {\n    key: OFFER_RECEIPT_KEY,\n\n    enrichDeclaration: (declaration) => {\n      // The offers will be populated async by the server when it generates\n      // the 402 response via createOffersFromRequirements(). This extension\n      // just declares the key so the framework knows to include it.\n      return {\n        ...(declaration as Record<string, unknown>),\n        info: {\n          offers: [],\n        },\n      };\n    },\n  };\n}\n","/**\n * Client-side offer-receipt extension.\n *\n * Verifies offers before making payment and\n * extracts/stores receipts from success responses.\n */\n\nimport type {\n  OfferPayload,\n  ReceiptPayload,\n  SignedOffer,\n  SignedReceipt,\n  EIP712OfferReceiptVerifier,\n} from \"./types\";\n\nimport { verifyOffer, verifyReceipt, matchOfferToRequirements, isOfferExpired } from \"./signing\";\nimport { OFFER_RECEIPT_KEY } from \"./server\";\n\n/**\n * Extract offers from a 402 response's extensions.\n */\nexport function extractOffers(\n  extensions?: Record<string, unknown>,\n): SignedOffer[] {\n  if (!extensions) return [];\n\n  const ext = extensions[OFFER_RECEIPT_KEY] as\n    | { info?: { offers?: SignedOffer[] } }\n    | undefined;\n\n  return ext?.info?.offers ?? [];\n}\n\n/**\n * Extract a receipt from a success response's extensions.\n */\nexport function extractReceipt(\n  extensions?: Record<string, unknown>,\n): SignedReceipt | null {\n  if (!extensions) return null;\n\n  const ext = extensions[OFFER_RECEIPT_KEY] as\n    | { info?: { receipt?: SignedReceipt } }\n    | undefined;\n\n  return ext?.info?.receipt ?? null;\n}\n\n/**\n * Find and verify the offer that matches specific payment requirements.\n *\n * Returns the verified offer if found and valid, null otherwise.\n */\nexport async function findAndVerifyOffer(\n  verifier: EIP712OfferReceiptVerifier,\n  offers: SignedOffer[],\n  requirements: {\n    scheme: string;\n    network: string;\n    asset: string;\n    payTo: string;\n    amount: string;\n  },\n  options?: {\n    /** Expected signer address (e.g., payTo). If set, verification checks this. */\n    expectedSigner?: string;\n    /** Current time in seconds (for expiry check). Defaults to now. */\n    nowSeconds?: number;\n  },\n): Promise<{\n  offer: SignedOffer;\n  signer: string;\n  payload: OfferPayload;\n} | null> {\n  for (const offer of offers) {\n    // Check if offer matches requirements\n    if (!matchOfferToRequirements(offer, requirements)) continue;\n\n    // Check expiry\n    if (isOfferExpired(offer, options?.nowSeconds)) continue;\n\n    // Verify signature\n    const result = await verifyOffer(verifier, offer);\n    if (!result.valid || !result.signer || !result.payload) continue;\n\n    // Check expected signer if specified\n    if (\n      options?.expectedSigner &&\n      result.signer.toLowerCase() !== options.expectedSigner.toLowerCase()\n    ) {\n      continue;\n    }\n\n    return {\n      offer,\n      signer: result.signer,\n      payload: result.payload,\n    };\n  }\n\n  return null;\n}\n\n/**\n * Verify a receipt from a success response.\n *\n * Returns the verified receipt data if valid, null otherwise.\n */\nexport async function verifyReceiptFromResponse(\n  verifier: EIP712OfferReceiptVerifier,\n  extensions?: Record<string, unknown>,\n  options?: {\n    /** Expected signer address. */\n    expectedSigner?: string;\n  },\n): Promise<{\n  signer: string;\n  payload: ReceiptPayload;\n} | null> {\n  const receipt = extractReceipt(extensions);\n  if (!receipt) return null;\n\n  const result = await verifyReceipt(verifier, receipt);\n  if (!result.valid || !result.signer || !result.payload) return null;\n\n  if (\n    options?.expectedSigner &&\n    result.signer.toLowerCase() !== options.expectedSigner.toLowerCase()\n  ) {\n    return null;\n  }\n\n  return {\n    signer: result.signer,\n    payload: result.payload,\n  };\n}\n"],"mappings":"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","names":[]}