@unicitylabs/sphere-sdk 0.7.1-dev.2 → 0.7.1-dev.3
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/core/index.cjs +230 -81
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +70 -5
- package/dist/core/index.d.ts +70 -5
- package/dist/core/index.js +230 -81
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/index.cjs +11 -0
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js +11 -0
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/nodejs/index.cjs +11 -0
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.d.cts +10 -1
- package/dist/impl/nodejs/index.d.ts +10 -1
- package/dist/impl/nodejs/index.js +11 -0
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/index.cjs +230 -81
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +230 -81
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/core/index.cjs
CHANGED
|
@@ -1445,6 +1445,17 @@ var NostrTransportProvider = class _NostrTransportProvider {
|
|
|
1445
1445
|
getStorageAdapter() {
|
|
1446
1446
|
return this.storage;
|
|
1447
1447
|
}
|
|
1448
|
+
/**
|
|
1449
|
+
* Get the underlying NostrClient (or null if not yet connected).
|
|
1450
|
+
*
|
|
1451
|
+
* Exposed so {@link MultiAddressTransportMux} can share the same
|
|
1452
|
+
* client/socket pair instead of opening a duplicate WebSocket per
|
|
1453
|
+
* relay (#123). The transport owns the client's lifecycle — callers
|
|
1454
|
+
* MUST NOT call {@code disconnect()} on the returned instance.
|
|
1455
|
+
*/
|
|
1456
|
+
getNostrClient() {
|
|
1457
|
+
return this.nostrClient;
|
|
1458
|
+
}
|
|
1448
1459
|
/**
|
|
1449
1460
|
* Suppress event subscriptions — unsubscribe wallet/chat filters
|
|
1450
1461
|
* but keep the connection alive for resolve/identity-binding operations.
|
|
@@ -3083,9 +3094,6 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3083
3094
|
chatSubscriptionId = null;
|
|
3084
3095
|
chatEoseFired = false;
|
|
3085
3096
|
resubscribeTimer = null;
|
|
3086
|
-
lastWalletEventAt = Date.now();
|
|
3087
|
-
lastChatEventAt = Date.now();
|
|
3088
|
-
healthCheckTimer = null;
|
|
3089
3097
|
chatEoseHandlers = [];
|
|
3090
3098
|
// Dedup — bounded to prevent memory leak in long-running sessions.
|
|
3091
3099
|
// Set preserves insertion order; evict oldest entries when cap is reached.
|
|
@@ -3096,6 +3104,19 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3096
3104
|
// Identity key for the Mux's NostrClient — relays may filter gift-wrap
|
|
3097
3105
|
// delivery to the recipient's subscription key.
|
|
3098
3106
|
identityPrivateKey;
|
|
3107
|
+
// Resolves the shared NostrClient at use-time (the source provider may
|
|
3108
|
+
// create its client lazily, after the Mux is constructed). null means
|
|
3109
|
+
// "no shared client; create our own."
|
|
3110
|
+
sharedNostrClientGetter;
|
|
3111
|
+
// True when this Mux is using a shared NostrClient and therefore must
|
|
3112
|
+
// not call connect()/disconnect() on it.
|
|
3113
|
+
usingSharedClient = false;
|
|
3114
|
+
// Listener registered on the underlying NostrClient. Tracked so we can
|
|
3115
|
+
// remove it on disconnect / rebind — otherwise a long-lived shared
|
|
3116
|
+
// client accumulates listeners across address switches and (worse)
|
|
3117
|
+
// a "disconnected" Mux still sees onReconnected callbacks fire and
|
|
3118
|
+
// re-establish subscriptions it shouldn't have.
|
|
3119
|
+
connectionListener = null;
|
|
3099
3120
|
constructor(config) {
|
|
3100
3121
|
this.identityPrivateKey = config.identityPrivateKey;
|
|
3101
3122
|
this.config = {
|
|
@@ -3108,6 +3129,14 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3108
3129
|
generateUUID: config.generateUUID ?? defaultUUIDGenerator
|
|
3109
3130
|
};
|
|
3110
3131
|
this.storage = config.storage ?? null;
|
|
3132
|
+
if (typeof config.sharedNostrClient === "function") {
|
|
3133
|
+
this.sharedNostrClientGetter = config.sharedNostrClient;
|
|
3134
|
+
} else if (config.sharedNostrClient) {
|
|
3135
|
+
const c = config.sharedNostrClient;
|
|
3136
|
+
this.sharedNostrClientGetter = () => c;
|
|
3137
|
+
} else {
|
|
3138
|
+
this.sharedNostrClientGetter = null;
|
|
3139
|
+
}
|
|
3111
3140
|
}
|
|
3112
3141
|
// ===========================================================================
|
|
3113
3142
|
// Address Management
|
|
@@ -3198,53 +3227,49 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3198
3227
|
if (this.status === "connected") return;
|
|
3199
3228
|
this.status = "connecting";
|
|
3200
3229
|
try {
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3230
|
+
const shared = this.sharedNostrClientGetter ? this.sharedNostrClientGetter() : null;
|
|
3231
|
+
if (shared) {
|
|
3232
|
+
if (!shared.isConnected()) {
|
|
3233
|
+
throw new SphereError(
|
|
3234
|
+
"sharedNostrClient is not connected; the Mux cannot share a closed socket",
|
|
3235
|
+
"TRANSPORT_ERROR"
|
|
3205
3236
|
);
|
|
3206
|
-
} else {
|
|
3207
|
-
const tempKey = import_buffer2.Buffer.alloc(32);
|
|
3208
|
-
crypto.getRandomValues(tempKey);
|
|
3209
|
-
this.primaryKeyManager = import_nostr_js_sdk2.NostrKeyManager.fromPrivateKey(tempKey);
|
|
3210
3237
|
}
|
|
3238
|
+
this.nostrClient = shared;
|
|
3239
|
+
this.usingSharedClient = true;
|
|
3240
|
+
} else {
|
|
3241
|
+
if (!this.primaryKeyManager) {
|
|
3242
|
+
if (this.identityPrivateKey) {
|
|
3243
|
+
this.primaryKeyManager = import_nostr_js_sdk2.NostrKeyManager.fromPrivateKey(
|
|
3244
|
+
import_buffer2.Buffer.from(this.identityPrivateKey)
|
|
3245
|
+
);
|
|
3246
|
+
} else {
|
|
3247
|
+
const tempKey = import_buffer2.Buffer.alloc(32);
|
|
3248
|
+
crypto.getRandomValues(tempKey);
|
|
3249
|
+
this.primaryKeyManager = import_nostr_js_sdk2.NostrKeyManager.fromPrivateKey(tempKey);
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
this.nostrClient = new import_nostr_js_sdk2.NostrClient(this.primaryKeyManager, {
|
|
3253
|
+
autoReconnect: this.config.autoReconnect,
|
|
3254
|
+
reconnectIntervalMs: this.config.reconnectDelay,
|
|
3255
|
+
maxReconnectIntervalMs: this.config.reconnectDelay * 16,
|
|
3256
|
+
pingIntervalMs: 15e3
|
|
3257
|
+
});
|
|
3211
3258
|
}
|
|
3212
|
-
this.
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
},
|
|
3226
|
-
onReconnecting: (url, attempt) => {
|
|
3227
|
-
logger.debug("Mux", "Reconnecting to relay:", url, "attempt:", attempt);
|
|
3228
|
-
this.emitEvent({ type: "transport:reconnecting", timestamp: Date.now() });
|
|
3229
|
-
},
|
|
3230
|
-
onReconnected: (url) => {
|
|
3231
|
-
logger.debug("Mux", "Reconnected to relay:", url);
|
|
3232
|
-
this.emitEvent({ type: "transport:connected", timestamp: Date.now() });
|
|
3233
|
-
this.updateSubscriptions().catch((err) => {
|
|
3234
|
-
logger.error("Mux", "Failed to re-subscribe after reconnect:", err);
|
|
3235
|
-
});
|
|
3259
|
+
this.connectionListener = this.buildConnectionListener();
|
|
3260
|
+
this.nostrClient.addConnectionListener(this.connectionListener);
|
|
3261
|
+
if (!this.usingSharedClient) {
|
|
3262
|
+
await Promise.race([
|
|
3263
|
+
this.nostrClient.connect(...this.config.relays),
|
|
3264
|
+
new Promise(
|
|
3265
|
+
(_, reject) => setTimeout(() => reject(new Error(
|
|
3266
|
+
`Transport connection timed out after ${this.config.timeout}ms`
|
|
3267
|
+
)), this.config.timeout)
|
|
3268
|
+
)
|
|
3269
|
+
]);
|
|
3270
|
+
if (!this.nostrClient.isConnected()) {
|
|
3271
|
+
throw new SphereError("Failed to connect to any relay", "TRANSPORT_ERROR");
|
|
3236
3272
|
}
|
|
3237
|
-
});
|
|
3238
|
-
await Promise.race([
|
|
3239
|
-
this.nostrClient.connect(...this.config.relays),
|
|
3240
|
-
new Promise(
|
|
3241
|
-
(_, reject) => setTimeout(() => reject(new Error(
|
|
3242
|
-
`Transport connection timed out after ${this.config.timeout}ms`
|
|
3243
|
-
)), this.config.timeout)
|
|
3244
|
-
)
|
|
3245
|
-
]);
|
|
3246
|
-
if (!this.nostrClient.isConnected()) {
|
|
3247
|
-
throw new SphereError("Failed to connect to any relay", "TRANSPORT_ERROR");
|
|
3248
3273
|
}
|
|
3249
3274
|
this.status = "connected";
|
|
3250
3275
|
this.emitEvent({ type: "transport:connected", timestamp: Date.now() });
|
|
@@ -3253,6 +3278,21 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3253
3278
|
}
|
|
3254
3279
|
} catch (error) {
|
|
3255
3280
|
this.status = "error";
|
|
3281
|
+
if (this.connectionListener && this.nostrClient) {
|
|
3282
|
+
try {
|
|
3283
|
+
this.nostrClient.removeConnectionListener(this.connectionListener);
|
|
3284
|
+
} catch {
|
|
3285
|
+
}
|
|
3286
|
+
}
|
|
3287
|
+
this.connectionListener = null;
|
|
3288
|
+
if (this.nostrClient && !this.usingSharedClient) {
|
|
3289
|
+
try {
|
|
3290
|
+
this.nostrClient.disconnect();
|
|
3291
|
+
} catch {
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
3294
|
+
this.nostrClient = null;
|
|
3295
|
+
this.usingSharedClient = false;
|
|
3256
3296
|
throw error;
|
|
3257
3297
|
}
|
|
3258
3298
|
}
|
|
@@ -3261,25 +3301,153 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3261
3301
|
clearTimeout(this.resubscribeTimer);
|
|
3262
3302
|
this.resubscribeTimer = null;
|
|
3263
3303
|
}
|
|
3264
|
-
if (this.healthCheckTimer) {
|
|
3265
|
-
clearInterval(this.healthCheckTimer);
|
|
3266
|
-
this.healthCheckTimer = null;
|
|
3267
|
-
}
|
|
3268
3304
|
if (this.nostrClient) {
|
|
3269
|
-
this.
|
|
3305
|
+
if (this.walletSubscriptionId) {
|
|
3306
|
+
try {
|
|
3307
|
+
this.nostrClient.unsubscribe(this.walletSubscriptionId);
|
|
3308
|
+
} catch {
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3311
|
+
if (this.chatSubscriptionId) {
|
|
3312
|
+
try {
|
|
3313
|
+
this.nostrClient.unsubscribe(this.chatSubscriptionId);
|
|
3314
|
+
} catch {
|
|
3315
|
+
}
|
|
3316
|
+
}
|
|
3317
|
+
if (this.connectionListener) {
|
|
3318
|
+
try {
|
|
3319
|
+
this.nostrClient.removeConnectionListener(this.connectionListener);
|
|
3320
|
+
} catch {
|
|
3321
|
+
}
|
|
3322
|
+
}
|
|
3323
|
+
if (!this.usingSharedClient) {
|
|
3324
|
+
this.nostrClient.disconnect();
|
|
3325
|
+
}
|
|
3270
3326
|
this.nostrClient = null;
|
|
3271
3327
|
}
|
|
3328
|
+
this.connectionListener = null;
|
|
3329
|
+
this.usingSharedClient = false;
|
|
3272
3330
|
this.walletSubscriptionId = null;
|
|
3273
3331
|
this.chatSubscriptionId = null;
|
|
3274
3332
|
this.chatEoseFired = false;
|
|
3275
|
-
this.lastWalletEventAt = Date.now();
|
|
3276
|
-
this.lastChatEventAt = Date.now();
|
|
3277
3333
|
this.status = "disconnected";
|
|
3278
3334
|
this.emitEvent({ type: "transport:disconnected", timestamp: Date.now() });
|
|
3279
3335
|
}
|
|
3280
3336
|
isConnected() {
|
|
3281
3337
|
return this.status === "connected" && this.nostrClient?.isConnected() === true;
|
|
3282
3338
|
}
|
|
3339
|
+
/**
|
|
3340
|
+
* Build the connection listener used by both {@link connect} and
|
|
3341
|
+
* {@link rebindToSharedClient}.
|
|
3342
|
+
*
|
|
3343
|
+
* Behavioral notes:
|
|
3344
|
+
* - When the Mux is sharing a {@link NostrClient} with the host
|
|
3345
|
+
* transport (#123), we deliberately do NOT emit
|
|
3346
|
+
* {@code transport:connected} / {@code transport:reconnecting} here
|
|
3347
|
+
* — the host transport's own listener already emits those for the
|
|
3348
|
+
* same socket event. Re-subscribing after a reconnect IS still our
|
|
3349
|
+
* responsibility, since the host has
|
|
3350
|
+
* {@code suppressSubscriptions()}'d its own filters.
|
|
3351
|
+
* - {@code onConnect} does not emit {@code transport:connected}.
|
|
3352
|
+
* The SDK only fires {@code onConnect} on the initial socket
|
|
3353
|
+
* connection (subsequent reconnects use {@code onReconnected}),
|
|
3354
|
+
* and {@link connect()}'s bottom already emits
|
|
3355
|
+
* {@code transport:connected} once that returns. Emitting here too
|
|
3356
|
+
* would double-fire on every initial connect.
|
|
3357
|
+
* - Each callback bails out early when the Mux is not in an active
|
|
3358
|
+
* state ({@code disconnected} / {@code error}). Listeners are
|
|
3359
|
+
* removed on {@code disconnect()} before the callback can fire,
|
|
3360
|
+
* so this guard is mainly defense-in-depth against any in-flight
|
|
3361
|
+
* callback that lands during teardown — but having it at the top
|
|
3362
|
+
* means we never emit a misleading {@code transport:connected}
|
|
3363
|
+
* from a Mux that has already torn down.
|
|
3364
|
+
*/
|
|
3365
|
+
buildConnectionListener() {
|
|
3366
|
+
const isInactive = () => this.status === "disconnected" || this.status === "error";
|
|
3367
|
+
return {
|
|
3368
|
+
onConnect: (url) => {
|
|
3369
|
+
if (isInactive()) return;
|
|
3370
|
+
logger.debug("Mux", "Connected to relay:", url);
|
|
3371
|
+
},
|
|
3372
|
+
onDisconnect: (url, reason) => {
|
|
3373
|
+
logger.debug("Mux", "Disconnected from relay:", url, "reason:", reason);
|
|
3374
|
+
},
|
|
3375
|
+
onReconnecting: (url, attempt) => {
|
|
3376
|
+
if (isInactive()) return;
|
|
3377
|
+
logger.debug("Mux", "Reconnecting to relay:", url, "attempt:", attempt);
|
|
3378
|
+
if (!this.usingSharedClient) {
|
|
3379
|
+
this.emitEvent({ type: "transport:reconnecting", timestamp: Date.now() });
|
|
3380
|
+
}
|
|
3381
|
+
},
|
|
3382
|
+
onReconnected: (url) => {
|
|
3383
|
+
if (isInactive()) return;
|
|
3384
|
+
logger.debug("Mux", "Reconnected to relay:", url);
|
|
3385
|
+
if (!this.usingSharedClient) {
|
|
3386
|
+
this.emitEvent({ type: "transport:connected", timestamp: Date.now() });
|
|
3387
|
+
}
|
|
3388
|
+
this.updateSubscriptions().catch((err) => {
|
|
3389
|
+
logger.error("Mux", "Failed to re-subscribe after reconnect:", err);
|
|
3390
|
+
});
|
|
3391
|
+
}
|
|
3392
|
+
};
|
|
3393
|
+
}
|
|
3394
|
+
/**
|
|
3395
|
+
* Re-attach to a freshly-created shared NostrClient.
|
|
3396
|
+
*
|
|
3397
|
+
* Call this after the host (e.g. {@link NostrTransportProvider}) has
|
|
3398
|
+
* recreated its NostrClient — typically because the wallet's active
|
|
3399
|
+
* identity changed and the SDK's NostrClient does not support
|
|
3400
|
+
* changing identity at runtime. The previous client has already
|
|
3401
|
+
* been disconnected by the host, so its server-side subscriptions
|
|
3402
|
+
* are gone — we just adopt the new client and re-issue our own.
|
|
3403
|
+
*
|
|
3404
|
+
* The caller is responsible for ordering: by the time rebind runs,
|
|
3405
|
+
* the host transport's new NostrClient must already be created and
|
|
3406
|
+
* connected. In Sphere this is guaranteed because we await
|
|
3407
|
+
* {@code transport.setIdentity()} before calling rebind.
|
|
3408
|
+
*
|
|
3409
|
+
* Returns silently in two cases that are not caller errors:
|
|
3410
|
+
* - the Mux owns its own client (not sharing) — nothing to rebind
|
|
3411
|
+
* - the shared client reference hasn't changed (rebind is a no-op)
|
|
3412
|
+
*
|
|
3413
|
+
* Throws otherwise (rather than silently no-op'ing) so a wiring
|
|
3414
|
+
* mistake — for instance, calling rebind before the host's new
|
|
3415
|
+
* client is ready — surfaces immediately instead of leaving the
|
|
3416
|
+
* Mux pinned to a stale client.
|
|
3417
|
+
*/
|
|
3418
|
+
async rebindToSharedClient() {
|
|
3419
|
+
if (!this.usingSharedClient) return;
|
|
3420
|
+
if (!this.sharedNostrClientGetter) return;
|
|
3421
|
+
const newClient = this.sharedNostrClientGetter();
|
|
3422
|
+
if (!newClient) {
|
|
3423
|
+
throw new SphereError(
|
|
3424
|
+
"rebindToSharedClient: shared client getter returned null. The host transport must finish (re)creating its NostrClient before rebind is called.",
|
|
3425
|
+
"TRANSPORT_ERROR"
|
|
3426
|
+
);
|
|
3427
|
+
}
|
|
3428
|
+
if (this.nostrClient === newClient) return;
|
|
3429
|
+
if (!newClient.isConnected()) {
|
|
3430
|
+
throw new SphereError(
|
|
3431
|
+
"rebindToSharedClient: new shared client is not connected. Await transport.setIdentity() / transport.connect() before rebinding.",
|
|
3432
|
+
"TRANSPORT_ERROR"
|
|
3433
|
+
);
|
|
3434
|
+
}
|
|
3435
|
+
if (this.nostrClient && this.connectionListener && this.nostrClient !== newClient) {
|
|
3436
|
+
try {
|
|
3437
|
+
this.nostrClient.removeConnectionListener(this.connectionListener);
|
|
3438
|
+
} catch {
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
3441
|
+
this.nostrClient = newClient;
|
|
3442
|
+
this.walletSubscriptionId = null;
|
|
3443
|
+
this.chatSubscriptionId = null;
|
|
3444
|
+
this.chatEoseFired = false;
|
|
3445
|
+
this.connectionListener = this.buildConnectionListener();
|
|
3446
|
+
this.nostrClient.addConnectionListener(this.connectionListener);
|
|
3447
|
+
if (this.addresses.size > 0) {
|
|
3448
|
+
await this.updateSubscriptions();
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3283
3451
|
/**
|
|
3284
3452
|
* One-shot fetch of pending events from the relay.
|
|
3285
3453
|
* Creates a temporary subscription, waits for EOSE (or timeout),
|
|
@@ -3408,8 +3576,6 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3408
3576
|
this.nostrClient.unsubscribe(this.chatSubscriptionId);
|
|
3409
3577
|
this.chatSubscriptionId = null;
|
|
3410
3578
|
}
|
|
3411
|
-
this.lastWalletEventAt = Date.now();
|
|
3412
|
-
this.lastChatEventAt = Date.now();
|
|
3413
3579
|
if (this.addresses.size === 0) return;
|
|
3414
3580
|
const allPubkeys = [];
|
|
3415
3581
|
for (const entry of this.addresses.values()) {
|
|
@@ -3496,25 +3662,6 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3496
3662
|
}
|
|
3497
3663
|
});
|
|
3498
3664
|
logger.debug("Mux", `updateSubscriptions: walletSub=${this.walletSubscriptionId} chatSub=${this.chatSubscriptionId}`);
|
|
3499
|
-
this.startHealthCheck();
|
|
3500
|
-
}
|
|
3501
|
-
startHealthCheck() {
|
|
3502
|
-
if (this.healthCheckTimer) return;
|
|
3503
|
-
this.healthCheckTimer = setInterval(() => {
|
|
3504
|
-
if (!this.isConnected()) return;
|
|
3505
|
-
const chatElapsed = Date.now() - this.lastChatEventAt;
|
|
3506
|
-
const walletElapsed = Date.now() - this.lastWalletEventAt;
|
|
3507
|
-
const needResubscribe = chatElapsed > 6e4 || walletElapsed > 3e5;
|
|
3508
|
-
if (needResubscribe) {
|
|
3509
|
-
const reason = chatElapsed > 6e4 ? `No chat events for ${Math.round(chatElapsed / 1e3)}s` : `No wallet events for ${Math.round(walletElapsed / 1e3)}s`;
|
|
3510
|
-
logger.warn("Mux", `${reason} \u2014 re-subscribing`);
|
|
3511
|
-
this.lastChatEventAt = Date.now();
|
|
3512
|
-
this.lastWalletEventAt = Date.now();
|
|
3513
|
-
this.updateSubscriptions().catch((err) => {
|
|
3514
|
-
logger.warn("Mux", "Health check re-subscription failed:", err);
|
|
3515
|
-
});
|
|
3516
|
-
}
|
|
3517
|
-
}, 3e4);
|
|
3518
3665
|
}
|
|
3519
3666
|
/**
|
|
3520
3667
|
* Schedule a re-subscription after a relay-initiated subscription closure.
|
|
@@ -3575,12 +3722,6 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3575
3722
|
}
|
|
3576
3723
|
}
|
|
3577
3724
|
}
|
|
3578
|
-
if (event.kind !== import_nostr_js_sdk2.EventKinds.GIFT_WRAP) {
|
|
3579
|
-
this.lastWalletEventAt = Date.now();
|
|
3580
|
-
}
|
|
3581
|
-
if (event.kind === import_nostr_js_sdk2.EventKinds.GIFT_WRAP) {
|
|
3582
|
-
this.lastChatEventAt = Date.now();
|
|
3583
|
-
}
|
|
3584
3725
|
try {
|
|
3585
3726
|
if (event.kind === import_nostr_js_sdk2.EventKinds.GIFT_WRAP) {
|
|
3586
3727
|
await this.routeGiftWrap(event);
|
|
@@ -28295,6 +28436,9 @@ var Sphere = class _Sphere {
|
|
|
28295
28436
|
this._transport.setFallbackSince(fallbackTs);
|
|
28296
28437
|
}
|
|
28297
28438
|
await this._transport.setIdentity(this._identity);
|
|
28439
|
+
if (this._transportMux && typeof this._transportMux.rebindToSharedClient === "function") {
|
|
28440
|
+
await this._transportMux.rebindToSharedClient();
|
|
28441
|
+
}
|
|
28298
28442
|
this.emitEvent("identity:changed", {
|
|
28299
28443
|
l1Address: this._identity.l1Address,
|
|
28300
28444
|
directAddress: this._identity.directAddress,
|
|
@@ -28505,7 +28649,12 @@ var Sphere = class _Sphere {
|
|
|
28505
28649
|
this._transportMux = new MultiAddressTransportMux({
|
|
28506
28650
|
relays: nostrTransport.getConfiguredRelays(),
|
|
28507
28651
|
createWebSocket: nostrTransport.getWebSocketFactory(),
|
|
28508
|
-
storage: nostrTransport.getStorageAdapter() ?? void 0
|
|
28652
|
+
storage: nostrTransport.getStorageAdapter() ?? void 0,
|
|
28653
|
+
// #123: share the original transport's NostrClient instead of
|
|
28654
|
+
// opening a second WebSocket per relay. Pass a getter so the
|
|
28655
|
+
// Mux resolves it at connect-time (after the transport finishes
|
|
28656
|
+
// its own connect()).
|
|
28657
|
+
sharedNostrClient: typeof nostrTransport.getNostrClient === "function" ? () => nostrTransport.getNostrClient() : void 0
|
|
28509
28658
|
});
|
|
28510
28659
|
await this._transportMux.connect();
|
|
28511
28660
|
if (typeof nostrTransport.suppressSubscriptions === "function") {
|