@unicitylabs/sphere-sdk 0.3.7 → 0.3.9
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/connect/index.cjs +770 -0
- package/dist/connect/index.cjs.map +1 -0
- package/dist/connect/index.d.cts +312 -0
- package/dist/connect/index.d.ts +312 -0
- package/dist/connect/index.js +747 -0
- package/dist/connect/index.js.map +1 -0
- package/dist/core/index.cjs +90 -2502
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +10 -165
- package/dist/core/index.d.ts +10 -165
- package/dist/core/index.js +86 -2498
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs +271 -0
- package/dist/impl/browser/connect/index.cjs.map +1 -0
- package/dist/impl/browser/connect/index.d.cts +137 -0
- package/dist/impl/browser/connect/index.d.ts +137 -0
- package/dist/impl/browser/connect/index.js +248 -0
- package/dist/impl/browser/connect/index.js.map +1 -0
- package/dist/impl/browser/index.cjs +201 -28
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js +201 -28
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/browser/ipfs.cjs +6 -1
- package/dist/impl/browser/ipfs.cjs.map +1 -1
- package/dist/impl/browser/ipfs.js +6 -1
- package/dist/impl/browser/ipfs.js.map +1 -1
- package/dist/impl/nodejs/connect/index.cjs +372 -0
- package/dist/impl/nodejs/connect/index.cjs.map +1 -0
- package/dist/impl/nodejs/connect/index.d.cts +178 -0
- package/dist/impl/nodejs/connect/index.d.ts +178 -0
- package/dist/impl/nodejs/connect/index.js +333 -0
- package/dist/impl/nodejs/connect/index.js.map +1 -0
- package/dist/impl/nodejs/index.cjs +201 -28
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.d.cts +2 -21
- package/dist/impl/nodejs/index.d.ts +2 -21
- package/dist/impl/nodejs/index.js +201 -28
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/index.cjs +232 -2513
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -169
- package/dist/index.d.ts +59 -169
- package/dist/index.js +228 -2506
- package/dist/index.js.map +1 -1
- package/package.json +31 -1
|
@@ -98,7 +98,11 @@ var STORAGE_KEYS_GLOBAL = {
|
|
|
98
98
|
/** Cached token registry JSON (fetched from remote) */
|
|
99
99
|
TOKEN_REGISTRY_CACHE: "token_registry_cache",
|
|
100
100
|
/** Timestamp of last token registry cache update (ms since epoch) */
|
|
101
|
-
TOKEN_REGISTRY_CACHE_TS: "token_registry_cache_ts"
|
|
101
|
+
TOKEN_REGISTRY_CACHE_TS: "token_registry_cache_ts",
|
|
102
|
+
/** Cached price data JSON (from CoinGecko or other provider) */
|
|
103
|
+
PRICE_CACHE: "price_cache",
|
|
104
|
+
/** Timestamp of last price cache update (ms since epoch) */
|
|
105
|
+
PRICE_CACHE_TS: "price_cache_ts"
|
|
102
106
|
};
|
|
103
107
|
var STORAGE_KEYS_ADDRESS = {
|
|
104
108
|
/** Pending transfers for this address */
|
|
@@ -223,7 +227,6 @@ var TIMEOUTS = {
|
|
|
223
227
|
/** Sync interval */
|
|
224
228
|
SYNC_INTERVAL: 6e4
|
|
225
229
|
};
|
|
226
|
-
var DEFAULT_MARKET_API_URL = "https://market-api.unicity.network";
|
|
227
230
|
|
|
228
231
|
// impl/browser/storage/LocalStorageProvider.ts
|
|
229
232
|
var LocalStorageProvider = class {
|
|
@@ -3412,6 +3415,7 @@ async function loadIpnsModule() {
|
|
|
3412
3415
|
async function createSignedRecord(keyPair, cid, sequenceNumber, lifetimeMs = DEFAULT_LIFETIME_MS) {
|
|
3413
3416
|
const { createIPNSRecord, marshalIPNSRecord } = await loadIpnsModule();
|
|
3414
3417
|
const record = await createIPNSRecord(
|
|
3418
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3415
3419
|
keyPair,
|
|
3416
3420
|
`/ipfs/${cid}`,
|
|
3417
3421
|
sequenceNumber,
|
|
@@ -5156,26 +5160,37 @@ var CoinGeckoPriceProvider = class {
|
|
|
5156
5160
|
timeout;
|
|
5157
5161
|
debug;
|
|
5158
5162
|
baseUrl;
|
|
5163
|
+
storage;
|
|
5164
|
+
/** In-flight fetch promise for deduplication of concurrent getPrices() calls */
|
|
5165
|
+
fetchPromise = null;
|
|
5166
|
+
/** Token names being fetched in the current in-flight request */
|
|
5167
|
+
fetchNames = null;
|
|
5168
|
+
/** Whether persistent cache has been loaded into memory */
|
|
5169
|
+
persistentCacheLoaded = false;
|
|
5170
|
+
/** Promise for loading persistent cache (deduplication) */
|
|
5171
|
+
loadCachePromise = null;
|
|
5159
5172
|
constructor(config) {
|
|
5160
5173
|
this.apiKey = config?.apiKey;
|
|
5161
5174
|
this.cacheTtlMs = config?.cacheTtlMs ?? 6e4;
|
|
5162
5175
|
this.timeout = config?.timeout ?? 1e4;
|
|
5163
5176
|
this.debug = config?.debug ?? false;
|
|
5177
|
+
this.storage = config?.storage ?? null;
|
|
5164
5178
|
this.baseUrl = config?.baseUrl ?? (this.apiKey ? "https://pro-api.coingecko.com/api/v3" : "https://api.coingecko.com/api/v3");
|
|
5165
5179
|
}
|
|
5166
5180
|
async getPrices(tokenNames) {
|
|
5167
5181
|
if (tokenNames.length === 0) {
|
|
5168
5182
|
return /* @__PURE__ */ new Map();
|
|
5169
5183
|
}
|
|
5184
|
+
if (!this.persistentCacheLoaded && this.storage) {
|
|
5185
|
+
await this.loadFromStorage();
|
|
5186
|
+
}
|
|
5170
5187
|
const now = Date.now();
|
|
5171
5188
|
const result = /* @__PURE__ */ new Map();
|
|
5172
5189
|
const uncachedNames = [];
|
|
5173
5190
|
for (const name of tokenNames) {
|
|
5174
5191
|
const cached = this.cache.get(name);
|
|
5175
5192
|
if (cached && cached.expiresAt > now) {
|
|
5176
|
-
|
|
5177
|
-
result.set(name, cached.price);
|
|
5178
|
-
}
|
|
5193
|
+
result.set(name, cached.price);
|
|
5179
5194
|
} else {
|
|
5180
5195
|
uncachedNames.push(name);
|
|
5181
5196
|
}
|
|
@@ -5183,6 +5198,41 @@ var CoinGeckoPriceProvider = class {
|
|
|
5183
5198
|
if (uncachedNames.length === 0) {
|
|
5184
5199
|
return result;
|
|
5185
5200
|
}
|
|
5201
|
+
if (this.fetchPromise && this.fetchNames) {
|
|
5202
|
+
const allCovered = uncachedNames.every((n) => this.fetchNames.has(n));
|
|
5203
|
+
if (allCovered) {
|
|
5204
|
+
if (this.debug) {
|
|
5205
|
+
console.log(`[CoinGecko] Deduplicating request, reusing in-flight fetch`);
|
|
5206
|
+
}
|
|
5207
|
+
const fetched = await this.fetchPromise;
|
|
5208
|
+
for (const name of uncachedNames) {
|
|
5209
|
+
const price = fetched.get(name);
|
|
5210
|
+
if (price) {
|
|
5211
|
+
result.set(name, price);
|
|
5212
|
+
}
|
|
5213
|
+
}
|
|
5214
|
+
return result;
|
|
5215
|
+
}
|
|
5216
|
+
}
|
|
5217
|
+
const fetchPromise = this.doFetch(uncachedNames);
|
|
5218
|
+
this.fetchPromise = fetchPromise;
|
|
5219
|
+
this.fetchNames = new Set(uncachedNames);
|
|
5220
|
+
try {
|
|
5221
|
+
const fetched = await fetchPromise;
|
|
5222
|
+
for (const [name, price] of fetched) {
|
|
5223
|
+
result.set(name, price);
|
|
5224
|
+
}
|
|
5225
|
+
} finally {
|
|
5226
|
+
if (this.fetchPromise === fetchPromise) {
|
|
5227
|
+
this.fetchPromise = null;
|
|
5228
|
+
this.fetchNames = null;
|
|
5229
|
+
}
|
|
5230
|
+
}
|
|
5231
|
+
return result;
|
|
5232
|
+
}
|
|
5233
|
+
async doFetch(uncachedNames) {
|
|
5234
|
+
const result = /* @__PURE__ */ new Map();
|
|
5235
|
+
const now = Date.now();
|
|
5186
5236
|
try {
|
|
5187
5237
|
const ids = uncachedNames.join(",");
|
|
5188
5238
|
const url = `${this.baseUrl}/simple/price?ids=${encodeURIComponent(ids)}&vs_currencies=usd,eur&include_24hr_change=true`;
|
|
@@ -5198,6 +5248,9 @@ var CoinGeckoPriceProvider = class {
|
|
|
5198
5248
|
signal: AbortSignal.timeout(this.timeout)
|
|
5199
5249
|
});
|
|
5200
5250
|
if (!response.ok) {
|
|
5251
|
+
if (response.status === 429) {
|
|
5252
|
+
this.extendCacheOnRateLimit(uncachedNames);
|
|
5253
|
+
}
|
|
5201
5254
|
throw new Error(`CoinGecko API error: ${response.status} ${response.statusText}`);
|
|
5202
5255
|
}
|
|
5203
5256
|
const data = await response.json();
|
|
@@ -5216,25 +5269,113 @@ var CoinGeckoPriceProvider = class {
|
|
|
5216
5269
|
}
|
|
5217
5270
|
for (const name of uncachedNames) {
|
|
5218
5271
|
if (!result.has(name)) {
|
|
5219
|
-
|
|
5272
|
+
const zeroPrice = {
|
|
5273
|
+
tokenName: name,
|
|
5274
|
+
priceUsd: 0,
|
|
5275
|
+
priceEur: 0,
|
|
5276
|
+
change24h: 0,
|
|
5277
|
+
timestamp: now
|
|
5278
|
+
};
|
|
5279
|
+
this.cache.set(name, { price: zeroPrice, expiresAt: now + this.cacheTtlMs });
|
|
5280
|
+
result.set(name, zeroPrice);
|
|
5220
5281
|
}
|
|
5221
5282
|
}
|
|
5222
5283
|
if (this.debug) {
|
|
5223
5284
|
console.log(`[CoinGecko] Fetched ${result.size} prices`);
|
|
5224
5285
|
}
|
|
5286
|
+
this.saveToStorage();
|
|
5225
5287
|
} catch (error) {
|
|
5226
5288
|
if (this.debug) {
|
|
5227
5289
|
console.warn("[CoinGecko] Fetch failed, using stale cache:", error);
|
|
5228
5290
|
}
|
|
5229
5291
|
for (const name of uncachedNames) {
|
|
5230
5292
|
const stale = this.cache.get(name);
|
|
5231
|
-
if (stale
|
|
5293
|
+
if (stale) {
|
|
5232
5294
|
result.set(name, stale.price);
|
|
5233
5295
|
}
|
|
5234
5296
|
}
|
|
5235
5297
|
}
|
|
5236
5298
|
return result;
|
|
5237
5299
|
}
|
|
5300
|
+
// ===========================================================================
|
|
5301
|
+
// Persistent Storage
|
|
5302
|
+
// ===========================================================================
|
|
5303
|
+
/**
|
|
5304
|
+
* Load cached prices from StorageProvider into in-memory cache.
|
|
5305
|
+
* Only loads entries that are still within cacheTtlMs.
|
|
5306
|
+
*/
|
|
5307
|
+
async loadFromStorage() {
|
|
5308
|
+
if (this.loadCachePromise) {
|
|
5309
|
+
return this.loadCachePromise;
|
|
5310
|
+
}
|
|
5311
|
+
this.loadCachePromise = this.doLoadFromStorage();
|
|
5312
|
+
try {
|
|
5313
|
+
await this.loadCachePromise;
|
|
5314
|
+
} finally {
|
|
5315
|
+
this.loadCachePromise = null;
|
|
5316
|
+
}
|
|
5317
|
+
}
|
|
5318
|
+
async doLoadFromStorage() {
|
|
5319
|
+
this.persistentCacheLoaded = true;
|
|
5320
|
+
if (!this.storage) return;
|
|
5321
|
+
try {
|
|
5322
|
+
const [cached, cachedTs] = await Promise.all([
|
|
5323
|
+
this.storage.get(STORAGE_KEYS_GLOBAL.PRICE_CACHE),
|
|
5324
|
+
this.storage.get(STORAGE_KEYS_GLOBAL.PRICE_CACHE_TS)
|
|
5325
|
+
]);
|
|
5326
|
+
if (!cached || !cachedTs) return;
|
|
5327
|
+
const ts = parseInt(cachedTs, 10);
|
|
5328
|
+
if (isNaN(ts)) return;
|
|
5329
|
+
const age = Date.now() - ts;
|
|
5330
|
+
if (age > this.cacheTtlMs) return;
|
|
5331
|
+
const data = JSON.parse(cached);
|
|
5332
|
+
const expiresAt = ts + this.cacheTtlMs;
|
|
5333
|
+
for (const [name, price] of Object.entries(data)) {
|
|
5334
|
+
if (!this.cache.has(name)) {
|
|
5335
|
+
this.cache.set(name, { price, expiresAt });
|
|
5336
|
+
}
|
|
5337
|
+
}
|
|
5338
|
+
if (this.debug) {
|
|
5339
|
+
console.log(`[CoinGecko] Loaded ${Object.keys(data).length} prices from persistent cache`);
|
|
5340
|
+
}
|
|
5341
|
+
} catch {
|
|
5342
|
+
}
|
|
5343
|
+
}
|
|
5344
|
+
/**
|
|
5345
|
+
* Save current prices to StorageProvider (fire-and-forget).
|
|
5346
|
+
*/
|
|
5347
|
+
saveToStorage() {
|
|
5348
|
+
if (!this.storage) return;
|
|
5349
|
+
const data = {};
|
|
5350
|
+
for (const [name, entry] of this.cache) {
|
|
5351
|
+
data[name] = entry.price;
|
|
5352
|
+
}
|
|
5353
|
+
Promise.all([
|
|
5354
|
+
this.storage.set(STORAGE_KEYS_GLOBAL.PRICE_CACHE, JSON.stringify(data)),
|
|
5355
|
+
this.storage.set(STORAGE_KEYS_GLOBAL.PRICE_CACHE_TS, String(Date.now()))
|
|
5356
|
+
]).catch(() => {
|
|
5357
|
+
});
|
|
5358
|
+
}
|
|
5359
|
+
// ===========================================================================
|
|
5360
|
+
// Rate-limit handling
|
|
5361
|
+
// ===========================================================================
|
|
5362
|
+
/**
|
|
5363
|
+
* On 429 rate-limit, extend stale cache entries so subsequent calls
|
|
5364
|
+
* don't immediately retry and hammer the API.
|
|
5365
|
+
*/
|
|
5366
|
+
extendCacheOnRateLimit(names) {
|
|
5367
|
+
const backoffMs = 6e4;
|
|
5368
|
+
const extendedExpiry = Date.now() + backoffMs;
|
|
5369
|
+
for (const name of names) {
|
|
5370
|
+
const existing = this.cache.get(name);
|
|
5371
|
+
if (existing) {
|
|
5372
|
+
existing.expiresAt = Math.max(existing.expiresAt, extendedExpiry);
|
|
5373
|
+
}
|
|
5374
|
+
}
|
|
5375
|
+
if (this.debug) {
|
|
5376
|
+
console.warn(`[CoinGecko] Rate-limited (429), extended cache TTL by ${backoffMs / 1e3}s`);
|
|
5377
|
+
}
|
|
5378
|
+
}
|
|
5238
5379
|
async getPrice(tokenName) {
|
|
5239
5380
|
const prices = await this.getPrices([tokenName]);
|
|
5240
5381
|
return prices.get(tokenName) ?? null;
|
|
@@ -5268,6 +5409,7 @@ var TokenRegistry = class _TokenRegistry {
|
|
|
5268
5409
|
refreshTimer = null;
|
|
5269
5410
|
lastRefreshAt = 0;
|
|
5270
5411
|
refreshPromise = null;
|
|
5412
|
+
initialLoadPromise = null;
|
|
5271
5413
|
constructor() {
|
|
5272
5414
|
this.definitionsById = /* @__PURE__ */ new Map();
|
|
5273
5415
|
this.definitionsBySymbol = /* @__PURE__ */ new Map();
|
|
@@ -5306,13 +5448,8 @@ var TokenRegistry = class _TokenRegistry {
|
|
|
5306
5448
|
if (options.refreshIntervalMs !== void 0) {
|
|
5307
5449
|
instance.refreshIntervalMs = options.refreshIntervalMs;
|
|
5308
5450
|
}
|
|
5309
|
-
if (instance.storage) {
|
|
5310
|
-
instance.loadFromCache();
|
|
5311
|
-
}
|
|
5312
5451
|
const autoRefresh = options.autoRefresh ?? true;
|
|
5313
|
-
|
|
5314
|
-
instance.startAutoRefresh();
|
|
5315
|
-
}
|
|
5452
|
+
instance.initialLoadPromise = instance.performInitialLoad(autoRefresh);
|
|
5316
5453
|
}
|
|
5317
5454
|
/**
|
|
5318
5455
|
* Reset the singleton instance (useful for testing).
|
|
@@ -5330,6 +5467,53 @@ var TokenRegistry = class _TokenRegistry {
|
|
|
5330
5467
|
static destroy() {
|
|
5331
5468
|
_TokenRegistry.resetInstance();
|
|
5332
5469
|
}
|
|
5470
|
+
/**
|
|
5471
|
+
* Wait for the initial data load (cache or remote) to complete.
|
|
5472
|
+
* Returns true if data was loaded, false if not (timeout or no data source).
|
|
5473
|
+
*
|
|
5474
|
+
* @param timeoutMs - Maximum wait time in ms (default: 10s). Set to 0 for no timeout.
|
|
5475
|
+
*/
|
|
5476
|
+
static async waitForReady(timeoutMs = 1e4) {
|
|
5477
|
+
const instance = _TokenRegistry.getInstance();
|
|
5478
|
+
if (!instance.initialLoadPromise) {
|
|
5479
|
+
return instance.definitionsById.size > 0;
|
|
5480
|
+
}
|
|
5481
|
+
if (timeoutMs <= 0) {
|
|
5482
|
+
return instance.initialLoadPromise;
|
|
5483
|
+
}
|
|
5484
|
+
return Promise.race([
|
|
5485
|
+
instance.initialLoadPromise,
|
|
5486
|
+
new Promise((resolve) => setTimeout(() => resolve(false), timeoutMs))
|
|
5487
|
+
]);
|
|
5488
|
+
}
|
|
5489
|
+
// ===========================================================================
|
|
5490
|
+
// Initial Load
|
|
5491
|
+
// ===========================================================================
|
|
5492
|
+
/**
|
|
5493
|
+
* Perform initial data load: try cache first, fall back to remote fetch.
|
|
5494
|
+
* After initial data is available, start periodic auto-refresh if configured.
|
|
5495
|
+
*/
|
|
5496
|
+
async performInitialLoad(autoRefresh) {
|
|
5497
|
+
let loaded = false;
|
|
5498
|
+
if (this.storage) {
|
|
5499
|
+
loaded = await this.loadFromCache();
|
|
5500
|
+
}
|
|
5501
|
+
if (loaded) {
|
|
5502
|
+
if (autoRefresh && this.remoteUrl) {
|
|
5503
|
+
this.startAutoRefresh();
|
|
5504
|
+
}
|
|
5505
|
+
return true;
|
|
5506
|
+
}
|
|
5507
|
+
if (autoRefresh && this.remoteUrl) {
|
|
5508
|
+
loaded = await this.refreshFromRemote();
|
|
5509
|
+
this.stopAutoRefresh();
|
|
5510
|
+
this.refreshTimer = setInterval(() => {
|
|
5511
|
+
this.refreshFromRemote();
|
|
5512
|
+
}, this.refreshIntervalMs);
|
|
5513
|
+
return loaded;
|
|
5514
|
+
}
|
|
5515
|
+
return false;
|
|
5516
|
+
}
|
|
5333
5517
|
// ===========================================================================
|
|
5334
5518
|
// Cache (StorageProvider)
|
|
5335
5519
|
// ===========================================================================
|
|
@@ -5659,7 +5843,7 @@ function resolveL1Config(network, config) {
|
|
|
5659
5843
|
enableVesting: config.enableVesting
|
|
5660
5844
|
};
|
|
5661
5845
|
}
|
|
5662
|
-
function resolvePriceConfig(config) {
|
|
5846
|
+
function resolvePriceConfig(config, storage) {
|
|
5663
5847
|
if (config === void 0) {
|
|
5664
5848
|
return void 0;
|
|
5665
5849
|
}
|
|
@@ -5669,7 +5853,8 @@ function resolvePriceConfig(config) {
|
|
|
5669
5853
|
baseUrl: config.baseUrl,
|
|
5670
5854
|
cacheTtlMs: config.cacheTtlMs,
|
|
5671
5855
|
timeout: config.timeout,
|
|
5672
|
-
debug: config.debug
|
|
5856
|
+
debug: config.debug,
|
|
5857
|
+
storage
|
|
5673
5858
|
};
|
|
5674
5859
|
}
|
|
5675
5860
|
function resolveArrayConfig(defaults, replace, additional) {
|
|
@@ -5696,16 +5881,6 @@ function resolveGroupChatConfig(network, config) {
|
|
|
5696
5881
|
relays: config.relays ?? [...netConfig.groupRelays]
|
|
5697
5882
|
};
|
|
5698
5883
|
}
|
|
5699
|
-
function resolveMarketConfig(config) {
|
|
5700
|
-
if (!config) return void 0;
|
|
5701
|
-
if (config === true) {
|
|
5702
|
-
return { apiUrl: DEFAULT_MARKET_API_URL };
|
|
5703
|
-
}
|
|
5704
|
-
return {
|
|
5705
|
-
apiUrl: config.apiUrl ?? DEFAULT_MARKET_API_URL,
|
|
5706
|
-
timeout: config.timeout
|
|
5707
|
-
};
|
|
5708
|
-
}
|
|
5709
5884
|
|
|
5710
5885
|
// impl/browser/index.ts
|
|
5711
5886
|
if (typeof globalThis.Buffer === "undefined") {
|
|
@@ -5763,8 +5938,8 @@ function createBrowserProviders(config) {
|
|
|
5763
5938
|
const oracleConfig = resolveOracleConfig(network, config?.oracle);
|
|
5764
5939
|
const l1Config = resolveL1Config(network, config?.l1);
|
|
5765
5940
|
const tokenSyncConfig = resolveTokenSyncConfig(network, config?.tokenSync);
|
|
5766
|
-
const priceConfig = resolvePriceConfig(config?.price);
|
|
5767
5941
|
const storage = createLocalStorageProvider(config?.storage);
|
|
5942
|
+
const priceConfig = resolvePriceConfig(config?.price, storage);
|
|
5768
5943
|
const ipfsConfig = tokenSyncConfig?.ipfs;
|
|
5769
5944
|
const ipfsTokenStorage = ipfsConfig?.enabled ? createBrowserIpfsStorageProvider({
|
|
5770
5945
|
gateways: ipfsConfig.gateways,
|
|
@@ -5774,11 +5949,9 @@ function createBrowserProviders(config) {
|
|
|
5774
5949
|
const groupChat = resolveGroupChatConfig(network, config?.groupChat);
|
|
5775
5950
|
const networkConfig = getNetworkConfig(network);
|
|
5776
5951
|
TokenRegistry.configure({ remoteUrl: networkConfig.tokenRegistryUrl, storage });
|
|
5777
|
-
const market = resolveMarketConfig(config?.market);
|
|
5778
5952
|
return {
|
|
5779
5953
|
storage,
|
|
5780
5954
|
groupChat,
|
|
5781
|
-
market,
|
|
5782
5955
|
transport: createNostrTransportProvider({
|
|
5783
5956
|
relays: transportConfig.relays,
|
|
5784
5957
|
timeout: transportConfig.timeout,
|