@unicitylabs/sphere-sdk 0.12.0-dev.1 → 0.13.0
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 +802 -110
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.d.cts +305 -16
- package/dist/connect/index.d.ts +305 -16
- package/dist/connect/index.js +802 -110
- package/dist/connect/index.js.map +1 -1
- package/dist/core/index.cjs +20 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +4 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.js +20 -1
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs +208 -41
- package/dist/impl/browser/connect/index.cjs.map +1 -1
- package/dist/impl/browser/connect/index.d.cts +33 -1
- package/dist/impl/browser/connect/index.d.ts +33 -1
- package/dist/impl/browser/connect/index.js +208 -41
- package/dist/impl/browser/connect/index.js.map +1 -1
- package/dist/impl/nodejs/connect/index.cjs +101 -1
- package/dist/impl/nodejs/connect/index.cjs.map +1 -1
- package/dist/impl/nodejs/connect/index.d.cts +6 -1
- package/dist/impl/nodejs/connect/index.d.ts +6 -1
- package/dist/impl/nodejs/connect/index.js +101 -1
- package/dist/impl/nodejs/connect/index.js.map +1 -1
- package/dist/index.cjs +20 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +20 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
|
@@ -124,26 +124,6 @@ var logger = {
|
|
|
124
124
|
}
|
|
125
125
|
};
|
|
126
126
|
|
|
127
|
-
// core/errors.ts
|
|
128
|
-
var SphereError = class extends Error {
|
|
129
|
-
code;
|
|
130
|
-
cause;
|
|
131
|
-
/**
|
|
132
|
-
* #441 deferred-paid linkage: the transferId of the possibly-committed send,
|
|
133
|
-
* stamped by `sendOnce` before the error leaves so a payment-request consumer
|
|
134
|
-
* can durably journal request→transfer and resolve 'paid' only when that
|
|
135
|
-
* transfer actually completes (never optimistically). Present ONLY on
|
|
136
|
-
* possibly-committed outcomes ({@link isPossiblyCommittedSendOutcome}).
|
|
137
|
-
*/
|
|
138
|
-
transferId;
|
|
139
|
-
constructor(message, code, cause) {
|
|
140
|
-
super(message);
|
|
141
|
-
this.name = "SphereError";
|
|
142
|
-
this.code = code;
|
|
143
|
-
this.cause = cause;
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
|
|
147
127
|
// connect/semver.ts
|
|
148
128
|
function majorOf(v) {
|
|
149
129
|
return parseInt(String(v).split(".")[0], 10);
|
|
@@ -342,7 +322,7 @@ var HOST_READY_TIMEOUT = 3e4;
|
|
|
342
322
|
|
|
343
323
|
// connect/protocol.ts
|
|
344
324
|
var SPHERE_CONNECT_NAMESPACE = "sphere-connect";
|
|
345
|
-
var SPHERE_CONNECT_VERSION = "2.
|
|
325
|
+
var SPHERE_CONNECT_VERSION = "2.1";
|
|
346
326
|
var RPC_METHODS = {
|
|
347
327
|
GET_IDENTITY: "sphere_getIdentity",
|
|
348
328
|
GET_BALANCE: "sphere_getBalance",
|
|
@@ -378,6 +358,78 @@ var INTENT_ACTIONS = {
|
|
|
378
358
|
SET_AUTO_RETURN: "set_auto_return",
|
|
379
359
|
MINT: "mint"
|
|
380
360
|
};
|
|
361
|
+
var ERROR_CODES = {
|
|
362
|
+
// Standard JSON-RPC
|
|
363
|
+
PARSE_ERROR: -32700,
|
|
364
|
+
INVALID_REQUEST: -32600,
|
|
365
|
+
METHOD_NOT_FOUND: -32601,
|
|
366
|
+
INVALID_PARAMS: -32602,
|
|
367
|
+
INTERNAL_ERROR: -32603,
|
|
368
|
+
// Sphere Connect (4xxx)
|
|
369
|
+
NOT_CONNECTED: 4001,
|
|
370
|
+
PERMISSION_DENIED: 4002,
|
|
371
|
+
USER_REJECTED: 4003,
|
|
372
|
+
SESSION_EXPIRED: 4004,
|
|
373
|
+
ORIGIN_BLOCKED: 4005,
|
|
374
|
+
RATE_LIMITED: 4006,
|
|
375
|
+
UNSUPPORTED_PROTOCOL_VERSION: 4007,
|
|
376
|
+
// Connect MAJOR mismatch (incompatible era)
|
|
377
|
+
INCOMPATIBLE_NETWORK: 4008,
|
|
378
|
+
// dApp targets a different network than the wallet
|
|
379
|
+
// Wallet locked; THE SESSION IS STILL ALIVE. A QUERY may be retried after wallet:unlocked.
|
|
380
|
+
// An INTENT already delegated to the wallet is NEVER answered with this code — it gets
|
|
381
|
+
// INTENT_OUTCOME_UNKNOWN (4201) instead, because a retry could double-spend.
|
|
382
|
+
WALLET_LOCKED: 4009,
|
|
383
|
+
INSUFFICIENT_BALANCE: 4100,
|
|
384
|
+
INVALID_RECIPIENT: 4101,
|
|
385
|
+
TRANSFER_FAILED: 4102,
|
|
386
|
+
INTENT_CANCELLED: 4200,
|
|
387
|
+
/**
|
|
388
|
+
* The intent was DELEGATED to the wallet and the host lost track of the answer — a host
|
|
389
|
+
* deadline fired, or the wallet locked / logged out mid-flight. **The outcome is UNKNOWN:
|
|
390
|
+
* the money may or may not have moved.**
|
|
391
|
+
*
|
|
392
|
+
* A dApp MUST NOT retry on this code. Reconcile out of band (poll the recipient, the
|
|
393
|
+
* aggregator, or your own backend) and only then decide.
|
|
394
|
+
*
|
|
395
|
+
* This code exists because every other answer would be a lie. `INTENT_CANCELLED` (4200)
|
|
396
|
+
* asserts the user declined and nothing happened; `WALLET_LOCKED` (4009) invites a retry
|
|
397
|
+
* after the unlock. Sending either for an intent the wallet had already submitted is how a
|
|
398
|
+
* paid-but-not-credited order — and then a double spend on retry — happens.
|
|
399
|
+
*/
|
|
400
|
+
INTENT_OUTCOME_UNKNOWN: 4201
|
|
401
|
+
};
|
|
402
|
+
var WALLET_EVENTS = {
|
|
403
|
+
/** Wallet is LOCKED — the session is STILL ALIVE. Requests are answered
|
|
404
|
+
* WALLET_LOCKED (4009) until `wallet:unlocked`. The dApp must NOT disconnect,
|
|
405
|
+
* must NOT clear its sessionId, and must NOT re-handshake.
|
|
406
|
+
* Payload: {@link WalletLockedPayload}. Pushed by ConnectHost.setLocked() and
|
|
407
|
+
* immediately after a handshake response carrying `locked: true`. */
|
|
408
|
+
LOCKED: "wallet:locked",
|
|
409
|
+
/** Wallet was unlocked — the SAME session continues: no re-handshake, no re-approval,
|
|
410
|
+
* no re-subscribe (the host re-arms the dApp's subscriptions before pushing this).
|
|
411
|
+
* Payload: {@link WalletUnlockedPayload} — carries the CURRENT identity, which may
|
|
412
|
+
* differ from the one the dApp connected with. Pushed by ConnectHost.updateSphere()
|
|
413
|
+
* on the locked -> live edge only. */
|
|
414
|
+
UNLOCKED: "wallet:unlocked",
|
|
415
|
+
/** The session is GONE (logout, wallet deleted, dApp sphere_disconnect, expiry seen at
|
|
416
|
+
* unlock, a different seed behind the lock screen, host destroy).
|
|
417
|
+
* The dApp must clear its session and re-handshake to continue. Unlocking does not cure it.
|
|
418
|
+
* Payload: {@link WalletDisconnectedPayload}. Pushed by ConnectHost.revokeSession(). */
|
|
419
|
+
DISCONNECTED: "wallet:disconnected",
|
|
420
|
+
/** Active wallet address changed. dApp should update displayed identity.
|
|
421
|
+
* Pushed automatically by ConnectHost — no sphere_subscribe needed. */
|
|
422
|
+
IDENTITY_CHANGED: "identity:changed"
|
|
423
|
+
};
|
|
424
|
+
var AUTO_PUSHED_EVENTS = [
|
|
425
|
+
WALLET_EVENTS.LOCKED,
|
|
426
|
+
WALLET_EVENTS.UNLOCKED,
|
|
427
|
+
WALLET_EVENTS.DISCONNECTED,
|
|
428
|
+
WALLET_EVENTS.IDENTITY_CHANGED
|
|
429
|
+
];
|
|
430
|
+
function isAutoPushedEvent(event) {
|
|
431
|
+
return AUTO_PUSHED_EVENTS.includes(event);
|
|
432
|
+
}
|
|
381
433
|
function isSphereConnectMessage(msg) {
|
|
382
434
|
if (!msg || typeof msg !== "object") return false;
|
|
383
435
|
const m = msg;
|
|
@@ -394,7 +446,7 @@ function createRequestId() {
|
|
|
394
446
|
}
|
|
395
447
|
|
|
396
448
|
// connect/version.ts
|
|
397
|
-
var SDK_VERSION = "0.
|
|
449
|
+
var SDK_VERSION = "0.13.0";
|
|
398
450
|
|
|
399
451
|
// connect/permissions.ts
|
|
400
452
|
var PERMISSION_SCOPES = {
|
|
@@ -453,6 +505,37 @@ var INTENT_PERMISSIONS = {
|
|
|
453
505
|
[INTENT_ACTIONS.MINT]: PERMISSION_SCOPES.MINT_REQUEST
|
|
454
506
|
};
|
|
455
507
|
|
|
508
|
+
// connect/host/host-state.ts
|
|
509
|
+
var WALLET_LOCKED_MESSAGE = "Wallet is locked";
|
|
510
|
+
var NOT_CONNECTED_MESSAGE = "Not connected";
|
|
511
|
+
var LOCKED_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
512
|
+
RPC_METHODS.GET_IDENTITY,
|
|
513
|
+
RPC_METHODS.SUBSCRIBE,
|
|
514
|
+
RPC_METHODS.UNSUBSCRIBE,
|
|
515
|
+
RPC_METHODS.DISCONNECT
|
|
516
|
+
]);
|
|
517
|
+
var REFUSE_NOT_CONNECTED = {
|
|
518
|
+
kind: "refuse",
|
|
519
|
+
error: { code: ERROR_CODES.NOT_CONNECTED, message: NOT_CONNECTED_MESSAGE }
|
|
520
|
+
};
|
|
521
|
+
var REFUSE_LOCKED = {
|
|
522
|
+
kind: "refuse",
|
|
523
|
+
error: {
|
|
524
|
+
code: ERROR_CODES.WALLET_LOCKED,
|
|
525
|
+
message: WALLET_LOCKED_MESSAGE,
|
|
526
|
+
data: { reason: "locked" }
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
|
|
530
|
+
// connect/host/WalletSnapshot.ts
|
|
531
|
+
var EMPTY_WALLET_SNAPSHOT = Object.freeze({ capturedAt: 0 });
|
|
532
|
+
|
|
533
|
+
// connect/host/ConnectHost.ts
|
|
534
|
+
var CHANNEL_ONLY_CODES = /* @__PURE__ */ new Set([
|
|
535
|
+
ERROR_CODES.WALLET_LOCKED,
|
|
536
|
+
ERROR_CODES.NOT_CONNECTED
|
|
537
|
+
]);
|
|
538
|
+
|
|
456
539
|
// connect/client/ConnectClient.ts
|
|
457
540
|
var ConnectError = class extends Error {
|
|
458
541
|
constructor(message, code, data) {
|
|
@@ -477,6 +560,8 @@ var ConnectClient = class {
|
|
|
477
560
|
grantedPermissions = [];
|
|
478
561
|
identity = null;
|
|
479
562
|
walletNet = null;
|
|
563
|
+
walletProto = null;
|
|
564
|
+
locked = false;
|
|
480
565
|
connected = false;
|
|
481
566
|
pendingRequests = /* @__PURE__ */ new Map();
|
|
482
567
|
eventHandlers = /* @__PURE__ */ new Map();
|
|
@@ -549,12 +634,37 @@ var ConnectClient = class {
|
|
|
549
634
|
get walletNetwork() {
|
|
550
635
|
return this.walletNet;
|
|
551
636
|
}
|
|
637
|
+
/**
|
|
638
|
+
* The wallet's Connect protocol version, captured from the handshake response `v`.
|
|
639
|
+
* Null before the first handshake response and after a disconnect.
|
|
640
|
+
*
|
|
641
|
+
* Feature-detect with it: compare against '2.1' to decide whether the wallet can be
|
|
642
|
+
* trusted to send wallet:unlocked / wallet:disconnected. A Connect 2.0 wallet destroys
|
|
643
|
+
* the session on lock and never emits either, so a dApp waiting for them against one
|
|
644
|
+
* waits forever.
|
|
645
|
+
*
|
|
646
|
+
* CAVEAT: on an ERROR response the host echoes the dApp's own `v` back
|
|
647
|
+
* (ConnectHost.sendHandshakeResponse), so after a refused connection this may be the
|
|
648
|
+
* dApp's version rather than the wallet's. Only trust it after a successful handshake.
|
|
649
|
+
*/
|
|
650
|
+
get walletProtocol() {
|
|
651
|
+
return this.walletProto;
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Whether the wallet was locked at the last handshake or lifecycle event.
|
|
655
|
+
* A locked client is still CONNECTED: `isConnected` stays true and `session` stays valid.
|
|
656
|
+
* Requests answer WALLET_LOCKED (4009) until `wallet:unlocked` arrives on the SAME
|
|
657
|
+
* session — do not disconnect, do not clear the session, do not re-handshake.
|
|
658
|
+
*/
|
|
659
|
+
get walletLocked() {
|
|
660
|
+
return this.locked;
|
|
661
|
+
}
|
|
552
662
|
// ===========================================================================
|
|
553
663
|
// Query (read data)
|
|
554
664
|
// ===========================================================================
|
|
555
665
|
/** Send a query request and return the result */
|
|
556
666
|
async query(method, params) {
|
|
557
|
-
if (!this.connected) throw new
|
|
667
|
+
if (!this.connected) throw new ConnectError("Not connected", ERROR_CODES.NOT_CONNECTED);
|
|
558
668
|
const id = createRequestId();
|
|
559
669
|
return new Promise((resolve, reject) => {
|
|
560
670
|
const timer = setTimeout(() => {
|
|
@@ -564,7 +674,8 @@ var ConnectClient = class {
|
|
|
564
674
|
this.pendingRequests.set(id, {
|
|
565
675
|
resolve,
|
|
566
676
|
reject,
|
|
567
|
-
timer
|
|
677
|
+
timer,
|
|
678
|
+
kind: "query"
|
|
568
679
|
});
|
|
569
680
|
this.transport.send({
|
|
570
681
|
ns: SPHERE_CONNECT_NAMESPACE,
|
|
@@ -581,17 +692,23 @@ var ConnectClient = class {
|
|
|
581
692
|
// ===========================================================================
|
|
582
693
|
/** Send an intent request. The wallet will open its UI for user confirmation. */
|
|
583
694
|
async intent(action, params) {
|
|
584
|
-
if (!this.connected) throw new
|
|
695
|
+
if (!this.connected) throw new ConnectError("Not connected", ERROR_CODES.NOT_CONNECTED);
|
|
585
696
|
const id = createRequestId();
|
|
586
697
|
return new Promise((resolve, reject) => {
|
|
587
698
|
const timer = setTimeout(() => {
|
|
588
699
|
this.pendingRequests.delete(id);
|
|
589
|
-
reject(
|
|
700
|
+
reject(
|
|
701
|
+
new ConnectError(
|
|
702
|
+
`Intent outcome unknown \u2014 do not retry; reconcile before acting: ${action}`,
|
|
703
|
+
ERROR_CODES.INTENT_OUTCOME_UNKNOWN
|
|
704
|
+
)
|
|
705
|
+
);
|
|
590
706
|
}, this.intentTimeout);
|
|
591
707
|
this.pendingRequests.set(id, {
|
|
592
708
|
resolve,
|
|
593
709
|
reject,
|
|
594
|
-
timer
|
|
710
|
+
timer,
|
|
711
|
+
kind: "intent"
|
|
595
712
|
});
|
|
596
713
|
this.transport.send({
|
|
597
714
|
ns: SPHERE_CONNECT_NAMESPACE,
|
|
@@ -610,7 +727,7 @@ var ConnectClient = class {
|
|
|
610
727
|
on(event, handler) {
|
|
611
728
|
if (!this.eventHandlers.has(event)) {
|
|
612
729
|
this.eventHandlers.set(event, /* @__PURE__ */ new Set());
|
|
613
|
-
if (this.connected) {
|
|
730
|
+
if (this.connected && !isAutoPushedEvent(event)) {
|
|
614
731
|
this.query(RPC_METHODS.SUBSCRIBE, { event }).catch((err) => logger.debug("Connect", "Event subscription failed", err));
|
|
615
732
|
}
|
|
616
733
|
}
|
|
@@ -621,7 +738,7 @@ var ConnectClient = class {
|
|
|
621
738
|
handlers.delete(handler);
|
|
622
739
|
if (handlers.size === 0) {
|
|
623
740
|
this.eventHandlers.delete(event);
|
|
624
|
-
if (this.connected) {
|
|
741
|
+
if (this.connected && !isAutoPushedEvent(event)) {
|
|
625
742
|
this.query(RPC_METHODS.UNSUBSCRIBE, { event }).catch((err) => logger.debug("Connect", "Event unsubscription failed", err));
|
|
626
743
|
}
|
|
627
744
|
}
|
|
@@ -645,15 +762,36 @@ var ConnectClient = class {
|
|
|
645
762
|
return;
|
|
646
763
|
}
|
|
647
764
|
if (msg.type === "event") {
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
765
|
+
if (!this.connected || !this.sessionId) {
|
|
766
|
+
logger.warn("Connect", `Ignoring wallet event before a session exists: ${msg.event}`);
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
if (msg.event === WALLET_EVENTS.LOCKED) {
|
|
770
|
+
this.locked = true;
|
|
771
|
+
} else if (msg.event === WALLET_EVENTS.UNLOCKED) {
|
|
772
|
+
this.locked = false;
|
|
773
|
+
const identity = msg.data?.identity;
|
|
774
|
+
if (identity) this.identity = identity;
|
|
775
|
+
} else if (msg.event === WALLET_EVENTS.DISCONNECTED) {
|
|
776
|
+
this.connected = false;
|
|
777
|
+
} else if (msg.event === WALLET_EVENTS.IDENTITY_CHANGED) {
|
|
778
|
+
const data = msg.data;
|
|
779
|
+
if (data && typeof data.chainPubkey === "string") this.identity = data;
|
|
780
|
+
}
|
|
781
|
+
this.dispatchEvent(msg.event, msg.data);
|
|
782
|
+
if (msg.event === WALLET_EVENTS.DISCONNECTED) {
|
|
783
|
+
this.cleanup();
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
dispatchEvent(event, data) {
|
|
788
|
+
const handlers = this.eventHandlers.get(event);
|
|
789
|
+
if (!handlers) return;
|
|
790
|
+
for (const handler of handlers) {
|
|
791
|
+
try {
|
|
792
|
+
handler(data);
|
|
793
|
+
} catch (err) {
|
|
794
|
+
logger.debug("Connect", "Event handler error", err);
|
|
657
795
|
}
|
|
658
796
|
}
|
|
659
797
|
}
|
|
@@ -661,6 +799,7 @@ var ConnectClient = class {
|
|
|
661
799
|
if (!this.handshakeResolver) return;
|
|
662
800
|
clearTimeout(this.handshakeResolver.timer);
|
|
663
801
|
const m = msg;
|
|
802
|
+
this.walletProto = msg.v ?? null;
|
|
664
803
|
if (m.error) {
|
|
665
804
|
this.handshakeResolver.reject(new ConnectError(m.error.message, m.error.code, m.error.data));
|
|
666
805
|
this.handshakeResolver = null;
|
|
@@ -671,12 +810,16 @@ var ConnectClient = class {
|
|
|
671
810
|
this.grantedPermissions = msg.permissions;
|
|
672
811
|
this.identity = msg.identity;
|
|
673
812
|
this.walletNet = m.network ?? null;
|
|
813
|
+
this.locked = m.locked === true;
|
|
674
814
|
this.connected = true;
|
|
675
815
|
if (m.warning) logger.warn("Connect", "Wallet deprecation notice", m.warning.message);
|
|
676
816
|
this.handshakeResolver.resolve({
|
|
677
817
|
sessionId: msg.sessionId,
|
|
678
818
|
permissions: this.grantedPermissions,
|
|
679
|
-
identity: msg.identity
|
|
819
|
+
identity: msg.identity,
|
|
820
|
+
// A resume DURING a lock succeeds: the dApp is connected on the same session and
|
|
821
|
+
// must not re-handshake. It will get wallet:unlocked when the user unlocks.
|
|
822
|
+
...this.locked ? { locked: true } : {}
|
|
680
823
|
});
|
|
681
824
|
} else {
|
|
682
825
|
this.handshakeResolver.reject(new Error("Connection rejected by wallet"));
|
|
@@ -702,9 +845,19 @@ var ConnectClient = class {
|
|
|
702
845
|
this.unsubscribeTransport();
|
|
703
846
|
this.unsubscribeTransport = null;
|
|
704
847
|
}
|
|
848
|
+
if (this.handshakeResolver) {
|
|
849
|
+
clearTimeout(this.handshakeResolver.timer);
|
|
850
|
+
this.handshakeResolver.reject(new ConnectError("Disconnected", ERROR_CODES.NOT_CONNECTED));
|
|
851
|
+
this.handshakeResolver = null;
|
|
852
|
+
}
|
|
705
853
|
for (const [, pending] of this.pendingRequests) {
|
|
706
854
|
clearTimeout(pending.timer);
|
|
707
|
-
pending.reject(
|
|
855
|
+
pending.reject(
|
|
856
|
+
pending.kind === "intent" ? new ConnectError(
|
|
857
|
+
"Intent outcome unknown \u2014 do not retry; reconcile before acting",
|
|
858
|
+
ERROR_CODES.INTENT_OUTCOME_UNKNOWN
|
|
859
|
+
) : new ConnectError("Disconnected", ERROR_CODES.NOT_CONNECTED)
|
|
860
|
+
);
|
|
708
861
|
}
|
|
709
862
|
this.pendingRequests.clear();
|
|
710
863
|
this.eventHandlers.clear();
|
|
@@ -713,11 +866,21 @@ var ConnectClient = class {
|
|
|
713
866
|
this.grantedPermissions = [];
|
|
714
867
|
this.identity = null;
|
|
715
868
|
this.walletNet = null;
|
|
869
|
+
this.walletProto = null;
|
|
870
|
+
this.locked = false;
|
|
716
871
|
}
|
|
717
872
|
};
|
|
718
873
|
|
|
719
874
|
// impl/browser/connect/PostMessageTransport.ts
|
|
720
875
|
var POPUP_CLOSE_CHECK_INTERVAL = 1e3;
|
|
876
|
+
function originOf(targetOrigin) {
|
|
877
|
+
if (targetOrigin === "*") return null;
|
|
878
|
+
try {
|
|
879
|
+
return [new URL(targetOrigin).origin];
|
|
880
|
+
} catch {
|
|
881
|
+
return null;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
721
884
|
var PostMessageTransport = class _PostMessageTransport {
|
|
722
885
|
targetWindow;
|
|
723
886
|
targetOrigin;
|
|
@@ -731,6 +894,9 @@ var PostMessageTransport = class _PostMessageTransport {
|
|
|
731
894
|
this.targetOrigin = targetOrigin;
|
|
732
895
|
this.allowedOrigins = allowedOrigins ? new Set(allowedOrigins) : null;
|
|
733
896
|
this.listener = (event) => {
|
|
897
|
+
if (event.source && event.source !== this.targetWindow) {
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
734
900
|
if (this.allowedOrigins && !this.allowedOrigins.has("*") && !this.allowedOrigins.has(event.origin)) {
|
|
735
901
|
return;
|
|
736
902
|
}
|
|
@@ -769,7 +935,8 @@ var PostMessageTransport = class _PostMessageTransport {
|
|
|
769
935
|
static forClient(options) {
|
|
770
936
|
const target = options?.target ?? window.parent;
|
|
771
937
|
const targetOrigin = options?.targetOrigin ?? "*";
|
|
772
|
-
const
|
|
938
|
+
const allowedOrigins = originOf(targetOrigin);
|
|
939
|
+
const transport = new _PostMessageTransport(target, targetOrigin, allowedOrigins);
|
|
773
940
|
if (options?.target && options.target !== window.parent) {
|
|
774
941
|
transport.startPopupCloseDetection(options.target);
|
|
775
942
|
}
|