@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/dist/index.mjs
CHANGED
|
@@ -513,7 +513,7 @@ var PartyLayerProvider = class {
|
|
|
513
513
|
};
|
|
514
514
|
|
|
515
515
|
// src/bridge.ts
|
|
516
|
-
var PROVIDER_VERSION = "0.
|
|
516
|
+
var PROVIDER_VERSION = "0.6.1" ;
|
|
517
517
|
function createProviderBridge(client) {
|
|
518
518
|
const eventBus = new CIP0103EventBus();
|
|
519
519
|
const pendingEmitted = /* @__PURE__ */ new Set();
|
|
@@ -578,9 +578,8 @@ async function handleRequest(client, args, eventBus, pendingEmitted) {
|
|
|
578
578
|
}
|
|
579
579
|
case "getActiveNetwork": {
|
|
580
580
|
const session = await client.getActiveSession();
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
);
|
|
581
|
+
if (!session) throw disconnected("No active session");
|
|
582
|
+
return toCAIP2Network(session.network);
|
|
584
583
|
}
|
|
585
584
|
case "listAccounts": {
|
|
586
585
|
const session = await client.getActiveSession();
|
|
@@ -605,55 +604,42 @@ async function handleRequest(client, args, eventBus, pendingEmitted) {
|
|
|
605
604
|
}
|
|
606
605
|
case "prepareExecute": {
|
|
607
606
|
const p = normalizeParams(params);
|
|
608
|
-
const
|
|
607
|
+
const session = await client.getActiveSession();
|
|
608
|
+
if (!session) throw disconnected("No active session");
|
|
609
|
+
const cmdId = nonempty(p.commandId) ? p.commandId : `cmd_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
610
|
+
if (pendingEmitted.has(cmdId)) throw resourceUnavailable("This commandId is already pending");
|
|
611
|
+
const payload = { ...p, commandId: cmdId };
|
|
609
612
|
pendingEmitted.add(cmdId);
|
|
610
|
-
eventBus.emit(CIP0103_EVENTS.TX_CHANGED, {
|
|
611
|
-
|
|
612
|
-
commandId: cmdId
|
|
613
|
-
});
|
|
613
|
+
eventBus.emit(CIP0103_EVENTS.TX_CHANGED, { status: "pending", commandId: cmdId });
|
|
614
|
+
let submitting = false;
|
|
614
615
|
try {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
commandId: cmdId,
|
|
621
|
-
payload: {
|
|
622
|
-
signature: String(signResult.transactionHash),
|
|
623
|
-
signedBy: partyId,
|
|
624
|
-
party: partyId
|
|
616
|
+
let signedTx = payload;
|
|
617
|
+
if (!session.capabilitiesSnapshot || session.capabilitiesSnapshot.includes("signTransaction")) {
|
|
618
|
+
const signed = await client.signTransaction({ tx: payload });
|
|
619
|
+
if (signed.partyId !== void 0 && signed.partyId !== session.partyId) {
|
|
620
|
+
throw disconnected("Wallet account changed during signing");
|
|
625
621
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
const
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
commandId: cmdId,
|
|
635
|
-
payload: {
|
|
636
|
-
updateId: receipt.updateId ?? receipt.commandId ?? String(receipt.transactionHash),
|
|
637
|
-
completionOffset: 0
|
|
638
|
-
}
|
|
639
|
-
});
|
|
640
|
-
} catch (submitErr) {
|
|
641
|
-
pendingEmitted.delete(cmdId);
|
|
642
|
-
eventBus.emit(CIP0103_EVENTS.TX_CHANGED, {
|
|
643
|
-
status: "failed",
|
|
644
|
-
commandId: cmdId
|
|
645
|
-
});
|
|
646
|
-
throw submitErr;
|
|
622
|
+
signedTx = signed.signedTx;
|
|
623
|
+
if (signedTx === void 0) throw new Error("Wallet returned no signed transaction");
|
|
624
|
+
const event2 = signedEvent({ signature: signed.signature, signedBy: signed.signedBy, party: signed.partyId }, cmdId);
|
|
625
|
+
if (event2) eventBus.emit(CIP0103_EVENTS.TX_CHANGED, event2);
|
|
626
|
+
}
|
|
627
|
+
const current = await client.getActiveSession();
|
|
628
|
+
if (!current || current.sessionId !== session.sessionId || current.partyId !== session.partyId || current.network !== session.network) {
|
|
629
|
+
throw disconnected("Wallet session changed before submission");
|
|
647
630
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
631
|
+
submitting = true;
|
|
632
|
+
const receipt = await client.submitTransaction({ signedTx });
|
|
633
|
+
const event = executedEvent(receipt, cmdId);
|
|
634
|
+
if (event) eventBus.emit(CIP0103_EVENTS.TX_CHANGED, event);
|
|
635
|
+
} catch (reason) {
|
|
636
|
+
const code = reason?.code;
|
|
637
|
+
if (!submitting || code === 4001 || code === "USER_REJECTED" || code === -32003) {
|
|
638
|
+
eventBus.emit(CIP0103_EVENTS.TX_CHANGED, { status: "failed", commandId: cmdId });
|
|
655
639
|
}
|
|
656
|
-
throw
|
|
640
|
+
throw reason;
|
|
641
|
+
} finally {
|
|
642
|
+
pendingEmitted.delete(cmdId);
|
|
657
643
|
}
|
|
658
644
|
return void 0;
|
|
659
645
|
}
|
|
@@ -728,59 +714,51 @@ function wireEvents(client, eventBus, pendingEmitted) {
|
|
|
728
714
|
});
|
|
729
715
|
});
|
|
730
716
|
client.on("tx:status", (event) => {
|
|
731
|
-
const e = event;
|
|
732
|
-
if (!e
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
committed: "executed",
|
|
738
|
-
rejected: "failed",
|
|
739
|
-
failed: "failed"
|
|
740
|
-
};
|
|
741
|
-
const mappedStatus = statusMap[e.status] ?? "pending";
|
|
742
|
-
const commandId = String(e.txId);
|
|
743
|
-
if (mappedStatus === "pending" && pendingEmitted.has(commandId)) {
|
|
744
|
-
return;
|
|
745
|
-
}
|
|
746
|
-
if (mappedStatus === "executed" || mappedStatus === "failed") {
|
|
747
|
-
pendingEmitted.delete(commandId);
|
|
748
|
-
}
|
|
717
|
+
const e = record(event);
|
|
718
|
+
if (!e) return;
|
|
719
|
+
const raw = record(e.raw);
|
|
720
|
+
const tx = record(raw?.tx) ?? raw;
|
|
721
|
+
const commandId = nonempty(tx?.commandId) ? tx.commandId : e.txId;
|
|
722
|
+
if (!nonempty(commandId)) return;
|
|
749
723
|
let txEvent;
|
|
750
|
-
switch (
|
|
724
|
+
switch (e.status) {
|
|
725
|
+
case "pending":
|
|
726
|
+
case "submitted":
|
|
727
|
+
if (pendingEmitted.has(commandId)) return;
|
|
728
|
+
txEvent = { status: "pending", commandId };
|
|
729
|
+
break;
|
|
751
730
|
case "signed":
|
|
752
|
-
txEvent =
|
|
753
|
-
status: "signed",
|
|
754
|
-
commandId,
|
|
755
|
-
payload: {
|
|
756
|
-
signature: "",
|
|
757
|
-
signedBy: "",
|
|
758
|
-
party: ""
|
|
759
|
-
}
|
|
760
|
-
};
|
|
731
|
+
txEvent = signedEvent(tx, commandId);
|
|
761
732
|
break;
|
|
762
|
-
case "
|
|
763
|
-
|
|
764
|
-
txEvent = {
|
|
765
|
-
status: "executed",
|
|
766
|
-
commandId,
|
|
767
|
-
payload: {
|
|
768
|
-
updateId: raw?.updateId ?? raw?.commandId ?? commandId,
|
|
769
|
-
completionOffset: 0
|
|
770
|
-
}
|
|
771
|
-
};
|
|
733
|
+
case "committed":
|
|
734
|
+
txEvent = executedEvent(tx, commandId);
|
|
772
735
|
break;
|
|
773
|
-
|
|
736
|
+
case "rejected":
|
|
774
737
|
case "failed":
|
|
775
738
|
txEvent = { status: "failed", commandId };
|
|
776
739
|
break;
|
|
777
740
|
default:
|
|
778
|
-
|
|
779
|
-
break;
|
|
741
|
+
return;
|
|
780
742
|
}
|
|
781
|
-
eventBus.emit(CIP0103_EVENTS.TX_CHANGED, txEvent);
|
|
743
|
+
if (txEvent) eventBus.emit(CIP0103_EVENTS.TX_CHANGED, txEvent);
|
|
782
744
|
});
|
|
783
745
|
}
|
|
746
|
+
function record(value) {
|
|
747
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
748
|
+
}
|
|
749
|
+
function nonempty(value) {
|
|
750
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
751
|
+
}
|
|
752
|
+
function signedEvent(value, commandId) {
|
|
753
|
+
const tx = record(value);
|
|
754
|
+
const p = record(tx?.payload) ?? tx;
|
|
755
|
+
return nonempty(p?.signature) && nonempty(p?.signedBy) && nonempty(p?.party) ? { status: "signed", commandId, payload: { signature: p.signature, signedBy: p.signedBy, party: p.party } } : null;
|
|
756
|
+
}
|
|
757
|
+
function executedEvent(value, commandId) {
|
|
758
|
+
const tx = record(value);
|
|
759
|
+
const p = record(tx?.payload) ?? tx;
|
|
760
|
+
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;
|
|
761
|
+
}
|
|
784
762
|
function normalizeParams(params) {
|
|
785
763
|
if (!params) return {};
|
|
786
764
|
if (Array.isArray(params)) return params[0] ?? {};
|
|
@@ -812,11 +790,33 @@ function createExtensionChannelProvider(options = {}) {
|
|
|
812
790
|
const eventBus = new CIP0103EventBus();
|
|
813
791
|
const channelId = `pl-${++channelSeq}-${target ?? "ext"}`;
|
|
814
792
|
let requestSeq = 0;
|
|
793
|
+
let listening = false;
|
|
794
|
+
let destroyed = false;
|
|
795
|
+
const subscribedEvents = /* @__PURE__ */ new Set();
|
|
796
|
+
function listen() {
|
|
797
|
+
if (!listening && typeof window !== "undefined") {
|
|
798
|
+
window.addEventListener("message", onMessage);
|
|
799
|
+
listening = true;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
function detachIfIdle() {
|
|
803
|
+
if (pending.size > 0 || [...subscribedEvents].some((name) => eventBus.listenerCount(name) > 0)) return;
|
|
804
|
+
if (listening && typeof window !== "undefined") window.removeEventListener("message", onMessage);
|
|
805
|
+
listening = false;
|
|
806
|
+
}
|
|
815
807
|
const pending = /* @__PURE__ */ new Map();
|
|
816
808
|
function onMessage(event) {
|
|
817
809
|
if (event.source !== window) return;
|
|
818
810
|
const selfOrigin = typeof window !== "undefined" ? window.location?.origin : void 0;
|
|
819
811
|
if (selfOrigin && selfOrigin !== "null" && event.origin !== selfOrigin) return;
|
|
812
|
+
const notification = event.data;
|
|
813
|
+
if (notification?.type === SPLICE_WALLET_REQUEST && notification.request?.jsonrpc === "2.0" && notification.request.id == null && (!target || notification.target === target)) {
|
|
814
|
+
const method = notification.request.method;
|
|
815
|
+
if (method && ["statusChanged", "accountsChanged", "txChanged", "connected"].includes(method)) {
|
|
816
|
+
eventBus.emit(method, notification.request.params);
|
|
817
|
+
}
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
820
|
const data = event.data;
|
|
821
821
|
if (!data || data.type !== SPLICE_WALLET_RESPONSE || !data.response) return;
|
|
822
822
|
const { id, result, error } = data.response;
|
|
@@ -825,6 +825,7 @@ function createExtensionChannelProvider(options = {}) {
|
|
|
825
825
|
if (!entry) return;
|
|
826
826
|
pending.delete(String(id));
|
|
827
827
|
clearTimeout(entry.timer);
|
|
828
|
+
detachIfIdle();
|
|
828
829
|
if (error) {
|
|
829
830
|
entry.reject(
|
|
830
831
|
new ProviderRpcError(
|
|
@@ -837,24 +838,24 @@ function createExtensionChannelProvider(options = {}) {
|
|
|
837
838
|
entry.resolve(result);
|
|
838
839
|
}
|
|
839
840
|
}
|
|
840
|
-
if (typeof window !== "undefined") {
|
|
841
|
-
window.addEventListener("message", onMessage);
|
|
842
|
-
}
|
|
843
841
|
function postTargetOrigin() {
|
|
844
842
|
const origin = typeof window !== "undefined" ? window.location?.origin : void 0;
|
|
845
843
|
return origin && origin !== "null" ? origin : "*";
|
|
846
844
|
}
|
|
847
845
|
const provider = {
|
|
848
846
|
request(args) {
|
|
847
|
+
if (destroyed) return Promise.reject(new ProviderRpcError("Extension channel was destroyed", RPC_ERRORS.DISCONNECTED));
|
|
849
848
|
if (typeof window === "undefined") {
|
|
850
849
|
return Promise.reject(
|
|
851
850
|
new ProviderRpcError("No window: extension channel unavailable", JSON_RPC_ERRORS.INTERNAL_ERROR)
|
|
852
851
|
);
|
|
853
852
|
}
|
|
853
|
+
listen();
|
|
854
854
|
const id = `${channelId}-${++requestSeq}`;
|
|
855
855
|
return new Promise((resolve, reject) => {
|
|
856
856
|
const timer = setTimeout(() => {
|
|
857
857
|
pending.delete(id);
|
|
858
|
+
detachIfIdle();
|
|
858
859
|
reject(
|
|
859
860
|
new ProviderRpcError(
|
|
860
861
|
`Wallet request "${args.method}" timed out after ${timeoutMs}ms`,
|
|
@@ -873,11 +874,21 @@ function createExtensionChannelProvider(options = {}) {
|
|
|
873
874
|
},
|
|
874
875
|
...target ? { target } : {}
|
|
875
876
|
};
|
|
876
|
-
|
|
877
|
+
try {
|
|
878
|
+
window.postMessage(message, postTargetOrigin());
|
|
879
|
+
} catch (error) {
|
|
880
|
+
pending.delete(id);
|
|
881
|
+
clearTimeout(timer);
|
|
882
|
+
detachIfIdle();
|
|
883
|
+
reject(error);
|
|
884
|
+
}
|
|
877
885
|
});
|
|
878
886
|
},
|
|
879
887
|
on(event, listener) {
|
|
888
|
+
if (destroyed) return provider;
|
|
880
889
|
eventBus.on(event, listener);
|
|
890
|
+
subscribedEvents.add(event);
|
|
891
|
+
listen();
|
|
881
892
|
return provider;
|
|
882
893
|
},
|
|
883
894
|
emit(event, ...args) {
|
|
@@ -885,7 +896,20 @@ function createExtensionChannelProvider(options = {}) {
|
|
|
885
896
|
},
|
|
886
897
|
removeListener(event, listener) {
|
|
887
898
|
eventBus.removeListener(event, listener);
|
|
899
|
+
detachIfIdle();
|
|
888
900
|
return provider;
|
|
901
|
+
},
|
|
902
|
+
destroy() {
|
|
903
|
+
if (destroyed) return;
|
|
904
|
+
destroyed = true;
|
|
905
|
+
eventBus.removeAllListeners();
|
|
906
|
+
subscribedEvents.clear();
|
|
907
|
+
for (const entry of pending.values()) {
|
|
908
|
+
clearTimeout(entry.timer);
|
|
909
|
+
entry.reject(new ProviderRpcError("Extension channel was destroyed", RPC_ERRORS.DISCONNECTED));
|
|
910
|
+
}
|
|
911
|
+
pending.clear();
|
|
912
|
+
detachIfIdle();
|
|
889
913
|
}
|
|
890
914
|
};
|
|
891
915
|
eventBus.setOwner(provider);
|