@partylayer/provider 0.5.2 → 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 +12 -4
- package/dist/index.d.ts +12 -4
- package/dist/index.js +118 -94
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +118 -94
- 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
|
@@ -255,17 +255,21 @@ interface BridgeableClient {
|
|
|
255
255
|
signTransaction(params: {
|
|
256
256
|
tx: unknown;
|
|
257
257
|
}): Promise<{
|
|
258
|
-
transactionHash
|
|
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;
|
|
264
267
|
}): Promise<{
|
|
265
|
-
transactionHash
|
|
268
|
+
transactionHash?: unknown;
|
|
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
|
@@ -255,17 +255,21 @@ interface BridgeableClient {
|
|
|
255
255
|
signTransaction(params: {
|
|
256
256
|
tx: unknown;
|
|
257
257
|
}): Promise<{
|
|
258
|
-
transactionHash
|
|
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;
|
|
264
267
|
}): Promise<{
|
|
265
|
-
transactionHash
|
|
268
|
+
transactionHash?: unknown;
|
|
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.
|
|
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,55 +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
|
-
commandId: cmdId,
|
|
622
|
-
payload: {
|
|
623
|
-
signature: String(signResult.transactionHash),
|
|
624
|
-
signedBy: partyId,
|
|
625
|
-
party: partyId
|
|
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");
|
|
626
622
|
}
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
const
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
commandId: cmdId,
|
|
636
|
-
payload: {
|
|
637
|
-
updateId: receipt.updateId ?? receipt.commandId ?? String(receipt.transactionHash),
|
|
638
|
-
completionOffset: 0
|
|
639
|
-
}
|
|
640
|
-
});
|
|
641
|
-
} catch (submitErr) {
|
|
642
|
-
pendingEmitted.delete(cmdId);
|
|
643
|
-
eventBus.emit(core.CIP0103_EVENTS.TX_CHANGED, {
|
|
644
|
-
status: "failed",
|
|
645
|
-
commandId: cmdId
|
|
646
|
-
});
|
|
647
|
-
throw submitErr;
|
|
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);
|
|
627
|
+
}
|
|
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");
|
|
648
631
|
}
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
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 });
|
|
656
640
|
}
|
|
657
|
-
throw
|
|
641
|
+
throw reason;
|
|
642
|
+
} finally {
|
|
643
|
+
pendingEmitted.delete(cmdId);
|
|
658
644
|
}
|
|
659
645
|
return void 0;
|
|
660
646
|
}
|
|
@@ -729,59 +715,51 @@ function wireEvents(client, eventBus, pendingEmitted) {
|
|
|
729
715
|
});
|
|
730
716
|
});
|
|
731
717
|
client.on("tx:status", (event) => {
|
|
732
|
-
const e = event;
|
|
733
|
-
if (!e
|
|
734
|
-
const
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
committed: "executed",
|
|
739
|
-
rejected: "failed",
|
|
740
|
-
failed: "failed"
|
|
741
|
-
};
|
|
742
|
-
const mappedStatus = statusMap[e.status] ?? "pending";
|
|
743
|
-
const commandId = String(e.txId);
|
|
744
|
-
if (mappedStatus === "pending" && pendingEmitted.has(commandId)) {
|
|
745
|
-
return;
|
|
746
|
-
}
|
|
747
|
-
if (mappedStatus === "executed" || mappedStatus === "failed") {
|
|
748
|
-
pendingEmitted.delete(commandId);
|
|
749
|
-
}
|
|
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;
|
|
750
724
|
let txEvent;
|
|
751
|
-
switch (
|
|
725
|
+
switch (e.status) {
|
|
726
|
+
case "pending":
|
|
727
|
+
case "submitted":
|
|
728
|
+
if (pendingEmitted.has(commandId)) return;
|
|
729
|
+
txEvent = { status: "pending", commandId };
|
|
730
|
+
break;
|
|
752
731
|
case "signed":
|
|
753
|
-
txEvent =
|
|
754
|
-
status: "signed",
|
|
755
|
-
commandId,
|
|
756
|
-
payload: {
|
|
757
|
-
signature: "",
|
|
758
|
-
signedBy: "",
|
|
759
|
-
party: ""
|
|
760
|
-
}
|
|
761
|
-
};
|
|
732
|
+
txEvent = signedEvent(tx, commandId);
|
|
762
733
|
break;
|
|
763
|
-
case "
|
|
764
|
-
|
|
765
|
-
txEvent = {
|
|
766
|
-
status: "executed",
|
|
767
|
-
commandId,
|
|
768
|
-
payload: {
|
|
769
|
-
updateId: raw?.updateId ?? raw?.commandId ?? commandId,
|
|
770
|
-
completionOffset: 0
|
|
771
|
-
}
|
|
772
|
-
};
|
|
734
|
+
case "committed":
|
|
735
|
+
txEvent = executedEvent(tx, commandId);
|
|
773
736
|
break;
|
|
774
|
-
|
|
737
|
+
case "rejected":
|
|
775
738
|
case "failed":
|
|
776
739
|
txEvent = { status: "failed", commandId };
|
|
777
740
|
break;
|
|
778
741
|
default:
|
|
779
|
-
|
|
780
|
-
break;
|
|
742
|
+
return;
|
|
781
743
|
}
|
|
782
|
-
eventBus.emit(core.CIP0103_EVENTS.TX_CHANGED, txEvent);
|
|
744
|
+
if (txEvent) eventBus.emit(core.CIP0103_EVENTS.TX_CHANGED, txEvent);
|
|
783
745
|
});
|
|
784
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
|
+
}
|
|
785
763
|
function normalizeParams(params) {
|
|
786
764
|
if (!params) return {};
|
|
787
765
|
if (Array.isArray(params)) return params[0] ?? {};
|
|
@@ -813,11 +791,33 @@ function createExtensionChannelProvider(options = {}) {
|
|
|
813
791
|
const eventBus = new CIP0103EventBus();
|
|
814
792
|
const channelId = `pl-${++channelSeq}-${target ?? "ext"}`;
|
|
815
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
|
+
}
|
|
816
808
|
const pending = /* @__PURE__ */ new Map();
|
|
817
809
|
function onMessage(event) {
|
|
818
810
|
if (event.source !== window) return;
|
|
819
811
|
const selfOrigin = typeof window !== "undefined" ? window.location?.origin : void 0;
|
|
820
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
|
+
}
|
|
821
821
|
const data = event.data;
|
|
822
822
|
if (!data || data.type !== SPLICE_WALLET_RESPONSE || !data.response) return;
|
|
823
823
|
const { id, result, error } = data.response;
|
|
@@ -826,6 +826,7 @@ function createExtensionChannelProvider(options = {}) {
|
|
|
826
826
|
if (!entry) return;
|
|
827
827
|
pending.delete(String(id));
|
|
828
828
|
clearTimeout(entry.timer);
|
|
829
|
+
detachIfIdle();
|
|
829
830
|
if (error) {
|
|
830
831
|
entry.reject(
|
|
831
832
|
new ProviderRpcError(
|
|
@@ -838,24 +839,24 @@ function createExtensionChannelProvider(options = {}) {
|
|
|
838
839
|
entry.resolve(result);
|
|
839
840
|
}
|
|
840
841
|
}
|
|
841
|
-
if (typeof window !== "undefined") {
|
|
842
|
-
window.addEventListener("message", onMessage);
|
|
843
|
-
}
|
|
844
842
|
function postTargetOrigin() {
|
|
845
843
|
const origin = typeof window !== "undefined" ? window.location?.origin : void 0;
|
|
846
844
|
return origin && origin !== "null" ? origin : "*";
|
|
847
845
|
}
|
|
848
846
|
const provider = {
|
|
849
847
|
request(args) {
|
|
848
|
+
if (destroyed) return Promise.reject(new ProviderRpcError("Extension channel was destroyed", RPC_ERRORS.DISCONNECTED));
|
|
850
849
|
if (typeof window === "undefined") {
|
|
851
850
|
return Promise.reject(
|
|
852
851
|
new ProviderRpcError("No window: extension channel unavailable", JSON_RPC_ERRORS.INTERNAL_ERROR)
|
|
853
852
|
);
|
|
854
853
|
}
|
|
854
|
+
listen();
|
|
855
855
|
const id = `${channelId}-${++requestSeq}`;
|
|
856
856
|
return new Promise((resolve, reject) => {
|
|
857
857
|
const timer = setTimeout(() => {
|
|
858
858
|
pending.delete(id);
|
|
859
|
+
detachIfIdle();
|
|
859
860
|
reject(
|
|
860
861
|
new ProviderRpcError(
|
|
861
862
|
`Wallet request "${args.method}" timed out after ${timeoutMs}ms`,
|
|
@@ -874,11 +875,21 @@ function createExtensionChannelProvider(options = {}) {
|
|
|
874
875
|
},
|
|
875
876
|
...target ? { target } : {}
|
|
876
877
|
};
|
|
877
|
-
|
|
878
|
+
try {
|
|
879
|
+
window.postMessage(message, postTargetOrigin());
|
|
880
|
+
} catch (error) {
|
|
881
|
+
pending.delete(id);
|
|
882
|
+
clearTimeout(timer);
|
|
883
|
+
detachIfIdle();
|
|
884
|
+
reject(error);
|
|
885
|
+
}
|
|
878
886
|
});
|
|
879
887
|
},
|
|
880
888
|
on(event, listener) {
|
|
889
|
+
if (destroyed) return provider;
|
|
881
890
|
eventBus.on(event, listener);
|
|
891
|
+
subscribedEvents.add(event);
|
|
892
|
+
listen();
|
|
882
893
|
return provider;
|
|
883
894
|
},
|
|
884
895
|
emit(event, ...args) {
|
|
@@ -886,7 +897,20 @@ function createExtensionChannelProvider(options = {}) {
|
|
|
886
897
|
},
|
|
887
898
|
removeListener(event, listener) {
|
|
888
899
|
eventBus.removeListener(event, listener);
|
|
900
|
+
detachIfIdle();
|
|
889
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();
|
|
890
914
|
}
|
|
891
915
|
};
|
|
892
916
|
eventBus.setOwner(provider);
|