diff --git a/typescript/packages/core/src/server/x402ResourceServer.ts b/typescript/packages/core/src/server/x402ResourceServer.ts index 35b5f6ea9..6f8d73b05 100644 --- a/typescript/packages/core/src/server/x402ResourceServer.ts +++ b/typescript/packages/core/src/server/x402ResourceServer.ts @@ -168,6 +168,16 @@ export class x402ResourceServer { return this; } + /** + * Check if an extension is registered. + * + * @param key - The extension key + * @returns True if the extension is registered + */ + hasExtension(key: string): boolean { + return this.registeredExtensions.has(key); + } + /** * Enriches declared extensions using registered extension hooks. * diff --git a/typescript/packages/http/express/src/index.ts b/typescript/packages/http/express/src/index.ts index 071f981c8..ad04ff4ba 100644 --- a/typescript/packages/http/express/src/index.ts +++ b/typescript/packages/http/express/src/index.ts @@ -89,9 +89,10 @@ export function paymentMiddleware( // httpServer.initialize() fetches facilitator support and validates routes let initPromise: Promise | null = syncFacilitatorOnStart ? httpServer.initialize() : null; - // Dynamically register bazaar extension if routes declare it + // Dynamically register bazaar extension if routes declare it and not already registered + // Skip if pre-registered (e.g., in serverless environments where static imports are used) let bazaarPromise: Promise | null = null; - if (checkIfBazaarNeeded(routes)) { + if (checkIfBazaarNeeded(routes) && !server.hasExtension("bazaar")) { bazaarPromise = import("@x402/extensions/bazaar") .then(({ bazaarResourceServerExtension }) => { server.registerExtension(bazaarResourceServerExtension); diff --git a/typescript/packages/http/hono/src/index.ts b/typescript/packages/http/hono/src/index.ts index 8255c4cd1..1d4253593 100644 --- a/typescript/packages/http/hono/src/index.ts +++ b/typescript/packages/http/hono/src/index.ts @@ -89,9 +89,10 @@ export function paymentMiddleware( // httpServer.initialize() fetches facilitator support and validates routes let initPromise: Promise | null = syncFacilitatorOnStart ? httpServer.initialize() : null; - // Dynamically register bazaar extension if routes declare it + // Dynamically register bazaar extension if routes declare it and not already registered + // Skip if pre-registered (e.g., in serverless environments where static imports are used) let bazaarPromise: Promise | null = null; - if (checkIfBazaarNeeded(routes)) { + if (checkIfBazaarNeeded(routes) && !server.hasExtension("bazaar")) { bazaarPromise = import("@x402/extensions/bazaar") .then(({ bazaarResourceServerExtension }) => { server.registerExtension(bazaarResourceServerExtension); diff --git a/typescript/packages/http/next/src/index.ts b/typescript/packages/http/next/src/index.ts index 798ca1720..75fbe4431 100644 --- a/typescript/packages/http/next/src/index.ts +++ b/typescript/packages/http/next/src/index.ts @@ -65,9 +65,10 @@ export function paymentProxy( ) { const { httpServer, init } = createHttpServer(routes, server, paywall, syncFacilitatorOnStart); - // Dynamically register bazaar extension if routes declare it + // Dynamically register bazaar extension if routes declare it and not already registered + // Skip if pre-registered (e.g., in serverless environments where static imports are used) let bazaarPromise: Promise | null = null; - if (checkIfBazaarNeeded(routes)) { + if (checkIfBazaarNeeded(routes) && !server.hasExtension("bazaar")) { bazaarPromise = import(/* webpackIgnore: true */ "@x402/extensions/bazaar") .then(({ bazaarResourceServerExtension }) => { server.registerExtension(bazaarResourceServerExtension); @@ -220,9 +221,10 @@ export function withX402( const routes = { "*": routeConfig }; const { httpServer, init } = createHttpServer(routes, server, paywall, syncFacilitatorOnStart); - // Dynamically register bazaar extension if route declares it + // Dynamically register bazaar extension if route declares it and not already registered + // Skip if pre-registered (e.g., in serverless environments where static imports are used) let bazaarPromise: Promise | null = null; - if (checkIfBazaarNeeded(routes)) { + if (checkIfBazaarNeeded(routes) && !server.hasExtension("bazaar")) { bazaarPromise = import(/* webpackIgnore: true */ "@x402/extensions/bazaar") .then(({ bazaarResourceServerExtension }) => { server.registerExtension(bazaarResourceServerExtension);