@partylayer/provider 0.1.7 → 0.2.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 +5 -2
- package/dist/index.d.mts +85 -34
- package/dist/index.d.ts +85 -34
- package/dist/index.js +213 -45
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +192 -39
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -42,12 +42,15 @@ npm install @partylayer/provider
|
|
|
42
42
|
```typescript
|
|
43
43
|
import { PartyLayerProvider, discoverProviders } from '@partylayer/provider';
|
|
44
44
|
|
|
45
|
-
// Discover
|
|
46
|
-
|
|
45
|
+
// Discover CIP-0103 wallets: the synchronous window.canton scan PLUS the
|
|
46
|
+
// canton:announceProvider handshake (async), merged + deduped by provider id.
|
|
47
|
+
const wallets = await discoverProviders();
|
|
47
48
|
|
|
48
49
|
// Create provider with first discovered wallet
|
|
49
50
|
const provider = new PartyLayerProvider({ walletProvider: wallets[0] });
|
|
50
51
|
|
|
52
|
+
// (For the synchronous window.canton-only scan, use discoverInjectedProviders().)
|
|
53
|
+
|
|
51
54
|
// Connect
|
|
52
55
|
const result = await provider.request({ method: 'connect' });
|
|
53
56
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CIP0103Provider, CIP0103RequestPayload, CIP0103EventListener, PartyLayerError, CIP0103ConnectResult, CIP0103TxChangedEvent,
|
|
2
|
-
export { CIP0103Account, CIP0103AccountStatus, CIP0103ConnectResult, CIP0103Event, CIP0103EventListener, CIP0103LedgerApiRequest, CIP0103LedgerApiResponse, CIP0103Method, CIP0103Network, CIP0103Provider, CIP0103ProviderInfo, CIP0103ProviderRpcError, CIP0103ProviderType, CIP0103RequestParams, CIP0103RequestPayload, CIP0103SignMessageRequest, CIP0103StatusEvent, CIP0103TxChangedEvent, CIP0103TxExecutedPayload, CIP0103TxFailedPayload, CIP0103TxPendingPayload, CIP0103TxSignedPayload, CIP0103TxStatus, CIP0103_EVENTS, CIP0103_MANDATORY_METHODS, CIP0103_METHODS } from '@partylayer/core';
|
|
1
|
+
import { CIP0103Provider, CIP0103RequestPayload, CIP0103EventListener, PartyLayerError, CIP0103ConnectResult, CIP0103TxChangedEvent, CIP0103RequestParams } from '@partylayer/core';
|
|
2
|
+
export { CANTON_NETWORKS, CIP0103Account, CIP0103AccountStatus, CIP0103ConnectResult, CIP0103Event, CIP0103EventListener, CIP0103LedgerApiRequest, CIP0103LedgerApiResponse, CIP0103Method, CIP0103Network, CIP0103Provider, CIP0103ProviderInfo, CIP0103ProviderRpcError, CIP0103ProviderType, CIP0103RequestParams, CIP0103RequestPayload, CIP0103SignMessageRequest, CIP0103StatusEvent, CIP0103TxChangedEvent, CIP0103TxExecutedPayload, CIP0103TxFailedPayload, CIP0103TxPendingPayload, CIP0103TxSignedPayload, CIP0103TxStatus, CIP0103_EVENTS, CIP0103_MANDATORY_METHODS, CIP0103_METHODS, fromCAIP2Network, isValidCAIP2, toCAIP2Network } from '@partylayer/core';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* CIP-0103 Wallet Discovery
|
|
@@ -21,6 +21,8 @@ interface DiscoveredProvider {
|
|
|
21
21
|
isAsync?: boolean;
|
|
22
22
|
/** Display name (if discoverable from status) */
|
|
23
23
|
name?: string;
|
|
24
|
+
/** Icon (data: URI or URL) — populated for announce-discovered wallets. */
|
|
25
|
+
icon?: string;
|
|
24
26
|
}
|
|
25
27
|
/**
|
|
26
28
|
* Check if an object implements the CIP-0103 Provider interface.
|
|
@@ -47,6 +49,54 @@ declare function discoverInjectedProviders(): DiscoveredProvider[];
|
|
|
47
49
|
* @param timeoutMs - Maximum wait time (default 3000ms)
|
|
48
50
|
*/
|
|
49
51
|
declare function waitForProvider(id: string, timeoutMs?: number): Promise<DiscoveredProvider | null>;
|
|
52
|
+
/** Metadata carried by a `canton:announceProvider` event. */
|
|
53
|
+
interface AnnouncedWallet {
|
|
54
|
+
/** Stable provider id (extension id), e.g. "ldmoh…" for Send. */
|
|
55
|
+
id: string;
|
|
56
|
+
/** Display name. */
|
|
57
|
+
name?: string;
|
|
58
|
+
/** Icon (data: URI or URL). */
|
|
59
|
+
icon?: string;
|
|
60
|
+
/** Routing key for the extension postMessage channel. */
|
|
61
|
+
target?: string;
|
|
62
|
+
}
|
|
63
|
+
interface AnnounceDiscoveryOptions {
|
|
64
|
+
/** How long to collect announce replies after the request (ms). Default 300. */
|
|
65
|
+
timeoutMs?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Build a CIP-0103 provider from an announced wallet. Defaults to the
|
|
68
|
+
* self-contained `createExtensionChannelProvider` (splice postMessage over
|
|
69
|
+
* the `target` channel). Injectable so apps can substitute the official
|
|
70
|
+
* `@canton-network/dapp-sdk` `ExtensionAdapter`, and tests a mock.
|
|
71
|
+
*/
|
|
72
|
+
createProvider?: (announced: AnnouncedWallet) => CIP0103Provider | Promise<CIP0103Provider>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Discover wallets that advertise via `canton:announceProvider` (EIP-6963-style).
|
|
76
|
+
*
|
|
77
|
+
* Works regardless of who owns `window.canton` — this is how Send (and
|
|
78
|
+
* Console-via-announce) are found. Each result is a working CIP-0103 provider.
|
|
79
|
+
* Announce replies are deduped by id within a single call.
|
|
80
|
+
*/
|
|
81
|
+
declare function discoverAnnouncedProviders(options?: AnnounceDiscoveryOptions): Promise<DiscoveredProvider[]>;
|
|
82
|
+
/**
|
|
83
|
+
* Discover ALL CIP-0103 wallets: the synchronous `window.canton` scan PLUS the
|
|
84
|
+
* `canton:announceProvider` handshake, MERGED and deduped by stable provider id.
|
|
85
|
+
*
|
|
86
|
+
* Dedup keys:
|
|
87
|
+
* - INJECTED entries: resolved via {@link resolveInjectedKey} (sync id →
|
|
88
|
+
* capped read-only status() probe → path id). Resolved in PARALLEL.
|
|
89
|
+
* - ANNOUNCE entries: their `d.id` (== announce id == target == the wallet's
|
|
90
|
+
* `provider.id`). NOT status-probed — an offline announce wallet (e.g. Send)
|
|
91
|
+
* would otherwise hang up to the channel timeout.
|
|
92
|
+
*
|
|
93
|
+
* INJECTED entries are processed FIRST so the direct `window.canton` provider
|
|
94
|
+
* wins over the announce postMessage shim for a wallet reachable both ways
|
|
95
|
+
* (e.g. Console announces AND owns `window.canton` → appears exactly once).
|
|
96
|
+
*
|
|
97
|
+
* Backward-compatible superset of `discoverInjectedProviders()` (left unchanged).
|
|
98
|
+
*/
|
|
99
|
+
declare function discoverProviders(options?: AnnounceDiscoveryOptions): Promise<DiscoveredProvider[]>;
|
|
50
100
|
|
|
51
101
|
/**
|
|
52
102
|
* PartyLayerProvider — CIP-0103 Native Provider Implementation
|
|
@@ -261,6 +311,38 @@ declare function toProviderRpcError(err: unknown): ProviderRpcError;
|
|
|
261
311
|
*/
|
|
262
312
|
declare function toPartyLayerError(err: ProviderRpcError): PartyLayerError;
|
|
263
313
|
|
|
314
|
+
/**
|
|
315
|
+
* Extension target-channel CIP-0103 provider.
|
|
316
|
+
*
|
|
317
|
+
* Builds a working CIP-0103 provider for a wallet discovered via
|
|
318
|
+
* `canton:announceProvider` (see discovery.ts). Announce wallets route requests
|
|
319
|
+
* over the splice-wallet postMessage protocol — the dApp posts a
|
|
320
|
+
* `SPLICE_WALLET_REQUEST` on `window` and the extension replies with a
|
|
321
|
+
* `SPLICE_WALLET_RESPONSE`, correlated by JSON-RPC id and routed by `target`.
|
|
322
|
+
*
|
|
323
|
+
* This is a self-contained, dependency-free implementation of that wire
|
|
324
|
+
* protocol. We deliberately do NOT depend on `@canton-network/dapp-sdk`'s
|
|
325
|
+
* `ExtensionAdapter`: its single bundled entry statically imports
|
|
326
|
+
* `@walletconnect/sign-client` (an optional peer used only by its
|
|
327
|
+
* WalletConnectAdapter), which is not installed and breaks every downstream
|
|
328
|
+
* webpack/Next build that pulls `@partylayer/provider` into its graph
|
|
329
|
+
* (confirmed against the live demo's `next build`). The protocol constants and
|
|
330
|
+
* message shapes below mirror `@canton-network/core-types` (`WalletEvent`,
|
|
331
|
+
* `SpliceMessage`) verbatim, so behaviour matches the official adapter.
|
|
332
|
+
*/
|
|
333
|
+
|
|
334
|
+
interface ExtensionChannelOptions {
|
|
335
|
+
/** Routing key (announce `target`) included on every request message. */
|
|
336
|
+
target?: string;
|
|
337
|
+
/** Per-request timeout in ms. Default 30000. */
|
|
338
|
+
timeoutMs?: number;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Create a CIP-0103 provider that talks the splice-wallet postMessage protocol
|
|
342
|
+
* over the page `window`, routed by `target`.
|
|
343
|
+
*/
|
|
344
|
+
declare function createExtensionChannelProvider(options?: ExtensionChannelOptions): CIP0103Provider;
|
|
345
|
+
|
|
264
346
|
/**
|
|
265
347
|
* Async Wallet Handling
|
|
266
348
|
*
|
|
@@ -302,37 +384,6 @@ declare function handleAsyncConnect(walletProvider: CIP0103Provider, connectResu
|
|
|
302
384
|
*/
|
|
303
385
|
declare function handleAsyncPrepareExecute(walletProvider: CIP0103Provider, commandId: string, userUrl: string | undefined, options?: AsyncPrepareExecuteOptions): Promise<CIP0103TxChangedEvent>;
|
|
304
386
|
|
|
305
|
-
/**
|
|
306
|
-
* CAIP-2 Network Identity Utilities
|
|
307
|
-
*
|
|
308
|
-
* All CIP-0103 network identifiers use CAIP-2 format: "namespace:reference"
|
|
309
|
-
* e.g. "canton:da-mainnet", "canton:da-devnet"
|
|
310
|
-
*
|
|
311
|
-
* Reference: https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-2.md
|
|
312
|
-
*/
|
|
313
|
-
|
|
314
|
-
declare const CANTON_NETWORKS: Record<string, string>;
|
|
315
|
-
/**
|
|
316
|
-
* Convert a legacy PartyLayer NetworkId (e.g. "devnet") or already-CAIP-2
|
|
317
|
-
* string to a CIP-0103 Network object.
|
|
318
|
-
*
|
|
319
|
-
* @throws {Error} if the resulting network ID is not valid CAIP-2
|
|
320
|
-
*/
|
|
321
|
-
declare function toCAIP2Network(networkId: string): CIP0103Network;
|
|
322
|
-
/**
|
|
323
|
-
* Extract the short network name from a CAIP-2 ID.
|
|
324
|
-
* Returns the original string if no reverse mapping exists.
|
|
325
|
-
*/
|
|
326
|
-
declare function fromCAIP2Network(caip2: string): string;
|
|
327
|
-
/**
|
|
328
|
-
* Validate that a string conforms to CAIP-2 format.
|
|
329
|
-
*
|
|
330
|
-
* CAIP-2 format: namespace:reference
|
|
331
|
-
* - namespace: [-a-z0-9]{3,8}
|
|
332
|
-
* - reference: [-_a-zA-Z0-9]{1,32}
|
|
333
|
-
*/
|
|
334
|
-
declare function isValidCAIP2(networkId: string): boolean;
|
|
335
|
-
|
|
336
387
|
/**
|
|
337
388
|
* CIP-0103 Event Bus
|
|
338
389
|
*
|
|
@@ -386,4 +437,4 @@ declare class MethodRouter {
|
|
|
386
437
|
private registerDefaults;
|
|
387
438
|
}
|
|
388
439
|
|
|
389
|
-
export { type AsyncConnectOptions, type AsyncPrepareExecuteOptions,
|
|
440
|
+
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CIP0103Provider, CIP0103RequestPayload, CIP0103EventListener, PartyLayerError, CIP0103ConnectResult, CIP0103TxChangedEvent,
|
|
2
|
-
export { CIP0103Account, CIP0103AccountStatus, CIP0103ConnectResult, CIP0103Event, CIP0103EventListener, CIP0103LedgerApiRequest, CIP0103LedgerApiResponse, CIP0103Method, CIP0103Network, CIP0103Provider, CIP0103ProviderInfo, CIP0103ProviderRpcError, CIP0103ProviderType, CIP0103RequestParams, CIP0103RequestPayload, CIP0103SignMessageRequest, CIP0103StatusEvent, CIP0103TxChangedEvent, CIP0103TxExecutedPayload, CIP0103TxFailedPayload, CIP0103TxPendingPayload, CIP0103TxSignedPayload, CIP0103TxStatus, CIP0103_EVENTS, CIP0103_MANDATORY_METHODS, CIP0103_METHODS } from '@partylayer/core';
|
|
1
|
+
import { CIP0103Provider, CIP0103RequestPayload, CIP0103EventListener, PartyLayerError, CIP0103ConnectResult, CIP0103TxChangedEvent, CIP0103RequestParams } from '@partylayer/core';
|
|
2
|
+
export { CANTON_NETWORKS, CIP0103Account, CIP0103AccountStatus, CIP0103ConnectResult, CIP0103Event, CIP0103EventListener, CIP0103LedgerApiRequest, CIP0103LedgerApiResponse, CIP0103Method, CIP0103Network, CIP0103Provider, CIP0103ProviderInfo, CIP0103ProviderRpcError, CIP0103ProviderType, CIP0103RequestParams, CIP0103RequestPayload, CIP0103SignMessageRequest, CIP0103StatusEvent, CIP0103TxChangedEvent, CIP0103TxExecutedPayload, CIP0103TxFailedPayload, CIP0103TxPendingPayload, CIP0103TxSignedPayload, CIP0103TxStatus, CIP0103_EVENTS, CIP0103_MANDATORY_METHODS, CIP0103_METHODS, fromCAIP2Network, isValidCAIP2, toCAIP2Network } from '@partylayer/core';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* CIP-0103 Wallet Discovery
|
|
@@ -21,6 +21,8 @@ interface DiscoveredProvider {
|
|
|
21
21
|
isAsync?: boolean;
|
|
22
22
|
/** Display name (if discoverable from status) */
|
|
23
23
|
name?: string;
|
|
24
|
+
/** Icon (data: URI or URL) — populated for announce-discovered wallets. */
|
|
25
|
+
icon?: string;
|
|
24
26
|
}
|
|
25
27
|
/**
|
|
26
28
|
* Check if an object implements the CIP-0103 Provider interface.
|
|
@@ -47,6 +49,54 @@ declare function discoverInjectedProviders(): DiscoveredProvider[];
|
|
|
47
49
|
* @param timeoutMs - Maximum wait time (default 3000ms)
|
|
48
50
|
*/
|
|
49
51
|
declare function waitForProvider(id: string, timeoutMs?: number): Promise<DiscoveredProvider | null>;
|
|
52
|
+
/** Metadata carried by a `canton:announceProvider` event. */
|
|
53
|
+
interface AnnouncedWallet {
|
|
54
|
+
/** Stable provider id (extension id), e.g. "ldmoh…" for Send. */
|
|
55
|
+
id: string;
|
|
56
|
+
/** Display name. */
|
|
57
|
+
name?: string;
|
|
58
|
+
/** Icon (data: URI or URL). */
|
|
59
|
+
icon?: string;
|
|
60
|
+
/** Routing key for the extension postMessage channel. */
|
|
61
|
+
target?: string;
|
|
62
|
+
}
|
|
63
|
+
interface AnnounceDiscoveryOptions {
|
|
64
|
+
/** How long to collect announce replies after the request (ms). Default 300. */
|
|
65
|
+
timeoutMs?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Build a CIP-0103 provider from an announced wallet. Defaults to the
|
|
68
|
+
* self-contained `createExtensionChannelProvider` (splice postMessage over
|
|
69
|
+
* the `target` channel). Injectable so apps can substitute the official
|
|
70
|
+
* `@canton-network/dapp-sdk` `ExtensionAdapter`, and tests a mock.
|
|
71
|
+
*/
|
|
72
|
+
createProvider?: (announced: AnnouncedWallet) => CIP0103Provider | Promise<CIP0103Provider>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Discover wallets that advertise via `canton:announceProvider` (EIP-6963-style).
|
|
76
|
+
*
|
|
77
|
+
* Works regardless of who owns `window.canton` — this is how Send (and
|
|
78
|
+
* Console-via-announce) are found. Each result is a working CIP-0103 provider.
|
|
79
|
+
* Announce replies are deduped by id within a single call.
|
|
80
|
+
*/
|
|
81
|
+
declare function discoverAnnouncedProviders(options?: AnnounceDiscoveryOptions): Promise<DiscoveredProvider[]>;
|
|
82
|
+
/**
|
|
83
|
+
* Discover ALL CIP-0103 wallets: the synchronous `window.canton` scan PLUS the
|
|
84
|
+
* `canton:announceProvider` handshake, MERGED and deduped by stable provider id.
|
|
85
|
+
*
|
|
86
|
+
* Dedup keys:
|
|
87
|
+
* - INJECTED entries: resolved via {@link resolveInjectedKey} (sync id →
|
|
88
|
+
* capped read-only status() probe → path id). Resolved in PARALLEL.
|
|
89
|
+
* - ANNOUNCE entries: their `d.id` (== announce id == target == the wallet's
|
|
90
|
+
* `provider.id`). NOT status-probed — an offline announce wallet (e.g. Send)
|
|
91
|
+
* would otherwise hang up to the channel timeout.
|
|
92
|
+
*
|
|
93
|
+
* INJECTED entries are processed FIRST so the direct `window.canton` provider
|
|
94
|
+
* wins over the announce postMessage shim for a wallet reachable both ways
|
|
95
|
+
* (e.g. Console announces AND owns `window.canton` → appears exactly once).
|
|
96
|
+
*
|
|
97
|
+
* Backward-compatible superset of `discoverInjectedProviders()` (left unchanged).
|
|
98
|
+
*/
|
|
99
|
+
declare function discoverProviders(options?: AnnounceDiscoveryOptions): Promise<DiscoveredProvider[]>;
|
|
50
100
|
|
|
51
101
|
/**
|
|
52
102
|
* PartyLayerProvider — CIP-0103 Native Provider Implementation
|
|
@@ -261,6 +311,38 @@ declare function toProviderRpcError(err: unknown): ProviderRpcError;
|
|
|
261
311
|
*/
|
|
262
312
|
declare function toPartyLayerError(err: ProviderRpcError): PartyLayerError;
|
|
263
313
|
|
|
314
|
+
/**
|
|
315
|
+
* Extension target-channel CIP-0103 provider.
|
|
316
|
+
*
|
|
317
|
+
* Builds a working CIP-0103 provider for a wallet discovered via
|
|
318
|
+
* `canton:announceProvider` (see discovery.ts). Announce wallets route requests
|
|
319
|
+
* over the splice-wallet postMessage protocol — the dApp posts a
|
|
320
|
+
* `SPLICE_WALLET_REQUEST` on `window` and the extension replies with a
|
|
321
|
+
* `SPLICE_WALLET_RESPONSE`, correlated by JSON-RPC id and routed by `target`.
|
|
322
|
+
*
|
|
323
|
+
* This is a self-contained, dependency-free implementation of that wire
|
|
324
|
+
* protocol. We deliberately do NOT depend on `@canton-network/dapp-sdk`'s
|
|
325
|
+
* `ExtensionAdapter`: its single bundled entry statically imports
|
|
326
|
+
* `@walletconnect/sign-client` (an optional peer used only by its
|
|
327
|
+
* WalletConnectAdapter), which is not installed and breaks every downstream
|
|
328
|
+
* webpack/Next build that pulls `@partylayer/provider` into its graph
|
|
329
|
+
* (confirmed against the live demo's `next build`). The protocol constants and
|
|
330
|
+
* message shapes below mirror `@canton-network/core-types` (`WalletEvent`,
|
|
331
|
+
* `SpliceMessage`) verbatim, so behaviour matches the official adapter.
|
|
332
|
+
*/
|
|
333
|
+
|
|
334
|
+
interface ExtensionChannelOptions {
|
|
335
|
+
/** Routing key (announce `target`) included on every request message. */
|
|
336
|
+
target?: string;
|
|
337
|
+
/** Per-request timeout in ms. Default 30000. */
|
|
338
|
+
timeoutMs?: number;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Create a CIP-0103 provider that talks the splice-wallet postMessage protocol
|
|
342
|
+
* over the page `window`, routed by `target`.
|
|
343
|
+
*/
|
|
344
|
+
declare function createExtensionChannelProvider(options?: ExtensionChannelOptions): CIP0103Provider;
|
|
345
|
+
|
|
264
346
|
/**
|
|
265
347
|
* Async Wallet Handling
|
|
266
348
|
*
|
|
@@ -302,37 +384,6 @@ declare function handleAsyncConnect(walletProvider: CIP0103Provider, connectResu
|
|
|
302
384
|
*/
|
|
303
385
|
declare function handleAsyncPrepareExecute(walletProvider: CIP0103Provider, commandId: string, userUrl: string | undefined, options?: AsyncPrepareExecuteOptions): Promise<CIP0103TxChangedEvent>;
|
|
304
386
|
|
|
305
|
-
/**
|
|
306
|
-
* CAIP-2 Network Identity Utilities
|
|
307
|
-
*
|
|
308
|
-
* All CIP-0103 network identifiers use CAIP-2 format: "namespace:reference"
|
|
309
|
-
* e.g. "canton:da-mainnet", "canton:da-devnet"
|
|
310
|
-
*
|
|
311
|
-
* Reference: https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-2.md
|
|
312
|
-
*/
|
|
313
|
-
|
|
314
|
-
declare const CANTON_NETWORKS: Record<string, string>;
|
|
315
|
-
/**
|
|
316
|
-
* Convert a legacy PartyLayer NetworkId (e.g. "devnet") or already-CAIP-2
|
|
317
|
-
* string to a CIP-0103 Network object.
|
|
318
|
-
*
|
|
319
|
-
* @throws {Error} if the resulting network ID is not valid CAIP-2
|
|
320
|
-
*/
|
|
321
|
-
declare function toCAIP2Network(networkId: string): CIP0103Network;
|
|
322
|
-
/**
|
|
323
|
-
* Extract the short network name from a CAIP-2 ID.
|
|
324
|
-
* Returns the original string if no reverse mapping exists.
|
|
325
|
-
*/
|
|
326
|
-
declare function fromCAIP2Network(caip2: string): string;
|
|
327
|
-
/**
|
|
328
|
-
* Validate that a string conforms to CAIP-2 format.
|
|
329
|
-
*
|
|
330
|
-
* CAIP-2 format: namespace:reference
|
|
331
|
-
* - namespace: [-a-z0-9]{3,8}
|
|
332
|
-
* - reference: [-_a-zA-Z0-9]{1,32}
|
|
333
|
-
*/
|
|
334
|
-
declare function isValidCAIP2(networkId: string): boolean;
|
|
335
|
-
|
|
336
387
|
/**
|
|
337
388
|
* CIP-0103 Event Bus
|
|
338
389
|
*
|
|
@@ -386,4 +437,4 @@ declare class MethodRouter {
|
|
|
386
437
|
private registerDefaults;
|
|
387
438
|
}
|
|
388
439
|
|
|
389
|
-
export { type AsyncConnectOptions, type AsyncPrepareExecuteOptions,
|
|
440
|
+
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 };
|
package/dist/index.js
CHANGED
|
@@ -165,6 +165,7 @@ var ERROR_CODE_TO_RPC = {
|
|
|
165
165
|
REGISTRY_VERIFICATION_FAILED: JSON_RPC_ERRORS.INTERNAL_ERROR,
|
|
166
166
|
REGISTRY_SCHEMA_INVALID: JSON_RPC_ERRORS.INTERNAL_ERROR,
|
|
167
167
|
INTERNAL_ERROR: JSON_RPC_ERRORS.INTERNAL_ERROR,
|
|
168
|
+
NETWORK_MISMATCH: JSON_RPC_ERRORS.INVALID_INPUT,
|
|
168
169
|
TIMEOUT: JSON_RPC_ERRORS.INVALID_INPUT
|
|
169
170
|
};
|
|
170
171
|
var RPC_TO_ERROR_CODE = {
|
|
@@ -504,43 +505,8 @@ var PartyLayerProvider = class {
|
|
|
504
505
|
}
|
|
505
506
|
};
|
|
506
507
|
|
|
507
|
-
// src/network.ts
|
|
508
|
-
var CANTON_NETWORKS = {
|
|
509
|
-
mainnet: "canton:da-mainnet",
|
|
510
|
-
testnet: "canton:da-testnet",
|
|
511
|
-
devnet: "canton:da-devnet",
|
|
512
|
-
local: "canton:da-local"
|
|
513
|
-
};
|
|
514
|
-
var CAIP2_TO_SHORT = Object.fromEntries(
|
|
515
|
-
Object.entries(CANTON_NETWORKS).map(([short, full]) => [full, short])
|
|
516
|
-
);
|
|
517
|
-
function toCAIP2Network(networkId) {
|
|
518
|
-
let result;
|
|
519
|
-
if (networkId.includes(":")) {
|
|
520
|
-
result = networkId;
|
|
521
|
-
} else {
|
|
522
|
-
const caip2 = CANTON_NETWORKS[networkId];
|
|
523
|
-
result = caip2 ?? `canton:${networkId}`;
|
|
524
|
-
}
|
|
525
|
-
if (!isValidCAIP2(result)) {
|
|
526
|
-
throw new Error(
|
|
527
|
-
`Invalid CAIP-2 network identifier: "${result}". Expected format: "namespace:reference"`
|
|
528
|
-
);
|
|
529
|
-
}
|
|
530
|
-
return { networkId: result };
|
|
531
|
-
}
|
|
532
|
-
function fromCAIP2Network(caip2) {
|
|
533
|
-
const short = CAIP2_TO_SHORT[caip2];
|
|
534
|
-
if (short) return short;
|
|
535
|
-
const colonIndex = caip2.indexOf(":");
|
|
536
|
-
return colonIndex >= 0 ? caip2.slice(colonIndex + 1) : caip2;
|
|
537
|
-
}
|
|
538
|
-
function isValidCAIP2(networkId) {
|
|
539
|
-
return /^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}$/.test(networkId);
|
|
540
|
-
}
|
|
541
|
-
|
|
542
508
|
// src/bridge.ts
|
|
543
|
-
var PROVIDER_VERSION = "0.1
|
|
509
|
+
var PROVIDER_VERSION = "0.2.1" ;
|
|
544
510
|
function createProviderBridge(client) {
|
|
545
511
|
const eventBus = new CIP0103EventBus();
|
|
546
512
|
const pendingEmitted = /* @__PURE__ */ new Set();
|
|
@@ -596,7 +562,7 @@ async function handleRequest(client, args, eventBus, pendingEmitted) {
|
|
|
596
562
|
version: PROVIDER_VERSION,
|
|
597
563
|
providerType: "browser"
|
|
598
564
|
},
|
|
599
|
-
network: session ? toCAIP2Network(session.network) : void 0,
|
|
565
|
+
network: session ? core.toCAIP2Network(session.network) : void 0,
|
|
600
566
|
session: session ? {
|
|
601
567
|
accessToken: "",
|
|
602
568
|
userId: String(session.partyId)
|
|
@@ -605,7 +571,7 @@ async function handleRequest(client, args, eventBus, pendingEmitted) {
|
|
|
605
571
|
}
|
|
606
572
|
case "getActiveNetwork": {
|
|
607
573
|
const session = await client.getActiveSession();
|
|
608
|
-
return toCAIP2Network(
|
|
574
|
+
return core.toCAIP2Network(
|
|
609
575
|
session?.network ?? "devnet"
|
|
610
576
|
);
|
|
611
577
|
}
|
|
@@ -715,7 +681,7 @@ function wireEvents(client, eventBus, pendingEmitted) {
|
|
|
715
681
|
version: PROVIDER_VERSION,
|
|
716
682
|
providerType: "browser"
|
|
717
683
|
},
|
|
718
|
-
network: toCAIP2Network(session.network),
|
|
684
|
+
network: core.toCAIP2Network(session.network),
|
|
719
685
|
session: {
|
|
720
686
|
accessToken: "",
|
|
721
687
|
userId: String(session.partyId)
|
|
@@ -729,7 +695,7 @@ function wireEvents(client, eventBus, pendingEmitted) {
|
|
|
729
695
|
hint: "",
|
|
730
696
|
publicKey: "",
|
|
731
697
|
namespace: "",
|
|
732
|
-
networkId: toCAIP2Network(session.network).networkId,
|
|
698
|
+
networkId: core.toCAIP2Network(session.network).networkId,
|
|
733
699
|
signingProviderId: ""
|
|
734
700
|
}
|
|
735
701
|
]);
|
|
@@ -814,11 +780,101 @@ function sessionToAccount(session) {
|
|
|
814
780
|
hint: "",
|
|
815
781
|
publicKey: "",
|
|
816
782
|
namespace: "",
|
|
817
|
-
networkId: toCAIP2Network(session.network).networkId,
|
|
783
|
+
networkId: core.toCAIP2Network(session.network).networkId,
|
|
818
784
|
signingProviderId: ""
|
|
819
785
|
};
|
|
820
786
|
}
|
|
821
787
|
|
|
788
|
+
// src/extension-channel.ts
|
|
789
|
+
var SPLICE_WALLET_REQUEST = "SPLICE_WALLET_REQUEST";
|
|
790
|
+
var SPLICE_WALLET_RESPONSE = "SPLICE_WALLET_RESPONSE";
|
|
791
|
+
var channelSeq = 0;
|
|
792
|
+
function createExtensionChannelProvider(options = {}) {
|
|
793
|
+
const target = options.target;
|
|
794
|
+
const timeoutMs = options.timeoutMs ?? 3e4;
|
|
795
|
+
const eventBus = new CIP0103EventBus();
|
|
796
|
+
const channelId = `pl-${++channelSeq}-${target ?? "ext"}`;
|
|
797
|
+
let requestSeq = 0;
|
|
798
|
+
const pending = /* @__PURE__ */ new Map();
|
|
799
|
+
function onMessage(event) {
|
|
800
|
+
if (event.source !== window) return;
|
|
801
|
+
const selfOrigin = typeof window !== "undefined" ? window.location?.origin : void 0;
|
|
802
|
+
if (selfOrigin && selfOrigin !== "null" && event.origin !== selfOrigin) return;
|
|
803
|
+
const data = event.data;
|
|
804
|
+
if (!data || data.type !== SPLICE_WALLET_RESPONSE || !data.response) return;
|
|
805
|
+
const { id, result, error } = data.response;
|
|
806
|
+
if (id === void 0 || id === null) return;
|
|
807
|
+
const entry = pending.get(String(id));
|
|
808
|
+
if (!entry) return;
|
|
809
|
+
pending.delete(String(id));
|
|
810
|
+
clearTimeout(entry.timer);
|
|
811
|
+
if (error) {
|
|
812
|
+
entry.reject(
|
|
813
|
+
new ProviderRpcError(
|
|
814
|
+
error.message || "Wallet request failed",
|
|
815
|
+
typeof error.code === "number" ? error.code : JSON_RPC_ERRORS.INTERNAL_ERROR,
|
|
816
|
+
error.data
|
|
817
|
+
)
|
|
818
|
+
);
|
|
819
|
+
} else {
|
|
820
|
+
entry.resolve(result);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
if (typeof window !== "undefined") {
|
|
824
|
+
window.addEventListener("message", onMessage);
|
|
825
|
+
}
|
|
826
|
+
function postTargetOrigin() {
|
|
827
|
+
const origin = typeof window !== "undefined" ? window.location?.origin : void 0;
|
|
828
|
+
return origin && origin !== "null" ? origin : "*";
|
|
829
|
+
}
|
|
830
|
+
const provider = {
|
|
831
|
+
request(args) {
|
|
832
|
+
if (typeof window === "undefined") {
|
|
833
|
+
return Promise.reject(
|
|
834
|
+
new ProviderRpcError("No window: extension channel unavailable", JSON_RPC_ERRORS.INTERNAL_ERROR)
|
|
835
|
+
);
|
|
836
|
+
}
|
|
837
|
+
const id = `${channelId}-${++requestSeq}`;
|
|
838
|
+
return new Promise((resolve, reject) => {
|
|
839
|
+
const timer = setTimeout(() => {
|
|
840
|
+
pending.delete(id);
|
|
841
|
+
reject(
|
|
842
|
+
new ProviderRpcError(
|
|
843
|
+
`Wallet request "${args.method}" timed out after ${timeoutMs}ms`,
|
|
844
|
+
JSON_RPC_ERRORS.INTERNAL_ERROR
|
|
845
|
+
)
|
|
846
|
+
);
|
|
847
|
+
}, timeoutMs);
|
|
848
|
+
pending.set(id, { resolve, reject, timer });
|
|
849
|
+
const message = {
|
|
850
|
+
type: SPLICE_WALLET_REQUEST,
|
|
851
|
+
request: {
|
|
852
|
+
jsonrpc: "2.0",
|
|
853
|
+
id,
|
|
854
|
+
method: args.method,
|
|
855
|
+
...args.params !== void 0 ? { params: args.params } : {}
|
|
856
|
+
},
|
|
857
|
+
...target ? { target } : {}
|
|
858
|
+
};
|
|
859
|
+
window.postMessage(message, postTargetOrigin());
|
|
860
|
+
});
|
|
861
|
+
},
|
|
862
|
+
on(event, listener) {
|
|
863
|
+
eventBus.on(event, listener);
|
|
864
|
+
return provider;
|
|
865
|
+
},
|
|
866
|
+
emit(event, ...args) {
|
|
867
|
+
return eventBus.emit(event, ...args);
|
|
868
|
+
},
|
|
869
|
+
removeListener(event, listener) {
|
|
870
|
+
eventBus.removeListener(event, listener);
|
|
871
|
+
return provider;
|
|
872
|
+
}
|
|
873
|
+
};
|
|
874
|
+
eventBus.setOwner(provider);
|
|
875
|
+
return provider;
|
|
876
|
+
}
|
|
877
|
+
|
|
822
878
|
// src/discovery.ts
|
|
823
879
|
var KNOWN_INJECTION_PATHS = [
|
|
824
880
|
"canton",
|
|
@@ -892,7 +948,108 @@ function findById(id) {
|
|
|
892
948
|
(p) => p.id === id || p.id.endsWith(`.${id}`)
|
|
893
949
|
);
|
|
894
950
|
}
|
|
951
|
+
var CANTON_REQUEST_PROVIDER_EVENT = "canton:requestProvider";
|
|
952
|
+
var CANTON_ANNOUNCE_PROVIDER_EVENT = "canton:announceProvider";
|
|
953
|
+
function defaultAnnounceProvider(announced) {
|
|
954
|
+
return createExtensionChannelProvider({ target: announced.target });
|
|
955
|
+
}
|
|
956
|
+
async function discoverAnnouncedProviders(options = {}) {
|
|
957
|
+
if (typeof window === "undefined") return [];
|
|
958
|
+
const timeoutMs = options.timeoutMs ?? 300;
|
|
959
|
+
const make = options.createProvider ?? defaultAnnounceProvider;
|
|
960
|
+
const announced = /* @__PURE__ */ new Map();
|
|
961
|
+
const onAnnounce = (event) => {
|
|
962
|
+
const detail = event.detail;
|
|
963
|
+
if (!detail) return;
|
|
964
|
+
const rawId = detail.providerId ?? detail.id;
|
|
965
|
+
if (typeof rawId !== "string" || rawId.length === 0) return;
|
|
966
|
+
if (announced.has(rawId)) return;
|
|
967
|
+
announced.set(rawId, {
|
|
968
|
+
id: rawId,
|
|
969
|
+
name: typeof detail.name === "string" ? detail.name : void 0,
|
|
970
|
+
icon: typeof detail.icon === "string" ? detail.icon : void 0,
|
|
971
|
+
target: typeof detail.target === "string" ? detail.target : void 0
|
|
972
|
+
});
|
|
973
|
+
};
|
|
974
|
+
window.addEventListener(
|
|
975
|
+
CANTON_ANNOUNCE_PROVIDER_EVENT,
|
|
976
|
+
onAnnounce
|
|
977
|
+
);
|
|
978
|
+
try {
|
|
979
|
+
window.dispatchEvent(new CustomEvent(CANTON_REQUEST_PROVIDER_EVENT));
|
|
980
|
+
await new Promise((resolve) => setTimeout(resolve, timeoutMs));
|
|
981
|
+
} finally {
|
|
982
|
+
window.removeEventListener(
|
|
983
|
+
CANTON_ANNOUNCE_PROVIDER_EVENT,
|
|
984
|
+
onAnnounce
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
const results = [];
|
|
988
|
+
for (const wallet of announced.values()) {
|
|
989
|
+
let provider;
|
|
990
|
+
try {
|
|
991
|
+
provider = await make(wallet);
|
|
992
|
+
} catch {
|
|
993
|
+
continue;
|
|
994
|
+
}
|
|
995
|
+
if (!isCIP0103Provider(provider)) continue;
|
|
996
|
+
results.push({
|
|
997
|
+
id: wallet.id,
|
|
998
|
+
provider,
|
|
999
|
+
source: "injected",
|
|
1000
|
+
name: wallet.name,
|
|
1001
|
+
icon: wallet.icon
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
return results;
|
|
1005
|
+
}
|
|
1006
|
+
var INJECTED_ID_PROBE_TIMEOUT_MS = 1500;
|
|
1007
|
+
function raceTimeout(promise, ms) {
|
|
1008
|
+
return Promise.race([
|
|
1009
|
+
promise,
|
|
1010
|
+
new Promise(
|
|
1011
|
+
(_, reject) => setTimeout(() => reject(new Error("id-probe timeout")), ms)
|
|
1012
|
+
)
|
|
1013
|
+
]);
|
|
1014
|
+
}
|
|
1015
|
+
async function resolveInjectedKey(d) {
|
|
1016
|
+
const sync = d.provider.id;
|
|
1017
|
+
if (typeof sync === "string" && sync.length > 0) return sync;
|
|
1018
|
+
try {
|
|
1019
|
+
const status = await raceTimeout(
|
|
1020
|
+
d.provider.request({ method: "status" }),
|
|
1021
|
+
INJECTED_ID_PROBE_TIMEOUT_MS
|
|
1022
|
+
);
|
|
1023
|
+
const pid = status?.provider?.id;
|
|
1024
|
+
if (typeof pid === "string" && pid.length > 0) return pid;
|
|
1025
|
+
} catch {
|
|
1026
|
+
}
|
|
1027
|
+
return d.id;
|
|
1028
|
+
}
|
|
1029
|
+
async function discoverProviders(options = {}) {
|
|
1030
|
+
const injected = discoverInjectedProviders();
|
|
1031
|
+
const announcedResults = await discoverAnnouncedProviders(options);
|
|
1032
|
+
const injectedKeys = await Promise.all(injected.map(resolveInjectedKey));
|
|
1033
|
+
const out = [];
|
|
1034
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1035
|
+
injected.forEach((d, i) => {
|
|
1036
|
+
const key = injectedKeys[i];
|
|
1037
|
+
if (seen.has(key)) return;
|
|
1038
|
+
seen.add(key);
|
|
1039
|
+
out.push(d);
|
|
1040
|
+
});
|
|
1041
|
+
for (const d of announcedResults) {
|
|
1042
|
+
if (seen.has(d.id)) continue;
|
|
1043
|
+
seen.add(d.id);
|
|
1044
|
+
out.push(d);
|
|
1045
|
+
}
|
|
1046
|
+
return out;
|
|
1047
|
+
}
|
|
895
1048
|
|
|
1049
|
+
Object.defineProperty(exports, "CANTON_NETWORKS", {
|
|
1050
|
+
enumerable: true,
|
|
1051
|
+
get: function () { return core.CANTON_NETWORKS; }
|
|
1052
|
+
});
|
|
896
1053
|
Object.defineProperty(exports, "CIP0103_EVENTS", {
|
|
897
1054
|
enumerable: true,
|
|
898
1055
|
get: function () { return core.CIP0103_EVENTS; }
|
|
@@ -905,7 +1062,18 @@ Object.defineProperty(exports, "CIP0103_METHODS", {
|
|
|
905
1062
|
enumerable: true,
|
|
906
1063
|
get: function () { return core.CIP0103_METHODS; }
|
|
907
1064
|
});
|
|
908
|
-
exports
|
|
1065
|
+
Object.defineProperty(exports, "fromCAIP2Network", {
|
|
1066
|
+
enumerable: true,
|
|
1067
|
+
get: function () { return core.fromCAIP2Network; }
|
|
1068
|
+
});
|
|
1069
|
+
Object.defineProperty(exports, "isValidCAIP2", {
|
|
1070
|
+
enumerable: true,
|
|
1071
|
+
get: function () { return core.isValidCAIP2; }
|
|
1072
|
+
});
|
|
1073
|
+
Object.defineProperty(exports, "toCAIP2Network", {
|
|
1074
|
+
enumerable: true,
|
|
1075
|
+
get: function () { return core.toCAIP2Network; }
|
|
1076
|
+
});
|
|
909
1077
|
exports.CIP0103EventBus = CIP0103EventBus;
|
|
910
1078
|
exports.JSON_RPC_ERRORS = JSON_RPC_ERRORS;
|
|
911
1079
|
exports.MethodRouter = MethodRouter;
|
|
@@ -913,20 +1081,20 @@ exports.PartyLayerProvider = PartyLayerProvider;
|
|
|
913
1081
|
exports.ProviderRpcError = ProviderRpcError;
|
|
914
1082
|
exports.RPC_ERRORS = RPC_ERRORS;
|
|
915
1083
|
exports.chainDisconnected = chainDisconnected;
|
|
1084
|
+
exports.createExtensionChannelProvider = createExtensionChannelProvider;
|
|
916
1085
|
exports.createProviderBridge = createProviderBridge;
|
|
917
1086
|
exports.disconnected = disconnected;
|
|
1087
|
+
exports.discoverAnnouncedProviders = discoverAnnouncedProviders;
|
|
918
1088
|
exports.discoverInjectedProviders = discoverInjectedProviders;
|
|
919
|
-
exports.
|
|
1089
|
+
exports.discoverProviders = discoverProviders;
|
|
920
1090
|
exports.handleAsyncConnect = handleAsyncConnect;
|
|
921
1091
|
exports.handleAsyncPrepareExecute = handleAsyncPrepareExecute;
|
|
922
1092
|
exports.internalError = internalError;
|
|
923
1093
|
exports.invalidParams = invalidParams;
|
|
924
1094
|
exports.isCIP0103Provider = isCIP0103Provider;
|
|
925
|
-
exports.isValidCAIP2 = isValidCAIP2;
|
|
926
1095
|
exports.methodNotFound = methodNotFound;
|
|
927
1096
|
exports.resourceNotFound = resourceNotFound;
|
|
928
1097
|
exports.resourceUnavailable = resourceUnavailable;
|
|
929
|
-
exports.toCAIP2Network = toCAIP2Network;
|
|
930
1098
|
exports.toPartyLayerError = toPartyLayerError;
|
|
931
1099
|
exports.toProviderRpcError = toProviderRpcError;
|
|
932
1100
|
exports.transactionRejected = transactionRejected;
|