@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
|
@@ -40,7 +40,11 @@ var STORAGE_KEYS_GLOBAL = {
|
|
|
40
40
|
/** Cached token registry JSON (fetched from remote) */
|
|
41
41
|
TOKEN_REGISTRY_CACHE: "token_registry_cache",
|
|
42
42
|
/** Timestamp of last token registry cache update (ms since epoch) */
|
|
43
|
-
TOKEN_REGISTRY_CACHE_TS: "token_registry_cache_ts"
|
|
43
|
+
TOKEN_REGISTRY_CACHE_TS: "token_registry_cache_ts",
|
|
44
|
+
/** Cached price data JSON (from CoinGecko or other provider) */
|
|
45
|
+
PRICE_CACHE: "price_cache",
|
|
46
|
+
/** Timestamp of last price cache update (ms since epoch) */
|
|
47
|
+
PRICE_CACHE_TS: "price_cache_ts"
|
|
44
48
|
};
|
|
45
49
|
var STORAGE_KEYS_ADDRESS = {
|
|
46
50
|
/** Pending transfers for this address */
|
|
@@ -165,7 +169,6 @@ var TIMEOUTS = {
|
|
|
165
169
|
/** Sync interval */
|
|
166
170
|
SYNC_INTERVAL: 6e4
|
|
167
171
|
};
|
|
168
|
-
var DEFAULT_MARKET_API_URL = "https://market-api.unicity.network";
|
|
169
172
|
|
|
170
173
|
// impl/browser/storage/LocalStorageProvider.ts
|
|
171
174
|
var LocalStorageProvider = class {
|
|
@@ -3365,6 +3368,7 @@ async function loadIpnsModule() {
|
|
|
3365
3368
|
async function createSignedRecord(keyPair, cid, sequenceNumber, lifetimeMs = DEFAULT_LIFETIME_MS) {
|
|
3366
3369
|
const { createIPNSRecord, marshalIPNSRecord } = await loadIpnsModule();
|
|
3367
3370
|
const record = await createIPNSRecord(
|
|
3371
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3368
3372
|
keyPair,
|
|
3369
3373
|
`/ipfs/${cid}`,
|
|
3370
3374
|
sequenceNumber,
|
|
@@ -5109,26 +5113,37 @@ var CoinGeckoPriceProvider = class {
|
|
|
5109
5113
|
timeout;
|
|
5110
5114
|
debug;
|
|
5111
5115
|
baseUrl;
|
|
5116
|
+
storage;
|
|
5117
|
+
/** In-flight fetch promise for deduplication of concurrent getPrices() calls */
|
|
5118
|
+
fetchPromise = null;
|
|
5119
|
+
/** Token names being fetched in the current in-flight request */
|
|
5120
|
+
fetchNames = null;
|
|
5121
|
+
/** Whether persistent cache has been loaded into memory */
|
|
5122
|
+
persistentCacheLoaded = false;
|
|
5123
|
+
/** Promise for loading persistent cache (deduplication) */
|
|
5124
|
+
loadCachePromise = null;
|
|
5112
5125
|
constructor(config) {
|
|
5113
5126
|
this.apiKey = config?.apiKey;
|
|
5114
5127
|
this.cacheTtlMs = config?.cacheTtlMs ?? 6e4;
|
|
5115
5128
|
this.timeout = config?.timeout ?? 1e4;
|
|
5116
5129
|
this.debug = config?.debug ?? false;
|
|
5130
|
+
this.storage = config?.storage ?? null;
|
|
5117
5131
|
this.baseUrl = config?.baseUrl ?? (this.apiKey ? "https://pro-api.coingecko.com/api/v3" : "https://api.coingecko.com/api/v3");
|
|
5118
5132
|
}
|
|
5119
5133
|
async getPrices(tokenNames) {
|
|
5120
5134
|
if (tokenNames.length === 0) {
|
|
5121
5135
|
return /* @__PURE__ */ new Map();
|
|
5122
5136
|
}
|
|
5137
|
+
if (!this.persistentCacheLoaded && this.storage) {
|
|
5138
|
+
await this.loadFromStorage();
|
|
5139
|
+
}
|
|
5123
5140
|
const now = Date.now();
|
|
5124
5141
|
const result = /* @__PURE__ */ new Map();
|
|
5125
5142
|
const uncachedNames = [];
|
|
5126
5143
|
for (const name of tokenNames) {
|
|
5127
5144
|
const cached = this.cache.get(name);
|
|
5128
5145
|
if (cached && cached.expiresAt > now) {
|
|
5129
|
-
|
|
5130
|
-
result.set(name, cached.price);
|
|
5131
|
-
}
|
|
5146
|
+
result.set(name, cached.price);
|
|
5132
5147
|
} else {
|
|
5133
5148
|
uncachedNames.push(name);
|
|
5134
5149
|
}
|
|
@@ -5136,6 +5151,41 @@ var CoinGeckoPriceProvider = class {
|
|
|
5136
5151
|
if (uncachedNames.length === 0) {
|
|
5137
5152
|
return result;
|
|
5138
5153
|
}
|
|
5154
|
+
if (this.fetchPromise && this.fetchNames) {
|
|
5155
|
+
const allCovered = uncachedNames.every((n) => this.fetchNames.has(n));
|
|
5156
|
+
if (allCovered) {
|
|
5157
|
+
if (this.debug) {
|
|
5158
|
+
console.log(`[CoinGecko] Deduplicating request, reusing in-flight fetch`);
|
|
5159
|
+
}
|
|
5160
|
+
const fetched = await this.fetchPromise;
|
|
5161
|
+
for (const name of uncachedNames) {
|
|
5162
|
+
const price = fetched.get(name);
|
|
5163
|
+
if (price) {
|
|
5164
|
+
result.set(name, price);
|
|
5165
|
+
}
|
|
5166
|
+
}
|
|
5167
|
+
return result;
|
|
5168
|
+
}
|
|
5169
|
+
}
|
|
5170
|
+
const fetchPromise = this.doFetch(uncachedNames);
|
|
5171
|
+
this.fetchPromise = fetchPromise;
|
|
5172
|
+
this.fetchNames = new Set(uncachedNames);
|
|
5173
|
+
try {
|
|
5174
|
+
const fetched = await fetchPromise;
|
|
5175
|
+
for (const [name, price] of fetched) {
|
|
5176
|
+
result.set(name, price);
|
|
5177
|
+
}
|
|
5178
|
+
} finally {
|
|
5179
|
+
if (this.fetchPromise === fetchPromise) {
|
|
5180
|
+
this.fetchPromise = null;
|
|
5181
|
+
this.fetchNames = null;
|
|
5182
|
+
}
|
|
5183
|
+
}
|
|
5184
|
+
return result;
|
|
5185
|
+
}
|
|
5186
|
+
async doFetch(uncachedNames) {
|
|
5187
|
+
const result = /* @__PURE__ */ new Map();
|
|
5188
|
+
const now = Date.now();
|
|
5139
5189
|
try {
|
|
5140
5190
|
const ids = uncachedNames.join(",");
|
|
5141
5191
|
const url = `${this.baseUrl}/simple/price?ids=${encodeURIComponent(ids)}&vs_currencies=usd,eur&include_24hr_change=true`;
|
|
@@ -5151,6 +5201,9 @@ var CoinGeckoPriceProvider = class {
|
|
|
5151
5201
|
signal: AbortSignal.timeout(this.timeout)
|
|
5152
5202
|
});
|
|
5153
5203
|
if (!response.ok) {
|
|
5204
|
+
if (response.status === 429) {
|
|
5205
|
+
this.extendCacheOnRateLimit(uncachedNames);
|
|
5206
|
+
}
|
|
5154
5207
|
throw new Error(`CoinGecko API error: ${response.status} ${response.statusText}`);
|
|
5155
5208
|
}
|
|
5156
5209
|
const data = await response.json();
|
|
@@ -5169,25 +5222,113 @@ var CoinGeckoPriceProvider = class {
|
|
|
5169
5222
|
}
|
|
5170
5223
|
for (const name of uncachedNames) {
|
|
5171
5224
|
if (!result.has(name)) {
|
|
5172
|
-
|
|
5225
|
+
const zeroPrice = {
|
|
5226
|
+
tokenName: name,
|
|
5227
|
+
priceUsd: 0,
|
|
5228
|
+
priceEur: 0,
|
|
5229
|
+
change24h: 0,
|
|
5230
|
+
timestamp: now
|
|
5231
|
+
};
|
|
5232
|
+
this.cache.set(name, { price: zeroPrice, expiresAt: now + this.cacheTtlMs });
|
|
5233
|
+
result.set(name, zeroPrice);
|
|
5173
5234
|
}
|
|
5174
5235
|
}
|
|
5175
5236
|
if (this.debug) {
|
|
5176
5237
|
console.log(`[CoinGecko] Fetched ${result.size} prices`);
|
|
5177
5238
|
}
|
|
5239
|
+
this.saveToStorage();
|
|
5178
5240
|
} catch (error) {
|
|
5179
5241
|
if (this.debug) {
|
|
5180
5242
|
console.warn("[CoinGecko] Fetch failed, using stale cache:", error);
|
|
5181
5243
|
}
|
|
5182
5244
|
for (const name of uncachedNames) {
|
|
5183
5245
|
const stale = this.cache.get(name);
|
|
5184
|
-
if (stale
|
|
5246
|
+
if (stale) {
|
|
5185
5247
|
result.set(name, stale.price);
|
|
5186
5248
|
}
|
|
5187
5249
|
}
|
|
5188
5250
|
}
|
|
5189
5251
|
return result;
|
|
5190
5252
|
}
|
|
5253
|
+
// ===========================================================================
|
|
5254
|
+
// Persistent Storage
|
|
5255
|
+
// ===========================================================================
|
|
5256
|
+
/**
|
|
5257
|
+
* Load cached prices from StorageProvider into in-memory cache.
|
|
5258
|
+
* Only loads entries that are still within cacheTtlMs.
|
|
5259
|
+
*/
|
|
5260
|
+
async loadFromStorage() {
|
|
5261
|
+
if (this.loadCachePromise) {
|
|
5262
|
+
return this.loadCachePromise;
|
|
5263
|
+
}
|
|
5264
|
+
this.loadCachePromise = this.doLoadFromStorage();
|
|
5265
|
+
try {
|
|
5266
|
+
await this.loadCachePromise;
|
|
5267
|
+
} finally {
|
|
5268
|
+
this.loadCachePromise = null;
|
|
5269
|
+
}
|
|
5270
|
+
}
|
|
5271
|
+
async doLoadFromStorage() {
|
|
5272
|
+
this.persistentCacheLoaded = true;
|
|
5273
|
+
if (!this.storage) return;
|
|
5274
|
+
try {
|
|
5275
|
+
const [cached, cachedTs] = await Promise.all([
|
|
5276
|
+
this.storage.get(STORAGE_KEYS_GLOBAL.PRICE_CACHE),
|
|
5277
|
+
this.storage.get(STORAGE_KEYS_GLOBAL.PRICE_CACHE_TS)
|
|
5278
|
+
]);
|
|
5279
|
+
if (!cached || !cachedTs) return;
|
|
5280
|
+
const ts = parseInt(cachedTs, 10);
|
|
5281
|
+
if (isNaN(ts)) return;
|
|
5282
|
+
const age = Date.now() - ts;
|
|
5283
|
+
if (age > this.cacheTtlMs) return;
|
|
5284
|
+
const data = JSON.parse(cached);
|
|
5285
|
+
const expiresAt = ts + this.cacheTtlMs;
|
|
5286
|
+
for (const [name, price] of Object.entries(data)) {
|
|
5287
|
+
if (!this.cache.has(name)) {
|
|
5288
|
+
this.cache.set(name, { price, expiresAt });
|
|
5289
|
+
}
|
|
5290
|
+
}
|
|
5291
|
+
if (this.debug) {
|
|
5292
|
+
console.log(`[CoinGecko] Loaded ${Object.keys(data).length} prices from persistent cache`);
|
|
5293
|
+
}
|
|
5294
|
+
} catch {
|
|
5295
|
+
}
|
|
5296
|
+
}
|
|
5297
|
+
/**
|
|
5298
|
+
* Save current prices to StorageProvider (fire-and-forget).
|
|
5299
|
+
*/
|
|
5300
|
+
saveToStorage() {
|
|
5301
|
+
if (!this.storage) return;
|
|
5302
|
+
const data = {};
|
|
5303
|
+
for (const [name, entry] of this.cache) {
|
|
5304
|
+
data[name] = entry.price;
|
|
5305
|
+
}
|
|
5306
|
+
Promise.all([
|
|
5307
|
+
this.storage.set(STORAGE_KEYS_GLOBAL.PRICE_CACHE, JSON.stringify(data)),
|
|
5308
|
+
this.storage.set(STORAGE_KEYS_GLOBAL.PRICE_CACHE_TS, String(Date.now()))
|
|
5309
|
+
]).catch(() => {
|
|
5310
|
+
});
|
|
5311
|
+
}
|
|
5312
|
+
// ===========================================================================
|
|
5313
|
+
// Rate-limit handling
|
|
5314
|
+
// ===========================================================================
|
|
5315
|
+
/**
|
|
5316
|
+
* On 429 rate-limit, extend stale cache entries so subsequent calls
|
|
5317
|
+
* don't immediately retry and hammer the API.
|
|
5318
|
+
*/
|
|
5319
|
+
extendCacheOnRateLimit(names) {
|
|
5320
|
+
const backoffMs = 6e4;
|
|
5321
|
+
const extendedExpiry = Date.now() + backoffMs;
|
|
5322
|
+
for (const name of names) {
|
|
5323
|
+
const existing = this.cache.get(name);
|
|
5324
|
+
if (existing) {
|
|
5325
|
+
existing.expiresAt = Math.max(existing.expiresAt, extendedExpiry);
|
|
5326
|
+
}
|
|
5327
|
+
}
|
|
5328
|
+
if (this.debug) {
|
|
5329
|
+
console.warn(`[CoinGecko] Rate-limited (429), extended cache TTL by ${backoffMs / 1e3}s`);
|
|
5330
|
+
}
|
|
5331
|
+
}
|
|
5191
5332
|
async getPrice(tokenName) {
|
|
5192
5333
|
const prices = await this.getPrices([tokenName]);
|
|
5193
5334
|
return prices.get(tokenName) ?? null;
|
|
@@ -5221,6 +5362,7 @@ var TokenRegistry = class _TokenRegistry {
|
|
|
5221
5362
|
refreshTimer = null;
|
|
5222
5363
|
lastRefreshAt = 0;
|
|
5223
5364
|
refreshPromise = null;
|
|
5365
|
+
initialLoadPromise = null;
|
|
5224
5366
|
constructor() {
|
|
5225
5367
|
this.definitionsById = /* @__PURE__ */ new Map();
|
|
5226
5368
|
this.definitionsBySymbol = /* @__PURE__ */ new Map();
|
|
@@ -5259,13 +5401,8 @@ var TokenRegistry = class _TokenRegistry {
|
|
|
5259
5401
|
if (options.refreshIntervalMs !== void 0) {
|
|
5260
5402
|
instance.refreshIntervalMs = options.refreshIntervalMs;
|
|
5261
5403
|
}
|
|
5262
|
-
if (instance.storage) {
|
|
5263
|
-
instance.loadFromCache();
|
|
5264
|
-
}
|
|
5265
5404
|
const autoRefresh = options.autoRefresh ?? true;
|
|
5266
|
-
|
|
5267
|
-
instance.startAutoRefresh();
|
|
5268
|
-
}
|
|
5405
|
+
instance.initialLoadPromise = instance.performInitialLoad(autoRefresh);
|
|
5269
5406
|
}
|
|
5270
5407
|
/**
|
|
5271
5408
|
* Reset the singleton instance (useful for testing).
|
|
@@ -5283,6 +5420,53 @@ var TokenRegistry = class _TokenRegistry {
|
|
|
5283
5420
|
static destroy() {
|
|
5284
5421
|
_TokenRegistry.resetInstance();
|
|
5285
5422
|
}
|
|
5423
|
+
/**
|
|
5424
|
+
* Wait for the initial data load (cache or remote) to complete.
|
|
5425
|
+
* Returns true if data was loaded, false if not (timeout or no data source).
|
|
5426
|
+
*
|
|
5427
|
+
* @param timeoutMs - Maximum wait time in ms (default: 10s). Set to 0 for no timeout.
|
|
5428
|
+
*/
|
|
5429
|
+
static async waitForReady(timeoutMs = 1e4) {
|
|
5430
|
+
const instance = _TokenRegistry.getInstance();
|
|
5431
|
+
if (!instance.initialLoadPromise) {
|
|
5432
|
+
return instance.definitionsById.size > 0;
|
|
5433
|
+
}
|
|
5434
|
+
if (timeoutMs <= 0) {
|
|
5435
|
+
return instance.initialLoadPromise;
|
|
5436
|
+
}
|
|
5437
|
+
return Promise.race([
|
|
5438
|
+
instance.initialLoadPromise,
|
|
5439
|
+
new Promise((resolve) => setTimeout(() => resolve(false), timeoutMs))
|
|
5440
|
+
]);
|
|
5441
|
+
}
|
|
5442
|
+
// ===========================================================================
|
|
5443
|
+
// Initial Load
|
|
5444
|
+
// ===========================================================================
|
|
5445
|
+
/**
|
|
5446
|
+
* Perform initial data load: try cache first, fall back to remote fetch.
|
|
5447
|
+
* After initial data is available, start periodic auto-refresh if configured.
|
|
5448
|
+
*/
|
|
5449
|
+
async performInitialLoad(autoRefresh) {
|
|
5450
|
+
let loaded = false;
|
|
5451
|
+
if (this.storage) {
|
|
5452
|
+
loaded = await this.loadFromCache();
|
|
5453
|
+
}
|
|
5454
|
+
if (loaded) {
|
|
5455
|
+
if (autoRefresh && this.remoteUrl) {
|
|
5456
|
+
this.startAutoRefresh();
|
|
5457
|
+
}
|
|
5458
|
+
return true;
|
|
5459
|
+
}
|
|
5460
|
+
if (autoRefresh && this.remoteUrl) {
|
|
5461
|
+
loaded = await this.refreshFromRemote();
|
|
5462
|
+
this.stopAutoRefresh();
|
|
5463
|
+
this.refreshTimer = setInterval(() => {
|
|
5464
|
+
this.refreshFromRemote();
|
|
5465
|
+
}, this.refreshIntervalMs);
|
|
5466
|
+
return loaded;
|
|
5467
|
+
}
|
|
5468
|
+
return false;
|
|
5469
|
+
}
|
|
5286
5470
|
// ===========================================================================
|
|
5287
5471
|
// Cache (StorageProvider)
|
|
5288
5472
|
// ===========================================================================
|
|
@@ -5612,7 +5796,7 @@ function resolveL1Config(network, config) {
|
|
|
5612
5796
|
enableVesting: config.enableVesting
|
|
5613
5797
|
};
|
|
5614
5798
|
}
|
|
5615
|
-
function resolvePriceConfig(config) {
|
|
5799
|
+
function resolvePriceConfig(config, storage) {
|
|
5616
5800
|
if (config === void 0) {
|
|
5617
5801
|
return void 0;
|
|
5618
5802
|
}
|
|
@@ -5622,7 +5806,8 @@ function resolvePriceConfig(config) {
|
|
|
5622
5806
|
baseUrl: config.baseUrl,
|
|
5623
5807
|
cacheTtlMs: config.cacheTtlMs,
|
|
5624
5808
|
timeout: config.timeout,
|
|
5625
|
-
debug: config.debug
|
|
5809
|
+
debug: config.debug,
|
|
5810
|
+
storage
|
|
5626
5811
|
};
|
|
5627
5812
|
}
|
|
5628
5813
|
function resolveArrayConfig(defaults, replace, additional) {
|
|
@@ -5649,16 +5834,6 @@ function resolveGroupChatConfig(network, config) {
|
|
|
5649
5834
|
relays: config.relays ?? [...netConfig.groupRelays]
|
|
5650
5835
|
};
|
|
5651
5836
|
}
|
|
5652
|
-
function resolveMarketConfig(config) {
|
|
5653
|
-
if (!config) return void 0;
|
|
5654
|
-
if (config === true) {
|
|
5655
|
-
return { apiUrl: DEFAULT_MARKET_API_URL };
|
|
5656
|
-
}
|
|
5657
|
-
return {
|
|
5658
|
-
apiUrl: config.apiUrl ?? DEFAULT_MARKET_API_URL,
|
|
5659
|
-
timeout: config.timeout
|
|
5660
|
-
};
|
|
5661
|
-
}
|
|
5662
5837
|
|
|
5663
5838
|
// impl/browser/index.ts
|
|
5664
5839
|
if (typeof globalThis.Buffer === "undefined") {
|
|
@@ -5716,8 +5891,8 @@ function createBrowserProviders(config) {
|
|
|
5716
5891
|
const oracleConfig = resolveOracleConfig(network, config?.oracle);
|
|
5717
5892
|
const l1Config = resolveL1Config(network, config?.l1);
|
|
5718
5893
|
const tokenSyncConfig = resolveTokenSyncConfig(network, config?.tokenSync);
|
|
5719
|
-
const priceConfig = resolvePriceConfig(config?.price);
|
|
5720
5894
|
const storage = createLocalStorageProvider(config?.storage);
|
|
5895
|
+
const priceConfig = resolvePriceConfig(config?.price, storage);
|
|
5721
5896
|
const ipfsConfig = tokenSyncConfig?.ipfs;
|
|
5722
5897
|
const ipfsTokenStorage = ipfsConfig?.enabled ? createBrowserIpfsStorageProvider({
|
|
5723
5898
|
gateways: ipfsConfig.gateways,
|
|
@@ -5727,11 +5902,9 @@ function createBrowserProviders(config) {
|
|
|
5727
5902
|
const groupChat = resolveGroupChatConfig(network, config?.groupChat);
|
|
5728
5903
|
const networkConfig = getNetworkConfig(network);
|
|
5729
5904
|
TokenRegistry.configure({ remoteUrl: networkConfig.tokenRegistryUrl, storage });
|
|
5730
|
-
const market = resolveMarketConfig(config?.market);
|
|
5731
5905
|
return {
|
|
5732
5906
|
storage,
|
|
5733
5907
|
groupChat,
|
|
5734
|
-
market,
|
|
5735
5908
|
transport: createNostrTransportProvider({
|
|
5736
5909
|
relays: transportConfig.relays,
|
|
5737
5910
|
timeout: transportConfig.timeout,
|