@chipi-stack/starknet-connector 0.2.0 → 0.3.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.
@@ -0,0 +1,236 @@
1
+ import { Connector } from '@starknet-react/core';
2
+ import { ProviderInterface, AccountInterface } from 'starknet';
3
+ import { StarknetWindowObject, RpcMessage, RequestFnCall, RpcTypeToMessageMap } from '@starknet-io/types-js';
4
+
5
+ /**
6
+ * Wire protocol between the "Connect with Chipi" connector (running in the dApp)
7
+ * and the Chipi hosted wallet (running at `wallet.chipipay.com` in a popup).
8
+ *
9
+ * Both sides import these shapes so the contract stays in lock-step. The
10
+ * transport is `window.postMessage`: the dApp opens the wallet in a popup,
11
+ * forwards get-starknet `wallet_*` RPC calls over the channel, and the wallet
12
+ * answers after the user approves in its own (already-built) approval UI.
13
+ */
14
+ /** A get-starknet RPC call as sent over the wire: just the discriminant +
15
+ * optional params (the full typed `RpcMessage` carries result/errors we don't
16
+ * serialize). */
17
+ interface ChipiRpcCall {
18
+ type: string;
19
+ params?: unknown;
20
+ }
21
+ /** Namespace tag on every message so we ignore unrelated postMessages. */
22
+ declare const CHIPI_WC: "chipi-connect/v1";
23
+ /** wallet → dApp: the hosted wallet page finished loading and is listening. */
24
+ interface ChipiReadyMessage {
25
+ channel: typeof CHIPI_WC;
26
+ type: "ready";
27
+ }
28
+ /** dApp → wallet: forward a get-starknet `wallet_*` RPC call. */
29
+ interface ChipiRpcRequestMessage {
30
+ channel: typeof CHIPI_WC;
31
+ type: "rpc";
32
+ id: string;
33
+ /** The dApp origin, so the wallet can show it + enforce Verify checks. */
34
+ origin: string;
35
+ call: ChipiRpcCall;
36
+ }
37
+ /** wallet → dApp: the result (or error) for a given request id. */
38
+ type ChipiRpcResultMessage = {
39
+ channel: typeof CHIPI_WC;
40
+ type: "rpc-result";
41
+ id: string;
42
+ ok: true;
43
+ result: unknown;
44
+ } | {
45
+ channel: typeof CHIPI_WC;
46
+ type: "rpc-result";
47
+ id: string;
48
+ ok: false;
49
+ error: {
50
+ code: number;
51
+ message: string;
52
+ };
53
+ };
54
+ /** wallet → dApp: an account/network change to propagate to the dApp. */
55
+ interface ChipiEventMessage {
56
+ channel: typeof CHIPI_WC;
57
+ type: "event";
58
+ event: "accountsChanged" | "networkChanged";
59
+ data: unknown;
60
+ }
61
+ type ChipiWalletMessage = ChipiReadyMessage | ChipiRpcResultMessage | ChipiEventMessage;
62
+ type ChipiDappMessage = ChipiRpcRequestMessage;
63
+ declare function isChipiWalletMessage(data: unknown): data is ChipiWalletMessage;
64
+ /** Type guard for a dApp→wallet message (used by the hosted wallet side). */
65
+ declare function isChipiDappMessage(data: unknown): data is ChipiDappMessage;
66
+
67
+ /**
68
+ * Client-side (dApp) transport: opens the Chipi hosted wallet in a popup,
69
+ * performs the ready handshake, and forwards get-starknet `wallet_*` RPC calls
70
+ * over `postMessage`, correlating responses by id. The popup is reused across
71
+ * requests; if the user closed it, the next request reopens it.
72
+ */
73
+
74
+ interface ChipiTransportOptions {
75
+ /** Hosted wallet base URL, e.g. `https://wallet.chipipay.com`. */
76
+ walletUrl: string;
77
+ /**
78
+ * Transport mode:
79
+ * - `"popup"` (default): open the hosted wallet in a popup window: the
80
+ * universal model, works for any external dApp.
81
+ * - `"parent"`: the dApp is embedded in an iframe INSIDE the Chipi wallet
82
+ * (in-app browser); talk to `window.parent` instead of opening a popup, so
83
+ * approval renders inline in the wallet. Only works when the dApp is
84
+ * actually iframed by the Chipi host.
85
+ * - `"auto"`: use `"parent"` when running inside an iframe, else `"popup"`.
86
+ */
87
+ mode?: "popup" | "parent" | "auto";
88
+ /** Popup window name. */
89
+ windowName?: string;
90
+ /** Popup window features. */
91
+ windowFeatures?: string;
92
+ /** Ready-handshake timeout (ms). */
93
+ openTimeoutMs?: number;
94
+ }
95
+ type EventName = "accountsChanged" | "networkChanged";
96
+ type EventHandler = (data: unknown) => void;
97
+ declare class ChipiPopupTransport {
98
+ private readonly opts;
99
+ private readonly walletOrigin;
100
+ private readonly url;
101
+ private target;
102
+ private ownsTarget;
103
+ private ready;
104
+ private listening;
105
+ private readonly pending;
106
+ private readonly handlers;
107
+ private readyDeferred;
108
+ private openPromise;
109
+ private closeWatch;
110
+ constructor(opts: ChipiTransportOptions);
111
+ on(event: EventName, handler: EventHandler): void;
112
+ off(event: EventName, handler: EventHandler): void;
113
+ private ensureListener;
114
+ private onMessage;
115
+ /** Resolve "auto" → "parent" when iframed, else "popup". */
116
+ private resolveMode;
117
+ /** Open (or reuse) the wallet (popup window OR the parent frame) and wait for
118
+ * its ready handshake. Concurrent calls share ONE handshake. */
119
+ open(): Promise<void>;
120
+ private doOpen;
121
+ private awaitReady;
122
+ /** Reject every in-flight request (popup closed / disconnected). */
123
+ private rejectAllPending;
124
+ /** While requests are in flight, watch for the user closing the popup and
125
+ * reject them: otherwise the dApp's promise would hang forever. */
126
+ private startCloseWatch;
127
+ private stopCloseWatch;
128
+ /** Forward a get-starknet RPC call to the wallet, awaiting its response. */
129
+ request(call: ChipiRpcCall): Promise<unknown>;
130
+ /** Close the popup (if we own one) + reject in-flight requests. */
131
+ close(): void;
132
+ }
133
+
134
+ /**
135
+ * `ChipiConnector`: a starknet-react / get-starknet connector for the Chipi
136
+ * hosted smart-account wallet. A self-contained connector package any dApp
137
+ * adds to its `connectors` array (`new ChipiConnector()`) directly: no
138
+ * whitelisting, no dependency on a third-party wallet kit, and NO browser
139
+ * extension required. Clicking "Connect with Chipi" opens our hosted wallet
140
+ * (passkey + gasless paymaster) in a popup; the dApp's `wallet_*` RPC calls are
141
+ * forwarded over postMessage and answered after the user approves in Chipi's
142
+ * own (already-built) approval UI.
143
+ */
144
+
145
+ type ConnectorIcons = StarknetWindowObject["icon"];
146
+ type ConnectorData = {
147
+ account?: string;
148
+ chainId?: bigint;
149
+ };
150
+ interface ChipiConnectorOptions {
151
+ /** Hosted wallet base URL. Defaults to `https://wallet.chipipay.com`. */
152
+ walletUrl?: string;
153
+ /** Override the connector id / display name / icon if embedding. */
154
+ id?: string;
155
+ name?: string;
156
+ icon?: ConnectorIcons;
157
+ transport?: ChipiTransportOptions;
158
+ /**
159
+ * Self-register the wallet on `window` (set `window.starknet_chipi` + announce
160
+ * via `starknet:announceWallet`) so dApps that *scan* for wallets, raw
161
+ * get-starknet / Wallet-Standard consumers that don't import this connector,
162
+ * also discover "Connect with Chipi". Defaults to `true` in a browser; pass
163
+ * `false` to opt out (e.g. to avoid a double entry in a picker that already
164
+ * lists the connector explicitly). No-op during SSR.
165
+ */
166
+ register?: boolean;
167
+ }
168
+ declare class ChipiConnector extends Connector {
169
+ private readonly transport;
170
+ private readonly _id;
171
+ private readonly _name;
172
+ private readonly _icon;
173
+ private _account;
174
+ private _swo;
175
+ private _registration;
176
+ constructor(options?: ChipiConnectorOptions);
177
+ /**
178
+ * Announce this wallet to scanning dApps (`window.starknet_chipi` +
179
+ * `starknet:announceWallet`). Called automatically from the constructor
180
+ * unless `register: false`. Idempotent and SSR-safe.
181
+ */
182
+ register(): void;
183
+ /** Undo {@link register}: remove the window object + announce listener. */
184
+ unregister(): void;
185
+ get id(): string;
186
+ get name(): string;
187
+ get icon(): ConnectorIcons;
188
+ /** Hosted wallet: always available (no extension to detect). */
189
+ available(): boolean;
190
+ /** No silent reconnect in v1: the user re-approves the popup each session. */
191
+ ready(): Promise<boolean>;
192
+ /** Lazily build the postMessage-backed get-starknet window object. */
193
+ private swo;
194
+ connect(): Promise<ConnectorData>;
195
+ disconnect(): Promise<void>;
196
+ private emitEvent;
197
+ account(provider: ProviderInterface): Promise<AccountInterface>;
198
+ chainId(): Promise<bigint>;
199
+ request<T extends RpcMessage["type"]>(call: RequestFnCall<T>): Promise<RpcTypeToMessageMap[T]["result"]>;
200
+ }
201
+
202
+ /**
203
+ * Plain-function form of {@link ChipiConnector}, for parity with
204
+ * `@starknet-react/core`'s built-in factories (`ready()`, `braavos()`):
205
+ *
206
+ * const connectors = [chipi(), ready(), braavos()];
207
+ *
208
+ * Equivalent to `new ChipiConnector(options)`: use whichever reads better
209
+ * in your `connectors` array.
210
+ */
211
+ declare function chipi(options?: ChipiConnectorOptions): ChipiConnector;
212
+
213
+ /** Window key get-starknet discovers by scanning for `starknet*` properties. */
214
+ declare const CHIPI_WINDOW_KEY = "starknet_chipi";
215
+ interface ChipiRegistration {
216
+ /** Remove `window.starknet_chipi` + the announce listener. */
217
+ dispose: () => void;
218
+ }
219
+ /**
220
+ * Make a Chipi `StarknetWindowObject` discoverable to any get-starknet /
221
+ * starknet-react / starknetkit dApp on the page: WITHOUT an upstream PR and
222
+ * WITHOUT whitelisting. This self-registration covers the apps that scan for
223
+ * wallets rather than importing our connector explicitly.
224
+ *
225
+ * Discovery is announced two ways for maximum reach:
226
+ * 1. **window scan**: set `window.starknet_chipi`. get-starknet v4's
227
+ * `getAvailableWallets()` finds every `window` key starting with `starknet`.
228
+ * 2. **event announce**: dispatch `starknet:announceWallet` now and again on
229
+ * the dApp's `starknet:requestWallets` (the EIP-6963-style, timing-robust
230
+ * Starknet Wallet Standard discovery path).
231
+ *
232
+ * SSR-safe (no-ops when there's no `window`) and idempotent per (target, wallet).
233
+ */
234
+ declare function registerChipiWallet(wallet: StarknetWindowObject, target?: (Window & typeof globalThis) | undefined): ChipiRegistration;
235
+
236
+ export { CHIPI_WC, CHIPI_WINDOW_KEY, ChipiConnector, type ChipiConnectorOptions, type ChipiDappMessage, type ChipiEventMessage, ChipiPopupTransport, type ChipiReadyMessage, type ChipiRegistration, type ChipiRpcCall, type ChipiRpcRequestMessage, type ChipiRpcResultMessage, type ChipiTransportOptions, type ChipiWalletMessage, chipi, isChipiDappMessage, isChipiWalletMessage, registerChipiWallet };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,236 @@
1
- export { chipi } from "./factory.js";
2
- export { ChipiConnector } from "./connector.js";
3
- export type { ChipiConnectorOptions } from "./connector.js";
4
- export { ChipiPopupTransport } from "./transport.js";
5
- export type { ChipiTransportOptions } from "./transport.js";
6
- export { registerChipiWallet, CHIPI_WINDOW_KEY } from "./register.js";
7
- export type { ChipiRegistration } from "./register.js";
8
- export { CHIPI_WC, isChipiWalletMessage, isChipiDappMessage } from "./protocol.js";
9
- export type { ChipiRpcCall, ChipiReadyMessage, ChipiRpcRequestMessage, ChipiRpcResultMessage, ChipiEventMessage, ChipiWalletMessage, ChipiDappMessage, } from "./protocol.js";
10
- //# sourceMappingURL=index.d.ts.map
1
+ import { Connector } from '@starknet-react/core';
2
+ import { ProviderInterface, AccountInterface } from 'starknet';
3
+ import { StarknetWindowObject, RpcMessage, RequestFnCall, RpcTypeToMessageMap } from '@starknet-io/types-js';
4
+
5
+ /**
6
+ * Wire protocol between the "Connect with Chipi" connector (running in the dApp)
7
+ * and the Chipi hosted wallet (running at `wallet.chipipay.com` in a popup).
8
+ *
9
+ * Both sides import these shapes so the contract stays in lock-step. The
10
+ * transport is `window.postMessage`: the dApp opens the wallet in a popup,
11
+ * forwards get-starknet `wallet_*` RPC calls over the channel, and the wallet
12
+ * answers after the user approves in its own (already-built) approval UI.
13
+ */
14
+ /** A get-starknet RPC call as sent over the wire: just the discriminant +
15
+ * optional params (the full typed `RpcMessage` carries result/errors we don't
16
+ * serialize). */
17
+ interface ChipiRpcCall {
18
+ type: string;
19
+ params?: unknown;
20
+ }
21
+ /** Namespace tag on every message so we ignore unrelated postMessages. */
22
+ declare const CHIPI_WC: "chipi-connect/v1";
23
+ /** wallet → dApp: the hosted wallet page finished loading and is listening. */
24
+ interface ChipiReadyMessage {
25
+ channel: typeof CHIPI_WC;
26
+ type: "ready";
27
+ }
28
+ /** dApp → wallet: forward a get-starknet `wallet_*` RPC call. */
29
+ interface ChipiRpcRequestMessage {
30
+ channel: typeof CHIPI_WC;
31
+ type: "rpc";
32
+ id: string;
33
+ /** The dApp origin, so the wallet can show it + enforce Verify checks. */
34
+ origin: string;
35
+ call: ChipiRpcCall;
36
+ }
37
+ /** wallet → dApp: the result (or error) for a given request id. */
38
+ type ChipiRpcResultMessage = {
39
+ channel: typeof CHIPI_WC;
40
+ type: "rpc-result";
41
+ id: string;
42
+ ok: true;
43
+ result: unknown;
44
+ } | {
45
+ channel: typeof CHIPI_WC;
46
+ type: "rpc-result";
47
+ id: string;
48
+ ok: false;
49
+ error: {
50
+ code: number;
51
+ message: string;
52
+ };
53
+ };
54
+ /** wallet → dApp: an account/network change to propagate to the dApp. */
55
+ interface ChipiEventMessage {
56
+ channel: typeof CHIPI_WC;
57
+ type: "event";
58
+ event: "accountsChanged" | "networkChanged";
59
+ data: unknown;
60
+ }
61
+ type ChipiWalletMessage = ChipiReadyMessage | ChipiRpcResultMessage | ChipiEventMessage;
62
+ type ChipiDappMessage = ChipiRpcRequestMessage;
63
+ declare function isChipiWalletMessage(data: unknown): data is ChipiWalletMessage;
64
+ /** Type guard for a dApp→wallet message (used by the hosted wallet side). */
65
+ declare function isChipiDappMessage(data: unknown): data is ChipiDappMessage;
66
+
67
+ /**
68
+ * Client-side (dApp) transport: opens the Chipi hosted wallet in a popup,
69
+ * performs the ready handshake, and forwards get-starknet `wallet_*` RPC calls
70
+ * over `postMessage`, correlating responses by id. The popup is reused across
71
+ * requests; if the user closed it, the next request reopens it.
72
+ */
73
+
74
+ interface ChipiTransportOptions {
75
+ /** Hosted wallet base URL, e.g. `https://wallet.chipipay.com`. */
76
+ walletUrl: string;
77
+ /**
78
+ * Transport mode:
79
+ * - `"popup"` (default): open the hosted wallet in a popup window: the
80
+ * universal model, works for any external dApp.
81
+ * - `"parent"`: the dApp is embedded in an iframe INSIDE the Chipi wallet
82
+ * (in-app browser); talk to `window.parent` instead of opening a popup, so
83
+ * approval renders inline in the wallet. Only works when the dApp is
84
+ * actually iframed by the Chipi host.
85
+ * - `"auto"`: use `"parent"` when running inside an iframe, else `"popup"`.
86
+ */
87
+ mode?: "popup" | "parent" | "auto";
88
+ /** Popup window name. */
89
+ windowName?: string;
90
+ /** Popup window features. */
91
+ windowFeatures?: string;
92
+ /** Ready-handshake timeout (ms). */
93
+ openTimeoutMs?: number;
94
+ }
95
+ type EventName = "accountsChanged" | "networkChanged";
96
+ type EventHandler = (data: unknown) => void;
97
+ declare class ChipiPopupTransport {
98
+ private readonly opts;
99
+ private readonly walletOrigin;
100
+ private readonly url;
101
+ private target;
102
+ private ownsTarget;
103
+ private ready;
104
+ private listening;
105
+ private readonly pending;
106
+ private readonly handlers;
107
+ private readyDeferred;
108
+ private openPromise;
109
+ private closeWatch;
110
+ constructor(opts: ChipiTransportOptions);
111
+ on(event: EventName, handler: EventHandler): void;
112
+ off(event: EventName, handler: EventHandler): void;
113
+ private ensureListener;
114
+ private onMessage;
115
+ /** Resolve "auto" → "parent" when iframed, else "popup". */
116
+ private resolveMode;
117
+ /** Open (or reuse) the wallet (popup window OR the parent frame) and wait for
118
+ * its ready handshake. Concurrent calls share ONE handshake. */
119
+ open(): Promise<void>;
120
+ private doOpen;
121
+ private awaitReady;
122
+ /** Reject every in-flight request (popup closed / disconnected). */
123
+ private rejectAllPending;
124
+ /** While requests are in flight, watch for the user closing the popup and
125
+ * reject them: otherwise the dApp's promise would hang forever. */
126
+ private startCloseWatch;
127
+ private stopCloseWatch;
128
+ /** Forward a get-starknet RPC call to the wallet, awaiting its response. */
129
+ request(call: ChipiRpcCall): Promise<unknown>;
130
+ /** Close the popup (if we own one) + reject in-flight requests. */
131
+ close(): void;
132
+ }
133
+
134
+ /**
135
+ * `ChipiConnector`: a starknet-react / get-starknet connector for the Chipi
136
+ * hosted smart-account wallet. A self-contained connector package any dApp
137
+ * adds to its `connectors` array (`new ChipiConnector()`) directly: no
138
+ * whitelisting, no dependency on a third-party wallet kit, and NO browser
139
+ * extension required. Clicking "Connect with Chipi" opens our hosted wallet
140
+ * (passkey + gasless paymaster) in a popup; the dApp's `wallet_*` RPC calls are
141
+ * forwarded over postMessage and answered after the user approves in Chipi's
142
+ * own (already-built) approval UI.
143
+ */
144
+
145
+ type ConnectorIcons = StarknetWindowObject["icon"];
146
+ type ConnectorData = {
147
+ account?: string;
148
+ chainId?: bigint;
149
+ };
150
+ interface ChipiConnectorOptions {
151
+ /** Hosted wallet base URL. Defaults to `https://wallet.chipipay.com`. */
152
+ walletUrl?: string;
153
+ /** Override the connector id / display name / icon if embedding. */
154
+ id?: string;
155
+ name?: string;
156
+ icon?: ConnectorIcons;
157
+ transport?: ChipiTransportOptions;
158
+ /**
159
+ * Self-register the wallet on `window` (set `window.starknet_chipi` + announce
160
+ * via `starknet:announceWallet`) so dApps that *scan* for wallets, raw
161
+ * get-starknet / Wallet-Standard consumers that don't import this connector,
162
+ * also discover "Connect with Chipi". Defaults to `true` in a browser; pass
163
+ * `false` to opt out (e.g. to avoid a double entry in a picker that already
164
+ * lists the connector explicitly). No-op during SSR.
165
+ */
166
+ register?: boolean;
167
+ }
168
+ declare class ChipiConnector extends Connector {
169
+ private readonly transport;
170
+ private readonly _id;
171
+ private readonly _name;
172
+ private readonly _icon;
173
+ private _account;
174
+ private _swo;
175
+ private _registration;
176
+ constructor(options?: ChipiConnectorOptions);
177
+ /**
178
+ * Announce this wallet to scanning dApps (`window.starknet_chipi` +
179
+ * `starknet:announceWallet`). Called automatically from the constructor
180
+ * unless `register: false`. Idempotent and SSR-safe.
181
+ */
182
+ register(): void;
183
+ /** Undo {@link register}: remove the window object + announce listener. */
184
+ unregister(): void;
185
+ get id(): string;
186
+ get name(): string;
187
+ get icon(): ConnectorIcons;
188
+ /** Hosted wallet: always available (no extension to detect). */
189
+ available(): boolean;
190
+ /** No silent reconnect in v1: the user re-approves the popup each session. */
191
+ ready(): Promise<boolean>;
192
+ /** Lazily build the postMessage-backed get-starknet window object. */
193
+ private swo;
194
+ connect(): Promise<ConnectorData>;
195
+ disconnect(): Promise<void>;
196
+ private emitEvent;
197
+ account(provider: ProviderInterface): Promise<AccountInterface>;
198
+ chainId(): Promise<bigint>;
199
+ request<T extends RpcMessage["type"]>(call: RequestFnCall<T>): Promise<RpcTypeToMessageMap[T]["result"]>;
200
+ }
201
+
202
+ /**
203
+ * Plain-function form of {@link ChipiConnector}, for parity with
204
+ * `@starknet-react/core`'s built-in factories (`ready()`, `braavos()`):
205
+ *
206
+ * const connectors = [chipi(), ready(), braavos()];
207
+ *
208
+ * Equivalent to `new ChipiConnector(options)`: use whichever reads better
209
+ * in your `connectors` array.
210
+ */
211
+ declare function chipi(options?: ChipiConnectorOptions): ChipiConnector;
212
+
213
+ /** Window key get-starknet discovers by scanning for `starknet*` properties. */
214
+ declare const CHIPI_WINDOW_KEY = "starknet_chipi";
215
+ interface ChipiRegistration {
216
+ /** Remove `window.starknet_chipi` + the announce listener. */
217
+ dispose: () => void;
218
+ }
219
+ /**
220
+ * Make a Chipi `StarknetWindowObject` discoverable to any get-starknet /
221
+ * starknet-react / starknetkit dApp on the page: WITHOUT an upstream PR and
222
+ * WITHOUT whitelisting. This self-registration covers the apps that scan for
223
+ * wallets rather than importing our connector explicitly.
224
+ *
225
+ * Discovery is announced two ways for maximum reach:
226
+ * 1. **window scan**: set `window.starknet_chipi`. get-starknet v4's
227
+ * `getAvailableWallets()` finds every `window` key starting with `starknet`.
228
+ * 2. **event announce**: dispatch `starknet:announceWallet` now and again on
229
+ * the dApp's `starknet:requestWallets` (the EIP-6963-style, timing-robust
230
+ * Starknet Wallet Standard discovery path).
231
+ *
232
+ * SSR-safe (no-ops when there's no `window`) and idempotent per (target, wallet).
233
+ */
234
+ declare function registerChipiWallet(wallet: StarknetWindowObject, target?: (Window & typeof globalThis) | undefined): ChipiRegistration;
235
+
236
+ export { CHIPI_WC, CHIPI_WINDOW_KEY, ChipiConnector, type ChipiConnectorOptions, type ChipiDappMessage, type ChipiEventMessage, ChipiPopupTransport, type ChipiReadyMessage, type ChipiRegistration, type ChipiRpcCall, type ChipiRpcRequestMessage, type ChipiRpcResultMessage, type ChipiTransportOptions, type ChipiWalletMessage, chipi, isChipiDappMessage, isChipiWalletMessage, registerChipiWallet };