@partylayer/provider 0.6.0 → 0.6.1
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/README.md +14 -4
- package/dist/index.d.mts +10 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.js +118 -100
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +118 -100
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
### Features
|
|
20
20
|
|
|
21
|
-
- **
|
|
21
|
+
- **Provider request surface**: Handles the ten method names according to backing wallet capabilities (`connect`, `disconnect`, `isConnected`, `status`, `getActiveNetwork`, `listAccounts`, `getPrimaryAccount`, `signMessage`, `prepareExecute`, `ledgerApi`)
|
|
22
22
|
- **Wallet Discovery**: Automatic scanning for injected CIP-0103 providers at `window.canton.*`
|
|
23
23
|
- **Async Wallet Support**: Handles both synchronous (browser extension) and asynchronous (mobile/QR) wallet flows
|
|
24
24
|
- **Standard Error Model**: `ProviderRpcError` with EIP-1193 / EIP-1474 numeric codes
|
|
@@ -58,7 +58,15 @@ const result = await provider.request({ method: 'connect' });
|
|
|
58
58
|
const account = await provider.request({ method: 'getPrimaryAccount' });
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
###
|
|
61
|
+
### Client compatibility bridge
|
|
62
|
+
|
|
63
|
+
The bridge projects the active SDK party, retains the legacy `{ response: string }`
|
|
64
|
+
Ledger API result, and emits transaction states only with genuine evidence. It does
|
|
65
|
+
not establish full account/key enumeration or complete native protocol ownership.
|
|
66
|
+
See [alignment and limits](../../docs/CIP-0103-ALIGNMENT.md) before relying on it
|
|
67
|
+
as an exact standard wire implementation.
|
|
68
|
+
|
|
69
|
+
Existing low-level composition:
|
|
62
70
|
|
|
63
71
|
```typescript
|
|
64
72
|
import { createProviderBridge } from '@partylayer/provider';
|
|
@@ -67,8 +75,10 @@ import { createPartyLayer } from '@partylayer/sdk';
|
|
|
67
75
|
const client = createPartyLayer({ network: 'devnet' });
|
|
68
76
|
const provider = createProviderBridge(client);
|
|
69
77
|
|
|
70
|
-
//
|
|
71
|
-
await
|
|
78
|
+
// Choose a wallet through the SDK's documented application interface.
|
|
79
|
+
await client.connect({ walletId: 'console' });
|
|
80
|
+
// Then use the supported provider requests.
|
|
81
|
+
await provider.request({ method: 'status' });
|
|
72
82
|
```
|
|
73
83
|
|
|
74
84
|
---
|
package/dist/index.d.mts
CHANGED
|
@@ -258,6 +258,9 @@ interface BridgeableClient {
|
|
|
258
258
|
transactionHash?: unknown;
|
|
259
259
|
signedTx?: unknown;
|
|
260
260
|
partyId?: unknown;
|
|
261
|
+
/** Actual signature metadata, never a transaction hash. */
|
|
262
|
+
signature?: unknown;
|
|
263
|
+
signedBy?: unknown;
|
|
261
264
|
}>;
|
|
262
265
|
submitTransaction(params: {
|
|
263
266
|
signedTx: unknown;
|
|
@@ -266,6 +269,7 @@ interface BridgeableClient {
|
|
|
266
269
|
submittedAt?: number;
|
|
267
270
|
commandId?: string;
|
|
268
271
|
updateId?: string;
|
|
272
|
+
completionOffset?: number;
|
|
269
273
|
}>;
|
|
270
274
|
ledgerApi?(params: {
|
|
271
275
|
requestMethod: string;
|
|
@@ -396,11 +400,15 @@ interface ExtensionChannelOptions {
|
|
|
396
400
|
/** Per-request timeout in ms. Default 30000. */
|
|
397
401
|
timeoutMs?: number;
|
|
398
402
|
}
|
|
403
|
+
interface ExtensionChannelProvider extends CIP0103Provider {
|
|
404
|
+
/** Remove the channel listener, reject pending RPCs and release subscriptions. */
|
|
405
|
+
destroy(): void;
|
|
406
|
+
}
|
|
399
407
|
/**
|
|
400
408
|
* Create a CIP-0103 provider that talks the splice-wallet postMessage protocol
|
|
401
409
|
* over the page `window`, routed by `target`.
|
|
402
410
|
*/
|
|
403
|
-
declare function createExtensionChannelProvider(options?: ExtensionChannelOptions):
|
|
411
|
+
declare function createExtensionChannelProvider(options?: ExtensionChannelOptions): ExtensionChannelProvider;
|
|
404
412
|
|
|
405
413
|
/**
|
|
406
414
|
* Async Wallet Handling
|
|
@@ -496,4 +504,4 @@ declare class MethodRouter {
|
|
|
496
504
|
private registerDefaults;
|
|
497
505
|
}
|
|
498
506
|
|
|
499
|
-
export { type AnnounceDiscoveryOptions, type AnnounceSubscribeOptions, type AnnouncedWallet, type AsyncConnectOptions, type AsyncPrepareExecuteOptions, type BridgeableClient, CIP0103EventBus, type DiscoveredProvider, type ExtensionChannelOptions, JSON_RPC_ERRORS, type MethodHandler, MethodRouter, PartyLayerProvider, type PartyLayerProviderOptions, ProviderRpcError, RPC_ERRORS, type WaitForAnnouncedOptions, chainDisconnected, createExtensionChannelProvider, createProviderBridge, disconnected, discoverAnnouncedProviders, discoverInjectedProviders, discoverProviders, handleAsyncConnect, handleAsyncPrepareExecute, internalError, invalidParams, isCIP0103Provider, methodNotFound, resourceNotFound, resourceUnavailable, subscribeAnnouncedProviders, toPartyLayerError, toProviderRpcError, transactionRejected, unauthorized, unsupportedMethod, userRejected, waitForAnnouncedProvider, waitForProvider };
|
|
507
|
+
export { type AnnounceDiscoveryOptions, type AnnounceSubscribeOptions, type AnnouncedWallet, type AsyncConnectOptions, type AsyncPrepareExecuteOptions, type BridgeableClient, CIP0103EventBus, type DiscoveredProvider, type ExtensionChannelOptions, type ExtensionChannelProvider, JSON_RPC_ERRORS, type MethodHandler, MethodRouter, PartyLayerProvider, type PartyLayerProviderOptions, ProviderRpcError, RPC_ERRORS, type WaitForAnnouncedOptions, chainDisconnected, createExtensionChannelProvider, createProviderBridge, disconnected, discoverAnnouncedProviders, discoverInjectedProviders, discoverProviders, handleAsyncConnect, handleAsyncPrepareExecute, internalError, invalidParams, isCIP0103Provider, methodNotFound, resourceNotFound, resourceUnavailable, subscribeAnnouncedProviders, toPartyLayerError, toProviderRpcError, transactionRejected, unauthorized, unsupportedMethod, userRejected, waitForAnnouncedProvider, waitForProvider };
|
package/dist/index.d.ts
CHANGED
|
@@ -258,6 +258,9 @@ interface BridgeableClient {
|
|
|
258
258
|
transactionHash?: unknown;
|
|
259
259
|
signedTx?: unknown;
|
|
260
260
|
partyId?: unknown;
|
|
261
|
+
/** Actual signature metadata, never a transaction hash. */
|
|
262
|
+
signature?: unknown;
|
|
263
|
+
signedBy?: unknown;
|
|
261
264
|
}>;
|
|
262
265
|
submitTransaction(params: {
|
|
263
266
|
signedTx: unknown;
|
|
@@ -266,6 +269,7 @@ interface BridgeableClient {
|
|
|
266
269
|
submittedAt?: number;
|
|
267
270
|
commandId?: string;
|
|
268
271
|
updateId?: string;
|
|
272
|
+
completionOffset?: number;
|
|
269
273
|
}>;
|
|
270
274
|
ledgerApi?(params: {
|
|
271
275
|
requestMethod: string;
|
|
@@ -396,11 +400,15 @@ interface ExtensionChannelOptions {
|
|
|
396
400
|
/** Per-request timeout in ms. Default 30000. */
|
|
397
401
|
timeoutMs?: number;
|
|
398
402
|
}
|
|
403
|
+
interface ExtensionChannelProvider extends CIP0103Provider {
|
|
404
|
+
/** Remove the channel listener, reject pending RPCs and release subscriptions. */
|
|
405
|
+
destroy(): void;
|
|
406
|
+
}
|
|
399
407
|
/**
|
|
400
408
|
* Create a CIP-0103 provider that talks the splice-wallet postMessage protocol
|
|
401
409
|
* over the page `window`, routed by `target`.
|
|
402
410
|
*/
|
|
403
|
-
declare function createExtensionChannelProvider(options?: ExtensionChannelOptions):
|
|
411
|
+
declare function createExtensionChannelProvider(options?: ExtensionChannelOptions): ExtensionChannelProvider;
|
|
404
412
|
|
|
405
413
|
/**
|
|
406
414
|
* Async Wallet Handling
|
|
@@ -496,4 +504,4 @@ declare class MethodRouter {
|
|
|
496
504
|
private registerDefaults;
|
|
497
505
|
}
|
|
498
506
|
|
|
499
|
-
export { type AnnounceDiscoveryOptions, type AnnounceSubscribeOptions, type AnnouncedWallet, type AsyncConnectOptions, type AsyncPrepareExecuteOptions, type BridgeableClient, CIP0103EventBus, type DiscoveredProvider, type ExtensionChannelOptions, JSON_RPC_ERRORS, type MethodHandler, MethodRouter, PartyLayerProvider, type PartyLayerProviderOptions, ProviderRpcError, RPC_ERRORS, type WaitForAnnouncedOptions, chainDisconnected, createExtensionChannelProvider, createProviderBridge, disconnected, discoverAnnouncedProviders, discoverInjectedProviders, discoverProviders, handleAsyncConnect, handleAsyncPrepareExecute, internalError, invalidParams, isCIP0103Provider, methodNotFound, resourceNotFound, resourceUnavailable, subscribeAnnouncedProviders, toPartyLayerError, toProviderRpcError, transactionRejected, unauthorized, unsupportedMethod, userRejected, waitForAnnouncedProvider, waitForProvider };
|
|
507
|
+
export { type AnnounceDiscoveryOptions, type AnnounceSubscribeOptions, type AnnouncedWallet, type AsyncConnectOptions, type AsyncPrepareExecuteOptions, type BridgeableClient, CIP0103EventBus, type DiscoveredProvider, type ExtensionChannelOptions, type ExtensionChannelProvider, JSON_RPC_ERRORS, type MethodHandler, MethodRouter, PartyLayerProvider, type PartyLayerProviderOptions, ProviderRpcError, RPC_ERRORS, type WaitForAnnouncedOptions, chainDisconnected, createExtensionChannelProvider, createProviderBridge, disconnected, discoverAnnouncedProviders, discoverInjectedProviders, discoverProviders, handleAsyncConnect, handleAsyncPrepareExecute, internalError, invalidParams, isCIP0103Provider, methodNotFound, resourceNotFound, resourceUnavailable, subscribeAnnouncedProviders, toPartyLayerError, toProviderRpcError, transactionRejected, unauthorized, unsupportedMethod, userRejected, waitForAnnouncedProvider, waitForProvider };
|
package/dist/index.js
CHANGED
|
@@ -514,7 +514,7 @@ var PartyLayerProvider = class {
|
|
|
514
514
|
};
|
|
515
515
|
|
|
516
516
|
// src/bridge.ts
|
|
517
|
-
var PROVIDER_VERSION = "0.6.
|
|
517
|
+
var PROVIDER_VERSION = "0.6.1" ;
|
|
518
518
|
function createProviderBridge(client) {
|
|
519
519
|
const eventBus = new CIP0103EventBus();
|
|
520
520
|
const pendingEmitted = /* @__PURE__ */ new Set();
|
|
@@ -579,9 +579,8 @@ async function handleRequest(client, args, eventBus, pendingEmitted) {
|
|
|
579
579
|
}
|
|
580
580
|
case "getActiveNetwork": {
|
|
581
581
|
const session = await client.getActiveSession();
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
);
|
|
582
|
+
if (!session) throw disconnected("No active session");
|
|
583
|
+
return core.toCAIP2Network(session.network);
|
|
585
584
|
}
|
|
586
585
|
case "listAccounts": {
|
|
587
586
|
const session = await client.getActiveSession();
|
|
@@ -606,61 +605,42 @@ async function handleRequest(client, args, eventBus, pendingEmitted) {
|
|
|
606
605
|
}
|
|
607
606
|
case "prepareExecute": {
|
|
608
607
|
const p = normalizeParams(params);
|
|
609
|
-
const
|
|
608
|
+
const session = await client.getActiveSession();
|
|
609
|
+
if (!session) throw disconnected("No active session");
|
|
610
|
+
const cmdId = nonempty(p.commandId) ? p.commandId : `cmd_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
611
|
+
if (pendingEmitted.has(cmdId)) throw resourceUnavailable("This commandId is already pending");
|
|
612
|
+
const payload = { ...p, commandId: cmdId };
|
|
610
613
|
pendingEmitted.add(cmdId);
|
|
611
|
-
eventBus.emit(core.CIP0103_EVENTS.TX_CHANGED, {
|
|
612
|
-
|
|
613
|
-
commandId: cmdId
|
|
614
|
-
});
|
|
614
|
+
eventBus.emit(core.CIP0103_EVENTS.TX_CHANGED, { status: "pending", commandId: cmdId });
|
|
615
|
+
let submitting = false;
|
|
615
616
|
try {
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
party: partyId
|
|
627
|
-
}
|
|
628
|
-
});
|
|
617
|
+
let signedTx = payload;
|
|
618
|
+
if (!session.capabilitiesSnapshot || session.capabilitiesSnapshot.includes("signTransaction")) {
|
|
619
|
+
const signed = await client.signTransaction({ tx: payload });
|
|
620
|
+
if (signed.partyId !== void 0 && signed.partyId !== session.partyId) {
|
|
621
|
+
throw disconnected("Wallet account changed during signing");
|
|
622
|
+
}
|
|
623
|
+
signedTx = signed.signedTx;
|
|
624
|
+
if (signedTx === void 0) throw new Error("Wallet returned no signed transaction");
|
|
625
|
+
const event2 = signedEvent({ signature: signed.signature, signedBy: signed.signedBy, party: signed.partyId }, cmdId);
|
|
626
|
+
if (event2) eventBus.emit(core.CIP0103_EVENTS.TX_CHANGED, event2);
|
|
629
627
|
}
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
});
|
|
634
|
-
pendingEmitted.delete(cmdId);
|
|
635
|
-
eventBus.emit(core.CIP0103_EVENTS.TX_CHANGED, {
|
|
636
|
-
status: "executed",
|
|
637
|
-
commandId: cmdId,
|
|
638
|
-
payload: {
|
|
639
|
-
// All three are real identifiers — the receipt's update id, the
|
|
640
|
-
// wallet's command id, or the bridge's own command id for this
|
|
641
|
-
// operation. `String(receipt.transactionHash)` was the old tail
|
|
642
|
-
// and would now stringify `undefined`.
|
|
643
|
-
updateId: receipt.updateId ?? receipt.commandId ?? cmdId,
|
|
644
|
-
completionOffset: 0
|
|
645
|
-
}
|
|
646
|
-
});
|
|
647
|
-
} catch (submitErr) {
|
|
648
|
-
pendingEmitted.delete(cmdId);
|
|
649
|
-
eventBus.emit(core.CIP0103_EVENTS.TX_CHANGED, {
|
|
650
|
-
status: "failed",
|
|
651
|
-
commandId: cmdId
|
|
652
|
-
});
|
|
653
|
-
throw submitErr;
|
|
628
|
+
const current = await client.getActiveSession();
|
|
629
|
+
if (!current || current.sessionId !== session.sessionId || current.partyId !== session.partyId || current.network !== session.network) {
|
|
630
|
+
throw disconnected("Wallet session changed before submission");
|
|
654
631
|
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
632
|
+
submitting = true;
|
|
633
|
+
const receipt = await client.submitTransaction({ signedTx });
|
|
634
|
+
const event = executedEvent(receipt, cmdId);
|
|
635
|
+
if (event) eventBus.emit(core.CIP0103_EVENTS.TX_CHANGED, event);
|
|
636
|
+
} catch (reason) {
|
|
637
|
+
const code = reason?.code;
|
|
638
|
+
if (!submitting || code === 4001 || code === "USER_REJECTED" || code === -32003) {
|
|
639
|
+
eventBus.emit(core.CIP0103_EVENTS.TX_CHANGED, { status: "failed", commandId: cmdId });
|
|
662
640
|
}
|
|
663
|
-
throw
|
|
641
|
+
throw reason;
|
|
642
|
+
} finally {
|
|
643
|
+
pendingEmitted.delete(cmdId);
|
|
664
644
|
}
|
|
665
645
|
return void 0;
|
|
666
646
|
}
|
|
@@ -735,59 +715,51 @@ function wireEvents(client, eventBus, pendingEmitted) {
|
|
|
735
715
|
});
|
|
736
716
|
});
|
|
737
717
|
client.on("tx:status", (event) => {
|
|
738
|
-
const e = event;
|
|
739
|
-
if (!e
|
|
740
|
-
const
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
committed: "executed",
|
|
745
|
-
rejected: "failed",
|
|
746
|
-
failed: "failed"
|
|
747
|
-
};
|
|
748
|
-
const mappedStatus = statusMap[e.status] ?? "pending";
|
|
749
|
-
const commandId = String(e.txId);
|
|
750
|
-
if (mappedStatus === "pending" && pendingEmitted.has(commandId)) {
|
|
751
|
-
return;
|
|
752
|
-
}
|
|
753
|
-
if (mappedStatus === "executed" || mappedStatus === "failed") {
|
|
754
|
-
pendingEmitted.delete(commandId);
|
|
755
|
-
}
|
|
718
|
+
const e = record(event);
|
|
719
|
+
if (!e) return;
|
|
720
|
+
const raw = record(e.raw);
|
|
721
|
+
const tx = record(raw?.tx) ?? raw;
|
|
722
|
+
const commandId = nonempty(tx?.commandId) ? tx.commandId : e.txId;
|
|
723
|
+
if (!nonempty(commandId)) return;
|
|
756
724
|
let txEvent;
|
|
757
|
-
switch (
|
|
725
|
+
switch (e.status) {
|
|
726
|
+
case "pending":
|
|
727
|
+
case "submitted":
|
|
728
|
+
if (pendingEmitted.has(commandId)) return;
|
|
729
|
+
txEvent = { status: "pending", commandId };
|
|
730
|
+
break;
|
|
758
731
|
case "signed":
|
|
759
|
-
txEvent =
|
|
760
|
-
status: "signed",
|
|
761
|
-
commandId,
|
|
762
|
-
payload: {
|
|
763
|
-
signature: "",
|
|
764
|
-
signedBy: "",
|
|
765
|
-
party: ""
|
|
766
|
-
}
|
|
767
|
-
};
|
|
732
|
+
txEvent = signedEvent(tx, commandId);
|
|
768
733
|
break;
|
|
769
|
-
case "
|
|
770
|
-
|
|
771
|
-
txEvent = {
|
|
772
|
-
status: "executed",
|
|
773
|
-
commandId,
|
|
774
|
-
payload: {
|
|
775
|
-
updateId: raw?.updateId ?? raw?.commandId ?? commandId,
|
|
776
|
-
completionOffset: 0
|
|
777
|
-
}
|
|
778
|
-
};
|
|
734
|
+
case "committed":
|
|
735
|
+
txEvent = executedEvent(tx, commandId);
|
|
779
736
|
break;
|
|
780
|
-
|
|
737
|
+
case "rejected":
|
|
781
738
|
case "failed":
|
|
782
739
|
txEvent = { status: "failed", commandId };
|
|
783
740
|
break;
|
|
784
741
|
default:
|
|
785
|
-
|
|
786
|
-
break;
|
|
742
|
+
return;
|
|
787
743
|
}
|
|
788
|
-
eventBus.emit(core.CIP0103_EVENTS.TX_CHANGED, txEvent);
|
|
744
|
+
if (txEvent) eventBus.emit(core.CIP0103_EVENTS.TX_CHANGED, txEvent);
|
|
789
745
|
});
|
|
790
746
|
}
|
|
747
|
+
function record(value) {
|
|
748
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
749
|
+
}
|
|
750
|
+
function nonempty(value) {
|
|
751
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
752
|
+
}
|
|
753
|
+
function signedEvent(value, commandId) {
|
|
754
|
+
const tx = record(value);
|
|
755
|
+
const p = record(tx?.payload) ?? tx;
|
|
756
|
+
return nonempty(p?.signature) && nonempty(p?.signedBy) && nonempty(p?.party) ? { status: "signed", commandId, payload: { signature: p.signature, signedBy: p.signedBy, party: p.party } } : null;
|
|
757
|
+
}
|
|
758
|
+
function executedEvent(value, commandId) {
|
|
759
|
+
const tx = record(value);
|
|
760
|
+
const p = record(tx?.payload) ?? tx;
|
|
761
|
+
return nonempty(p?.updateId) && typeof p.completionOffset === "number" && Number.isSafeInteger(p.completionOffset) && p.completionOffset >= 0 ? { status: "executed", commandId, payload: { updateId: p.updateId, completionOffset: p.completionOffset } } : null;
|
|
762
|
+
}
|
|
791
763
|
function normalizeParams(params) {
|
|
792
764
|
if (!params) return {};
|
|
793
765
|
if (Array.isArray(params)) return params[0] ?? {};
|
|
@@ -819,11 +791,33 @@ function createExtensionChannelProvider(options = {}) {
|
|
|
819
791
|
const eventBus = new CIP0103EventBus();
|
|
820
792
|
const channelId = `pl-${++channelSeq}-${target ?? "ext"}`;
|
|
821
793
|
let requestSeq = 0;
|
|
794
|
+
let listening = false;
|
|
795
|
+
let destroyed = false;
|
|
796
|
+
const subscribedEvents = /* @__PURE__ */ new Set();
|
|
797
|
+
function listen() {
|
|
798
|
+
if (!listening && typeof window !== "undefined") {
|
|
799
|
+
window.addEventListener("message", onMessage);
|
|
800
|
+
listening = true;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
function detachIfIdle() {
|
|
804
|
+
if (pending.size > 0 || [...subscribedEvents].some((name) => eventBus.listenerCount(name) > 0)) return;
|
|
805
|
+
if (listening && typeof window !== "undefined") window.removeEventListener("message", onMessage);
|
|
806
|
+
listening = false;
|
|
807
|
+
}
|
|
822
808
|
const pending = /* @__PURE__ */ new Map();
|
|
823
809
|
function onMessage(event) {
|
|
824
810
|
if (event.source !== window) return;
|
|
825
811
|
const selfOrigin = typeof window !== "undefined" ? window.location?.origin : void 0;
|
|
826
812
|
if (selfOrigin && selfOrigin !== "null" && event.origin !== selfOrigin) return;
|
|
813
|
+
const notification = event.data;
|
|
814
|
+
if (notification?.type === SPLICE_WALLET_REQUEST && notification.request?.jsonrpc === "2.0" && notification.request.id == null && (!target || notification.target === target)) {
|
|
815
|
+
const method = notification.request.method;
|
|
816
|
+
if (method && ["statusChanged", "accountsChanged", "txChanged", "connected"].includes(method)) {
|
|
817
|
+
eventBus.emit(method, notification.request.params);
|
|
818
|
+
}
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
827
821
|
const data = event.data;
|
|
828
822
|
if (!data || data.type !== SPLICE_WALLET_RESPONSE || !data.response) return;
|
|
829
823
|
const { id, result, error } = data.response;
|
|
@@ -832,6 +826,7 @@ function createExtensionChannelProvider(options = {}) {
|
|
|
832
826
|
if (!entry) return;
|
|
833
827
|
pending.delete(String(id));
|
|
834
828
|
clearTimeout(entry.timer);
|
|
829
|
+
detachIfIdle();
|
|
835
830
|
if (error) {
|
|
836
831
|
entry.reject(
|
|
837
832
|
new ProviderRpcError(
|
|
@@ -844,24 +839,24 @@ function createExtensionChannelProvider(options = {}) {
|
|
|
844
839
|
entry.resolve(result);
|
|
845
840
|
}
|
|
846
841
|
}
|
|
847
|
-
if (typeof window !== "undefined") {
|
|
848
|
-
window.addEventListener("message", onMessage);
|
|
849
|
-
}
|
|
850
842
|
function postTargetOrigin() {
|
|
851
843
|
const origin = typeof window !== "undefined" ? window.location?.origin : void 0;
|
|
852
844
|
return origin && origin !== "null" ? origin : "*";
|
|
853
845
|
}
|
|
854
846
|
const provider = {
|
|
855
847
|
request(args) {
|
|
848
|
+
if (destroyed) return Promise.reject(new ProviderRpcError("Extension channel was destroyed", RPC_ERRORS.DISCONNECTED));
|
|
856
849
|
if (typeof window === "undefined") {
|
|
857
850
|
return Promise.reject(
|
|
858
851
|
new ProviderRpcError("No window: extension channel unavailable", JSON_RPC_ERRORS.INTERNAL_ERROR)
|
|
859
852
|
);
|
|
860
853
|
}
|
|
854
|
+
listen();
|
|
861
855
|
const id = `${channelId}-${++requestSeq}`;
|
|
862
856
|
return new Promise((resolve, reject) => {
|
|
863
857
|
const timer = setTimeout(() => {
|
|
864
858
|
pending.delete(id);
|
|
859
|
+
detachIfIdle();
|
|
865
860
|
reject(
|
|
866
861
|
new ProviderRpcError(
|
|
867
862
|
`Wallet request "${args.method}" timed out after ${timeoutMs}ms`,
|
|
@@ -880,11 +875,21 @@ function createExtensionChannelProvider(options = {}) {
|
|
|
880
875
|
},
|
|
881
876
|
...target ? { target } : {}
|
|
882
877
|
};
|
|
883
|
-
|
|
878
|
+
try {
|
|
879
|
+
window.postMessage(message, postTargetOrigin());
|
|
880
|
+
} catch (error) {
|
|
881
|
+
pending.delete(id);
|
|
882
|
+
clearTimeout(timer);
|
|
883
|
+
detachIfIdle();
|
|
884
|
+
reject(error);
|
|
885
|
+
}
|
|
884
886
|
});
|
|
885
887
|
},
|
|
886
888
|
on(event, listener) {
|
|
889
|
+
if (destroyed) return provider;
|
|
887
890
|
eventBus.on(event, listener);
|
|
891
|
+
subscribedEvents.add(event);
|
|
892
|
+
listen();
|
|
888
893
|
return provider;
|
|
889
894
|
},
|
|
890
895
|
emit(event, ...args) {
|
|
@@ -892,7 +897,20 @@ function createExtensionChannelProvider(options = {}) {
|
|
|
892
897
|
},
|
|
893
898
|
removeListener(event, listener) {
|
|
894
899
|
eventBus.removeListener(event, listener);
|
|
900
|
+
detachIfIdle();
|
|
895
901
|
return provider;
|
|
902
|
+
},
|
|
903
|
+
destroy() {
|
|
904
|
+
if (destroyed) return;
|
|
905
|
+
destroyed = true;
|
|
906
|
+
eventBus.removeAllListeners();
|
|
907
|
+
subscribedEvents.clear();
|
|
908
|
+
for (const entry of pending.values()) {
|
|
909
|
+
clearTimeout(entry.timer);
|
|
910
|
+
entry.reject(new ProviderRpcError("Extension channel was destroyed", RPC_ERRORS.DISCONNECTED));
|
|
911
|
+
}
|
|
912
|
+
pending.clear();
|
|
913
|
+
detachIfIdle();
|
|
896
914
|
}
|
|
897
915
|
};
|
|
898
916
|
eventBus.setOwner(provider);
|