@arcblock/payment-service 1.29.4 → 1.29.6

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 (3) hide show
  1. package/dist/cf.js +155 -174
  2. package/dist/index.js +292 -171
  3. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -376,6 +376,7 @@ __export(env_exports, {
376
376
  hasConfig: () => hasConfig,
377
377
  iapReconcileBatchSize: () => iapReconcileBatchSize,
378
378
  iapReconcileCronTime: () => iapReconcileCronTime,
379
+ isBlockletServer: () => isBlockletServer,
379
380
  isCfWorker: () => isCfWorker,
380
381
  isDevelopmentEnv: () => isDevelopmentEnv,
381
382
  isProduction: () => isProduction,
@@ -436,7 +437,7 @@ function hasConfig(key) {
436
437
  const v = readConfig(key);
437
438
  return v !== void 0 && v !== "";
438
439
  }
439
- var import_env, activeConfig, numConfig, paymentStatCronTime, subscriptionCronTime, notificationCronTime, expiredSessionCleanupCronTime, notificationCronConcurrency, stripeInvoiceCronTime, stripePaymentCronTime, stripeSubscriptionCronTime, revokeStakeCronTime, daysUntilCancel, meteringSubscriptionDetectionCronTime, overdueDetectionCronTime, overdueThreshold, depositVaultCronTime, creditConsumptionCronTime, vendorStatusCheckCronTime, vendorReturnScanCronTime, iapReconcileCronTime, eventRetryCronTime, quoteCleanupCronTime, vendorTimeoutMinutes, webhookAlertWindowMinutes, webhookAlertMinFailures, shortUrlApiKey, shortUrlDomain, sequelizeOptionsPoolMin, sequelizeOptionsPoolMax, sequelizeOptionsPoolIdle, updateDataConcurrency, stopAcceptingOrders, exchangeRateCacheTTLSeconds, systemMaxPendingAmount, allowChangeLockedPrice, blockletMode, isProduction, nodeEnv, isTestEnv, isDevelopmentEnv, enableDevFakeAuth, tenantModeRaw, blockletAppPid, blockletAppId, blockletAppName, blockletAppUrl, blockletAppHost, blockletAppDir, blockletPort, blockletMountPoints, appStoreWriteEnabled, appStoreSkipSignatureVerify, googlePubsubSkipSignatureVerify, googlePubsubPushServiceAccount, googlePubsubAllowUnverifiedSender, googlePlayWebhookUrl, stripeWebhookSecret, iapReconcileBatchSize, paymentBillingThreshold, paymentMinStakeAmount, paymentDaysUntilDue, paymentDaysUntilCancel, paymentReloadSubscriptionJobs, paymentRateVolatilityThreshold, paymentLivemode, creditLowBalanceThresholdPercentage, creditBatchSize, creditBatchWindowMs, creditQueueConcurrency, exchangeRateCacheTTLFromEnv, sqlLog, sqlBenchmark, cfEnv, isCfWorker, env_default;
440
+ var import_env, activeConfig, numConfig, paymentStatCronTime, subscriptionCronTime, notificationCronTime, expiredSessionCleanupCronTime, notificationCronConcurrency, stripeInvoiceCronTime, stripePaymentCronTime, stripeSubscriptionCronTime, revokeStakeCronTime, daysUntilCancel, meteringSubscriptionDetectionCronTime, overdueDetectionCronTime, overdueThreshold, depositVaultCronTime, creditConsumptionCronTime, vendorStatusCheckCronTime, vendorReturnScanCronTime, iapReconcileCronTime, eventRetryCronTime, quoteCleanupCronTime, vendorTimeoutMinutes, webhookAlertWindowMinutes, webhookAlertMinFailures, shortUrlApiKey, shortUrlDomain, sequelizeOptionsPoolMin, sequelizeOptionsPoolMax, sequelizeOptionsPoolIdle, updateDataConcurrency, stopAcceptingOrders, exchangeRateCacheTTLSeconds, systemMaxPendingAmount, allowChangeLockedPrice, blockletMode, isProduction, nodeEnv, isTestEnv, isDevelopmentEnv, enableDevFakeAuth, tenantModeRaw, blockletAppPid, blockletAppId, blockletAppName, blockletAppUrl, blockletAppHost, blockletAppDir, blockletPort, blockletMountPoints, appStoreWriteEnabled, appStoreSkipSignatureVerify, googlePubsubSkipSignatureVerify, googlePubsubPushServiceAccount, googlePubsubAllowUnverifiedSender, googlePlayWebhookUrl, stripeWebhookSecret, iapReconcileBatchSize, paymentBillingThreshold, paymentMinStakeAmount, paymentDaysUntilDue, paymentDaysUntilCancel, paymentReloadSubscriptionJobs, paymentRateVolatilityThreshold, paymentLivemode, creditLowBalanceThresholdPercentage, creditBatchSize, creditBatchWindowMs, creditQueueConcurrency, exchangeRateCacheTTLFromEnv, sqlLog, sqlBenchmark, cfEnv, isCfWorker, isBlockletServer, env_default;
440
441
  var init_env = __esm({
441
442
  "../../blocklets/core/api/src/libs/env.ts"() {
442
443
  "use strict";
@@ -517,6 +518,7 @@ var init_env = __esm({
517
518
  sqlBenchmark = () => readConfig("SQL_BENCHMARK") === "1";
518
519
  cfEnv = () => globalThis.__CF_ENV__;
519
520
  isCfWorker = () => !!cfEnv();
521
+ isBlockletServer = () => hasConfig("BLOCKLET_APP_ID");
520
522
  env_default = {
521
523
  ...import_env.env
522
524
  };
@@ -1002,9 +1004,9 @@ function createNodeStaticHandler(webRoot) {
1002
1004
  throw new Error(`createNodeStaticHandler: webRoot has no index.html: ${indexPath}`);
1003
1005
  }
1004
1006
  let cachedIndex = null;
1005
- return (app42) => {
1007
+ return (app43) => {
1006
1008
  const { serveStatic } = require("@hono/node-server/serve-static");
1007
- app42.use("*", async (c, next) => {
1009
+ app43.use("*", async (c, next) => {
1008
1010
  const method = c.req.method.toUpperCase();
1009
1011
  if (method !== "GET" && method !== "HEAD" || !acceptsHtml(c.req.header("accept") || "") || import_constant.RESOURCE_PATTERN.test(c.req.path)) {
1010
1012
  return next();
@@ -1012,7 +1014,7 @@ function createNodeStaticHandler(webRoot) {
1012
1014
  if (cachedIndex == null) cachedIndex = import_fs.default.readFileSync(indexPath, "utf8");
1013
1015
  return c.html(cachedIndex);
1014
1016
  });
1015
- app42.use("*", serveStatic({ root: webRoot }));
1017
+ app43.use("*", serveStatic({ root: webRoot }));
1016
1018
  };
1017
1019
  }
1018
1020
  var import_fs, import_path, import_constant, serve_static_arc_default;
@@ -16594,8 +16596,9 @@ function isCreditSufficientForPayment(args) {
16594
16596
  }
16595
16597
  return { sufficient: true, balance };
16596
16598
  }
16597
- async function getGasPayerExtra(txBuffer, headers) {
16598
- if (headers && headers["x-gas-payer-sig"] && headers["x-gas-payer-pk"]) {
16599
+ async function getGasPayerExtra(txBuffer, headers, client) {
16600
+ const appStaked = client ? await getAppStakeAddressWithFallback({ client }).then((r) => !!r).catch(() => false) : false;
16601
+ if (!appStaked && headers && headers["x-gas-payer-sig"] && headers["x-gas-payer-pk"]) {
16599
16602
  return { headers };
16600
16603
  }
16601
16604
  const txHash = (0, import_mcrypto.toTxHash)(txBuffer);
@@ -22505,16 +22508,38 @@ var init_setting2 = __esm({
22505
22508
  });
22506
22509
 
22507
22510
  // ../../blocklets/core/api/src/libs/notification/index.ts
22508
- var import_notification, Notification;
22511
+ var notification_exports = {};
22512
+ __export(notification_exports, {
22513
+ Notification: () => Notification,
22514
+ ensureBlockletSdkTransportGuard: () => ensureBlockletSdkTransportGuard
22515
+ });
22516
+ function noopSdkTransport(mod, fns) {
22517
+ const noop = async () => void 0;
22518
+ for (const target of [mod, mod?.default]) {
22519
+ if (!target) continue;
22520
+ for (const fn3 of fns) target[fn3] = noop;
22521
+ }
22522
+ }
22523
+ function ensureBlockletSdkTransportGuard() {
22524
+ if (blockletSdkTransportGuarded) return;
22525
+ blockletSdkTransportGuarded = true;
22526
+ if (isBlockletServer()) return;
22527
+ noopSdkTransport(require("@blocklet/sdk/service/notification"), ["sendToUser", "sendToRelay", "sendToMail"]);
22528
+ noopSdkTransport(require("@blocklet/sdk/service/eventbus"), ["publish", "subscribe", "unsubscribe"]);
22529
+ logger_default.info("[blocklet-sdk] notification + eventbus transport disabled \u2014 no BLOCKLET_APP_ID (off blocklet-server)");
22530
+ }
22531
+ var import_notification, blockletSdkTransportGuarded, Notification;
22509
22532
  var init_notification = __esm({
22510
22533
  "../../blocklets/core/api/src/libs/notification/index.ts"() {
22511
22534
  "use strict";
22512
22535
  import_notification = __toESM(require("@blocklet/sdk/service/notification"));
22513
22536
  init_models();
22514
22537
  init_setting2();
22538
+ init_env();
22515
22539
  init_logger();
22516
22540
  init_event2();
22517
22541
  init_audit();
22542
+ blockletSdkTransportGuarded = false;
22518
22543
  Notification = class {
22519
22544
  constructor(template, type) {
22520
22545
  this.template = template;
@@ -32556,8 +32581,8 @@ var init_exchange_rate_alert = __esm({
32556
32581
  });
32557
32582
 
32558
32583
  // ../../blocklets/core/api/src/queues/notification.ts
32559
- var notification_exports = {};
32560
- __export(notification_exports, {
32584
+ var notification_exports2 = {};
32585
+ __export(notification_exports2, {
32561
32586
  addNotificationJob: () => addNotificationJob,
32562
32587
  addNotificationJobWithDelay: () => addNotificationJobWithDelay,
32563
32588
  aggregatedNotificationQueue: () => aggregatedNotificationQueue,
@@ -33637,6 +33662,45 @@ var init_subscription3 = __esm({
33637
33662
  }
33638
33663
  });
33639
33664
 
33665
+ // ../../blocklets/core/api/src/crons/tenant-fanout.ts
33666
+ async function listProvisionedTenants() {
33667
+ const { PaymentMethod: PaymentMethod3 } = (init_models(), __toCommonJS(models_exports));
33668
+ const rows = await systemFindAll(PaymentMethod3, {
33669
+ attributes: ["instance_did"],
33670
+ raw: true
33671
+ });
33672
+ const dids = /* @__PURE__ */ new Set();
33673
+ for (const row of rows) {
33674
+ if (row?.instance_did) dids.add(row.instance_did);
33675
+ }
33676
+ return [...dids];
33677
+ }
33678
+ function perTenant(name, fn3, listTenants = listProvisionedTenants) {
33679
+ return async () => {
33680
+ if (getTenantMode() === "single") {
33681
+ await fn3();
33682
+ return;
33683
+ }
33684
+ const dids = await listTenants();
33685
+ if (dids.length === 0) return;
33686
+ logger_default.info("cron.tenant.fanout", { cron: name, tenantCount: dids.length });
33687
+ for (const instanceDid of dids) {
33688
+ await withTenant(instanceDid, async () => fn3()).catch(
33689
+ (error) => logger_default.error("cron tenant pass failed", { cron: name, instanceDid, error })
33690
+ );
33691
+ }
33692
+ };
33693
+ }
33694
+ var init_tenant_fanout = __esm({
33695
+ "../../blocklets/core/api/src/crons/tenant-fanout.ts"() {
33696
+ "use strict";
33697
+ init_context();
33698
+ init_logger();
33699
+ init_tenant();
33700
+ init_scoped();
33701
+ }
33702
+ });
33703
+
33640
33704
  // ../../blocklets/core/api/src/integrations/stripe/handlers/invoice.ts
33641
33705
  async function handleStripeInvoicePaid(invoice, event) {
33642
33706
  logger_default.info("invoice paid on stripe event", { locale: invoice.id });
@@ -33829,7 +33893,7 @@ async function ensureStripeInvoice(stripeInvoice, subscription, client) {
33829
33893
  if (subscription) {
33830
33894
  await subscription.update({ latest_invoice_id: invoice.id });
33831
33895
  }
33832
- await client.invoices.update(stripeInvoice.id, { metadata: { appPid: import_env19.env.appPid, id: invoice.id } });
33896
+ await client.invoices.update(stripeInvoice.id, { metadata: { appPid: import_env20.env.appPid, id: invoice.id } });
33833
33897
  logger_default.info("stripe invoice mirrored", { local: invoice.id, remote: stripeInvoice.id });
33834
33898
  await Promise.all(
33835
33899
  stripeInvoice.lines.data.map(async (line) => {
@@ -33887,7 +33951,7 @@ async function handleStripeInvoiceCreated(event, client) {
33887
33951
  logger_default.warn("abort because subscription not found", { id: event.id, type: event.type });
33888
33952
  return null;
33889
33953
  }
33890
- if (stripeSubscription.metadata?.appPid !== import_env19.env.appPid) {
33954
+ if (stripeSubscription.metadata?.appPid !== import_env20.env.appPid) {
33891
33955
  logger_default.warn("abort because subscription not interested", { id: event.id, type: event.type });
33892
33956
  return null;
33893
33957
  }
@@ -33938,7 +34002,7 @@ async function handleInvoiceEvent(event, client) {
33938
34002
  const subscriptionAppPid = event.data.object.subscription_details?.metadata?.appPid;
33939
34003
  const autoRechargeConfigId = event.data.object.metadata?.recharge_id;
33940
34004
  if (!localInvoiceId) {
33941
- if (subscriptionId && subscriptionAppPid && subscriptionAppPid === import_env19.env.appPid) {
34005
+ if (subscriptionId && subscriptionAppPid && subscriptionAppPid === import_env20.env.appPid) {
33942
34006
  logger_default.warn("try mirror invoice from stripe", { invoiceId: event.data.object.id });
33943
34007
  const subscription = await Subscription.findByPk(subscriptionId);
33944
34008
  if (subscription) {
@@ -34023,11 +34087,11 @@ async function handleInvoiceEvent(event, client) {
34023
34087
  }
34024
34088
  }
34025
34089
  }
34026
- var import_env19, import_merge2, import_pick11, import_p_wait_for5, processInvoiceDiscounts, waitForStripeInvoiceMirrored;
34090
+ var import_env20, import_merge2, import_pick11, import_p_wait_for5, processInvoiceDiscounts, waitForStripeInvoiceMirrored;
34027
34091
  var init_invoice3 = __esm({
34028
34092
  "../../blocklets/core/api/src/integrations/stripe/handlers/invoice.ts"() {
34029
34093
  "use strict";
34030
- import_env19 = require("@blocklet/sdk/lib/env");
34094
+ import_env20 = require("@blocklet/sdk/lib/env");
34031
34095
  import_merge2 = __toESM(require("lodash/merge"));
34032
34096
  import_pick11 = __toESM(require("lodash/pick"));
34033
34097
  import_p_wait_for5 = __toESM(require("p-wait-for"));
@@ -34153,7 +34217,7 @@ async function handleStripePaymentCreated(event, client) {
34153
34217
  stripe_id: stripeIntent.id
34154
34218
  }
34155
34219
  });
34156
- await client.paymentIntents.update(stripeIntent.id, { metadata: { appPid: import_env20.env.appPid, id: paymentIntent.id } });
34220
+ await client.paymentIntents.update(stripeIntent.id, { metadata: { appPid: import_env21.env.appPid, id: paymentIntent.id } });
34157
34221
  await invoice.update({ payment_intent_id: paymentIntent.id });
34158
34222
  if (checkoutSession) {
34159
34223
  checkoutSession.update({ payment_intent_id: paymentIntent.id });
@@ -34220,11 +34284,11 @@ async function handlePaymentIntentEvent(event, client) {
34220
34284
  }
34221
34285
  }
34222
34286
  }
34223
- var import_env20, import_merge3, import_pick12, import_p_wait_for6, waitForStripePaymentMirrored;
34287
+ var import_env21, import_merge3, import_pick12, import_p_wait_for6, waitForStripePaymentMirrored;
34224
34288
  var init_payment_intent2 = __esm({
34225
34289
  "../../blocklets/core/api/src/integrations/stripe/handlers/payment-intent.ts"() {
34226
34290
  "use strict";
34227
- import_env20 = require("@blocklet/sdk/lib/env");
34291
+ import_env21 = require("@blocklet/sdk/lib/env");
34228
34292
  import_merge3 = __toESM(require("lodash/merge"));
34229
34293
  import_pick12 = __toESM(require("lodash/pick"));
34230
34294
  import_p_wait_for6 = __toESM(require("p-wait-for"));
@@ -34258,7 +34322,7 @@ async function ensureStripeProduct(internal, method) {
34258
34322
  name: internal.name,
34259
34323
  description: internal.description,
34260
34324
  metadata: {
34261
- appPid: import_env21.env.appPid,
34325
+ appPid: import_env22.env.appPid,
34262
34326
  id: internal.id
34263
34327
  }
34264
34328
  };
@@ -34285,7 +34349,7 @@ async function ensureStripePrice(internal, method, currency) {
34285
34349
  lookup_key: internal.lookup_key,
34286
34350
  billing_scheme: internal.billing_scheme,
34287
34351
  metadata: {
34288
- appPid: import_env21.env.appPid,
34352
+ appPid: import_env22.env.appPid,
34289
34353
  id: internal.id
34290
34354
  }
34291
34355
  };
@@ -34357,7 +34421,7 @@ async function ensureStripeCustomer(internal, method) {
34357
34421
  email: internal.email,
34358
34422
  phone: internal.phone,
34359
34423
  metadata: {
34360
- appPid: import_env21.env.appPid,
34424
+ appPid: import_env22.env.appPid,
34361
34425
  id: internal.id,
34362
34426
  did: internal.did
34363
34427
  }
@@ -34396,7 +34460,7 @@ async function ensureStripePaymentIntent(internal, method, currency, checkoutSes
34396
34460
  const meta = stripeIntent.metadata || {};
34397
34461
  if (meta.id !== internal.id || checkoutSessionId && meta.checkoutSessionId !== checkoutSessionId) {
34398
34462
  stripeIntent = await client.paymentIntents.update(stripeIntent.id, {
34399
- metadata: { ...meta, appPid: import_env21.env.appPid, id: internal.id, checkoutSessionId: checkoutSessionId || "" }
34463
+ metadata: { ...meta, appPid: import_env22.env.appPid, id: internal.id, checkoutSessionId: checkoutSessionId || "" }
34400
34464
  });
34401
34465
  }
34402
34466
  } else {
@@ -34410,7 +34474,7 @@ async function ensureStripePaymentIntent(internal, method, currency, checkoutSes
34410
34474
  allow_redirects: "never"
34411
34475
  },
34412
34476
  metadata: {
34413
- appPid: import_env21.env.appPid,
34477
+ appPid: import_env22.env.appPid,
34414
34478
  id: internal.id,
34415
34479
  checkoutSessionId: checkoutSessionId || ""
34416
34480
  }
@@ -34481,7 +34545,7 @@ async function ensureStripeSubscription(internal, method, currency, items, trial
34481
34545
  payment_behavior: "default_incomplete",
34482
34546
  payment_settings: { save_default_payment_method: "on_subscription" },
34483
34547
  metadata: {
34484
- appPid: import_env21.env.appPid,
34548
+ appPid: import_env22.env.appPid,
34485
34549
  id: internal.id
34486
34550
  },
34487
34551
  expand: ["latest_invoice.payment_intent", "pending_setup_intent"]
@@ -34511,7 +34575,7 @@ async function ensureStripeSubscription(internal, method, currency, items, trial
34511
34575
  });
34512
34576
  if (exist) {
34513
34577
  await exist.update({ metadata: { stripe_id: x.id, stripe_subscription_id: stripeSubscription.id } });
34514
- await client.subscriptionItems.update(x.id, { metadata: { appPid: import_env21.env.appPid, id: exist.id } });
34578
+ await client.subscriptionItems.update(x.id, { metadata: { appPid: import_env22.env.appPid, id: exist.id } });
34515
34579
  logger_default.info("stripe subscription items related", { local: exist.id, remote: x.id });
34516
34580
  } else {
34517
34581
  exist = await SubscriptionItem.create({
@@ -34525,7 +34589,7 @@ async function ensureStripeSubscription(internal, method, currency, items, trial
34525
34589
  stripe_subscription_id: stripeSubscription.id
34526
34590
  }
34527
34591
  });
34528
- await client.subscriptionItems.update(x.id, { metadata: { appPid: import_env21.env.appPid, id: exist.id } });
34592
+ await client.subscriptionItems.update(x.id, { metadata: { appPid: import_env22.env.appPid, id: exist.id } });
34529
34593
  logger_default.info("stripe subscription items mirrored", { local: exist.id, remote: x.id });
34530
34594
  }
34531
34595
  })
@@ -34685,7 +34749,7 @@ async function createStripeSubscriptionCoupon(localCoupon, subscriptionId, metho
34685
34749
  duration: localCoupon.duration,
34686
34750
  redeem_by: Math.floor(((/* @__PURE__ */ new Date()).getTime() + 24 * 60 * 60 * 1e3) / 1e3),
34687
34751
  metadata: {
34688
- appPid: import_env21.env.appPid,
34752
+ appPid: import_env22.env.appPid,
34689
34753
  local_coupon_id: localCoupon.id,
34690
34754
  subscription_id: subscriptionId,
34691
34755
  created_for: "subscription"
@@ -34904,7 +34968,7 @@ async function ensureStripeSetupIntentForAutoRecharge(customer, method, autoRech
34904
34968
  payment_method_types: ["card"],
34905
34969
  usage: "off_session",
34906
34970
  metadata: {
34907
- appPid: import_env21.env.appPid,
34971
+ appPid: import_env22.env.appPid,
34908
34972
  auto_recharge_config_id: autoRechargeConfig.id,
34909
34973
  customer_id: customer.id
34910
34974
  }
@@ -34924,7 +34988,7 @@ async function ensureStripeSetupIntentForInvoicePayment(customer, method, metada
34924
34988
  payment_method_types: ["card"],
34925
34989
  usage: "off_session",
34926
34990
  metadata: {
34927
- appPid: import_env21.env.appPid,
34991
+ appPid: import_env22.env.appPid,
34928
34992
  customer_id: customer.id,
34929
34993
  action: "pay_overdue_batch",
34930
34994
  ...metadata
@@ -35052,7 +35116,7 @@ async function createStripeInvoiceForAutoRecharge(params) {
35052
35116
  auto_advance: true,
35053
35117
  default_payment_method: stripePaymentMethodId,
35054
35118
  metadata: {
35055
- appPid: import_env21.env.appPid,
35119
+ appPid: import_env22.env.appPid,
35056
35120
  recharge_id: autoRechargeConfig.id,
35057
35121
  id: invoice.id
35058
35122
  }
@@ -35085,7 +35149,7 @@ async function createStripeInvoiceForAutoRecharge(params) {
35085
35149
  quantity: item.quantity,
35086
35150
  description: item.description || price.nickname || "",
35087
35151
  metadata: {
35088
- appPid: import_env21.env.appPid,
35152
+ appPid: import_env22.env.appPid,
35089
35153
  invoice_item_id: item.id
35090
35154
  }
35091
35155
  });
@@ -35126,11 +35190,11 @@ async function createStripeInvoiceForAutoRecharge(params) {
35126
35190
  throw error;
35127
35191
  }
35128
35192
  }
35129
- var import_env21, import_merge4, import_omit3, import_pick13, import_sequelize61;
35193
+ var import_env22, import_merge4, import_omit3, import_pick13, import_sequelize61;
35130
35194
  var init_resource2 = __esm({
35131
35195
  "../../blocklets/core/api/src/integrations/stripe/resource.ts"() {
35132
35196
  "use strict";
35133
- import_env21 = require("@blocklet/sdk/lib/env");
35197
+ import_env22 = require("@blocklet/sdk/lib/env");
35134
35198
  import_merge4 = __toESM(require("lodash/merge"));
35135
35199
  import_omit3 = __toESM(require("lodash/omit"));
35136
35200
  import_pick13 = __toESM(require("lodash/pick"));
@@ -35159,6 +35223,8 @@ var init_invoice4 = __esm({
35159
35223
  "use strict";
35160
35224
  import_sequelize62 = require("sequelize");
35161
35225
  init_scoped();
35226
+ init_context();
35227
+ init_tenant_fanout();
35162
35228
  init_invoice2();
35163
35229
  init_audit();
35164
35230
  init_dayjs();
@@ -35357,22 +35423,25 @@ var init_invoice4 = __esm({
35357
35423
  }
35358
35424
  });
35359
35425
  const results = await Promise.allSettled(
35360
- invoices.map(async (x) => {
35361
- const supportAutoCharge = await PaymentMethod.supportAutoCharge(x.default_payment_method_id);
35362
- if (supportAutoCharge === false) {
35363
- return;
35364
- }
35365
- const exist = await invoiceQueue.get(x.id);
35366
- if (!exist) {
35367
- await invoiceQueue.push({ id: x.id, job: { invoiceId: x.id, retryOnError: true } });
35368
- }
35426
+ invoices.map((x) => {
35427
+ const dispatch = async () => {
35428
+ const supportAutoCharge = await PaymentMethod.supportAutoCharge(x.default_payment_method_id);
35429
+ if (supportAutoCharge === false) {
35430
+ return;
35431
+ }
35432
+ const exist = await invoiceQueue.get(x.id);
35433
+ if (!exist) {
35434
+ await invoiceQueue.push({ id: x.id, job: { invoiceId: x.id, retryOnError: true } });
35435
+ }
35436
+ };
35437
+ return x.instance_did ? withTenant(x.instance_did, dispatch) : dispatch();
35369
35438
  })
35370
35439
  );
35371
35440
  const failed = results.filter((r) => r.status === "rejected").length;
35372
35441
  if (failed > 0) {
35373
35442
  logger_default.warn(`Failed to process ${failed} invoices in startInvoiceQueue`);
35374
35443
  }
35375
- await batchHandleStripeInvoices();
35444
+ await perTenant("startInvoiceQueue.stripe", batchHandleStripeInvoices)();
35376
35445
  } catch (error) {
35377
35446
  logger_default.error("Error in startInvoiceQueue:", error);
35378
35447
  } finally {
@@ -36929,6 +36998,8 @@ var init_subscription4 = __esm({
36929
36998
  import_sequelize65 = require("sequelize");
36930
36999
  init_env();
36931
37000
  init_scoped();
37001
+ init_context();
37002
+ init_tenant_fanout();
36932
37003
  init_audit();
36933
37004
  init_passport();
36934
37005
  init_resource2();
@@ -38165,34 +38236,37 @@ var init_subscription4 = __esm({
38165
38236
  }
38166
38237
  });
38167
38238
  const results = await Promise.allSettled(
38168
- subscriptions.map(async (x) => {
38169
- const supportAutoCharge = await PaymentMethod.supportAutoCharge(x.default_payment_method_id);
38170
- if (supportAutoCharge === false) {
38171
- return;
38172
- }
38173
- if (["past_due", "paused"].includes(x.status)) {
38174
- const willCancel = x.cancel_at || x.cancel_at_period_end;
38175
- if (x.status === "past_due" && willCancel) {
38176
- const existingJob = await subscriptionQueue.get(`cancel-${x.id}`);
38177
- if (!existingJob) {
38178
- await addSubscriptionJob(x, "cancel", true, x.cancel_at || x.current_period_end);
38239
+ subscriptions.map((x) => {
38240
+ const dispatch = async () => {
38241
+ const supportAutoCharge = await PaymentMethod.supportAutoCharge(x.default_payment_method_id);
38242
+ if (supportAutoCharge === false) {
38243
+ return;
38244
+ }
38245
+ if (["past_due", "paused"].includes(x.status)) {
38246
+ const willCancel = x.cancel_at || x.cancel_at_period_end;
38247
+ if (x.status === "past_due" && willCancel) {
38248
+ const existingJob = await subscriptionQueue.get(`cancel-${x.id}`);
38249
+ if (!existingJob) {
38250
+ await addSubscriptionJob(x, "cancel", true, x.cancel_at || x.current_period_end);
38251
+ }
38179
38252
  }
38253
+ logger_default.info(`skip add cycle subscription job because status is ${x.status}`, {
38254
+ subscription: x.id,
38255
+ action: "cycle"
38256
+ });
38257
+ return;
38180
38258
  }
38181
- logger_default.info(`skip add cycle subscription job because status is ${x.status}`, {
38182
- subscription: x.id,
38183
- action: "cycle"
38184
- });
38185
- return;
38186
- }
38187
- logger_default.info("add subscription job", { subscription: x.id, action: "cycle" });
38188
- await addSubscriptionJob(x, "cycle", paymentReloadSubscriptionJobs());
38259
+ logger_default.info("add subscription job", { subscription: x.id, action: "cycle" });
38260
+ await addSubscriptionJob(x, "cycle", paymentReloadSubscriptionJobs());
38261
+ };
38262
+ return x.instance_did ? withTenant(x.instance_did, dispatch) : dispatch();
38189
38263
  })
38190
38264
  );
38191
38265
  const failed = results.filter((r) => r.status === "rejected").length;
38192
38266
  if (failed > 0) {
38193
38267
  logger_default.warn(`Failed to process ${failed} subscriptions in startSubscriptionQueue`);
38194
38268
  }
38195
- await batchHandleStripeSubscriptions();
38269
+ await perTenant("startSubscriptionQueue.stripe", batchHandleStripeSubscriptions)();
38196
38270
  } catch (error) {
38197
38271
  logger_default.error("Error in startSubscriptionQueue:", error);
38198
38272
  } finally {
@@ -39688,7 +39762,7 @@ async function executeSingleTransaction(client, claim, type, userDid, userPk, ga
39688
39762
  const { buffer: buffer2 } = await client[`encode${type}Tx`]({ tx });
39689
39763
  return client[`send${type}Tx`](
39690
39764
  { tx, wallet: (0, import_wallet2.fromPublicKey)(userPk, (0, import_did5.toTypeInfo)(userDid)) },
39691
- await getGasPayerExtra(buffer2, gasPayerHeaders)
39765
+ await getGasPayerExtra(buffer2, gasPayerHeaders, client)
39692
39766
  );
39693
39767
  }
39694
39768
  async function executeOcapTransactions(userDid, userPk, claims, paymentMethod, requestSource, subscriptionId, paymentCurrencyContract, nonce) {
@@ -47111,11 +47185,11 @@ async function ensureWebhookRegistered() {
47111
47185
  }
47112
47186
  const stripe = method.getStripeClient();
47113
47187
  const { data } = await stripe.webhookEndpoints.list({ limit: 100 });
47114
- const exist = data.find((webhook) => webhook.metadata?.appPid === import_env28.env.appPid);
47188
+ const exist = data.find((webhook) => webhook.metadata?.appPid === import_env29.env.appPid);
47115
47189
  if (exist) {
47116
47190
  await stripe.webhookEndpoints.update(exist.id, {
47117
47191
  url: STRIPE_ENDPOINT,
47118
- description: import_env28.env.appName,
47192
+ description: import_env29.env.appName,
47119
47193
  enabled_events: STRIPE_EVENTS,
47120
47194
  disabled: false
47121
47195
  });
@@ -47123,11 +47197,11 @@ async function ensureWebhookRegistered() {
47123
47197
  } else {
47124
47198
  const result = await stripe.webhookEndpoints.create({
47125
47199
  url: STRIPE_ENDPOINT,
47126
- description: import_env28.env.appName,
47200
+ description: import_env29.env.appName,
47127
47201
  enabled_events: STRIPE_EVENTS,
47128
47202
  api_version: STRIPE_API_VERSION,
47129
47203
  metadata: {
47130
- appPid: import_env28.env.appPid
47204
+ appPid: import_env29.env.appPid
47131
47205
  }
47132
47206
  });
47133
47207
  logger_default.info("stripe webhook created");
@@ -47152,7 +47226,7 @@ async function validateStripeKeys(secretKey) {
47152
47226
  async function cleanupStripeWebhook(stripe) {
47153
47227
  try {
47154
47228
  const { data } = await stripe.webhookEndpoints.list({ limit: 100 });
47155
- const existingWebhook = data.find((webhook) => webhook.metadata?.appPid === import_env28.env.appPid);
47229
+ const existingWebhook = data.find((webhook) => webhook.metadata?.appPid === import_env29.env.appPid);
47156
47230
  if (existingWebhook) {
47157
47231
  await stripe.webhookEndpoints.del(existingWebhook.id);
47158
47232
  logger_default.info("stripe webhook deleted", { id: existingWebhook.id });
@@ -47161,11 +47235,11 @@ async function cleanupStripeWebhook(stripe) {
47161
47235
  logger_default.error("Failed to clean old webhook:", err);
47162
47236
  }
47163
47237
  }
47164
- var import_env28, import_stripe2;
47238
+ var import_env29, import_stripe2;
47165
47239
  var init_setup = __esm({
47166
47240
  "../../blocklets/core/api/src/integrations/stripe/setup.ts"() {
47167
47241
  "use strict";
47168
- import_env28 = require("@blocklet/sdk/lib/env");
47242
+ import_env29 = require("@blocklet/sdk/lib/env");
47169
47243
  import_stripe2 = __toESM(require("stripe"));
47170
47244
  init_logger();
47171
47245
  init_util();
@@ -55200,6 +55274,7 @@ var init_credit_grant3 = __esm({
55200
55274
  init_dayjs();
55201
55275
  init_queue2();
55202
55276
  init_scoped();
55277
+ init_context();
55203
55278
  init_models();
55204
55279
  init_event2();
55205
55280
  init_credit_grant2();
@@ -55292,7 +55367,8 @@ var init_credit_grant3 = __esm({
55292
55367
  });
55293
55368
  const invoiceResults = await Promise.allSettled(
55294
55369
  invoicesToSchedule.map(async (invoice) => {
55295
- await addInvoiceCreditJob(invoice.id);
55370
+ const dispatch = () => addInvoiceCreditJob(invoice.id);
55371
+ await (invoice.instance_did ? withTenant(invoice.instance_did, dispatch) : dispatch());
55296
55372
  return invoice.id;
55297
55373
  })
55298
55374
  );
@@ -55304,7 +55380,8 @@ var init_credit_grant3 = __esm({
55304
55380
  }
55305
55381
  const results = await Promise.allSettled(
55306
55382
  grantsToSchedule.map(async (grant) => {
55307
- await scheduleCreditGrantJobs(grant);
55383
+ const dispatch = () => scheduleCreditGrantJobs(grant);
55384
+ await (grant.instance_did ? withTenant(grant.instance_did, dispatch) : dispatch());
55308
55385
  return grant.id;
55309
55386
  })
55310
55387
  );
@@ -58006,12 +58083,12 @@ var init_handlers = __esm({
58006
58083
  });
58007
58084
 
58008
58085
  // ../../blocklets/core/api/src/routes/hono/integrations/stripe.ts
58009
- var import_hono21, import_env33, import_get3, app21, verifyWebhookSig, handleEvent, stripe_default;
58086
+ var import_hono21, import_env34, import_get3, app21, verifyWebhookSig, handleEvent, stripe_default;
58010
58087
  var init_stripe = __esm({
58011
58088
  "../../blocklets/core/api/src/routes/hono/integrations/stripe.ts"() {
58012
58089
  "use strict";
58013
58090
  import_hono21 = require("hono");
58014
- import_env33 = require("@blocklet/sdk/lib/env");
58091
+ import_env34 = require("@blocklet/sdk/lib/env");
58015
58092
  import_get3 = __toESM(require("lodash/get"));
58016
58093
  init_env();
58017
58094
  init_handlers();
@@ -58050,7 +58127,7 @@ var init_stripe = __esm({
58050
58127
  return c.json({ skipped: true });
58051
58128
  }
58052
58129
  const appPid = (0, import_get3.default)(stripeEvent, "data.object.metadata.appPid");
58053
- if (appPid && appPid !== import_env33.env.appPid) {
58130
+ if (appPid && appPid !== import_env34.env.appPid) {
58054
58131
  logger_default.debug("webhook event for other app", { id: stripeEvent.id, type: stripeEvent.type });
58055
58132
  return c.json({ skipped: true });
58056
58133
  }
@@ -66597,6 +66674,49 @@ var init_archive2 = __esm({
66597
66674
  }
66598
66675
  });
66599
66676
 
66677
+ // ../../blocklets/core/api/src/routes/hono/bootstrap.ts
66678
+ var import_hono42, app42, authAdmin9, bootstrap_default;
66679
+ var init_bootstrap = __esm({
66680
+ "../../blocklets/core/api/src/routes/hono/bootstrap.ts"() {
66681
+ "use strict";
66682
+ import_hono42 = require("hono");
66683
+ init_security();
66684
+ init_context();
66685
+ init_auth();
66686
+ init_stake();
66687
+ init_models();
66688
+ init_logger();
66689
+ app42 = new import_hono42.Hono();
66690
+ authAdmin9 = authenticate({ component: true, roles: ["owner", "admin"] });
66691
+ app42.get("/", authAdmin9, async (c) => {
66692
+ const instanceDid = getInstanceDid();
66693
+ try {
66694
+ const { bootstrapTenant: bootstrapTenant2 } = (init_service2(), __toCommonJS(service_exports));
66695
+ await bootstrapTenant2(instanceDid);
66696
+ const methods = await PaymentMethod.findAll({ where: { type: "arcblock", active: true } });
66697
+ const chains = await Promise.all(
66698
+ methods.map(async (method) => {
66699
+ const host = method.settings?.arcblock?.api_host;
66700
+ try {
66701
+ const client = method.getOcapClient();
66702
+ const { state } = await client.getAccountState({ address: wallet.address });
66703
+ const stakedForGas = await hasStakedForGas(method);
66704
+ return { method: method.name, host, declared: !!state, balance: state?.balance ?? null, stakedForGas };
66705
+ } catch (err) {
66706
+ return { method: method.name, host, error: err.message };
66707
+ }
66708
+ })
66709
+ );
66710
+ return c.json({ ok: true, instanceDid, appWallet: wallet.address, chains });
66711
+ } catch (err) {
66712
+ logger_default.error("bootstrap endpoint failed", { instanceDid, error: err });
66713
+ return c.json({ ok: false, instanceDid, error: err.message }, 500);
66714
+ }
66715
+ });
66716
+ bootstrap_default = app42;
66717
+ }
66718
+ });
66719
+
66600
66720
  // ../../blocklets/core/api/src/routes/hono/index.ts
66601
66721
  var hono_exports = {};
66602
66722
  __export(hono_exports, {
@@ -66647,6 +66767,7 @@ function mountMigratedResources(native, opts = {}) {
66647
66767
  g("/api/webhook-attempts", webhook_attempts_default);
66648
66768
  g("/api/webhook-endpoints", webhook_endpoints_default);
66649
66769
  g("/api/archive", archive_default);
66770
+ g("/api/bootstrap", bootstrap_default);
66650
66771
  }
66651
66772
  var hono_default;
66652
66773
  var init_hono = __esm({
@@ -66694,6 +66815,7 @@ var init_hono = __esm({
66694
66815
  init_webhook_attempts();
66695
66816
  init_webhook_endpoints();
66696
66817
  init_archive2();
66818
+ init_bootstrap();
66697
66819
  hono_default = mountMigratedResources;
66698
66820
  }
66699
66821
  });
@@ -67032,7 +67154,7 @@ var init_collect = __esm({
67032
67154
  const txHash = await client.sendTransferV3Tx(
67033
67155
  // @ts-ignore
67034
67156
  { tx, wallet: (0, import_wallet3.fromAddress)(userDid) },
67035
- await getGasPayerExtra(buffer2, client.pickGasPayerHeaders(request))
67157
+ await getGasPayerExtra(buffer2, client.pickGasPayerHeaders(request), client)
67036
67158
  );
67037
67159
  await afterTxExecution({
67038
67160
  tx_hash: txHash,
@@ -67199,7 +67321,7 @@ var init_collect_batch = __esm({
67199
67321
  const txHash = await client.sendTransferV3Tx(
67200
67322
  // @ts-ignore
67201
67323
  { tx, wallet: (0, import_wallet4.fromAddress)(userDid) },
67202
- await getGasPayerExtra(buffer2, client.pickGasPayerHeaders(request))
67324
+ await getGasPayerExtra(buffer2, client.pickGasPayerHeaders(request), client)
67203
67325
  );
67204
67326
  await afterTxExecution({ tx_hash: txHash, payer: userDid, type: "transfer" });
67205
67327
  return { hash: txHash };
@@ -67393,7 +67515,7 @@ var init_pay = __esm({
67393
67515
  const txHash = await client.sendTransferV3Tx(
67394
67516
  // @ts-ignore
67395
67517
  { tx, wallet: (0, import_wallet5.fromAddress)(userDid) },
67396
- await getGasPayerExtra(buffer2, client.pickGasPayerHeaders(request))
67518
+ await getGasPayerExtra(buffer2, client.pickGasPayerHeaders(request), client)
67397
67519
  );
67398
67520
  const quoteValidation = await validateQuoteForPayment({
67399
67521
  checkoutSessionId: checkoutSession?.id,
@@ -68909,7 +69031,7 @@ var init_recharge = __esm({
68909
69031
  const txHash = await client.sendTransferV3Tx(
68910
69032
  // @ts-ignore
68911
69033
  { tx, wallet: (0, import_wallet6.fromAddress)(userDid) },
68912
- await getGasPayerExtra(buffer2, client.pickGasPayerHeaders(request))
69034
+ await getGasPayerExtra(buffer2, client.pickGasPayerHeaders(request), client)
68913
69035
  );
68914
69036
  logger_default.info("Recharge successful", {
68915
69037
  receiverAddress,
@@ -69688,7 +69810,7 @@ var init_recharge_account = __esm({
69688
69810
  const txHash = await client.sendTransferV3Tx(
69689
69811
  // @ts-ignore
69690
69812
  { tx, wallet: (0, import_wallet7.fromAddress)(userDid) },
69691
- await getGasPayerExtra(buffer2, client.pickGasPayerHeaders(request))
69813
+ await getGasPayerExtra(buffer2, client.pickGasPayerHeaders(request), client)
69692
69814
  );
69693
69815
  await afterTxExecution({
69694
69816
  tx_hash: txHash,
@@ -71073,7 +71195,7 @@ async function startTokenTransferQueue() {
71073
71195
  logger_default.info("Found pending token transfers to process", { count: pendingTransactions.length });
71074
71196
  await Promise.all(
71075
71197
  pendingTransactions.map(async (transaction) => {
71076
- try {
71198
+ const dispatch = async () => {
71077
71199
  const customer = await systemFindByPk(Customer, transaction.customer_id);
71078
71200
  const creditGrant = await systemFindByPk(CreditGrant, transaction.credit_grant_id);
71079
71201
  await addTokenTransferJob({
@@ -71085,6 +71207,9 @@ async function startTokenTransferQueue() {
71085
71207
  meterEventId: transaction.source,
71086
71208
  subscriptionId: transaction.subscription_id || void 0
71087
71209
  });
71210
+ };
71211
+ try {
71212
+ await (transaction.instance_did ? withTenant(transaction.instance_did, dispatch) : dispatch());
71088
71213
  } catch (error) {
71089
71214
  logger_default.error("Failed to add pending transfer job", {
71090
71215
  transactionId: transaction.id,
@@ -71102,6 +71227,7 @@ var init_token_transfer = __esm({
71102
71227
  "../../blocklets/core/api/src/queues/token-transfer.ts"() {
71103
71228
  "use strict";
71104
71229
  import_util190 = require("@ocap/util");
71230
+ init_context();
71105
71231
  init_logger();
71106
71232
  init_queue2();
71107
71233
  init_token2();
@@ -73727,6 +73853,7 @@ var init_status_check = __esm({
73727
73853
  "use strict";
73728
73854
  import_ufo15 = require("ufo");
73729
73855
  import_payment_vendor4 = require("@blocklet/payment-vendor");
73856
+ init_context();
73730
73857
  init_queue2();
73731
73858
  init_checkout_session();
73732
73859
  init_models();
@@ -73744,17 +73871,26 @@ var init_status_check = __esm({
73744
73871
  }
73745
73872
  for (const checkoutSession of checkoutSessions) {
73746
73873
  const vendorInfo = checkoutSession.vendor_info;
73747
- if (!vendorInfo?.length) {
73748
- return;
73749
- }
73750
- for (const vendor of vendorInfo) {
73751
- if (vendor.status === "sent") {
73752
- vendorStatusCheckQueue.push({
73753
- id: `vendor-status-check-${checkoutSession.id}-${vendor.vendor_id}`,
73754
- job: {
73755
- checkoutSessionId: checkoutSession.id,
73756
- vendorId: vendor.vendor_id
73874
+ if (vendorInfo?.length) {
73875
+ const dispatch = () => {
73876
+ for (const vendor of vendorInfo) {
73877
+ if (vendor.status === "sent") {
73878
+ vendorStatusCheckQueue.push({
73879
+ id: `vendor-status-check-${checkoutSession.id}-${vendor.vendor_id}`,
73880
+ job: {
73881
+ checkoutSessionId: checkoutSession.id,
73882
+ vendorId: vendor.vendor_id
73883
+ }
73884
+ });
73757
73885
  }
73886
+ }
73887
+ };
73888
+ try {
73889
+ await (checkoutSession.instance_did ? withTenant(checkoutSession.instance_did, dispatch) : dispatch());
73890
+ } catch (error) {
73891
+ logger_default.error("startVendorStatusCheckSchedule: enqueue failed", {
73892
+ checkoutSessionId: checkoutSession.id,
73893
+ error
73758
73894
  });
73759
73895
  }
73760
73896
  }
@@ -74583,45 +74719,6 @@ var init_retry_pending_events = __esm({
74583
74719
  }
74584
74720
  });
74585
74721
 
74586
- // ../../blocklets/core/api/src/crons/tenant-fanout.ts
74587
- async function listProvisionedTenants() {
74588
- const { PaymentMethod: PaymentMethod3 } = (init_models(), __toCommonJS(models_exports));
74589
- const rows = await systemFindAll(PaymentMethod3, {
74590
- attributes: ["instance_did"],
74591
- raw: true
74592
- });
74593
- const dids = /* @__PURE__ */ new Set();
74594
- for (const row of rows) {
74595
- if (row?.instance_did) dids.add(row.instance_did);
74596
- }
74597
- return [...dids];
74598
- }
74599
- function perTenant(name, fn3, listTenants = listProvisionedTenants) {
74600
- return async () => {
74601
- if (getTenantMode() === "single") {
74602
- await fn3();
74603
- return;
74604
- }
74605
- const dids = await listTenants();
74606
- if (dids.length === 0) return;
74607
- logger_default.info("cron.tenant.fanout", { cron: name, tenantCount: dids.length });
74608
- for (const instanceDid of dids) {
74609
- await withTenant(instanceDid, async () => fn3()).catch(
74610
- (error) => logger_default.error("cron tenant pass failed", { cron: name, instanceDid, error })
74611
- );
74612
- }
74613
- };
74614
- }
74615
- var init_tenant_fanout = __esm({
74616
- "../../blocklets/core/api/src/crons/tenant-fanout.ts"() {
74617
- "use strict";
74618
- init_context();
74619
- init_logger();
74620
- init_tenant();
74621
- init_scoped();
74622
- }
74623
- });
74624
-
74625
74722
  // ../../blocklets/core/api/src/crons/subscription-trial-will-end.ts
74626
74723
  var import_dayjs45, import_sequelize110, SubscriptionTrialWillEndSchedule;
74627
74724
  var init_subscription_trial_will_end2 = __esm({
@@ -75505,7 +75602,10 @@ function init() {
75505
75602
  {
75506
75603
  name: "deposit.vault",
75507
75604
  time: depositVaultCronTime(),
75508
- fn: () => startDepositVaultQueue(),
75605
+ // startDepositVaultQueue uses a SCOPED findAll (not systemFindAll), so it
75606
+ // must run inside a tenant — perTenant fans it out per provisioned tenant
75607
+ // (multi) or runs it once for the default tenant (single).
75608
+ fn: perTenant("deposit.vault", () => startDepositVaultQueue()),
75509
75609
  options: { runOnInit: true }
75510
75610
  },
75511
75611
  {
@@ -75951,6 +76051,7 @@ var handleVendorCommission, vendorCommissionQueue, startVendorCommissionQueue;
75951
76051
  var init_commission = __esm({
75952
76052
  "../../blocklets/core/api/src/queues/vendors/commission.ts"() {
75953
76053
  "use strict";
76054
+ init_context();
75954
76055
  init_event2();
75955
76056
  init_logger();
75956
76057
  init_queue2();
@@ -76027,13 +76128,23 @@ var init_commission = __esm({
76027
76128
  capture_method: "automatic"
76028
76129
  }
76029
76130
  });
76030
- payments.forEach(async (x) => {
76031
- const id = `vendor-commission-${x.invoice_id}`;
76032
- const exist = await vendorCommissionQueue.get(id);
76033
- if (!exist && x.invoice_id) {
76034
- vendorCommissionQueue.push({ id, job: { invoiceId: x.invoice_id, retryOnError: true } });
76131
+ for (const x of payments) {
76132
+ const invoiceId = x.invoice_id;
76133
+ if (invoiceId) {
76134
+ const dispatch = async () => {
76135
+ const id = `vendor-commission-${invoiceId}`;
76136
+ const exist = await vendorCommissionQueue.get(id);
76137
+ if (!exist) {
76138
+ vendorCommissionQueue.push({ id, job: { invoiceId, retryOnError: true } });
76139
+ }
76140
+ };
76141
+ try {
76142
+ await (x.instance_did ? withTenant(x.instance_did, dispatch) : dispatch());
76143
+ } catch (error) {
76144
+ logger_default.error("startVendorCommissionQueue: re-queue failed", { invoiceId, error });
76145
+ }
76035
76146
  }
76036
- });
76147
+ }
76037
76148
  };
76038
76149
  events.on("invoice.paid", async (invoice) => {
76039
76150
  try {
@@ -76851,6 +76962,7 @@ var init_discount_status = __esm({
76851
76962
  "../../blocklets/core/api/src/queues/discount-status.ts"() {
76852
76963
  "use strict";
76853
76964
  import_p_all8 = __toESM(require("p-all"));
76965
+ init_context();
76854
76966
  init_queue2();
76855
76967
  init_models();
76856
76968
  init_logger();
@@ -76870,19 +76982,21 @@ var init_discount_status = __esm({
76870
76982
  logger_default.info("Starting discount status queue...");
76871
76983
  const coupons = await systemFindAll(Coupon, { where: { valid: true } });
76872
76984
  const promotionCodes = await systemFindAll(PromotionCode, { where: { active: true } });
76985
+ const enqueue = (record, type, options) => async () => {
76986
+ const dispatch = () => addDiscountStatusJob(record, type, false, options);
76987
+ try {
76988
+ await (record.instance_did ? withTenant(record.instance_did, dispatch) : dispatch());
76989
+ } catch (error) {
76990
+ logger_default.error("startDiscountStatusQueue: enqueue failed", { type, id: record.id, error });
76991
+ }
76992
+ };
76873
76993
  await (0, import_p_all8.default)(
76874
- coupons.map(
76875
- (coupon) => () => addDiscountStatusJob(coupon, "coupon", false, {
76876
- runAt: coupon.redeem_by
76877
- })
76878
- ),
76994
+ coupons.map((coupon) => enqueue(coupon, "coupon", { runAt: coupon.redeem_by })),
76879
76995
  { concurrency: 5 }
76880
76996
  );
76881
76997
  await (0, import_p_all8.default)(
76882
76998
  promotionCodes.map(
76883
- (promotionCode) => () => addDiscountStatusJob(promotionCode, "promotion-code", false, {
76884
- runAt: promotionCode.expires_at
76885
- })
76999
+ (promotionCode) => enqueue(promotionCode, "promotion-code", { runAt: promotionCode.expires_at })
76886
77000
  ),
76887
77001
  { concurrency: 5 }
76888
77002
  );
@@ -77037,13 +77151,18 @@ function contextMiddleware() {
77037
77151
  requestedBy = user4.did;
77038
77152
  }
77039
77153
  let instanceDid;
77040
- try {
77041
- instanceDid = await resolveTenantForHost(c.req.header("host"));
77042
- } catch (err) {
77043
- if (err instanceof TenantError && err.code === TENANT_HOST_UNRESOLVED) {
77044
- return c.json({ error: { code: err.code, message: err.message } }, 400);
77154
+ const preResolved = context.peekInstanceDid();
77155
+ if (preResolved) {
77156
+ instanceDid = preResolved;
77157
+ } else {
77158
+ try {
77159
+ instanceDid = await resolveTenantForHost(c.req.header("host"));
77160
+ } catch (err) {
77161
+ if (err instanceof TenantError && err.code === TENANT_HOST_UNRESOLVED) {
77162
+ return c.json({ error: { code: err.code, message: err.message } }, 400);
77163
+ }
77164
+ throw err;
77045
77165
  }
77046
- throw err;
77047
77166
  }
77048
77167
  return context.run({ requestId, requestedBy, instanceDid }, async () => {
77049
77168
  await warmTenantIdentity(instanceDid);
@@ -77115,7 +77234,7 @@ var http_fetch_adapter_exports = {};
77115
77234
  __export(http_fetch_adapter_exports, {
77116
77235
  createFetchHandler: () => createFetchHandler
77117
77236
  });
77118
- function createFetchHandler(app42) {
77237
+ function createFetchHandler(app43) {
77119
77238
  const handler = (async (request, opts) => {
77120
77239
  const url = new URL(request.url);
77121
77240
  const basePath = opts?.basePath ?? "";
@@ -77126,9 +77245,9 @@ function createFetchHandler(app42) {
77126
77245
  const body = hasBody ? await request.arrayBuffer() : void 0;
77127
77246
  const headers = new Headers(request.headers);
77128
77247
  if (!headers.has("x-path-prefix")) headers.set("x-path-prefix", basePath);
77129
- return app42.fetch(new Request(url.toString(), { method, headers, body }));
77248
+ return app43.fetch(new Request(url.toString(), { method, headers, body }));
77130
77249
  }
77131
- return app42.fetch(request);
77250
+ return app43.fetch(request);
77132
77251
  });
77133
77252
  handler.close = () => Promise.resolve();
77134
77253
  return handler;
@@ -77145,16 +77264,17 @@ __export(service_exports, {
77145
77264
  MissingConfigError: () => MissingConfigError,
77146
77265
  PaymentCoreSlotError: () => PaymentCoreSlotError,
77147
77266
  TenancySlotError: () => TenancySlotError,
77267
+ bootstrapTenant: () => bootstrapTenant,
77148
77268
  buildConnectRoutesHono: () => buildConnectRoutesHono,
77149
77269
  buildHonoApp: () => buildHonoApp,
77150
77270
  createEmbeddedPaymentService: () => createEmbeddedPaymentService
77151
77271
  });
77152
77272
  function buildResourceRoutesHono() {
77153
77273
  const { mountMigratedResources: mountMigratedResources2 } = (init_hono(), __toCommonJS(hono_exports));
77154
- const app42 = new import_hono42.Hono();
77155
- app42.get("/api/healthz", (c) => c.json({ ok: true }));
77156
- mountMigratedResources2(app42);
77157
- return app42;
77274
+ const app43 = new import_hono43.Hono();
77275
+ app43.get("/api/healthz", (c) => c.json({ ok: true }));
77276
+ mountMigratedResources2(app43);
77277
+ return app43;
77158
77278
  }
77159
77279
  function connectHandlerModules() {
77160
77280
  return [
@@ -77176,7 +77296,7 @@ function connectHandlerModules() {
77176
77296
  }
77177
77297
  function buildConnectRoutesHono() {
77178
77298
  const { handlers: handlers2 } = (init_auth(), __toCommonJS(auth_exports));
77179
- const connectApp = new import_hono42.Hono();
77299
+ const connectApp = new import_hono43.Hono();
77180
77300
  connectApp.use("*", async (c, next) => {
77181
77301
  const { context: requestCtx } = (init_context(), __toCommonJS(context_exports));
77182
77302
  if (requestCtx.peekInstanceDid()) return next();
@@ -77188,23 +77308,23 @@ function buildConnectRoutesHono() {
77188
77308
  return connectApp;
77189
77309
  }
77190
77310
  function buildHonoApp(configureNative, getConnectApp, attachStatic) {
77191
- const app42 = new import_hono42.Hono();
77192
- app42.onError((err, c) => {
77311
+ const app43 = new import_hono43.Hono();
77312
+ app43.onError((err, c) => {
77193
77313
  logger_default.error("handle router error", err);
77194
77314
  if (err instanceof import_error12.CustomError) {
77195
77315
  return c.json({ error: (0, import_error12.formatError)(err) }, (0, import_error12.getStatusFromError)(err));
77196
77316
  }
77197
77317
  return c.json({ error: err.message }, 500);
77198
77318
  });
77199
- app42.get("/api/healthz", (c) => c.json({ ok: true }));
77200
- const native = new import_hono42.Hono();
77319
+ app43.get("/api/healthz", (c) => c.json({ ok: true }));
77320
+ const native = new import_hono43.Hono();
77201
77321
  configureNative?.(native);
77202
- app42.route("/", native);
77322
+ app43.route("/", native);
77203
77323
  if (getConnectApp) {
77204
- app42.route("/", getConnectApp());
77324
+ app43.route("/", getConnectApp());
77205
77325
  }
77206
- attachStatic?.(app42);
77207
- return app42;
77326
+ attachStatic?.(app43);
77327
+ return app43;
77208
77328
  }
77209
77329
  function requireTenant() {
77210
77330
  return context.getInstanceDid();
@@ -77332,6 +77452,7 @@ async function startBackgroundServices() {
77332
77452
  return;
77333
77453
  }
77334
77454
  servicesStarted = true;
77455
+ (init_notification(), __toCommonJS(notification_exports)).ensureBlockletSdkTransportGuard();
77335
77456
  const crons = (init_crons(), __toCommonJS(crons_exports)).default;
77336
77457
  const { initResourceHandler: initResourceHandler2 } = (init_resource4(), __toCommonJS(resource_exports2));
77337
77458
  const { initUserHandler: initUserHandler2 } = (init_user(), __toCommonJS(user_exports));
@@ -77346,7 +77467,7 @@ async function startBackgroundServices() {
77346
77467
  ["vendor fulfillment", (init_fulfillment2(), __toCommonJS(fulfillment_exports)).startVendorFulfillmentQueue],
77347
77468
  ["coordinated fulfillment", (init_fulfillment_coordinator(), __toCommonJS(fulfillment_coordinator_exports)).startCoordinatedFulfillmentQueue],
77348
77469
  ["checkoutSession", (init_checkout_session2(), __toCommonJS(checkout_session_exports)).startCheckoutSessionQueue],
77349
- ["notification", (init_notification3(), __toCommonJS(notification_exports)).startNotificationQueue],
77470
+ ["notification", (init_notification3(), __toCommonJS(notification_exports2)).startNotificationQueue],
77350
77471
  ["refund", (init_refund3(), __toCommonJS(refund_exports)).startRefundQueue],
77351
77472
  ["credit", (init_credit_consume(), __toCommonJS(credit_consume_exports)).startCreditConsumeQueue],
77352
77473
  ["credit grant", (init_credit_grant3(), __toCommonJS(credit_grant_exports)).startCreditGrantQueue],
@@ -77355,7 +77476,7 @@ async function startBackgroundServices() {
77355
77476
  ["discount status", (init_discount_status(), __toCommonJS(discount_status_exports)).startDiscountStatusQueue]
77356
77477
  ];
77357
77478
  for (const [name, start] of starters) {
77358
- Promise.resolve(start()).then(() => logger_default.info(`${name} queue started`));
77479
+ Promise.resolve(start()).then(() => logger_default.info(`${name} queue started`)).catch((error) => logger_default.error(`${name} queue failed to start`, { error }));
77359
77480
  }
77360
77481
  crons.init();
77361
77482
  initEventBroadcast2();
@@ -77512,12 +77633,12 @@ function createEmbeddedPaymentService(slots) {
77512
77633
  provisionTenant
77513
77634
  };
77514
77635
  }
77515
- var import_error12, import_hono42, PaymentCoreSlotError, MissingConfigError, TenancySlotError, VALID_TENANT_MODES, servicesStarted, listInstanceDidsHook;
77636
+ var import_error12, import_hono43, PaymentCoreSlotError, MissingConfigError, TenancySlotError, VALID_TENANT_MODES, servicesStarted, listInstanceDidsHook;
77516
77637
  var init_service2 = __esm({
77517
77638
  "../../blocklets/core/api/src/service.ts"() {
77518
77639
  "use strict";
77519
77640
  import_error12 = require("@blocklet/error");
77520
- import_hono42 = require("hono");
77641
+ import_hono43 = require("hono");
77521
77642
  init_env();
77522
77643
  init_logger();
77523
77644
  init_context();