@chipi-stack/starknet-connector 0.2.0 → 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.ts CHANGED
@@ -1,10 +1,372 @@
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, RequestFn } 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 closes it, later requests reject with `POPUP_CLOSED`
72
+ * instead of reopening it: `window.open` outside a click is blocked by
73
+ * browsers, so the dApp must call `connect()` (or `open()`) again from a click.
74
+ */
75
+
76
+ interface ChipiTransportOptions {
77
+ /** Hosted wallet base URL, e.g. `https://wallet.chipipay.com`. */
78
+ walletUrl: string;
79
+ /**
80
+ * Transport mode:
81
+ * - `"popup"` (default): open the hosted wallet in a popup window: the
82
+ * universal model, works for any external dApp.
83
+ * - `"parent"`: the dApp is embedded in an iframe INSIDE the Chipi wallet
84
+ * (in-app browser); talk to `window.parent` instead of opening a popup, so
85
+ * approval renders inline in the wallet. Only works when the dApp is
86
+ * actually iframed by the Chipi host.
87
+ * - `"auto"`: use `"parent"` when running inside an iframe, else `"popup"`.
88
+ */
89
+ mode?: "popup" | "parent" | "auto";
90
+ /** Popup window name. */
91
+ windowName?: string;
92
+ /** Popup window features. */
93
+ windowFeatures?: string;
94
+ /** Ready-handshake timeout (ms). Defaults to 180_000. On timeout the popup is
95
+ * closed and the transport resets, so the next `open()` starts clean. */
96
+ openTimeoutMs?: number;
97
+ /**
98
+ * Per-request timeout (ms), counted from when the request is posted to the
99
+ * wallet. Defaults to 120_000. A request that gets no answer in time rejects
100
+ * with an Error whose `code` (and `name`) is `"REQUEST_TIMEOUT"`. Pass `0` to
101
+ * disable.
102
+ */
103
+ requestTimeoutMs?: number;
104
+ }
105
+ /** Error codes the transport attaches to `Error.code` (besides wallet codes). */
106
+ type ChipiTransportErrorCode = "REQUEST_TIMEOUT" | "POPUP_CLOSED";
107
+ type EventName = "accountsChanged" | "networkChanged";
108
+ type EventHandler = (data: unknown) => void;
109
+ declare class ChipiPopupTransport {
110
+ private readonly opts;
111
+ private readonly walletOrigin;
112
+ private readonly url;
113
+ private target;
114
+ private ownsTarget;
115
+ private ready;
116
+ private listening;
117
+ private readonly pending;
118
+ private readonly handlers;
119
+ private readyDeferred;
120
+ private openPromise;
121
+ private closeWatch;
122
+ /** True once this transport opened a popup. A later request with no live
123
+ * popup means the user closed it: reject instead of reopening off-gesture. */
124
+ private hadPopup;
125
+ constructor(opts: ChipiTransportOptions);
126
+ on(event: EventName, handler: EventHandler): void;
127
+ off(event: EventName, handler: EventHandler): void;
128
+ private ensureListener;
129
+ private onMessage;
130
+ /** Resolve "auto" → "parent" when iframed, else "popup". */
131
+ private resolveMode;
132
+ /** Open (or reuse) the wallet (popup window OR the parent frame) and wait for
133
+ * its ready handshake. Concurrent calls share ONE handshake. */
134
+ open(): Promise<void>;
135
+ private doOpen;
136
+ /** Close the popup (if we own one) and forget the target + ready state. */
137
+ private resetTarget;
138
+ private awaitReady;
139
+ /** Reject every in-flight request (popup closed / disconnected). */
140
+ private rejectAllPending;
141
+ /** While requests are in flight, watch for the user closing the popup and
142
+ * reject them: otherwise the dApp's promise would hang forever. */
143
+ private startCloseWatch;
144
+ private stopCloseWatch;
145
+ /**
146
+ * Forward a get-starknet RPC call to the wallet, awaiting its response.
147
+ *
148
+ * The first request may open the popup. Once a popup has been opened, a
149
+ * request made after it was closed rejects with `code: "POPUP_CLOSED"`
150
+ * instead of calling `window.open` again: requests usually run outside a
151
+ * click, where browsers block popups. Reopen via `connect()` / `open()`
152
+ * from a click.
153
+ */
154
+ request(call: ChipiRpcCall): Promise<unknown>;
155
+ /** Close the popup (if we own one) + reject in-flight requests. */
156
+ close(): void;
157
+ }
158
+
159
+ /**
160
+ * `ChipiConnector`: a starknet-react / get-starknet connector for the Chipi
161
+ * hosted smart-account wallet. A self-contained connector package any dApp
162
+ * adds to its `connectors` array (`new ChipiConnector()`) directly: no
163
+ * whitelisting, no dependency on a third-party wallet kit, and NO browser
164
+ * extension required. Clicking "Connect with Chipi" opens our hosted wallet
165
+ * (passkey + gasless paymaster) in a popup; the dApp's `wallet_*` RPC calls are
166
+ * forwarded over postMessage and answered after the user approves in Chipi's
167
+ * own (already-built) approval UI.
168
+ */
169
+
170
+ type ConnectorIcons = StarknetWindowObject["icon"];
171
+ type ConnectorData = {
172
+ account?: string;
173
+ chainId?: bigint;
174
+ };
175
+ /** Mirrors starknet-react's `ConnectArgs` (not exported by every version). */
176
+ type ConnectArgs = {
177
+ chainIdHint?: bigint;
178
+ };
179
+ interface ChipiConnectorOptions {
180
+ /** Hosted wallet base URL. Defaults to `https://wallet.chipipay.com`. */
181
+ walletUrl?: string;
182
+ /** Override the connector id / display name / icon if embedding. */
183
+ id?: string;
184
+ name?: string;
185
+ icon?: ConnectorIcons;
186
+ transport?: ChipiTransportOptions;
187
+ /**
188
+ * Self-register the wallet on `window` (set `window.starknet_chipi` + announce
189
+ * via `starknet:announceWallet`) so dApps that *scan* for wallets, raw
190
+ * get-starknet / Wallet-Standard consumers that don't import this connector,
191
+ * also discover "Connect with Chipi". Defaults to `true` in a browser; pass
192
+ * `false` to opt out (e.g. to avoid a double entry in a picker that already
193
+ * lists the connector explicitly). No-op during SSR.
194
+ */
195
+ register?: boolean;
196
+ }
197
+ declare class ChipiConnector extends Connector {
198
+ private readonly transport;
199
+ private readonly _id;
200
+ private readonly _name;
201
+ private readonly _icon;
202
+ private _account;
203
+ private _swo;
204
+ private _registration;
205
+ private readonly _autoRegister;
206
+ constructor(options?: ChipiConnectorOptions);
207
+ /**
208
+ * Announce this wallet to scanning dApps (`window.starknet_chipi` +
209
+ * `starknet:announceWallet`). Called automatically from the constructor
210
+ * unless `register: false`. Idempotent and SSR-safe.
211
+ */
212
+ register(): void;
213
+ /** Undo {@link register}: remove the window object + announce listener. */
214
+ unregister(): void;
215
+ get id(): string;
216
+ get name(): string;
217
+ get icon(): ConnectorIcons;
218
+ /** Hosted wallet: always available (no extension to detect). */
219
+ available(): boolean;
220
+ /** No silent reconnect in v1: the user re-approves the popup each session. */
221
+ ready(): Promise<boolean>;
222
+ /** Lazily build the postMessage-backed get-starknet window object. */
223
+ private swo;
224
+ /**
225
+ * Open the hosted wallet (call from a click: it opens a popup) and request
226
+ * the account. Chipi is mainnet-only: a `chainIdHint` other than SN_MAIN
227
+ * rejects before any popup opens.
228
+ */
229
+ connect(args?: ConnectArgs): Promise<ConnectorData>;
230
+ disconnect(): Promise<void>;
231
+ /** Forward the wallet's account/network events as starknet-react events. */
232
+ private subscribe;
233
+ private unsubscribe;
234
+ private onAccountsChanged;
235
+ private onNetworkChanged;
236
+ private emitEvent;
237
+ account(provider: ProviderInterface): Promise<AccountInterface>;
238
+ chainId(): Promise<bigint>;
239
+ request<T extends RpcMessage["type"]>(call: RequestFnCall<T>): Promise<RpcTypeToMessageMap[T]["result"]>;
240
+ }
241
+
242
+ /**
243
+ * Plain-function form of {@link ChipiConnector}, for parity with
244
+ * `@starknet-react/core`'s built-in factories (`ready()`, `braavos()`):
245
+ *
246
+ * const connectors = [chipi(), ready(), braavos()];
247
+ *
248
+ * Equivalent to `new ChipiConnector(options)`: use whichever reads better
249
+ * in your `connectors` array.
250
+ */
251
+ declare function chipi(options?: ChipiConnectorOptions): ChipiConnector;
252
+
253
+ /** Window key get-starknet discovers by scanning for `starknet*` properties. */
254
+ declare const CHIPI_WINDOW_KEY = "starknet_chipi";
255
+ interface ChipiRegistration {
256
+ /** Remove `window.starknet_chipi` + the announce listener. */
257
+ dispose: () => void;
258
+ }
259
+ /**
260
+ * Make a Chipi `StarknetWindowObject` discoverable to any get-starknet /
261
+ * starknet-react / starknetkit dApp on the page: WITHOUT an upstream PR and
262
+ * WITHOUT whitelisting. This self-registration covers the apps that scan for
263
+ * wallets rather than importing our connector explicitly.
264
+ *
265
+ * Discovery is announced two ways for maximum reach:
266
+ * 1. **window scan**: set `window.starknet_chipi`. get-starknet v4's
267
+ * `getAvailableWallets()` finds every `window` key starting with `starknet`.
268
+ * 2. **event announce**: dispatch `starknet:announceWallet` now and again on
269
+ * the dApp's `starknet:requestWallets` (the EIP-6963-style, timing-robust
270
+ * Starknet Wallet Standard discovery path).
271
+ *
272
+ * SSR-safe (no-ops when there's no `window`) and idempotent per (target, wallet).
273
+ */
274
+ declare function registerChipiWallet(wallet: StarknetWindowObject, target?: (Window & typeof globalThis) | undefined): ChipiRegistration;
275
+
276
+ /**
277
+ * Chipi as a Wallet Standard wallet with Starknet features
278
+ * (`WalletWithStarknetFeatures` from `@starknet-io/get-starknet-wallet-standard`),
279
+ * so dApps on get-starknet v5+/v6 discovery (`@starknet-io/get-starknet-discovery`,
280
+ * `@starknet-start/react`, anything that listens for
281
+ * `wallet-standard:register-wallet`) list "Chipi" without importing this
282
+ * package's connector.
283
+ *
284
+ * Backed by the same popup transport as {@link ChipiConnector}. The types
285
+ * below mirror the upstream interfaces structurally so this package keeps no
286
+ * runtime (or type) dependency on `@wallet-standard/*`.
287
+ */
288
+
289
+ /** Wallet Standard chain id for Starknet mainnet: `starknet:` + hex of "SN_MAIN"
290
+ * (same as `WELL_KNOWN_STARKNET_CHAINS[0]` in get-starknet-wallet-standard). */
291
+ declare const CHIPI_STARKNET_MAINNET_CHAIN: "starknet:0x534e5f4d41494e";
292
+ /** `starknet:0x...` chain identifier. */
293
+ type ChipiStarknetChain = `starknet:0x${string}`;
294
+ /** Data-URI icon, as Wallet Standard requires. */
295
+ type ChipiWalletIcon = `data:image/${"svg+xml" | "webp" | "png" | "gif"};base64,${string}`;
296
+ /** Mirrors `@wallet-standard/base` `WalletAccount`. */
297
+ interface ChipiStandardWalletAccount {
298
+ readonly address: string;
299
+ readonly publicKey: Uint8Array;
300
+ readonly chains: readonly ChipiStarknetChain[];
301
+ readonly features: readonly `${string}:${string}`[];
302
+ }
303
+ /** Mirrors `@wallet-standard/features` `StandardEventsChangeProperties`. */
304
+ interface ChipiStandardChangeProperties {
305
+ readonly chains?: readonly ChipiStarknetChain[];
306
+ readonly accounts?: readonly ChipiStandardWalletAccount[];
307
+ }
308
+ /** Mirrors `StarknetFeatures` from `@starknet-io/get-starknet-wallet-standard`.
309
+ * (A type alias, not an interface, so it satisfies Wallet Standard's
310
+ * `IdentifierRecord` index signature.) */
311
+ type ChipiStandardWalletFeatures = {
312
+ readonly "starknet:walletApi": {
313
+ readonly version: "1.0.0";
314
+ readonly request: RequestFn;
315
+ readonly walletVersion: string;
316
+ readonly id: string;
317
+ };
318
+ readonly "standard:connect": {
319
+ readonly version: "1.0.0";
320
+ readonly connect: (input?: {
321
+ readonly silent?: boolean;
322
+ }) => Promise<{
323
+ readonly accounts: readonly ChipiStandardWalletAccount[];
324
+ }>;
325
+ };
326
+ readonly "standard:disconnect": {
327
+ readonly version: "1.0.0";
328
+ readonly disconnect: () => Promise<void>;
329
+ };
330
+ readonly "standard:events": {
331
+ readonly version: "1.0.0";
332
+ readonly on: <E extends "change">(event: E, listener: (properties: ChipiStandardChangeProperties) => void) => () => void;
333
+ };
334
+ };
335
+ /** Structurally a `WalletWithStarknetFeatures`. */
336
+ interface ChipiStandardWallet {
337
+ readonly version: "1.0.0";
338
+ readonly name: string;
339
+ readonly icon: ChipiWalletIcon;
340
+ readonly chains: readonly ChipiStarknetChain[];
341
+ readonly accounts: readonly ChipiStandardWalletAccount[];
342
+ readonly features: ChipiStandardWalletFeatures;
343
+ }
344
+ interface ChipiStandardWalletOptions {
345
+ /** Hosted wallet base URL. Defaults to `https://wallet.chipipay.com`. */
346
+ walletUrl?: string;
347
+ /** Display name. Defaults to `"Chipi"`. */
348
+ name?: string;
349
+ /** Data-URI icon. Defaults to the Chipi icon. */
350
+ icon?: ChipiWalletIcon;
351
+ /** Popup transport tuning (window name/features, timeouts). */
352
+ transport?: Omit<ChipiTransportOptions, "walletUrl" | "mode">;
353
+ }
354
+ /**
355
+ * Build the Chipi Wallet Standard wallet (without registering it). `connect`
356
+ * opens the popup, so dApps call it from a click; `connect({ silent: true })`
357
+ * never opens a popup and returns the current accounts (empty if not
358
+ * connected).
359
+ */
360
+ declare function createChipiStandardWallet(options?: ChipiStandardWalletOptions): ChipiStandardWallet;
361
+ /**
362
+ * Register Chipi with every Wallet Standard app on the page: dispatches
363
+ * `wallet-standard:register-wallet` now and answers later
364
+ * `wallet-standard:app-ready` events (the `@wallet-standard/wallet`
365
+ * `registerWallet` protocol, implemented here without the dependency).
366
+ *
367
+ * Returns an unregister function that removes the listener and unregisters
368
+ * from every app that accepted the wallet. SSR-safe: a no-op without `window`.
369
+ */
370
+ declare function registerChipiStandardWallet(options?: ChipiStandardWalletOptions, target?: (Window & typeof globalThis) | undefined): () => void;
371
+
372
+ export { CHIPI_STARKNET_MAINNET_CHAIN, CHIPI_WC, CHIPI_WINDOW_KEY, ChipiConnector, type ChipiConnectorOptions, type ChipiDappMessage, type ChipiEventMessage, ChipiPopupTransport, type ChipiReadyMessage, type ChipiRegistration, type ChipiRpcCall, type ChipiRpcRequestMessage, type ChipiRpcResultMessage, type ChipiStandardChangeProperties, type ChipiStandardWallet, type ChipiStandardWalletAccount, type ChipiStandardWalletFeatures, type ChipiStandardWalletOptions, type ChipiStarknetChain, type ChipiTransportErrorCode, type ChipiTransportOptions, type ChipiWalletIcon, type ChipiWalletMessage, chipi, createChipiStandardWallet, isChipiDappMessage, isChipiWalletMessage, registerChipiStandardWallet, registerChipiWallet };