@openzeppelin/ui-builder-adapter-stellar 1.1.0 → 1.1.2

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/dist/index.js CHANGED
@@ -3328,15 +3328,81 @@ import {
3328
3328
  IndexerUnavailable,
3329
3329
  OperationFailed as OperationFailed2
3330
3330
  } from "@openzeppelin/ui-builder-types";
3331
- import { appConfigService as appConfigService2, logger as logger19 } from "@openzeppelin/ui-builder-utils";
3331
+ import {
3332
+ appConfigService as appConfigService2,
3333
+ isValidUrl,
3334
+ logger as logger19,
3335
+ userNetworkServiceConfigService
3336
+ } from "@openzeppelin/ui-builder-utils";
3332
3337
  var LOG_SYSTEM3 = "StellarIndexerClient";
3338
+ function getUserIndexerEndpoints(networkId) {
3339
+ const svcCfg = userNetworkServiceConfigService.get(networkId, "indexer");
3340
+ if (!svcCfg || typeof svcCfg !== "object") {
3341
+ return void 0;
3342
+ }
3343
+ const endpoints = {};
3344
+ if ("indexerUri" in svcCfg && svcCfg.indexerUri) {
3345
+ const httpUrl = String(svcCfg.indexerUri).trim();
3346
+ if (httpUrl && isValidUrl(httpUrl)) {
3347
+ endpoints.http = httpUrl;
3348
+ } else if (httpUrl) {
3349
+ logger19.warn(
3350
+ LOG_SYSTEM3,
3351
+ `User-configured indexer HTTP URL for ${networkId} is invalid: ${httpUrl}. Ignoring.`
3352
+ );
3353
+ }
3354
+ }
3355
+ if ("indexerWsUri" in svcCfg && svcCfg.indexerWsUri) {
3356
+ const wsUrl = String(svcCfg.indexerWsUri).trim();
3357
+ if (wsUrl && isValidUrl(wsUrl)) {
3358
+ endpoints.ws = wsUrl;
3359
+ } else if (wsUrl) {
3360
+ logger19.warn(
3361
+ LOG_SYSTEM3,
3362
+ `User-configured indexer WebSocket URL for ${networkId} is invalid: ${wsUrl}. Ignoring.`
3363
+ );
3364
+ }
3365
+ }
3366
+ if (!endpoints.http && !endpoints.ws) {
3367
+ return void 0;
3368
+ }
3369
+ return endpoints;
3370
+ }
3333
3371
  var StellarIndexerClient = class {
3334
3372
  constructor(networkConfig) {
3335
3373
  __publicField(this, "networkConfig");
3336
3374
  __publicField(this, "resolvedEndpoints", null);
3337
3375
  __publicField(this, "availabilityChecked", false);
3338
3376
  __publicField(this, "isAvailable", false);
3377
+ __publicField(this, "unsubscribeFromConfigChanges");
3339
3378
  this.networkConfig = networkConfig;
3379
+ this.unsubscribeFromConfigChanges = userNetworkServiceConfigService.subscribe(
3380
+ networkConfig.id,
3381
+ "indexer",
3382
+ () => {
3383
+ logger19.info(
3384
+ LOG_SYSTEM3,
3385
+ `User indexer config changed for ${networkConfig.id}, resetting cache`
3386
+ );
3387
+ this.resetCache();
3388
+ }
3389
+ );
3390
+ }
3391
+ /**
3392
+ * Resets the resolved endpoints and availability cache.
3393
+ * Called when user configuration changes to force re-resolution.
3394
+ */
3395
+ resetCache() {
3396
+ this.resolvedEndpoints = null;
3397
+ this.availabilityChecked = false;
3398
+ this.isAvailable = false;
3399
+ }
3400
+ /**
3401
+ * Cleans up subscriptions when the client is no longer needed.
3402
+ * Call this method when disposing of the client to prevent memory leaks.
3403
+ */
3404
+ dispose() {
3405
+ this.unsubscribeFromConfigChanges();
3340
3406
  }
3341
3407
  /**
3342
3408
  * Check if indexer is available and configured
@@ -4033,10 +4099,11 @@ var StellarIndexerClient = class {
4033
4099
  /**
4034
4100
  * Resolve indexer endpoints with config precedence
4035
4101
  * Priority:
4036
- * 1. Runtime override from AppConfigService
4037
- * 2. Network config defaults (indexerUri/indexerWsUri)
4038
- * 3. Derived from RPC (if safe pattern exists)
4039
- * 4. None (returns empty object)
4102
+ * 1. User-configured indexer from UserNetworkServiceConfigService (localStorage)
4103
+ * 2. Runtime override from AppConfigService (environment/JSON config)
4104
+ * 3. Network config defaults (indexerUri/indexerWsUri)
4105
+ * 4. Derived from RPC (if safe pattern exists)
4106
+ * 5. None (returns empty object)
4040
4107
  *
4041
4108
  * @returns Resolved indexer endpoints
4042
4109
  */
@@ -4046,6 +4113,23 @@ var StellarIndexerClient = class {
4046
4113
  }
4047
4114
  const networkId = this.networkConfig.id;
4048
4115
  const endpoints = {};
4116
+ const userIndexerConfig = getUserIndexerEndpoints(networkId);
4117
+ if (userIndexerConfig) {
4118
+ if (userIndexerConfig.http) {
4119
+ endpoints.http = userIndexerConfig.http;
4120
+ }
4121
+ if (userIndexerConfig.ws) {
4122
+ endpoints.ws = userIndexerConfig.ws;
4123
+ }
4124
+ if (endpoints.http || endpoints.ws) {
4125
+ logger19.info(
4126
+ LOG_SYSTEM3,
4127
+ `Using user-configured indexer for ${networkId}: http=${endpoints.http}, ws=${endpoints.ws}`
4128
+ );
4129
+ this.resolvedEndpoints = endpoints;
4130
+ return endpoints;
4131
+ }
4132
+ }
4049
4133
  const indexerOverride = appConfigService2.getIndexerEndpointOverride(networkId);
4050
4134
  if (indexerOverride) {
4051
4135
  if (typeof indexerOverride === "string") {
@@ -4104,7 +4188,8 @@ var StellarIndexerClient = class {
4104
4188
  OWNERSHIP_TRANSFER_STARTED: "OWNERSHIP_TRANSFER_STARTED",
4105
4189
  OWNERSHIP_TRANSFER_COMPLETED: "OWNERSHIP_TRANSFER_COMPLETED",
4106
4190
  ADMIN_TRANSFER_INITIATED: "ADMIN_TRANSFER_INITIATED",
4107
- ADMIN_TRANSFER_COMPLETED: "ADMIN_TRANSFER_COMPLETED"
4191
+ ADMIN_TRANSFER_COMPLETED: "ADMIN_TRANSFER_COMPLETED",
4192
+ UNKNOWN: "UNKNOWN"
4108
4193
  };
4109
4194
  return mapping[changeType];
4110
4195
  }
@@ -5440,24 +5525,39 @@ var StellarAccessControlService = class {
5440
5525
  return [];
5441
5526
  }
5442
5527
  }
5528
+ /**
5529
+ * Disposes of the service and cleans up resources.
5530
+ *
5531
+ * Cleans up the indexer client's subscriptions to prevent memory leaks.
5532
+ * Call this method when the service is no longer needed.
5533
+ *
5534
+ * Note: In typical usage where the service is application-scoped and lives
5535
+ * for the duration of the application, calling dispose is not strictly necessary.
5536
+ * However, it should be called if the service is created/destroyed dynamically
5537
+ * (e.g., in tests or when switching networks).
5538
+ */
5539
+ dispose() {
5540
+ this.indexerClient.dispose();
5541
+ logger20.debug("StellarAccessControlService.dispose", "Service disposed");
5542
+ }
5443
5543
  };
5444
5544
  function createStellarAccessControlService(networkConfig) {
5445
5545
  return new StellarAccessControlService(networkConfig);
5446
5546
  }
5447
5547
 
5448
5548
  // src/configuration/network-services.ts
5449
- import { isValidUrl as isValidUrl2 } from "@openzeppelin/ui-builder-utils";
5549
+ import { isValidUrl as isValidUrl3 } from "@openzeppelin/ui-builder-utils";
5450
5550
 
5451
5551
  // src/configuration/rpc.ts
5452
5552
  import {
5453
5553
  appConfigService as appConfigService3,
5454
- isValidUrl,
5554
+ isValidUrl as isValidUrl2,
5455
5555
  logger as logger21,
5456
5556
  userRpcConfigService as userRpcConfigService4
5457
5557
  } from "@openzeppelin/ui-builder-utils";
5458
5558
  function validateStellarRpcEndpoint(rpcConfig) {
5459
5559
  try {
5460
- if (!isValidUrl(rpcConfig.url)) {
5560
+ if (!isValidUrl2(rpcConfig.url)) {
5461
5561
  logger21.error("validateStellarRpcEndpoint", `Invalid RPC URL format: ${rpcConfig.url}`);
5462
5562
  return false;
5463
5563
  }
@@ -5622,12 +5722,12 @@ async function validateStellarNetworkServiceConfig(serviceId, values) {
5622
5722
  }
5623
5723
  if (serviceId === "indexer") {
5624
5724
  if (values.indexerUri !== void 0 && values.indexerUri !== null && values.indexerUri !== "") {
5625
- if (!isValidUrl2(String(values.indexerUri))) {
5725
+ if (!isValidUrl3(String(values.indexerUri))) {
5626
5726
  return false;
5627
5727
  }
5628
5728
  }
5629
5729
  if (values.indexerWsUri !== void 0 && values.indexerWsUri !== null && values.indexerWsUri !== "") {
5630
- if (!isValidUrl2(String(values.indexerWsUri))) {
5730
+ if (!isValidUrl3(String(values.indexerWsUri))) {
5631
5731
  return false;
5632
5732
  }
5633
5733
  }
@@ -5648,7 +5748,7 @@ async function testStellarNetworkServiceConnection(serviceId, values) {
5648
5748
  if (!indexerUri || typeof indexerUri !== "string" || indexerUri.trim() === "") {
5649
5749
  return { success: true };
5650
5750
  }
5651
- if (!isValidUrl2(indexerUri)) {
5751
+ if (!isValidUrl3(indexerUri)) {
5652
5752
  return { success: false, error: "Invalid indexer URI format" };
5653
5753
  }
5654
5754
  try {
@@ -8299,8 +8399,8 @@ var stellarTestnet = {
8299
8399
  sorobanRpcUrl: "https://soroban-testnet.stellar.org",
8300
8400
  networkPassphrase: "Test SDF Network ; September 2015",
8301
8401
  explorerUrl: "https://stellar.expert/explorer/testnet",
8302
- iconComponent: NetworkStellar2
8303
- // indexerUri and indexerWsUri will be added here when stable testnet indexer endpoints are available
8402
+ iconComponent: NetworkStellar2,
8403
+ indexerUri: "https://openzepplin-stellar-testnet.graphql.subquery.network"
8304
8404
  };
8305
8405
 
8306
8406
  // src/networks/index.ts