@unicitylabs/sphere-sdk 0.7.1-dev.1 → 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 +2 -2
package/dist/index.js
CHANGED
|
@@ -1389,6 +1389,17 @@ var NostrTransportProvider = class _NostrTransportProvider {
|
|
|
1389
1389
|
getStorageAdapter() {
|
|
1390
1390
|
return this.storage;
|
|
1391
1391
|
}
|
|
1392
|
+
/**
|
|
1393
|
+
* Get the underlying NostrClient (or null if not yet connected).
|
|
1394
|
+
*
|
|
1395
|
+
* Exposed so {@link MultiAddressTransportMux} can share the same
|
|
1396
|
+
* client/socket pair instead of opening a duplicate WebSocket per
|
|
1397
|
+
* relay (#123). The transport owns the client's lifecycle — callers
|
|
1398
|
+
* MUST NOT call {@code disconnect()} on the returned instance.
|
|
1399
|
+
*/
|
|
1400
|
+
getNostrClient() {
|
|
1401
|
+
return this.nostrClient;
|
|
1402
|
+
}
|
|
1392
1403
|
/**
|
|
1393
1404
|
* Suppress event subscriptions — unsubscribe wallet/chat filters
|
|
1394
1405
|
* but keep the connection alive for resolve/identity-binding operations.
|
|
@@ -3027,9 +3038,6 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3027
3038
|
chatSubscriptionId = null;
|
|
3028
3039
|
chatEoseFired = false;
|
|
3029
3040
|
resubscribeTimer = null;
|
|
3030
|
-
lastWalletEventAt = Date.now();
|
|
3031
|
-
lastChatEventAt = Date.now();
|
|
3032
|
-
healthCheckTimer = null;
|
|
3033
3041
|
chatEoseHandlers = [];
|
|
3034
3042
|
// Dedup — bounded to prevent memory leak in long-running sessions.
|
|
3035
3043
|
// Set preserves insertion order; evict oldest entries when cap is reached.
|
|
@@ -3040,6 +3048,19 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3040
3048
|
// Identity key for the Mux's NostrClient — relays may filter gift-wrap
|
|
3041
3049
|
// delivery to the recipient's subscription key.
|
|
3042
3050
|
identityPrivateKey;
|
|
3051
|
+
// Resolves the shared NostrClient at use-time (the source provider may
|
|
3052
|
+
// create its client lazily, after the Mux is constructed). null means
|
|
3053
|
+
// "no shared client; create our own."
|
|
3054
|
+
sharedNostrClientGetter;
|
|
3055
|
+
// True when this Mux is using a shared NostrClient and therefore must
|
|
3056
|
+
// not call connect()/disconnect() on it.
|
|
3057
|
+
usingSharedClient = false;
|
|
3058
|
+
// Listener registered on the underlying NostrClient. Tracked so we can
|
|
3059
|
+
// remove it on disconnect / rebind — otherwise a long-lived shared
|
|
3060
|
+
// client accumulates listeners across address switches and (worse)
|
|
3061
|
+
// a "disconnected" Mux still sees onReconnected callbacks fire and
|
|
3062
|
+
// re-establish subscriptions it shouldn't have.
|
|
3063
|
+
connectionListener = null;
|
|
3043
3064
|
constructor(config) {
|
|
3044
3065
|
this.identityPrivateKey = config.identityPrivateKey;
|
|
3045
3066
|
this.config = {
|
|
@@ -3052,6 +3073,14 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3052
3073
|
generateUUID: config.generateUUID ?? defaultUUIDGenerator
|
|
3053
3074
|
};
|
|
3054
3075
|
this.storage = config.storage ?? null;
|
|
3076
|
+
if (typeof config.sharedNostrClient === "function") {
|
|
3077
|
+
this.sharedNostrClientGetter = config.sharedNostrClient;
|
|
3078
|
+
} else if (config.sharedNostrClient) {
|
|
3079
|
+
const c = config.sharedNostrClient;
|
|
3080
|
+
this.sharedNostrClientGetter = () => c;
|
|
3081
|
+
} else {
|
|
3082
|
+
this.sharedNostrClientGetter = null;
|
|
3083
|
+
}
|
|
3055
3084
|
}
|
|
3056
3085
|
// ===========================================================================
|
|
3057
3086
|
// Address Management
|
|
@@ -3142,53 +3171,49 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3142
3171
|
if (this.status === "connected") return;
|
|
3143
3172
|
this.status = "connecting";
|
|
3144
3173
|
try {
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3174
|
+
const shared = this.sharedNostrClientGetter ? this.sharedNostrClientGetter() : null;
|
|
3175
|
+
if (shared) {
|
|
3176
|
+
if (!shared.isConnected()) {
|
|
3177
|
+
throw new SphereError(
|
|
3178
|
+
"sharedNostrClient is not connected; the Mux cannot share a closed socket",
|
|
3179
|
+
"TRANSPORT_ERROR"
|
|
3149
3180
|
);
|
|
3150
|
-
} else {
|
|
3151
|
-
const tempKey = Buffer3.alloc(32);
|
|
3152
|
-
crypto.getRandomValues(tempKey);
|
|
3153
|
-
this.primaryKeyManager = NostrKeyManager2.fromPrivateKey(tempKey);
|
|
3154
3181
|
}
|
|
3182
|
+
this.nostrClient = shared;
|
|
3183
|
+
this.usingSharedClient = true;
|
|
3184
|
+
} else {
|
|
3185
|
+
if (!this.primaryKeyManager) {
|
|
3186
|
+
if (this.identityPrivateKey) {
|
|
3187
|
+
this.primaryKeyManager = NostrKeyManager2.fromPrivateKey(
|
|
3188
|
+
Buffer3.from(this.identityPrivateKey)
|
|
3189
|
+
);
|
|
3190
|
+
} else {
|
|
3191
|
+
const tempKey = Buffer3.alloc(32);
|
|
3192
|
+
crypto.getRandomValues(tempKey);
|
|
3193
|
+
this.primaryKeyManager = NostrKeyManager2.fromPrivateKey(tempKey);
|
|
3194
|
+
}
|
|
3195
|
+
}
|
|
3196
|
+
this.nostrClient = new NostrClient2(this.primaryKeyManager, {
|
|
3197
|
+
autoReconnect: this.config.autoReconnect,
|
|
3198
|
+
reconnectIntervalMs: this.config.reconnectDelay,
|
|
3199
|
+
maxReconnectIntervalMs: this.config.reconnectDelay * 16,
|
|
3200
|
+
pingIntervalMs: 15e3
|
|
3201
|
+
});
|
|
3155
3202
|
}
|
|
3156
|
-
this.
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
},
|
|
3170
|
-
onReconnecting: (url, attempt) => {
|
|
3171
|
-
logger.debug("Mux", "Reconnecting to relay:", url, "attempt:", attempt);
|
|
3172
|
-
this.emitEvent({ type: "transport:reconnecting", timestamp: Date.now() });
|
|
3173
|
-
},
|
|
3174
|
-
onReconnected: (url) => {
|
|
3175
|
-
logger.debug("Mux", "Reconnected to relay:", url);
|
|
3176
|
-
this.emitEvent({ type: "transport:connected", timestamp: Date.now() });
|
|
3177
|
-
this.updateSubscriptions().catch((err) => {
|
|
3178
|
-
logger.error("Mux", "Failed to re-subscribe after reconnect:", err);
|
|
3179
|
-
});
|
|
3203
|
+
this.connectionListener = this.buildConnectionListener();
|
|
3204
|
+
this.nostrClient.addConnectionListener(this.connectionListener);
|
|
3205
|
+
if (!this.usingSharedClient) {
|
|
3206
|
+
await Promise.race([
|
|
3207
|
+
this.nostrClient.connect(...this.config.relays),
|
|
3208
|
+
new Promise(
|
|
3209
|
+
(_, reject) => setTimeout(() => reject(new Error(
|
|
3210
|
+
`Transport connection timed out after ${this.config.timeout}ms`
|
|
3211
|
+
)), this.config.timeout)
|
|
3212
|
+
)
|
|
3213
|
+
]);
|
|
3214
|
+
if (!this.nostrClient.isConnected()) {
|
|
3215
|
+
throw new SphereError("Failed to connect to any relay", "TRANSPORT_ERROR");
|
|
3180
3216
|
}
|
|
3181
|
-
});
|
|
3182
|
-
await Promise.race([
|
|
3183
|
-
this.nostrClient.connect(...this.config.relays),
|
|
3184
|
-
new Promise(
|
|
3185
|
-
(_, reject) => setTimeout(() => reject(new Error(
|
|
3186
|
-
`Transport connection timed out after ${this.config.timeout}ms`
|
|
3187
|
-
)), this.config.timeout)
|
|
3188
|
-
)
|
|
3189
|
-
]);
|
|
3190
|
-
if (!this.nostrClient.isConnected()) {
|
|
3191
|
-
throw new SphereError("Failed to connect to any relay", "TRANSPORT_ERROR");
|
|
3192
3217
|
}
|
|
3193
3218
|
this.status = "connected";
|
|
3194
3219
|
this.emitEvent({ type: "transport:connected", timestamp: Date.now() });
|
|
@@ -3197,6 +3222,21 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3197
3222
|
}
|
|
3198
3223
|
} catch (error) {
|
|
3199
3224
|
this.status = "error";
|
|
3225
|
+
if (this.connectionListener && this.nostrClient) {
|
|
3226
|
+
try {
|
|
3227
|
+
this.nostrClient.removeConnectionListener(this.connectionListener);
|
|
3228
|
+
} catch {
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
this.connectionListener = null;
|
|
3232
|
+
if (this.nostrClient && !this.usingSharedClient) {
|
|
3233
|
+
try {
|
|
3234
|
+
this.nostrClient.disconnect();
|
|
3235
|
+
} catch {
|
|
3236
|
+
}
|
|
3237
|
+
}
|
|
3238
|
+
this.nostrClient = null;
|
|
3239
|
+
this.usingSharedClient = false;
|
|
3200
3240
|
throw error;
|
|
3201
3241
|
}
|
|
3202
3242
|
}
|
|
@@ -3205,25 +3245,153 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3205
3245
|
clearTimeout(this.resubscribeTimer);
|
|
3206
3246
|
this.resubscribeTimer = null;
|
|
3207
3247
|
}
|
|
3208
|
-
if (this.healthCheckTimer) {
|
|
3209
|
-
clearInterval(this.healthCheckTimer);
|
|
3210
|
-
this.healthCheckTimer = null;
|
|
3211
|
-
}
|
|
3212
3248
|
if (this.nostrClient) {
|
|
3213
|
-
this.
|
|
3249
|
+
if (this.walletSubscriptionId) {
|
|
3250
|
+
try {
|
|
3251
|
+
this.nostrClient.unsubscribe(this.walletSubscriptionId);
|
|
3252
|
+
} catch {
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
if (this.chatSubscriptionId) {
|
|
3256
|
+
try {
|
|
3257
|
+
this.nostrClient.unsubscribe(this.chatSubscriptionId);
|
|
3258
|
+
} catch {
|
|
3259
|
+
}
|
|
3260
|
+
}
|
|
3261
|
+
if (this.connectionListener) {
|
|
3262
|
+
try {
|
|
3263
|
+
this.nostrClient.removeConnectionListener(this.connectionListener);
|
|
3264
|
+
} catch {
|
|
3265
|
+
}
|
|
3266
|
+
}
|
|
3267
|
+
if (!this.usingSharedClient) {
|
|
3268
|
+
this.nostrClient.disconnect();
|
|
3269
|
+
}
|
|
3214
3270
|
this.nostrClient = null;
|
|
3215
3271
|
}
|
|
3272
|
+
this.connectionListener = null;
|
|
3273
|
+
this.usingSharedClient = false;
|
|
3216
3274
|
this.walletSubscriptionId = null;
|
|
3217
3275
|
this.chatSubscriptionId = null;
|
|
3218
3276
|
this.chatEoseFired = false;
|
|
3219
|
-
this.lastWalletEventAt = Date.now();
|
|
3220
|
-
this.lastChatEventAt = Date.now();
|
|
3221
3277
|
this.status = "disconnected";
|
|
3222
3278
|
this.emitEvent({ type: "transport:disconnected", timestamp: Date.now() });
|
|
3223
3279
|
}
|
|
3224
3280
|
isConnected() {
|
|
3225
3281
|
return this.status === "connected" && this.nostrClient?.isConnected() === true;
|
|
3226
3282
|
}
|
|
3283
|
+
/**
|
|
3284
|
+
* Build the connection listener used by both {@link connect} and
|
|
3285
|
+
* {@link rebindToSharedClient}.
|
|
3286
|
+
*
|
|
3287
|
+
* Behavioral notes:
|
|
3288
|
+
* - When the Mux is sharing a {@link NostrClient} with the host
|
|
3289
|
+
* transport (#123), we deliberately do NOT emit
|
|
3290
|
+
* {@code transport:connected} / {@code transport:reconnecting} here
|
|
3291
|
+
* — the host transport's own listener already emits those for the
|
|
3292
|
+
* same socket event. Re-subscribing after a reconnect IS still our
|
|
3293
|
+
* responsibility, since the host has
|
|
3294
|
+
* {@code suppressSubscriptions()}'d its own filters.
|
|
3295
|
+
* - {@code onConnect} does not emit {@code transport:connected}.
|
|
3296
|
+
* The SDK only fires {@code onConnect} on the initial socket
|
|
3297
|
+
* connection (subsequent reconnects use {@code onReconnected}),
|
|
3298
|
+
* and {@link connect()}'s bottom already emits
|
|
3299
|
+
* {@code transport:connected} once that returns. Emitting here too
|
|
3300
|
+
* would double-fire on every initial connect.
|
|
3301
|
+
* - Each callback bails out early when the Mux is not in an active
|
|
3302
|
+
* state ({@code disconnected} / {@code error}). Listeners are
|
|
3303
|
+
* removed on {@code disconnect()} before the callback can fire,
|
|
3304
|
+
* so this guard is mainly defense-in-depth against any in-flight
|
|
3305
|
+
* callback that lands during teardown — but having it at the top
|
|
3306
|
+
* means we never emit a misleading {@code transport:connected}
|
|
3307
|
+
* from a Mux that has already torn down.
|
|
3308
|
+
*/
|
|
3309
|
+
buildConnectionListener() {
|
|
3310
|
+
const isInactive = () => this.status === "disconnected" || this.status === "error";
|
|
3311
|
+
return {
|
|
3312
|
+
onConnect: (url) => {
|
|
3313
|
+
if (isInactive()) return;
|
|
3314
|
+
logger.debug("Mux", "Connected to relay:", url);
|
|
3315
|
+
},
|
|
3316
|
+
onDisconnect: (url, reason) => {
|
|
3317
|
+
logger.debug("Mux", "Disconnected from relay:", url, "reason:", reason);
|
|
3318
|
+
},
|
|
3319
|
+
onReconnecting: (url, attempt) => {
|
|
3320
|
+
if (isInactive()) return;
|
|
3321
|
+
logger.debug("Mux", "Reconnecting to relay:", url, "attempt:", attempt);
|
|
3322
|
+
if (!this.usingSharedClient) {
|
|
3323
|
+
this.emitEvent({ type: "transport:reconnecting", timestamp: Date.now() });
|
|
3324
|
+
}
|
|
3325
|
+
},
|
|
3326
|
+
onReconnected: (url) => {
|
|
3327
|
+
if (isInactive()) return;
|
|
3328
|
+
logger.debug("Mux", "Reconnected to relay:", url);
|
|
3329
|
+
if (!this.usingSharedClient) {
|
|
3330
|
+
this.emitEvent({ type: "transport:connected", timestamp: Date.now() });
|
|
3331
|
+
}
|
|
3332
|
+
this.updateSubscriptions().catch((err) => {
|
|
3333
|
+
logger.error("Mux", "Failed to re-subscribe after reconnect:", err);
|
|
3334
|
+
});
|
|
3335
|
+
}
|
|
3336
|
+
};
|
|
3337
|
+
}
|
|
3338
|
+
/**
|
|
3339
|
+
* Re-attach to a freshly-created shared NostrClient.
|
|
3340
|
+
*
|
|
3341
|
+
* Call this after the host (e.g. {@link NostrTransportProvider}) has
|
|
3342
|
+
* recreated its NostrClient — typically because the wallet's active
|
|
3343
|
+
* identity changed and the SDK's NostrClient does not support
|
|
3344
|
+
* changing identity at runtime. The previous client has already
|
|
3345
|
+
* been disconnected by the host, so its server-side subscriptions
|
|
3346
|
+
* are gone — we just adopt the new client and re-issue our own.
|
|
3347
|
+
*
|
|
3348
|
+
* The caller is responsible for ordering: by the time rebind runs,
|
|
3349
|
+
* the host transport's new NostrClient must already be created and
|
|
3350
|
+
* connected. In Sphere this is guaranteed because we await
|
|
3351
|
+
* {@code transport.setIdentity()} before calling rebind.
|
|
3352
|
+
*
|
|
3353
|
+
* Returns silently in two cases that are not caller errors:
|
|
3354
|
+
* - the Mux owns its own client (not sharing) — nothing to rebind
|
|
3355
|
+
* - the shared client reference hasn't changed (rebind is a no-op)
|
|
3356
|
+
*
|
|
3357
|
+
* Throws otherwise (rather than silently no-op'ing) so a wiring
|
|
3358
|
+
* mistake — for instance, calling rebind before the host's new
|
|
3359
|
+
* client is ready — surfaces immediately instead of leaving the
|
|
3360
|
+
* Mux pinned to a stale client.
|
|
3361
|
+
*/
|
|
3362
|
+
async rebindToSharedClient() {
|
|
3363
|
+
if (!this.usingSharedClient) return;
|
|
3364
|
+
if (!this.sharedNostrClientGetter) return;
|
|
3365
|
+
const newClient = this.sharedNostrClientGetter();
|
|
3366
|
+
if (!newClient) {
|
|
3367
|
+
throw new SphereError(
|
|
3368
|
+
"rebindToSharedClient: shared client getter returned null. The host transport must finish (re)creating its NostrClient before rebind is called.",
|
|
3369
|
+
"TRANSPORT_ERROR"
|
|
3370
|
+
);
|
|
3371
|
+
}
|
|
3372
|
+
if (this.nostrClient === newClient) return;
|
|
3373
|
+
if (!newClient.isConnected()) {
|
|
3374
|
+
throw new SphereError(
|
|
3375
|
+
"rebindToSharedClient: new shared client is not connected. Await transport.setIdentity() / transport.connect() before rebinding.",
|
|
3376
|
+
"TRANSPORT_ERROR"
|
|
3377
|
+
);
|
|
3378
|
+
}
|
|
3379
|
+
if (this.nostrClient && this.connectionListener && this.nostrClient !== newClient) {
|
|
3380
|
+
try {
|
|
3381
|
+
this.nostrClient.removeConnectionListener(this.connectionListener);
|
|
3382
|
+
} catch {
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
3385
|
+
this.nostrClient = newClient;
|
|
3386
|
+
this.walletSubscriptionId = null;
|
|
3387
|
+
this.chatSubscriptionId = null;
|
|
3388
|
+
this.chatEoseFired = false;
|
|
3389
|
+
this.connectionListener = this.buildConnectionListener();
|
|
3390
|
+
this.nostrClient.addConnectionListener(this.connectionListener);
|
|
3391
|
+
if (this.addresses.size > 0) {
|
|
3392
|
+
await this.updateSubscriptions();
|
|
3393
|
+
}
|
|
3394
|
+
}
|
|
3227
3395
|
/**
|
|
3228
3396
|
* One-shot fetch of pending events from the relay.
|
|
3229
3397
|
* Creates a temporary subscription, waits for EOSE (or timeout),
|
|
@@ -3352,8 +3520,6 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3352
3520
|
this.nostrClient.unsubscribe(this.chatSubscriptionId);
|
|
3353
3521
|
this.chatSubscriptionId = null;
|
|
3354
3522
|
}
|
|
3355
|
-
this.lastWalletEventAt = Date.now();
|
|
3356
|
-
this.lastChatEventAt = Date.now();
|
|
3357
3523
|
if (this.addresses.size === 0) return;
|
|
3358
3524
|
const allPubkeys = [];
|
|
3359
3525
|
for (const entry of this.addresses.values()) {
|
|
@@ -3440,25 +3606,6 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3440
3606
|
}
|
|
3441
3607
|
});
|
|
3442
3608
|
logger.debug("Mux", `updateSubscriptions: walletSub=${this.walletSubscriptionId} chatSub=${this.chatSubscriptionId}`);
|
|
3443
|
-
this.startHealthCheck();
|
|
3444
|
-
}
|
|
3445
|
-
startHealthCheck() {
|
|
3446
|
-
if (this.healthCheckTimer) return;
|
|
3447
|
-
this.healthCheckTimer = setInterval(() => {
|
|
3448
|
-
if (!this.isConnected()) return;
|
|
3449
|
-
const chatElapsed = Date.now() - this.lastChatEventAt;
|
|
3450
|
-
const walletElapsed = Date.now() - this.lastWalletEventAt;
|
|
3451
|
-
const needResubscribe = chatElapsed > 6e4 || walletElapsed > 3e5;
|
|
3452
|
-
if (needResubscribe) {
|
|
3453
|
-
const reason = chatElapsed > 6e4 ? `No chat events for ${Math.round(chatElapsed / 1e3)}s` : `No wallet events for ${Math.round(walletElapsed / 1e3)}s`;
|
|
3454
|
-
logger.warn("Mux", `${reason} \u2014 re-subscribing`);
|
|
3455
|
-
this.lastChatEventAt = Date.now();
|
|
3456
|
-
this.lastWalletEventAt = Date.now();
|
|
3457
|
-
this.updateSubscriptions().catch((err) => {
|
|
3458
|
-
logger.warn("Mux", "Health check re-subscription failed:", err);
|
|
3459
|
-
});
|
|
3460
|
-
}
|
|
3461
|
-
}, 3e4);
|
|
3462
3609
|
}
|
|
3463
3610
|
/**
|
|
3464
3611
|
* Schedule a re-subscription after a relay-initiated subscription closure.
|
|
@@ -3519,12 +3666,6 @@ var MultiAddressTransportMux = class _MultiAddressTransportMux {
|
|
|
3519
3666
|
}
|
|
3520
3667
|
}
|
|
3521
3668
|
}
|
|
3522
|
-
if (event.kind !== EventKinds2.GIFT_WRAP) {
|
|
3523
|
-
this.lastWalletEventAt = Date.now();
|
|
3524
|
-
}
|
|
3525
|
-
if (event.kind === EventKinds2.GIFT_WRAP) {
|
|
3526
|
-
this.lastChatEventAt = Date.now();
|
|
3527
|
-
}
|
|
3528
3669
|
try {
|
|
3529
3670
|
if (event.kind === EventKinds2.GIFT_WRAP) {
|
|
3530
3671
|
await this.routeGiftWrap(event);
|
|
@@ -28412,6 +28553,9 @@ var Sphere = class _Sphere {
|
|
|
28412
28553
|
this._transport.setFallbackSince(fallbackTs);
|
|
28413
28554
|
}
|
|
28414
28555
|
await this._transport.setIdentity(this._identity);
|
|
28556
|
+
if (this._transportMux && typeof this._transportMux.rebindToSharedClient === "function") {
|
|
28557
|
+
await this._transportMux.rebindToSharedClient();
|
|
28558
|
+
}
|
|
28415
28559
|
this.emitEvent("identity:changed", {
|
|
28416
28560
|
l1Address: this._identity.l1Address,
|
|
28417
28561
|
directAddress: this._identity.directAddress,
|
|
@@ -28622,7 +28766,12 @@ var Sphere = class _Sphere {
|
|
|
28622
28766
|
this._transportMux = new MultiAddressTransportMux({
|
|
28623
28767
|
relays: nostrTransport.getConfiguredRelays(),
|
|
28624
28768
|
createWebSocket: nostrTransport.getWebSocketFactory(),
|
|
28625
|
-
storage: nostrTransport.getStorageAdapter() ?? void 0
|
|
28769
|
+
storage: nostrTransport.getStorageAdapter() ?? void 0,
|
|
28770
|
+
// #123: share the original transport's NostrClient instead of
|
|
28771
|
+
// opening a second WebSocket per relay. Pass a getter so the
|
|
28772
|
+
// Mux resolves it at connect-time (after the transport finishes
|
|
28773
|
+
// its own connect()).
|
|
28774
|
+
sharedNostrClient: typeof nostrTransport.getNostrClient === "function" ? () => nostrTransport.getNostrClient() : void 0
|
|
28626
28775
|
});
|
|
28627
28776
|
await this._transportMux.connect();
|
|
28628
28777
|
if (typeof nostrTransport.suppressSubscriptions === "function") {
|