@partylayer/provider 0.2.6 → 0.3.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/dist/index.d.mts CHANGED
@@ -97,6 +97,40 @@ interface AnnounceDiscoveryOptions {
97
97
  * Announce replies are deduped by id within a single call.
98
98
  */
99
99
  declare function discoverAnnouncedProviders(options?: AnnounceDiscoveryOptions): Promise<DiscoveredProvider[]>;
100
+ /** Options for {@link subscribeAnnouncedProviders}. */
101
+ interface AnnounceSubscribeOptions {
102
+ /** Build a CIP-0103 provider from an announce. Defaults to the channel provider. */
103
+ createProvider?: (announced: AnnouncedWallet) => CIP0103Provider | Promise<CIP0103Provider>;
104
+ /** Dispatch `canton:requestProvider` on subscribe to elicit replies (default true). */
105
+ requestOnSubscribe?: boolean;
106
+ }
107
+ /**
108
+ * PERSISTENT (EIP-6963-style) announce subscription. Mounts a `window` listener
109
+ * for `canton:announceProvider` that stays up until the returned unsubscribe runs.
110
+ * Unlike {@link discoverAnnouncedProviders} (a one-shot snapshot that stops
111
+ * listening after `timeoutMs`), this captures announces that arrive AT ANY TIME —
112
+ * both LATE (slow/late extension injection, after the request window) and announces
113
+ * fired on inject BEFORE this subscription. Dispatches `canton:requestProvider`
114
+ * once on subscribe (unless disabled) to elicit replies. Calls `onProvider` once
115
+ * per newly-announced id (deduped) whose provider builds + passes the CIP-0103
116
+ * shape check.
117
+ *
118
+ * The caller MUST call the returned unsubscribe to remove the listener (no leak).
119
+ */
120
+ declare function subscribeAnnouncedProviders(onProvider: (provider: DiscoveredProvider) => void, options?: AnnounceSubscribeOptions): () => void;
121
+ /** Options for {@link waitForAnnouncedProvider}. */
122
+ interface WaitForAnnouncedOptions extends AnnounceSubscribeOptions {
123
+ /** Max wait before resolving null (default 3000ms). Resolves EARLY on a match. */
124
+ timeoutMs?: number;
125
+ }
126
+ /**
127
+ * Resolve the FIRST announced provider matching `predicate` the MOMENT it arrives,
128
+ * or `null` after `timeoutMs`. Built on {@link subscribeAnnouncedProviders}, so a
129
+ * LATE announce within the bound is captured (vs a fixed window that returns its
130
+ * snapshot at a fixed time and misses anything later). Auto-unsubscribes on
131
+ * resolve/timeout — no lingering listener.
132
+ */
133
+ declare function waitForAnnouncedProvider(predicate: (provider: DiscoveredProvider) => boolean, options?: WaitForAnnouncedOptions): Promise<DiscoveredProvider | null>;
100
134
  /**
101
135
  * Discover ALL CIP-0103 wallets: the synchronous `window.canton` scan PLUS the
102
136
  * `canton:announceProvider` handshake, MERGED and deduped by stable provider id.
@@ -229,7 +263,7 @@ interface BridgeableClient {
229
263
  ledgerApi?(params: {
230
264
  requestMethod: string;
231
265
  resource: string;
232
- body?: string;
266
+ body?: string | Record<string, unknown>;
233
267
  }): Promise<{
234
268
  response: string;
235
269
  }>;
@@ -455,4 +489,4 @@ declare class MethodRouter {
455
489
  private registerDefaults;
456
490
  }
457
491
 
458
- export { type AnnounceDiscoveryOptions, 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, chainDisconnected, createExtensionChannelProvider, createProviderBridge, disconnected, discoverAnnouncedProviders, discoverInjectedProviders, discoverProviders, handleAsyncConnect, handleAsyncPrepareExecute, internalError, invalidParams, isCIP0103Provider, methodNotFound, resourceNotFound, resourceUnavailable, toPartyLayerError, toProviderRpcError, transactionRejected, unauthorized, unsupportedMethod, userRejected, waitForProvider };
492
+ 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 };
package/dist/index.d.ts CHANGED
@@ -97,6 +97,40 @@ interface AnnounceDiscoveryOptions {
97
97
  * Announce replies are deduped by id within a single call.
98
98
  */
99
99
  declare function discoverAnnouncedProviders(options?: AnnounceDiscoveryOptions): Promise<DiscoveredProvider[]>;
100
+ /** Options for {@link subscribeAnnouncedProviders}. */
101
+ interface AnnounceSubscribeOptions {
102
+ /** Build a CIP-0103 provider from an announce. Defaults to the channel provider. */
103
+ createProvider?: (announced: AnnouncedWallet) => CIP0103Provider | Promise<CIP0103Provider>;
104
+ /** Dispatch `canton:requestProvider` on subscribe to elicit replies (default true). */
105
+ requestOnSubscribe?: boolean;
106
+ }
107
+ /**
108
+ * PERSISTENT (EIP-6963-style) announce subscription. Mounts a `window` listener
109
+ * for `canton:announceProvider` that stays up until the returned unsubscribe runs.
110
+ * Unlike {@link discoverAnnouncedProviders} (a one-shot snapshot that stops
111
+ * listening after `timeoutMs`), this captures announces that arrive AT ANY TIME —
112
+ * both LATE (slow/late extension injection, after the request window) and announces
113
+ * fired on inject BEFORE this subscription. Dispatches `canton:requestProvider`
114
+ * once on subscribe (unless disabled) to elicit replies. Calls `onProvider` once
115
+ * per newly-announced id (deduped) whose provider builds + passes the CIP-0103
116
+ * shape check.
117
+ *
118
+ * The caller MUST call the returned unsubscribe to remove the listener (no leak).
119
+ */
120
+ declare function subscribeAnnouncedProviders(onProvider: (provider: DiscoveredProvider) => void, options?: AnnounceSubscribeOptions): () => void;
121
+ /** Options for {@link waitForAnnouncedProvider}. */
122
+ interface WaitForAnnouncedOptions extends AnnounceSubscribeOptions {
123
+ /** Max wait before resolving null (default 3000ms). Resolves EARLY on a match. */
124
+ timeoutMs?: number;
125
+ }
126
+ /**
127
+ * Resolve the FIRST announced provider matching `predicate` the MOMENT it arrives,
128
+ * or `null` after `timeoutMs`. Built on {@link subscribeAnnouncedProviders}, so a
129
+ * LATE announce within the bound is captured (vs a fixed window that returns its
130
+ * snapshot at a fixed time and misses anything later). Auto-unsubscribes on
131
+ * resolve/timeout — no lingering listener.
132
+ */
133
+ declare function waitForAnnouncedProvider(predicate: (provider: DiscoveredProvider) => boolean, options?: WaitForAnnouncedOptions): Promise<DiscoveredProvider | null>;
100
134
  /**
101
135
  * Discover ALL CIP-0103 wallets: the synchronous `window.canton` scan PLUS the
102
136
  * `canton:announceProvider` handshake, MERGED and deduped by stable provider id.
@@ -229,7 +263,7 @@ interface BridgeableClient {
229
263
  ledgerApi?(params: {
230
264
  requestMethod: string;
231
265
  resource: string;
232
- body?: string;
266
+ body?: string | Record<string, unknown>;
233
267
  }): Promise<{
234
268
  response: string;
235
269
  }>;
@@ -455,4 +489,4 @@ declare class MethodRouter {
455
489
  private registerDefaults;
456
490
  }
457
491
 
458
- export { type AnnounceDiscoveryOptions, 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, chainDisconnected, createExtensionChannelProvider, createProviderBridge, disconnected, discoverAnnouncedProviders, discoverInjectedProviders, discoverProviders, handleAsyncConnect, handleAsyncPrepareExecute, internalError, invalidParams, isCIP0103Provider, methodNotFound, resourceNotFound, resourceUnavailable, toPartyLayerError, toProviderRpcError, transactionRejected, unauthorized, unsupportedMethod, userRejected, waitForProvider };
492
+ 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 };
package/dist/index.js CHANGED
@@ -509,7 +509,7 @@ var PartyLayerProvider = class {
509
509
  };
510
510
 
511
511
  // src/bridge.ts
512
- var PROVIDER_VERSION = "0.2.6" ;
512
+ var PROVIDER_VERSION = "0.3.1" ;
513
513
  function createProviderBridge(client) {
514
514
  const eventBus = new CIP0103EventBus();
515
515
  const pendingEmitted = /* @__PURE__ */ new Set();
@@ -659,9 +659,13 @@ async function handleRequest(client, args, eventBus, pendingEmitted) {
659
659
  }
660
660
  const p = normalizeParams(params);
661
661
  const result = await client.ledgerApi({
662
- requestMethod: String(p.requestMethod ?? "GET"),
662
+ // Forward the verb case AND the body type (string OR object) UNCHANGED;
663
+ // the active wallet's adapter normalizes to its required shape
664
+ // (lower+object for CIP-0103, string for Loop/Bron). Do NOT String()
665
+ // the body — that would turn an object into "[object Object]".
666
+ requestMethod: String(p.requestMethod ?? "get"),
663
667
  resource: String(p.resource ?? ""),
664
- body: p.body ? String(p.body) : void 0
668
+ body: p.body ?? void 0
665
669
  });
666
670
  return result;
667
671
  }
@@ -1006,6 +1010,70 @@ async function discoverAnnouncedProviders(options = {}) {
1006
1010
  }
1007
1011
  return results;
1008
1012
  }
1013
+ function subscribeAnnouncedProviders(onProvider, options = {}) {
1014
+ if (typeof window === "undefined") return () => {
1015
+ };
1016
+ const make = options.createProvider ?? defaultAnnounceProvider;
1017
+ const seen = /* @__PURE__ */ new Set();
1018
+ const onAnnounce = (event) => {
1019
+ const detail = event.detail;
1020
+ if (!detail) return;
1021
+ const rawId = detail.providerId ?? detail.id;
1022
+ if (typeof rawId !== "string" || rawId.length === 0) return;
1023
+ if (seen.has(rawId)) return;
1024
+ seen.add(rawId);
1025
+ const wallet = {
1026
+ id: rawId,
1027
+ name: typeof detail.name === "string" ? detail.name : void 0,
1028
+ icon: typeof detail.icon === "string" ? detail.icon : void 0,
1029
+ target: typeof detail.target === "string" ? detail.target : void 0
1030
+ };
1031
+ void Promise.resolve().then(() => make(wallet)).then((provider) => {
1032
+ if (!isCIP0103Provider(provider)) return;
1033
+ onProvider({
1034
+ id: wallet.id,
1035
+ provider,
1036
+ source: "injected",
1037
+ name: wallet.name,
1038
+ icon: wallet.icon
1039
+ });
1040
+ }).catch(() => {
1041
+ });
1042
+ };
1043
+ window.addEventListener(
1044
+ CANTON_ANNOUNCE_PROVIDER_EVENT,
1045
+ onAnnounce
1046
+ );
1047
+ if (options.requestOnSubscribe !== false) {
1048
+ window.dispatchEvent(new CustomEvent(CANTON_REQUEST_PROVIDER_EVENT));
1049
+ }
1050
+ return () => window.removeEventListener(
1051
+ CANTON_ANNOUNCE_PROVIDER_EVENT,
1052
+ onAnnounce
1053
+ );
1054
+ }
1055
+ function waitForAnnouncedProvider(predicate, options = {}) {
1056
+ if (typeof window === "undefined") return Promise.resolve(null);
1057
+ const timeoutMs = options.timeoutMs ?? 3e3;
1058
+ return new Promise((resolve) => {
1059
+ const h = {
1060
+ done: false,
1061
+ unsubscribe: () => {
1062
+ }
1063
+ };
1064
+ const finish = (value) => {
1065
+ if (h.done) return;
1066
+ h.done = true;
1067
+ if (h.timer) clearTimeout(h.timer);
1068
+ h.unsubscribe();
1069
+ resolve(value);
1070
+ };
1071
+ h.unsubscribe = subscribeAnnouncedProviders((p) => {
1072
+ if (predicate(p)) finish(p);
1073
+ }, { createProvider: options.createProvider, requestOnSubscribe: options.requestOnSubscribe });
1074
+ h.timer = setTimeout(() => finish(null), timeoutMs);
1075
+ });
1076
+ }
1009
1077
  var INJECTED_ID_PROBE_TIMEOUT_MS = 1500;
1010
1078
  function raceTimeout(promise, ms) {
1011
1079
  return Promise.race([
@@ -1098,12 +1166,14 @@ exports.isCIP0103Provider = isCIP0103Provider;
1098
1166
  exports.methodNotFound = methodNotFound;
1099
1167
  exports.resourceNotFound = resourceNotFound;
1100
1168
  exports.resourceUnavailable = resourceUnavailable;
1169
+ exports.subscribeAnnouncedProviders = subscribeAnnouncedProviders;
1101
1170
  exports.toPartyLayerError = toPartyLayerError;
1102
1171
  exports.toProviderRpcError = toProviderRpcError;
1103
1172
  exports.transactionRejected = transactionRejected;
1104
1173
  exports.unauthorized = unauthorized;
1105
1174
  exports.unsupportedMethod = unsupportedMethod;
1106
1175
  exports.userRejected = userRejected;
1176
+ exports.waitForAnnouncedProvider = waitForAnnouncedProvider;
1107
1177
  exports.waitForProvider = waitForProvider;
1108
1178
  //# sourceMappingURL=index.js.map
1109
1179
  //# sourceMappingURL=index.js.map