@xapps-platform/backend-kit 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -38,16 +38,62 @@ verify browser widget context server-side before exposing private runtime
38
38
  behavior:
39
39
 
40
40
  ```ts
41
- import { verifyBrowserWidgetContext } from "@xapps-platform/backend-kit";
41
+ import {
42
+ evaluateWidgetBootstrapOriginPolicy,
43
+ verifyBrowserWidgetContext,
44
+ } from "@xapps-platform/backend-kit";
45
+
46
+ const originPolicy = evaluateWidgetBootstrapOriginPolicy({
47
+ hostOrigin: request.body?.hostOrigin,
48
+ allowedOrigins: config.widgetBootstrap.allowedOrigins,
49
+ });
50
+
51
+ if (!originPolicy.ok) {
52
+ reply.code(originPolicy.code === "HOST_ORIGIN_REQUIRED" ? 400 : 403).send({
53
+ ok: false,
54
+ error: {
55
+ code: originPolicy.code,
56
+ message: originPolicy.message,
57
+ },
58
+ });
59
+ return;
60
+ }
42
61
 
43
62
  const verified = await verifyBrowserWidgetContext(gatewayClient, {
44
- hostOrigin: "https://tenant.example.test",
63
+ hostOrigin: originPolicy.hostOrigin,
45
64
  installationId: "inst_123",
46
65
  bindToolName: "submit_form",
47
66
  subjectId: "sub_123",
67
+ bootstrapTicket: request.body?.bootstrapTicket ?? null,
48
68
  });
49
69
  ```
50
70
 
71
+ Recommended shared local config contract for publisher-rendered bootstrap
72
+ routes:
73
+
74
+ - `widgetBootstrap.allowedOrigins`
75
+ - optional app env:
76
+ - `XAPPS_WIDGET_ALLOWED_ORIGINS=https://host.example.test,https://host-b.example.test`
77
+
78
+ This stays local/app-owned on purpose. The package helper standardizes the
79
+ policy behavior without forcing a repo-wide env parser or backend shape.
80
+
81
+ Recommended request-widget posture:
82
+
83
+ - treat the widget asset URL as a public/bootstrap shell
84
+ - keep request-capable UI blocked until widget context is verified server-side
85
+ - do not place private keys, secrets, or durable bearer tokens in `entry.url`
86
+ - direct raw browser hits should stay blocked instead of unlocking private runtime
87
+
88
+ Optional stronger bootstrap transport already supported:
89
+
90
+ - `widgets[].config.xapps.bootstrap_transport = "signed_ticket"`
91
+ - current first slice reuses the short-lived signed widget token as a bootstrap
92
+ ticket and carries it in the iframe URL hash
93
+ - browser widget code can forward it to your backend as `bootstrapTicket`
94
+ - the backend kit verification passthrough accepts that field without changing
95
+ the current default/public bootstrap contract
96
+
51
97
  This is now a real package, not a placeholder or extraction stub. Keep the
52
98
  public entry surface stable and split internal package code behind it.
53
99
 
package/dist/index.d.ts CHANGED
@@ -46,11 +46,29 @@ export type BackendKit = {
46
46
  };
47
47
  export type VerifyBrowserWidgetContextInput = {
48
48
  hostOrigin: string;
49
+ bootstrapTicket?: string | null;
49
50
  installationId?: string | null;
50
51
  bindToolName?: string | null;
51
52
  toolName?: string | null;
52
53
  subjectId?: string | null;
53
54
  };
55
+ export type WidgetBootstrapOriginPolicyInput = {
56
+ hostOrigin: string | null | undefined;
57
+ allowedOrigins?: string[] | string | null | undefined;
58
+ };
59
+ export type WidgetBootstrapOriginPolicyResult = {
60
+ ok: true;
61
+ hostOrigin: string;
62
+ allowedOrigins: string[];
63
+ } | {
64
+ ok: false;
65
+ code: "HOST_ORIGIN_REQUIRED" | "HOST_ORIGIN_NOT_ALLOWED";
66
+ message: string;
67
+ hostOrigin: string | null;
68
+ allowedOrigins: string[];
69
+ };
70
+ export declare function normalizeWidgetBootstrapAllowedOrigins(value: string[] | string | null | undefined): string[];
71
+ export declare function evaluateWidgetBootstrapOriginPolicy(input: WidgetBootstrapOriginPolicyInput): WidgetBootstrapOriginPolicyResult;
54
72
  export declare function verifyBrowserWidgetContext(gatewayClient: {
55
73
  verifyBrowserWidgetContext: (input: VerifyBrowserWidgetContextInput) => Promise<Record<string, unknown>>;
56
74
  }, input: VerifyBrowserWidgetContextInput): Promise<Record<string, unknown>>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -17,6 +17,49 @@ import {
17
17
  normalizeBackendKitOptions,
18
18
  resolvePlatformSecretRefFromEnv
19
19
  } from "./backend/options.js";
20
+ function normalizeOrigin(value) {
21
+ const raw = String(value || "").trim();
22
+ if (!raw) return null;
23
+ try {
24
+ const parsed = new URL(raw);
25
+ if (!parsed.protocol || !parsed.host) return null;
26
+ return parsed.origin;
27
+ } catch {
28
+ return null;
29
+ }
30
+ }
31
+ function normalizeWidgetBootstrapAllowedOrigins(value) {
32
+ const entries = Array.isArray(value) ? value : String(value || "").split(/[,\n]/);
33
+ const normalized = entries.map((entry) => normalizeOrigin(entry)).filter((entry) => Boolean(entry));
34
+ return Array.from(new Set(normalized));
35
+ }
36
+ function evaluateWidgetBootstrapOriginPolicy(input) {
37
+ const hostOrigin = normalizeOrigin(input.hostOrigin);
38
+ const allowedOrigins = normalizeWidgetBootstrapAllowedOrigins(input.allowedOrigins);
39
+ if (!hostOrigin) {
40
+ return {
41
+ ok: false,
42
+ code: "HOST_ORIGIN_REQUIRED",
43
+ message: "Host origin is required to verify browser widget context",
44
+ hostOrigin: null,
45
+ allowedOrigins
46
+ };
47
+ }
48
+ if (allowedOrigins.length > 0 && !allowedOrigins.includes(hostOrigin)) {
49
+ return {
50
+ ok: false,
51
+ code: "HOST_ORIGIN_NOT_ALLOWED",
52
+ message: "Host origin is not allowed for widget bootstrap verification",
53
+ hostOrigin,
54
+ allowedOrigins
55
+ };
56
+ }
57
+ return {
58
+ ok: true,
59
+ hostOrigin,
60
+ allowedOrigins
61
+ };
62
+ }
20
63
  async function verifyBrowserWidgetContext(gatewayClient, input) {
21
64
  return gatewayClient.verifyBrowserWidgetContext(input);
22
65
  }
@@ -78,8 +121,10 @@ export {
78
121
  createPaymentEvidenceHandler,
79
122
  createPaymentRuntime,
80
123
  createReferenceSurfaceModule,
124
+ evaluateWidgetBootstrapOriginPolicy,
81
125
  extractHostedPaymentSessionId,
82
126
  normalizeBackendKitOptions,
127
+ normalizeWidgetBootstrapAllowedOrigins,
83
128
  registerPaymentPageApiRoutes,
84
129
  registerPaymentPageAssetRoute,
85
130
  resolvePlatformSecretRefFromEnv,
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["import {\n createGatewayExecutionModule,\n createHostReferenceModule,\n createReferenceSurfaceModule,\n createHostProxyService,\n} from \"./backend/modules.js\";\nimport {\n buildHostedGatewayPaymentUrl,\n buildModeHostedGatewayPaymentUrl,\n createPaymentEvidenceHandler,\n createPaymentRuntime,\n extractHostedPaymentSessionId,\n registerPaymentPageApiRoutes,\n registerPaymentPageAssetRoute,\n} from \"./backend/paymentRuntime.js\";\nimport {\n normalizeBackendKitOptions,\n resolvePlatformSecretRefFromEnv,\n type BackendKitNormalizedOptions,\n type StringRecord,\n} from \"./backend/options.js\";\n\ntype ReplyLike = {\n code: (statusCode: number) => {\n send: (payload: unknown) => unknown;\n };\n};\n\ntype RegisterableApp = {\n setNotFoundHandler: (\n handler: (request: unknown, reply: ReplyLike) => Promise<unknown> | unknown,\n ) => void;\n};\n\ntype RouteModule = {\n registerRoutes: (app: RegisterableApp) => Promise<void> | void;\n};\n\ntype BackendKitDeps = {\n normalizeOptions?: (input: StringRecord) => BackendKitNormalizedOptions;\n createReferenceSurfaceModule?: (input: {\n gateway: BackendKitNormalizedOptions[\"gateway\"];\n branding: BackendKitNormalizedOptions[\"branding\"];\n enableReference: boolean;\n enableLifecycle: boolean;\n enableBridge: boolean;\n enabledModes: string[];\n reference: BackendKitNormalizedOptions[\"reference\"];\n }) => RouteModule;\n createHostReferenceModule?: (input: {\n gateway: BackendKitNormalizedOptions[\"gateway\"];\n branding: BackendKitNormalizedOptions[\"branding\"];\n reference: BackendKitNormalizedOptions[\"reference\"];\n enableLifecycle: boolean;\n enableBridge: boolean;\n allowedOrigins: string[];\n bootstrap: BackendKitNormalizedOptions[\"host\"][\"bootstrap\"];\n hostProxyService: unknown;\n }) => RouteModule;\n createGatewayExecutionModule?: (input: {\n enabledModes: string[];\n subjectProfiles: BackendKitNormalizedOptions[\"subjectProfiles\"];\n paymentRuntime: unknown;\n }) => RouteModule;\n};\n\nexport type BackendKit = {\n options: BackendKitNormalizedOptions;\n registerRoutes: (app: RegisterableApp) => Promise<void>;\n applyNotFoundHandler: (app: RegisterableApp) => void;\n};\n\nexport type VerifyBrowserWidgetContextInput = {\n hostOrigin: string;\n installationId?: string | null;\n bindToolName?: string | null;\n toolName?: string | null;\n subjectId?: string | null;\n};\n\nexport async function verifyBrowserWidgetContext(\n gatewayClient: {\n verifyBrowserWidgetContext: (\n input: VerifyBrowserWidgetContextInput,\n ) => Promise<Record<string, unknown>>;\n },\n input: VerifyBrowserWidgetContextInput,\n) {\n return gatewayClient.verifyBrowserWidgetContext(input);\n}\n\nexport async function createBackendKit(\n input: StringRecord = {},\n deps: BackendKitDeps = {},\n): Promise<BackendKit> {\n const normalizeOptions =\n typeof deps.normalizeOptions === \"function\" ? deps.normalizeOptions : null;\n const createReferenceSurfaceModuleDep =\n typeof deps.createReferenceSurfaceModule === \"function\"\n ? deps.createReferenceSurfaceModule\n : null;\n const createHostReferenceModuleDep =\n typeof deps.createHostReferenceModule === \"function\" ? deps.createHostReferenceModule : null;\n const createGatewayExecutionModuleDep =\n typeof deps.createGatewayExecutionModule === \"function\"\n ? deps.createGatewayExecutionModule\n : null;\n if (\n !normalizeOptions ||\n !createReferenceSurfaceModuleDep ||\n !createHostReferenceModuleDep ||\n !createGatewayExecutionModuleDep\n ) {\n throw new TypeError(\"backend kit dependencies are incomplete\");\n }\n\n const options = normalizeOptions(input);\n const paymentRuntime = await createPaymentRuntime(options, deps);\n\n const referenceSurfaceModule = createReferenceSurfaceModuleDep({\n gateway: options.gateway,\n branding: options.branding,\n enableReference: options.host.enableReference,\n enableLifecycle: options.host.enableLifecycle,\n enableBridge: options.host.enableBridge,\n enabledModes: options.payments.enabledModes,\n reference: options.reference,\n });\n const hostReferenceModule = createHostReferenceModuleDep({\n gateway: options.gateway,\n branding: options.branding,\n reference: options.reference,\n enableLifecycle: options.host.enableLifecycle,\n enableBridge: options.host.enableBridge,\n allowedOrigins: options.host.allowedOrigins,\n bootstrap: options.host.bootstrap,\n hostProxyService: options.overrides.hostProxyService,\n });\n const gatewayExecutionModule = createGatewayExecutionModuleDep({\n enabledModes: options.payments.enabledModes,\n subjectProfiles: options.subjectProfiles,\n paymentRuntime,\n });\n\n return {\n options,\n async registerRoutes(app) {\n await referenceSurfaceModule.registerRoutes(app);\n await hostReferenceModule.registerRoutes(app);\n await gatewayExecutionModule.registerRoutes(app);\n },\n applyNotFoundHandler(app) {\n app.setNotFoundHandler(async (_request, reply) =>\n reply.code(404).send({ message: \"Not found\" }),\n );\n },\n };\n}\n\nexport {\n buildHostedGatewayPaymentUrl as buildHostedGatewayPaymentUrl,\n buildModeHostedGatewayPaymentUrl as buildModeHostedGatewayPaymentUrl,\n createGatewayExecutionModule,\n createHostReferenceModule,\n createReferenceSurfaceModule,\n createHostProxyService,\n createPaymentEvidenceHandler,\n createPaymentRuntime,\n extractHostedPaymentSessionId,\n normalizeBackendKitOptions,\n registerPaymentPageApiRoutes,\n registerPaymentPageAssetRoute,\n resolvePlatformSecretRefFromEnv,\n};\n"],
5
- "mappings": "AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AA4DP,eAAsB,2BACpB,eAKA,OACA;AACA,SAAO,cAAc,2BAA2B,KAAK;AACvD;AAEA,eAAsB,iBACpB,QAAsB,CAAC,GACvB,OAAuB,CAAC,GACH;AACrB,QAAM,mBACJ,OAAO,KAAK,qBAAqB,aAAa,KAAK,mBAAmB;AACxE,QAAM,kCACJ,OAAO,KAAK,iCAAiC,aACzC,KAAK,+BACL;AACN,QAAM,+BACJ,OAAO,KAAK,8BAA8B,aAAa,KAAK,4BAA4B;AAC1F,QAAM,kCACJ,OAAO,KAAK,iCAAiC,aACzC,KAAK,+BACL;AACN,MACE,CAAC,oBACD,CAAC,mCACD,CAAC,gCACD,CAAC,iCACD;AACA,UAAM,IAAI,UAAU,yCAAyC;AAAA,EAC/D;AAEA,QAAM,UAAU,iBAAiB,KAAK;AACtC,QAAM,iBAAiB,MAAM,qBAAqB,SAAS,IAAI;AAE/D,QAAM,yBAAyB,gCAAgC;AAAA,IAC7D,SAAS,QAAQ;AAAA,IACjB,UAAU,QAAQ;AAAA,IAClB,iBAAiB,QAAQ,KAAK;AAAA,IAC9B,iBAAiB,QAAQ,KAAK;AAAA,IAC9B,cAAc,QAAQ,KAAK;AAAA,IAC3B,cAAc,QAAQ,SAAS;AAAA,IAC/B,WAAW,QAAQ;AAAA,EACrB,CAAC;AACD,QAAM,sBAAsB,6BAA6B;AAAA,IACvD,SAAS,QAAQ;AAAA,IACjB,UAAU,QAAQ;AAAA,IAClB,WAAW,QAAQ;AAAA,IACnB,iBAAiB,QAAQ,KAAK;AAAA,IAC9B,cAAc,QAAQ,KAAK;AAAA,IAC3B,gBAAgB,QAAQ,KAAK;AAAA,IAC7B,WAAW,QAAQ,KAAK;AAAA,IACxB,kBAAkB,QAAQ,UAAU;AAAA,EACtC,CAAC;AACD,QAAM,yBAAyB,gCAAgC;AAAA,IAC7D,cAAc,QAAQ,SAAS;AAAA,IAC/B,iBAAiB,QAAQ;AAAA,IACzB;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,MAAM,eAAe,KAAK;AACxB,YAAM,uBAAuB,eAAe,GAAG;AAC/C,YAAM,oBAAoB,eAAe,GAAG;AAC5C,YAAM,uBAAuB,eAAe,GAAG;AAAA,IACjD;AAAA,IACA,qBAAqB,KAAK;AACxB,UAAI;AAAA,QAAmB,OAAO,UAAU,UACtC,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,SAAS,YAAY,CAAC;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import {\n createGatewayExecutionModule,\n createHostReferenceModule,\n createReferenceSurfaceModule,\n createHostProxyService,\n} from \"./backend/modules.js\";\nimport {\n buildHostedGatewayPaymentUrl,\n buildModeHostedGatewayPaymentUrl,\n createPaymentEvidenceHandler,\n createPaymentRuntime,\n extractHostedPaymentSessionId,\n registerPaymentPageApiRoutes,\n registerPaymentPageAssetRoute,\n} from \"./backend/paymentRuntime.js\";\nimport {\n normalizeBackendKitOptions,\n resolvePlatformSecretRefFromEnv,\n type BackendKitNormalizedOptions,\n type StringRecord,\n} from \"./backend/options.js\";\n\ntype ReplyLike = {\n code: (statusCode: number) => {\n send: (payload: unknown) => unknown;\n };\n};\n\ntype RegisterableApp = {\n setNotFoundHandler: (\n handler: (request: unknown, reply: ReplyLike) => Promise<unknown> | unknown,\n ) => void;\n};\n\ntype RouteModule = {\n registerRoutes: (app: RegisterableApp) => Promise<void> | void;\n};\n\ntype BackendKitDeps = {\n normalizeOptions?: (input: StringRecord) => BackendKitNormalizedOptions;\n createReferenceSurfaceModule?: (input: {\n gateway: BackendKitNormalizedOptions[\"gateway\"];\n branding: BackendKitNormalizedOptions[\"branding\"];\n enableReference: boolean;\n enableLifecycle: boolean;\n enableBridge: boolean;\n enabledModes: string[];\n reference: BackendKitNormalizedOptions[\"reference\"];\n }) => RouteModule;\n createHostReferenceModule?: (input: {\n gateway: BackendKitNormalizedOptions[\"gateway\"];\n branding: BackendKitNormalizedOptions[\"branding\"];\n reference: BackendKitNormalizedOptions[\"reference\"];\n enableLifecycle: boolean;\n enableBridge: boolean;\n allowedOrigins: string[];\n bootstrap: BackendKitNormalizedOptions[\"host\"][\"bootstrap\"];\n hostProxyService: unknown;\n }) => RouteModule;\n createGatewayExecutionModule?: (input: {\n enabledModes: string[];\n subjectProfiles: BackendKitNormalizedOptions[\"subjectProfiles\"];\n paymentRuntime: unknown;\n }) => RouteModule;\n};\n\nexport type BackendKit = {\n options: BackendKitNormalizedOptions;\n registerRoutes: (app: RegisterableApp) => Promise<void>;\n applyNotFoundHandler: (app: RegisterableApp) => void;\n};\n\nexport type VerifyBrowserWidgetContextInput = {\n hostOrigin: string;\n bootstrapTicket?: string | null;\n installationId?: string | null;\n bindToolName?: string | null;\n toolName?: string | null;\n subjectId?: string | null;\n};\n\nexport type WidgetBootstrapOriginPolicyInput = {\n hostOrigin: string | null | undefined;\n allowedOrigins?: string[] | string | null | undefined;\n};\n\nexport type WidgetBootstrapOriginPolicyResult =\n | {\n ok: true;\n hostOrigin: string;\n allowedOrigins: string[];\n }\n | {\n ok: false;\n code: \"HOST_ORIGIN_REQUIRED\" | \"HOST_ORIGIN_NOT_ALLOWED\";\n message: string;\n hostOrigin: string | null;\n allowedOrigins: string[];\n };\n\nfunction normalizeOrigin(value: string | null | undefined) {\n const raw = String(value || \"\").trim();\n if (!raw) return null;\n try {\n const parsed = new URL(raw);\n if (!parsed.protocol || !parsed.host) return null;\n return parsed.origin;\n } catch {\n return null;\n }\n}\n\nexport function normalizeWidgetBootstrapAllowedOrigins(\n value: string[] | string | null | undefined,\n): string[] {\n const entries = Array.isArray(value) ? value : String(value || \"\").split(/[,\\n]/);\n const normalized = entries\n .map((entry) => normalizeOrigin(entry))\n .filter((entry): entry is string => Boolean(entry));\n return Array.from(new Set(normalized));\n}\n\nexport function evaluateWidgetBootstrapOriginPolicy(\n input: WidgetBootstrapOriginPolicyInput,\n): WidgetBootstrapOriginPolicyResult {\n const hostOrigin = normalizeOrigin(input.hostOrigin);\n const allowedOrigins = normalizeWidgetBootstrapAllowedOrigins(input.allowedOrigins);\n if (!hostOrigin) {\n return {\n ok: false,\n code: \"HOST_ORIGIN_REQUIRED\",\n message: \"Host origin is required to verify browser widget context\",\n hostOrigin: null,\n allowedOrigins,\n };\n }\n if (allowedOrigins.length > 0 && !allowedOrigins.includes(hostOrigin)) {\n return {\n ok: false,\n code: \"HOST_ORIGIN_NOT_ALLOWED\",\n message: \"Host origin is not allowed for widget bootstrap verification\",\n hostOrigin,\n allowedOrigins,\n };\n }\n return {\n ok: true,\n hostOrigin,\n allowedOrigins,\n };\n}\n\nexport async function verifyBrowserWidgetContext(\n gatewayClient: {\n verifyBrowserWidgetContext: (\n input: VerifyBrowserWidgetContextInput,\n ) => Promise<Record<string, unknown>>;\n },\n input: VerifyBrowserWidgetContextInput,\n) {\n return gatewayClient.verifyBrowserWidgetContext(input);\n}\n\nexport async function createBackendKit(\n input: StringRecord = {},\n deps: BackendKitDeps = {},\n): Promise<BackendKit> {\n const normalizeOptions =\n typeof deps.normalizeOptions === \"function\" ? deps.normalizeOptions : null;\n const createReferenceSurfaceModuleDep =\n typeof deps.createReferenceSurfaceModule === \"function\"\n ? deps.createReferenceSurfaceModule\n : null;\n const createHostReferenceModuleDep =\n typeof deps.createHostReferenceModule === \"function\" ? deps.createHostReferenceModule : null;\n const createGatewayExecutionModuleDep =\n typeof deps.createGatewayExecutionModule === \"function\"\n ? deps.createGatewayExecutionModule\n : null;\n if (\n !normalizeOptions ||\n !createReferenceSurfaceModuleDep ||\n !createHostReferenceModuleDep ||\n !createGatewayExecutionModuleDep\n ) {\n throw new TypeError(\"backend kit dependencies are incomplete\");\n }\n\n const options = normalizeOptions(input);\n const paymentRuntime = await createPaymentRuntime(options, deps);\n\n const referenceSurfaceModule = createReferenceSurfaceModuleDep({\n gateway: options.gateway,\n branding: options.branding,\n enableReference: options.host.enableReference,\n enableLifecycle: options.host.enableLifecycle,\n enableBridge: options.host.enableBridge,\n enabledModes: options.payments.enabledModes,\n reference: options.reference,\n });\n const hostReferenceModule = createHostReferenceModuleDep({\n gateway: options.gateway,\n branding: options.branding,\n reference: options.reference,\n enableLifecycle: options.host.enableLifecycle,\n enableBridge: options.host.enableBridge,\n allowedOrigins: options.host.allowedOrigins,\n bootstrap: options.host.bootstrap,\n hostProxyService: options.overrides.hostProxyService,\n });\n const gatewayExecutionModule = createGatewayExecutionModuleDep({\n enabledModes: options.payments.enabledModes,\n subjectProfiles: options.subjectProfiles,\n paymentRuntime,\n });\n\n return {\n options,\n async registerRoutes(app) {\n await referenceSurfaceModule.registerRoutes(app);\n await hostReferenceModule.registerRoutes(app);\n await gatewayExecutionModule.registerRoutes(app);\n },\n applyNotFoundHandler(app) {\n app.setNotFoundHandler(async (_request, reply) =>\n reply.code(404).send({ message: \"Not found\" }),\n );\n },\n };\n}\n\nexport {\n buildHostedGatewayPaymentUrl as buildHostedGatewayPaymentUrl,\n buildModeHostedGatewayPaymentUrl as buildModeHostedGatewayPaymentUrl,\n createGatewayExecutionModule,\n createHostReferenceModule,\n createReferenceSurfaceModule,\n createHostProxyService,\n createPaymentEvidenceHandler,\n createPaymentRuntime,\n extractHostedPaymentSessionId,\n normalizeBackendKitOptions,\n registerPaymentPageApiRoutes,\n registerPaymentPageAssetRoute,\n resolvePlatformSecretRefFromEnv,\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xapps-platform/backend-kit",
3
- "version": "0.1.6",
3
+ "version": "0.2.0",
4
4
  "license": "MIT",
5
5
  "author": "Daniel Vladescu <daniel.vladescu@gmail.com>",
6
6
  "description": "Modular Node backend kit for the current Xapps backend contract (tenant surface today, shared actor-adapter direction later)",
@@ -37,6 +37,6 @@
37
37
  "smoke": "npm run build && node examples/smoke/smoke.mjs"
38
38
  },
39
39
  "dependencies": {
40
- "@xapps-platform/server-sdk": "^0.1.0"
40
+ "@xapps-platform/server-sdk": "^0.2.0"
41
41
  }
42
42
  }