@partylayer/adapter-cantor8 0.2.20 → 0.4.0

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
@@ -1,97 +1,108 @@
1
1
  import * as _partylayer_core from '@partylayer/core';
2
- import { ConnectRequest, ConnectResponse, SignRequest, SignResponse, JobStatus, WalletAdapter, CapabilityKey, AdapterDetectResult, AdapterContext, AdapterConnectResult, SignMessageParams, SignTransactionParams } from '@partylayer/core';
2
+ import { WalletAdapter, CapabilityKey, AdapterDetectResult, AdapterContext, AdapterConnectResult, Session, SignMessageParams, SignedMessage, SubmitTransactionParams, TxReceipt, AdapterEventName } from '@partylayer/core';
3
3
 
4
4
  /**
5
- * Cantor8 Vendor Integration Module
6
- *
7
- * This module abstracts vendor-specific endpoints and can be swapped
8
- * without breaking the adapter API.
9
- *
10
- * References:
11
- * - Cantor8 ecosystem: https://www.canton.network/ecosystem/cantor8
12
- * - Cantor8 site: https://cantor8.tech/about
5
+ * The shape `submitTransaction` expects in `params.signedTx`: the Cantor8 SDK's
6
+ * `signAndExecute` input. The caller owns this shape (passthrough).
13
7
  */
14
-
15
- /**
16
- * Vendor configuration
17
- */
18
- interface Cantor8VendorConfig {
19
- /** Deep link scheme (e.g., "cantor8") */
20
- deepLinkScheme?: string;
21
- /** Universal link base URL (e.g., "https://app.cantor8.tech") */
22
- universalLinkBase?: string;
23
- /** Connect endpoint path */
24
- connectEndpoint?: string;
25
- /** Sign endpoint path */
26
- signEndpoint?: string;
27
- /** Job status endpoint path (for async approvals) */
28
- statusEndpoint?: string;
29
- /** Redirect URI for callbacks */
30
- redirectUri?: string;
8
+ interface Cantor8SubmitPayload {
9
+ note?: string;
10
+ partyId: string;
11
+ commandId: string;
12
+ commandsJson: string;
13
+ disclosedContracts?: string;
31
14
  }
32
15
  /**
33
- * Vendor module interface
34
- *
35
- * Implementations can be swapped without changing adapter code.
36
- */
37
- interface Cantor8VendorModule {
38
- /**
39
- * Create connect URL
40
- */
41
- createConnectUrl(request: ConnectRequest, config: Cantor8VendorConfig): string;
42
- /**
43
- * Parse connect callback
44
- */
45
- parseConnectCallback(callbackData: unknown, expectedState: string): ConnectResponse;
46
- /**
47
- * Create sign URL
48
- */
49
- createSignUrl(request: SignRequest, config: Cantor8VendorConfig): string;
50
- /**
51
- * Parse sign callback
52
- */
53
- parseSignCallback(callbackData: unknown, expectedState: string): SignResponse;
54
- /**
55
- * Poll job status (optional, for async approvals)
56
- */
57
- pollJobStatus?(jobId: string, statusUrl: string, timeoutMs: number): Promise<JobStatus>;
58
- }
59
-
60
- /**
61
- * Cantor8 adapter configuration
16
+ * Cantor8 adapter configuration.
62
17
  */
63
18
  interface Cantor8AdapterConfig {
64
- /** Vendor module (defaults to stub) */
65
- vendorModule?: Cantor8VendorModule;
66
- /** Vendor configuration */
67
- vendorConfig?: Cantor8VendorConfig;
68
- /** Use mock transport in development */
69
- useMockTransport?: boolean;
19
+ /** dApp URL passed to the Cantor8 SDK popup handshake. Defaults to `ctx.origin`. */
20
+ dappUrl?: string;
70
21
  }
71
22
  /**
72
- * Cantor8 Wallet Adapter
23
+ * Cantor8 Wallet Adapter.
73
24
  */
74
25
  declare class Cantor8Adapter implements WalletAdapter {
75
26
  readonly walletId: _partylayer_core.WalletId;
76
27
  readonly name = "Cantor8";
77
- private vendorModule;
78
- private vendorConfig;
79
- private transport;
28
+ private readonly config;
29
+ private provider;
80
30
  constructor(config?: Cantor8AdapterConfig);
81
31
  getCapabilities(): CapabilityKey[];
32
+ /** The SDK supports devnet and mainnet only; anything else fails at connect. */
33
+ private mapNetwork;
34
+ /**
35
+ * Cantor8 is a HOSTED POPUP wallet: connect() opens the wallet at
36
+ * wallet.dev.digik.cantor8.tech (devnet) or wallet.cantor8.tech (mainnet)
37
+ * through the SDK's C8WalletProvider. Nothing of Cantor8 runs in THIS page, so
38
+ * there is nothing here to detect.
39
+ *
40
+ * The SDK's discovery protocol has two sides. `announceC8Provider(get)` is the
41
+ * DISPATCH side, called by a wallet that lives in the page to advertise a
42
+ * provider factory; `onC8ProviderDiscovered(cb)` is the SUBSCRIBE side, called
43
+ * by a dApp to hear such an announcement. A hosted popup on another origin never
44
+ * calls `announceC8Provider` in our page, so subscribing and waiting for the
45
+ * `c8#provider_discovery` event can only ever time out. That is precisely what
46
+ * the previous strategy did, and it reported Cantor8 permanently unavailable,
47
+ * which hid it from the picker.
48
+ *
49
+ * The right model is the gateway contract the official ProviderAdapter path uses
50
+ * (see GenericDiscoveryAdapter.detectInstalled): a gateway is reachable wherever
51
+ * it can be opened, so detect reports available and the REAL availability check
52
+ * happens at connect(), when the popup opens. Walley, a popup wallet on that
53
+ * generic path, works in our demos for exactly this reason.
54
+ *
55
+ * This is the SECOND detection strategy to be wrong here, both from the same
56
+ * root cause: inferring the wallet's shape without the wallet in hand. First a
57
+ * user-agent sniff mislabeled this desktop popup as a mobile wallet; then the
58
+ * announcement wait assumed an in-page announcer that a hosted popup never
59
+ * provides. Do not reintroduce a probe that depends on something being in the
60
+ * page. If a future in-page Cantor8 ever announces over `c8#provider_discovery`,
61
+ * it may be adopted as a fast path, but it must NEVER be the condition for
62
+ * availability.
63
+ *
64
+ * detect still LOADS the SDK (the pre-fix detect did too; only its announcement
65
+ * wait was wrong). This is deliberate warming, not detection: a bespoke adapter
66
+ * does not get the SDK's popup-safe fast-path (that is for GenericDiscoveryAdapter),
67
+ * so connect() reaches window.open only after awaits. detect runs at picker
68
+ * render, off the click gesture, so the dynamic import resolves before the user
69
+ * clicks; connect()'s `await loadC8()` is then a resolved microtask instead of a
70
+ * cold import that would defer window.open past the gesture and let the browser
71
+ * block the popup.
72
+ */
82
73
  detectInstalled(): Promise<AdapterDetectResult>;
83
- connect(ctx: AdapterContext, opts?: {
74
+ connect(ctx: AdapterContext, _opts?: {
84
75
  timeoutMs?: number;
85
- partyId?: _partylayer_core.PartyId;
86
76
  }): Promise<AdapterConnectResult>;
87
- disconnect(_ctx: AdapterContext, _session: _partylayer_core.Session): Promise<void>;
88
- restore(_ctx: AdapterContext, persisted: _partylayer_core.PersistedSession): Promise<_partylayer_core.Session | null>;
89
- signMessage(ctx: AdapterContext, session: _partylayer_core.Session, params: SignMessageParams): Promise<_partylayer_core.SignedMessage>;
90
- signTransaction(ctx: AdapterContext, session: _partylayer_core.Session, params: SignTransactionParams): Promise<_partylayer_core.SignedTransaction>;
77
+ disconnect(_ctx: AdapterContext, _session: Session): Promise<void>;
78
+ /**
79
+ * Cantor8 has NO arbitrary-message signing. Per the honesty rule: do not
80
+ * simulate it, do not route it through `signAndExecute` (which is for
81
+ * transactions), and do not silently succeed. Fail with the typed capability
82
+ * error. `signMessage` is also absent from `getCapabilities()`, so the SDK's
83
+ * capability guard blocks it first; this is the belt-and-suspenders backstop.
84
+ */
85
+ signMessage(_ctx: AdapterContext, _session: Session, _params: SignMessageParams): Promise<SignedMessage>;
86
+ /**
87
+ * Submit a transaction through the SDK's `signAndExecute` (sign + execute
88
+ * fused; the wallet has no separate sign step). `params.signedTx` is passed
89
+ * through: the caller owns its shape, which must be a {@link Cantor8SubmitPayload}.
90
+ *
91
+ * The SDK's `signAndExecute` resolves with no id; Cantor8 delivers the
92
+ * on-ledger txId and status asynchronously via the `txChanged` event (surfaced
93
+ * through `on('txStatus')`). The receipt is therefore keyed on the
94
+ * caller-supplied `commandId`; the confirmed ledger id arrives on the event
95
+ * stream. A live run against the real wallet is required to confirm
96
+ * end-to-end execution.
97
+ */
98
+ submitTransaction(_ctx: AdapterContext, _session: Session, params: SubmitTransactionParams): Promise<TxReceipt>;
91
99
  /**
92
- * Generate random state nonce
100
+ * Forward the wallet's transaction-status stream. Cantor8 emits `txChanged`
101
+ * ({ txId, status }); PartyLayer surfaces this as the `events` capability under
102
+ * the `txStatus` event. Any other event name is a no-op. Returns an
103
+ * unsubscribe function.
93
104
  */
94
- private generateState;
105
+ on(event: AdapterEventName, handler: (payload: unknown) => void): () => void;
95
106
  }
96
107
 
97
- export { Cantor8Adapter, type Cantor8AdapterConfig };
108
+ export { Cantor8Adapter, type Cantor8AdapterConfig, type Cantor8SubmitPayload };
package/dist/index.d.ts CHANGED
@@ -1,97 +1,108 @@
1
1
  import * as _partylayer_core from '@partylayer/core';
2
- import { ConnectRequest, ConnectResponse, SignRequest, SignResponse, JobStatus, WalletAdapter, CapabilityKey, AdapterDetectResult, AdapterContext, AdapterConnectResult, SignMessageParams, SignTransactionParams } from '@partylayer/core';
2
+ import { WalletAdapter, CapabilityKey, AdapterDetectResult, AdapterContext, AdapterConnectResult, Session, SignMessageParams, SignedMessage, SubmitTransactionParams, TxReceipt, AdapterEventName } from '@partylayer/core';
3
3
 
4
4
  /**
5
- * Cantor8 Vendor Integration Module
6
- *
7
- * This module abstracts vendor-specific endpoints and can be swapped
8
- * without breaking the adapter API.
9
- *
10
- * References:
11
- * - Cantor8 ecosystem: https://www.canton.network/ecosystem/cantor8
12
- * - Cantor8 site: https://cantor8.tech/about
5
+ * The shape `submitTransaction` expects in `params.signedTx`: the Cantor8 SDK's
6
+ * `signAndExecute` input. The caller owns this shape (passthrough).
13
7
  */
14
-
15
- /**
16
- * Vendor configuration
17
- */
18
- interface Cantor8VendorConfig {
19
- /** Deep link scheme (e.g., "cantor8") */
20
- deepLinkScheme?: string;
21
- /** Universal link base URL (e.g., "https://app.cantor8.tech") */
22
- universalLinkBase?: string;
23
- /** Connect endpoint path */
24
- connectEndpoint?: string;
25
- /** Sign endpoint path */
26
- signEndpoint?: string;
27
- /** Job status endpoint path (for async approvals) */
28
- statusEndpoint?: string;
29
- /** Redirect URI for callbacks */
30
- redirectUri?: string;
8
+ interface Cantor8SubmitPayload {
9
+ note?: string;
10
+ partyId: string;
11
+ commandId: string;
12
+ commandsJson: string;
13
+ disclosedContracts?: string;
31
14
  }
32
15
  /**
33
- * Vendor module interface
34
- *
35
- * Implementations can be swapped without changing adapter code.
36
- */
37
- interface Cantor8VendorModule {
38
- /**
39
- * Create connect URL
40
- */
41
- createConnectUrl(request: ConnectRequest, config: Cantor8VendorConfig): string;
42
- /**
43
- * Parse connect callback
44
- */
45
- parseConnectCallback(callbackData: unknown, expectedState: string): ConnectResponse;
46
- /**
47
- * Create sign URL
48
- */
49
- createSignUrl(request: SignRequest, config: Cantor8VendorConfig): string;
50
- /**
51
- * Parse sign callback
52
- */
53
- parseSignCallback(callbackData: unknown, expectedState: string): SignResponse;
54
- /**
55
- * Poll job status (optional, for async approvals)
56
- */
57
- pollJobStatus?(jobId: string, statusUrl: string, timeoutMs: number): Promise<JobStatus>;
58
- }
59
-
60
- /**
61
- * Cantor8 adapter configuration
16
+ * Cantor8 adapter configuration.
62
17
  */
63
18
  interface Cantor8AdapterConfig {
64
- /** Vendor module (defaults to stub) */
65
- vendorModule?: Cantor8VendorModule;
66
- /** Vendor configuration */
67
- vendorConfig?: Cantor8VendorConfig;
68
- /** Use mock transport in development */
69
- useMockTransport?: boolean;
19
+ /** dApp URL passed to the Cantor8 SDK popup handshake. Defaults to `ctx.origin`. */
20
+ dappUrl?: string;
70
21
  }
71
22
  /**
72
- * Cantor8 Wallet Adapter
23
+ * Cantor8 Wallet Adapter.
73
24
  */
74
25
  declare class Cantor8Adapter implements WalletAdapter {
75
26
  readonly walletId: _partylayer_core.WalletId;
76
27
  readonly name = "Cantor8";
77
- private vendorModule;
78
- private vendorConfig;
79
- private transport;
28
+ private readonly config;
29
+ private provider;
80
30
  constructor(config?: Cantor8AdapterConfig);
81
31
  getCapabilities(): CapabilityKey[];
32
+ /** The SDK supports devnet and mainnet only; anything else fails at connect. */
33
+ private mapNetwork;
34
+ /**
35
+ * Cantor8 is a HOSTED POPUP wallet: connect() opens the wallet at
36
+ * wallet.dev.digik.cantor8.tech (devnet) or wallet.cantor8.tech (mainnet)
37
+ * through the SDK's C8WalletProvider. Nothing of Cantor8 runs in THIS page, so
38
+ * there is nothing here to detect.
39
+ *
40
+ * The SDK's discovery protocol has two sides. `announceC8Provider(get)` is the
41
+ * DISPATCH side, called by a wallet that lives in the page to advertise a
42
+ * provider factory; `onC8ProviderDiscovered(cb)` is the SUBSCRIBE side, called
43
+ * by a dApp to hear such an announcement. A hosted popup on another origin never
44
+ * calls `announceC8Provider` in our page, so subscribing and waiting for the
45
+ * `c8#provider_discovery` event can only ever time out. That is precisely what
46
+ * the previous strategy did, and it reported Cantor8 permanently unavailable,
47
+ * which hid it from the picker.
48
+ *
49
+ * The right model is the gateway contract the official ProviderAdapter path uses
50
+ * (see GenericDiscoveryAdapter.detectInstalled): a gateway is reachable wherever
51
+ * it can be opened, so detect reports available and the REAL availability check
52
+ * happens at connect(), when the popup opens. Walley, a popup wallet on that
53
+ * generic path, works in our demos for exactly this reason.
54
+ *
55
+ * This is the SECOND detection strategy to be wrong here, both from the same
56
+ * root cause: inferring the wallet's shape without the wallet in hand. First a
57
+ * user-agent sniff mislabeled this desktop popup as a mobile wallet; then the
58
+ * announcement wait assumed an in-page announcer that a hosted popup never
59
+ * provides. Do not reintroduce a probe that depends on something being in the
60
+ * page. If a future in-page Cantor8 ever announces over `c8#provider_discovery`,
61
+ * it may be adopted as a fast path, but it must NEVER be the condition for
62
+ * availability.
63
+ *
64
+ * detect still LOADS the SDK (the pre-fix detect did too; only its announcement
65
+ * wait was wrong). This is deliberate warming, not detection: a bespoke adapter
66
+ * does not get the SDK's popup-safe fast-path (that is for GenericDiscoveryAdapter),
67
+ * so connect() reaches window.open only after awaits. detect runs at picker
68
+ * render, off the click gesture, so the dynamic import resolves before the user
69
+ * clicks; connect()'s `await loadC8()` is then a resolved microtask instead of a
70
+ * cold import that would defer window.open past the gesture and let the browser
71
+ * block the popup.
72
+ */
82
73
  detectInstalled(): Promise<AdapterDetectResult>;
83
- connect(ctx: AdapterContext, opts?: {
74
+ connect(ctx: AdapterContext, _opts?: {
84
75
  timeoutMs?: number;
85
- partyId?: _partylayer_core.PartyId;
86
76
  }): Promise<AdapterConnectResult>;
87
- disconnect(_ctx: AdapterContext, _session: _partylayer_core.Session): Promise<void>;
88
- restore(_ctx: AdapterContext, persisted: _partylayer_core.PersistedSession): Promise<_partylayer_core.Session | null>;
89
- signMessage(ctx: AdapterContext, session: _partylayer_core.Session, params: SignMessageParams): Promise<_partylayer_core.SignedMessage>;
90
- signTransaction(ctx: AdapterContext, session: _partylayer_core.Session, params: SignTransactionParams): Promise<_partylayer_core.SignedTransaction>;
77
+ disconnect(_ctx: AdapterContext, _session: Session): Promise<void>;
78
+ /**
79
+ * Cantor8 has NO arbitrary-message signing. Per the honesty rule: do not
80
+ * simulate it, do not route it through `signAndExecute` (which is for
81
+ * transactions), and do not silently succeed. Fail with the typed capability
82
+ * error. `signMessage` is also absent from `getCapabilities()`, so the SDK's
83
+ * capability guard blocks it first; this is the belt-and-suspenders backstop.
84
+ */
85
+ signMessage(_ctx: AdapterContext, _session: Session, _params: SignMessageParams): Promise<SignedMessage>;
86
+ /**
87
+ * Submit a transaction through the SDK's `signAndExecute` (sign + execute
88
+ * fused; the wallet has no separate sign step). `params.signedTx` is passed
89
+ * through: the caller owns its shape, which must be a {@link Cantor8SubmitPayload}.
90
+ *
91
+ * The SDK's `signAndExecute` resolves with no id; Cantor8 delivers the
92
+ * on-ledger txId and status asynchronously via the `txChanged` event (surfaced
93
+ * through `on('txStatus')`). The receipt is therefore keyed on the
94
+ * caller-supplied `commandId`; the confirmed ledger id arrives on the event
95
+ * stream. A live run against the real wallet is required to confirm
96
+ * end-to-end execution.
97
+ */
98
+ submitTransaction(_ctx: AdapterContext, _session: Session, params: SubmitTransactionParams): Promise<TxReceipt>;
91
99
  /**
92
- * Generate random state nonce
100
+ * Forward the wallet's transaction-status stream. Cantor8 emits `txChanged`
101
+ * ({ txId, status }); PartyLayer surfaces this as the `events` capability under
102
+ * the `txStatus` event. Any other event name is a no-op. Returns an
103
+ * unsubscribe function.
93
104
  */
94
- private generateState;
105
+ on(event: AdapterEventName, handler: (payload: unknown) => void): () => void;
95
106
  }
96
107
 
97
- export { Cantor8Adapter, type Cantor8AdapterConfig };
108
+ export { Cantor8Adapter, type Cantor8AdapterConfig, type Cantor8SubmitPayload };