@chipi-stack/starknet-connector 0.4.0 → 0.5.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/README.md CHANGED
@@ -1,35 +1,41 @@
1
1
  # @chipi-stack/starknet-connector
2
2
 
3
- **"Connect with Chipi"**, a [starknet-react](https://starknet-react.com) /
4
- [get-starknet](https://github.com/starknet-io/get-starknet) connector that lets
5
- any Starknet dApp connect to a **Chipi hosted smart-account wallet** (passkey,
6
- gasless via paymaster). No browser extension, no WalletConnect, no whitelisting,
7
- just add the package to your own dApp and it works.
3
+ "Connect with Chipi" for Starknet dApps. A [starknet-react](https://starknet-react.com) /
4
+ [get-starknet](https://github.com/starknet-io/get-starknet) connector that opens the user's
5
+ Chipi wallet (passkey, gasless) in a popup. No browser extension, no WalletConnect, no
6
+ whitelisting. It works next to injected wallets such as Bramble, Ready and Braavos.
8
7
 
9
8
  ```bash
10
9
  npm install @chipi-stack/starknet-connector
11
10
  ```
12
11
 
13
- Ships both ESM and CommonJS. Versions before 0.3.0 were ESM-only and failed
14
- under any CommonJS resolver (plain Node, `tsx`, `ts-node`, Jest) with
15
- `ERR_PACKAGE_PATH_NOT_EXPORTED`. Bundlers were never affected.
12
+ Ships ESM and CommonJS. Versions before 0.3.0 were ESM-only and failed under CommonJS
13
+ resolvers (plain Node, `tsx`, `ts-node`, Jest) with `ERR_PACKAGE_PATH_NOT_EXPORTED`.
16
14
 
17
- ## Use it
15
+ ## Use it with starknet-react
18
16
 
19
- Add one connector to your `StarknetConfig`:
17
+ Offer Chipi next to Bramble, Ready and Braavos:
20
18
 
21
19
  ```tsx
22
- import { StarknetConfig, publicProvider, argent, braavos } from "@starknet-react/core";
20
+ import type { ReactNode } from "react";
21
+ import {
22
+ StarknetConfig,
23
+ InjectedConnector,
24
+ publicProvider,
25
+ ready,
26
+ braavos,
27
+ } from "@starknet-react/core";
23
28
  import { mainnet } from "@starknet-react/chains";
24
29
  import { chipi } from "@chipi-stack/starknet-connector";
25
30
 
26
31
  const connectors = [
27
32
  chipi(), // "Connect with Chipi"
28
- argent(),
33
+ new InjectedConnector({ options: { id: "bramble", name: "Bramble" } }),
34
+ ready(), // Ready (formerly Argent X)
29
35
  braavos(),
30
36
  ];
31
37
 
32
- export function App({ children }) {
38
+ export function Providers({ children }: { children: ReactNode }) {
33
39
  return (
34
40
  <StarknetConfig chains={[mainnet]} provider={publicProvider()} connectors={connectors}>
35
41
  {children}
@@ -38,9 +44,122 @@ export function App({ children }) {
38
44
  }
39
45
  ```
40
46
 
41
- That's it. Your existing `useConnect` / `useAccount` flow now offers "Connect
42
- with Chipi", and `account.signMessage(...)` / `account.execute(...)` route to the
43
- user's Chipi wallet, **gasless**, signed with their passkey.
47
+ Your `useConnect` / `useAccount` flow now offers all four. With Chipi, `account.execute(...)`
48
+ and `account.signMessage(...)` go to the user's Chipi wallet: gasless, signed with their
49
+ passkey.
50
+
51
+ Notes for `@starknet-react/core` 5:
52
+
53
+ - List every wallet yourself. `useInjectedConnectors` only picks up objects with the legacy keys
54
+ (`provider`, `isConnected`, `enable`, `isPreauthorized`). Neither `window.starknet_chipi` nor
55
+ `window.starknet_bramble` has all of them, so it finds neither.
56
+ - `injected({ id: "bramble" })` also works, but in 5.0.3 `injected()` takes only `id`. The label
57
+ is then the wallet's own name once Bramble has injected, and `"bramble"` before that.
58
+ - `argent()` is an alias of `ready()`. Use `ready()`.
59
+ - `InjectedConnector` looks up `window.starknet_bramble` each time it is used, so Bramble's late
60
+ injection is fine. `autoConnect` runs once on mount, though: if Bramble has not injected by
61
+ then, the last Bramble session is not restored.
62
+
63
+ ## Use it with get-starknet v4
64
+
65
+ get-starknet v4 (`@starknet-io/get-starknet-core`) lists every `window.starknet*` object that
66
+ has `id`, `name`, `version`, `icon`, `request`, `on` and `off`. Creating a Chipi connector puts
67
+ `window.starknet_chipi` on the page, so both wallets show up:
68
+
69
+ ```ts
70
+ import { getStarknet } from "@starknet-io/get-starknet-core";
71
+ import { chipi } from "@chipi-stack/starknet-connector";
72
+
73
+ declare const connectButton: HTMLButtonElement;
74
+ declare function pickedWalletId(): "chipi" | "bramble"; // from your wallet picker
75
+
76
+ // Puts window.starknet_chipi on the page.
77
+ chipi();
78
+
79
+ // Bramble injects window.starknet_bramble after page load, then fires
80
+ // "starknet#initialized". Scan after that, or after a short timeout.
81
+ function waitForInjectedWallets(timeoutMs = 3000): Promise<void> {
82
+ return new Promise((resolve) => {
83
+ if ("starknet_bramble" in window) return resolve();
84
+ const done = () => {
85
+ clearTimeout(timer);
86
+ window.removeEventListener("starknet#initialized", done);
87
+ resolve();
88
+ };
89
+ const timer = setTimeout(done, timeoutMs);
90
+ window.addEventListener("starknet#initialized", done);
91
+ });
92
+ }
93
+
94
+ await waitForInjectedWallets();
95
+ const gsc = getStarknet();
96
+ const wallets = await gsc.getAvailableWallets();
97
+ // Both are listed: wallets.map((w) => w.id) includes "chipi" and "bramble".
98
+
99
+ // Prompts only from a click: Chipi opens its popup, Bramble its side panel.
100
+ connectButton.onclick = async () => {
101
+ const wallet = wallets.find((w) => w.id === pickedWalletId());
102
+ if (wallet) await gsc.enable(wallet);
103
+ };
104
+ ```
105
+
106
+ `getAuthorizedWallets()` and `getLastConnectedWallet()` send `wallet_getPermissions` to every
107
+ wallet at page load. Chipi answers that locally with `[]` and does not open its popup (see
108
+ [Passive calls](#passive-calls)). There is no silent reconnect: the user clicks connect again
109
+ on each page load.
110
+
111
+ Bramble's guide notes that get-starknet v3 also requires a `provider` key, which Bramble lacks.
112
+ Chipi's object lacks it too.
113
+
114
+ ## Wallet Standard (get-starknet v5 and v6)
115
+
116
+ `@starknet-io/get-starknet-discovery` (5.0.0 and 6.0.6 ship the same code) builds its list in
117
+ `createStore()`:
118
+
119
+ - Wallet Standard wallets register through `wallet-standard:register-wallet`, at any time.
120
+ - `window.starknet*` objects are scanned once, when `createStore()` runs, and wrapped as
121
+ injected wallets. Entries are de-duplicated by name, and a Wallet Standard entry wins.
122
+
123
+ Bramble has no Wallet Standard registration, so get-starknet v5/v6 lists it only if
124
+ `window.starknet_bramble` exists when `createStore()` runs. Register Chipi as a Wallet Standard
125
+ wallet so the order does not matter:
126
+
127
+ ```ts
128
+ import { registerChipiStandardWallet } from "@chipi-stack/starknet-connector";
129
+
130
+ const unregister = registerChipiStandardWallet({
131
+ walletUrl: "https://wallet.chipipay.com", // default
132
+ });
133
+ // later: unregister();
134
+ ```
135
+
136
+ It dispatches `wallet-standard:register-wallet` and answers `wallet-standard:app-ready`, with no
137
+ extra dependency. It exposes `starknet:walletApi`, `standard:connect`, `standard:disconnect` and
138
+ `standard:events` on `starknet:0x534e5f4d41494e` (mainnet), backed by the same popup.
139
+ `connect({ silent: true })` never opens the popup. Its default name is `"Chipi"`; the
140
+ connector's is `"Connect with Chipi"`. If `window.starknet_chipi` also exists when the store is
141
+ created, the store lists two Chipi entries: pass `register: false` to the connector, or give both
142
+ the same `name`. `createChipiStandardWallet(options)` builds the wallet
143
+ without registering it.
144
+
145
+ ## Works next to Bramble
146
+
147
+ - **No id collision.** Chipi is `window.starknet_chipi` with id `"chipi"`. Bramble is
148
+ `window.starknet_bramble` with id `"bramble"`. get-starknet v4 and starknet-react key wallets
149
+ by id, so both are listed.
150
+ - **Neither writes `window.starknet`.**
151
+ - **When each object exists.** `window.starknet_chipi` exists only after a `ChipiConnector` is
152
+ created (unless `register: false`). `disconnect()` removes it until the next `connect()`.
153
+ `window.starknet_bramble` appears after page load, followed by a `starknet#initialized` event.
154
+ - **A wallet scan never opens Chipi.** Since 0.5.0, the calls scanners send at page load are
155
+ answered without opening the popup (see [Passive calls](#passive-calls)).
156
+ - **Bramble's own rules apply to Bramble.** Prompts only from a click, at most 5 pending prompts
157
+ per site, strict params (an extra key fails with `114`), a typed-data `chainId` equal to its
158
+ active network, no `wallet_disconnect` (`114`), one account per site. Signatures are `[r, s]`
159
+ for OpenZeppelin and Braavos accounts and `["1", "0", pub, r, s]` for Argent accounts: verify
160
+ them with the account's `is_valid_signature`, not by length. starknet-react's
161
+ `InjectedConnector.disconnect()` does not send `wallet_disconnect`. See
162
+ [Bramble rules to follow](https://docs.chipipay.com/sdk/guides/trusted-wallets#bramble-rules-to-follow).
44
163
 
45
164
  ## How it works
46
165
 
@@ -54,96 +173,88 @@ account.execute(calls)
54
173
  └─ wallet_addInvokeTransaction ─► user approves ─► sponsored tx ─► tx hash
55
174
  ```
56
175
 
57
- - The connector is **transport only**: it opens the hosted wallet in a popup and
58
- forwards get-starknet `wallet_*` RPC calls over `postMessage`. It holds no
59
- keys and signs nothing itself.
60
- - The hosted wallet renders a **decoded approval** for every sign/execute (it
61
- shows the actual intent, token, amount, spender, and hard-blocks typed data
62
- it can't read), then runs the real passkey + paymaster path.
63
- - `account()` wraps the channel in a `starknet.js` `WalletAccount`, so the dApp
64
- uses a standard `AccountInterface`.
176
+ - The connector only carries messages. It opens the hosted wallet in a popup and forwards
177
+ get-starknet `wallet_*` calls over `postMessage`. It holds no keys and signs nothing.
178
+ - Each request is posted right away and matched to its answer by id. Several can be in flight at
179
+ once; the connector neither queues nor rejects them.
180
+ - `account()` wraps the channel in a starknet.js `WalletAccount`, so the dApp gets a standard
181
+ `AccountInterface`.
182
+ - There is no silent reconnect. `ready()` is `true` only after `connect()` succeeded on this
183
+ page. Call `connect()` from a click: it opens a popup.
184
+ - Chipi is mainnet-only. `chainId()` always returns `SN_MAIN`.
185
+
186
+ ## Passive calls
187
+
188
+ While no wallet window is open (before `connect()`, or after the user closed it), the connector
189
+ answers these calls itself and does not open the popup. Once the window is open, they go to the
190
+ wallet.
191
+
192
+ | Call | Answer with no wallet window open |
193
+ | ------------------------------------------------- | --------------------------------- |
194
+ | `wallet_getPermissions` | `[]` |
195
+ | `wallet_requestAccounts` with `silent_mode: true` | `[]` |
196
+ | `wallet_requestChainId` | `"0x534e5f4d41494e"` (`SN_MAIN`) |
197
+
198
+ `wallet_requestAccounts` without `silent_mode: true` opens the popup, so send it from a click.
65
199
 
66
200
  ## Options
67
201
 
68
202
  ```ts
203
+ import { chipi } from "@chipi-stack/starknet-connector";
204
+
69
205
  chipi({
70
206
  walletUrl: "https://wallet.chipipay.com", // hosted wallet base URL (default)
71
- id: "chipi", // connector id
72
- name: "Connect with Chipi", // display name
73
- icon: "data:image/svg+xml;base64,...", // display icon
74
- register: true, // self-register on window (default)
207
+ id: "chipi", // connector id (default); the window key stays starknet_chipi
208
+ name: "Connect with Chipi", // display name (default)
209
+ icon: "data:image/png;base64,...", // default: a 48x48 PNG data URI
210
+ register: true, // put window.starknet_chipi on the page (default; no-op in SSR)
75
211
  transport: {
76
- openTimeoutMs: 180_000, // ready handshake; on timeout the popup is closed
77
- requestTimeoutMs: 120_000, // per request; 0 disables
212
+ windowName: "chipi-wallet", // default: a new random name per open
213
+ windowFeatures: "popup=yes,width=420,height=680", // default
214
+ openTimeoutMs: 180_000, // wait for the wallet page to load (default)
215
+ requestTimeoutMs: 120_000, // per request; 0 disables (default)
78
216
  },
79
217
  });
80
218
  ```
81
219
 
82
- `chipi(options)` is a thin wrapper: `new ChipiConnector(options)` still works
83
- identically if you prefer instantiating the class directly.
84
-
85
- ## Events and errors
220
+ `chipi(options)` is the same as `new ChipiConnector(options)`.
86
221
 
87
- - The connector forwards the wallet's `accountsChanged` / `networkChanged` as
88
- starknet-react `change` events (`{ account, chainId }`); an empty account list
89
- emits `disconnect`.
90
- - `connect({ chainIdHint })` rejects with `code: "UNSUPPORTED_CHAIN"` for any
91
- chain other than mainnet (`SN_MAIN`), before opening a popup.
92
- - A request that gets no answer within `requestTimeoutMs` rejects with
93
- `code: "REQUEST_TIMEOUT"`.
94
- - If the user closes the wallet window, later requests reject with
95
- `code: "POPUP_CLOSED"` instead of reopening it (browsers block popups outside
96
- a click). Call `connect()` again from a click.
97
- - `disconnect()` closes the popup and removes `window.starknet_chipi`; the next
98
- `connect()` registers it again.
222
+ ## Errors
99
223
 
100
- ## Compatibility
224
+ The connector rejects with an `Error`. Check `err.code` first, then `err.message`.
101
225
 
102
- - `@starknet-react/core` **>= 3** (peer) · tested against `5.x`
103
- - `starknet` **>= 8.1.2** (peer); `WalletAccount.connect` is identical across 8/9
104
- - **Starknet mainnet** (v1). The wallet is mainnet-only.
226
+ | `code` or message | When |
227
+ | ----------------------------------------------- | ---------------------------------------------------------------------------------------- |
228
+ | code `"UNSUPPORTED_CHAIN"` | `connect({ chainIdHint })` with a chain other than `SN_MAIN`. No popup opens. |
229
+ | code `"popup_blocked"` | The browser blocked the popup: `connect()` did not run from a click. |
230
+ | message `"wallet_open_timeout"` | The wallet page did not load within `transport.openTimeoutMs` (180 s). The popup closes. |
231
+ | code `"REQUEST_TIMEOUT"` | No answer within `transport.requestTimeoutMs` (120 s). |
232
+ | code `"POPUP_CLOSED"` | A request after the user closed the wallet window. Call `connect()` again from a click. |
233
+ | code `4001`, message `"User closed the wallet"` | The user closed the wallet window while a request was waiting. |
234
+ | code `4001`, message `"disconnected"` | `disconnect()` ran while a request, or the wallet page load, was waiting. |
235
+ | message `"chipi_no_account"` | The wallet returned no account on connect. |
236
+ | message `"chipi_not_connected"` | `account()` before `connect()`. |
237
+ | message `"chipi_connector_requires_browser"` | The popup was requested without `window` (SSR). |
238
+ | numeric code from the wallet (`113` … `163`) | The wallet's own error, passed through with its message (see below). |
105
239
 
106
- ## Discovery
240
+ Wallets built on `createChipiWindowObject` from `@chipi-stack/chipi-react` answer `113` (the
241
+ user refused), `114` (no calls, or typed data with no `chainId` or one for another chain), `115` (account
242
+ already deployed), `116` (deployment data not available) and `163` (unsupported method,
243
+ including `wallet_disconnect` and `wallet_switchStarknetChain`, or another failure).
107
244
 
108
- Instantiating the connector also **self-registers** the wallet on `window`
109
- (`window.starknet_chipi` + a `starknet:announceWallet` event, the get-starknet /
110
- Starknet-Wallet-Standard discovery path), so dApps that _scan_ for wallets find
111
- "Connect with Chipi" even if they don't import this package, no whitelisting,
112
- no coordination with us required. Pass `register: false` to opt out (e.g. to
113
- avoid a duplicate entry in a picker that already lists the connector
114
- explicitly). It's a no-op during SSR. You can also call
115
- `registerChipiWallet(swo)` directly.
245
+ ## Events
116
246
 
117
- ### Wallet Standard (get-starknet v5+ discovery)
247
+ - The wallet's `accountsChanged` / `networkChanged` become starknet-react `change` events
248
+ (`{ account, chainId }`). An empty account list emits `disconnect`.
249
+ - `disconnect()` closes the popup and removes `window.starknet_chipi`. The next `connect()` puts
250
+ it back.
118
251
 
119
- For dApps that discover wallets through the Wallet Standard
120
- (`@starknet-io/get-starknet-discovery`, `@starknet-start/react`), register Chipi
121
- as a `WalletWithStarknetFeatures` (`starknet:walletApi`, `standard:connect`,
122
- `standard:disconnect`, `standard:events`) backed by the same popup:
123
-
124
- ```ts
125
- import { registerChipiStandardWallet } from "@chipi-stack/starknet-connector";
126
-
127
- const unregister = registerChipiStandardWallet({
128
- walletUrl: "https://wallet.chipipay.com", // default
129
- });
130
- // later: unregister();
131
- ```
132
-
133
- It dispatches `wallet-standard:register-wallet` and answers
134
- `wallet-standard:app-ready`, with no extra dependency. Accounts are on
135
- `starknet:0x534e5f4d41494e` (mainnet). `connect({ silent: true })` never opens a
136
- popup. Use `createChipiStandardWallet(options)` to build the wallet object
137
- without registering it.
138
-
139
- ## Notes / limits (v1)
252
+ ## Compatibility
140
253
 
141
- - **Popup-based** (external dApps). The in-app-browser ("parent") mode is in the
142
- transport but not exposed yet; the hosted wallet side handles it in a later
143
- release.
144
- - Mainnet only, pass a mainnet `provider`.
145
- - One approval at a time; a dApp that fires two prompts truly simultaneously has
146
- its second request rejected (most dApps serialize).
254
+ - `@starknet-react/core` >= 3 (peer), tested against 5.0.3.
255
+ - `starknet` >= 8.1.2 (peer). `WalletAccount.connect` is the same in 8 and 9.
256
+ - Starknet mainnet only.
257
+ - Popup only. The in-app-browser ("parent") mode is in the transport but not exposed.
147
258
 
148
- MIT · [docs.chipipay.com](https://docs.chipipay.com) ·
259
+ MIT · [docs.chipipay.com](https://docs.chipipay.com/sdk/connector/overview) ·
149
260
  [example](https://github.com/chipi-pay/build-with-chipi/tree/main/tutorials/03-connect-with-chipi)
package/dist/index.cjs CHANGED
@@ -40,6 +40,21 @@ function deferred() {
40
40
  });
41
41
  return { promise, resolve, reject };
42
42
  }
43
+ var SN_MAIN_HEX = "0x534e5f4d41494e";
44
+ function passiveAnswer(call) {
45
+ switch (call.type) {
46
+ case "wallet_getPermissions":
47
+ return { value: [] };
48
+ case "wallet_requestAccounts": {
49
+ const params = call.params;
50
+ return params?.silent_mode === true ? { value: [] } : void 0;
51
+ }
52
+ case "wallet_requestChainId":
53
+ return { value: SN_MAIN_HEX };
54
+ default:
55
+ return void 0;
56
+ }
57
+ }
43
58
  function randomId() {
44
59
  return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
45
60
  }
@@ -199,6 +214,10 @@ var ChipiPopupTransport = class {
199
214
  /**
200
215
  * Forward a get-starknet RPC call to the wallet, awaiting its response.
201
216
  *
217
+ * With no wallet window open, passive calls are answered locally and never
218
+ * open it: `wallet_getPermissions` → `[]`, `wallet_requestAccounts` with
219
+ * `silent_mode: true` → `[]`, `wallet_requestChainId` → SN_MAIN.
220
+ *
202
221
  * The first request may open the popup. Once a popup has been opened, a
203
222
  * request made after it was closed rejects with `code: "POPUP_CLOSED"`
204
223
  * instead of calling `window.open` again: requests usually run outside a
@@ -206,6 +225,10 @@ var ChipiPopupTransport = class {
206
225
  * from a click.
207
226
  */
208
227
  async request(call) {
228
+ if (this.resolveMode() === "popup" && (!this.target || this.target.closed)) {
229
+ const passive = passiveAnswer(call);
230
+ if (passive) return passive.value;
231
+ }
209
232
  if (this.hadPopup && this.resolveMode() === "popup" && (!this.target || this.target.closed)) {
210
233
  throw transportError(
211
234
  "POPUP_CLOSED",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/protocol.ts","../src/transport.ts","../src/register.ts","../src/icon.ts","../src/connector.ts","../src/factory.ts","../src/standard.ts"],"names":["constants","Connector","WalletAccount"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Wire protocol between the \"Connect with Chipi\" connector (running in the dApp)\n * and the Chipi hosted wallet (running at `wallet.chipipay.com` in a popup).\n *\n * Both sides import these shapes so the contract stays in lock-step. The\n * transport is `window.postMessage`: the dApp opens the wallet in a popup,\n * forwards get-starknet `wallet_*` RPC calls over the channel, and the wallet\n * answers after the user approves in its own (already-built) approval UI.\n */\n/** A get-starknet RPC call as sent over the wire: just the discriminant +\n * optional params (the full typed `RpcMessage` carries result/errors we don't\n * serialize). */\nexport interface ChipiRpcCall {\n type: string;\n params?: unknown;\n}\n\n/** Namespace tag on every message so we ignore unrelated postMessages. */\nexport const CHIPI_WC = \"chipi-connect/v1\" as const;\n\n/** wallet → dApp: the hosted wallet page finished loading and is listening. */\nexport interface ChipiReadyMessage {\n channel: typeof CHIPI_WC;\n type: \"ready\";\n}\n\n/** dApp → wallet: forward a get-starknet `wallet_*` RPC call. */\nexport interface ChipiRpcRequestMessage {\n channel: typeof CHIPI_WC;\n type: \"rpc\";\n id: string;\n /** The dApp origin, so the wallet can show it + enforce Verify checks. */\n origin: string;\n call: ChipiRpcCall;\n}\n\n/** wallet → dApp: the result (or error) for a given request id. */\nexport type ChipiRpcResultMessage =\n | { channel: typeof CHIPI_WC; type: \"rpc-result\"; id: string; ok: true; result: unknown }\n | {\n channel: typeof CHIPI_WC;\n type: \"rpc-result\";\n id: string;\n ok: false;\n error: { code: number; message: string };\n };\n\n/** wallet → dApp: an account/network change to propagate to the dApp. */\nexport interface ChipiEventMessage {\n channel: typeof CHIPI_WC;\n type: \"event\";\n event: \"accountsChanged\" | \"networkChanged\";\n data: unknown;\n}\n\nexport type ChipiWalletMessage = ChipiReadyMessage | ChipiRpcResultMessage | ChipiEventMessage;\nexport type ChipiDappMessage = ChipiRpcRequestMessage;\n\nexport function isChipiWalletMessage(data: unknown): data is ChipiWalletMessage {\n return (\n typeof data === \"object\" &&\n data !== null &&\n (data as { channel?: unknown }).channel === CHIPI_WC\n );\n}\n\n/** Type guard for a dApp→wallet message (used by the hosted wallet side). */\nexport function isChipiDappMessage(data: unknown): data is ChipiDappMessage {\n return (\n typeof data === \"object\" &&\n data !== null &&\n (data as { channel?: unknown }).channel === CHIPI_WC &&\n (data as { type?: unknown }).type === \"rpc\"\n );\n}\n","/**\n * Client-side (dApp) transport: opens the Chipi hosted wallet in a popup,\n * performs the ready handshake, and forwards get-starknet `wallet_*` RPC calls\n * over `postMessage`, correlating responses by id. The popup is reused across\n * requests. If the user closes it, later requests reject with `POPUP_CLOSED`\n * instead of reopening it: `window.open` outside a click is blocked by\n * browsers, so the dApp must call `connect()` (or `open()`) again from a click.\n */\nimport {\n CHIPI_WC,\n isChipiWalletMessage,\n type ChipiRpcCall,\n type ChipiRpcRequestMessage,\n type ChipiWalletMessage,\n} from \"./protocol.js\";\n\nexport interface ChipiTransportOptions {\n /** Hosted wallet base URL, e.g. `https://wallet.chipipay.com`. */\n walletUrl: string;\n /**\n * Transport mode:\n * - `\"popup\"` (default): open the hosted wallet in a popup window: the\n * universal model, works for any external dApp.\n * - `\"parent\"`: the dApp is embedded in an iframe INSIDE the Chipi wallet\n * (in-app browser); talk to `window.parent` instead of opening a popup, so\n * approval renders inline in the wallet. Only works when the dApp is\n * actually iframed by the Chipi host.\n * - `\"auto\"`: use `\"parent\"` when running inside an iframe, else `\"popup\"`.\n */\n mode?: \"popup\" | \"parent\" | \"auto\";\n /** Popup window name. */\n windowName?: string;\n /** Popup window features. */\n windowFeatures?: string;\n /** Ready-handshake timeout (ms). Defaults to 180_000. On timeout the popup is\n * closed and the transport resets, so the next `open()` starts clean. */\n openTimeoutMs?: number;\n /**\n * Per-request timeout (ms), counted from when the request is posted to the\n * wallet. Defaults to 120_000. A request that gets no answer in time rejects\n * with an Error whose `code` (and `name`) is `\"REQUEST_TIMEOUT\"`. Pass `0` to\n * disable.\n */\n requestTimeoutMs?: number;\n}\n\n/** Error codes the transport attaches to `Error.code` (besides wallet codes). */\nexport type ChipiTransportErrorCode = \"REQUEST_TIMEOUT\" | \"POPUP_CLOSED\";\n\nfunction transportError(code: ChipiTransportErrorCode, message: string): Error {\n const err = Object.assign(new Error(message), { code });\n err.name = code;\n return err;\n}\n\n/** Drop `undefined` values from plain objects (recursively) so the wallet never\n * receives `{ key: undefined }`: a strict schema on the host side would reject\n * it, and `postMessage` would otherwise preserve the key. Arrays keep their\n * positions. */\nfunction stripUndefined<T>(value: T): T {\n if (Array.isArray(value)) return value.map((v) => stripUndefined(v)) as T;\n if (value === null || typeof value !== \"object\") return value;\n const proto = Object.getPrototypeOf(value);\n if (proto !== Object.prototype && proto !== null) return value;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (v !== undefined) out[k] = stripUndefined(v);\n }\n return out as T;\n}\n\ntype EventName = \"accountsChanged\" | \"networkChanged\";\ntype EventHandler = (data: unknown) => void;\n\nfunction deferred<T>() {\n let resolve!: (v: T) => void;\n let reject!: (e: unknown) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n return { promise, resolve, reject };\n}\n\nfunction randomId(): string {\n // App-runtime ids; uniqueness only needs to hold within one open popup.\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport class ChipiPopupTransport {\n private readonly walletOrigin: string;\n private readonly url: string;\n private target: Window | null = null;\n private ownsTarget = false;\n private ready = false;\n private listening = false;\n private readonly pending = new Map<\n string,\n {\n resolve: (v: unknown) => void;\n reject: (e: unknown) => void;\n message: ChipiRpcRequestMessage;\n timer?: ReturnType<typeof setTimeout>;\n }\n >();\n private readonly handlers = new Map<EventName, Set<EventHandler>>();\n private readyDeferred: ReturnType<typeof deferred<void>> | null = null;\n private openPromise: Promise<void> | null = null;\n private closeWatch: ReturnType<typeof setInterval> | null = null;\n /** True once this transport opened a popup. A later request with no live\n * popup means the user closed it: reject instead of reopening off-gesture. */\n private hadPopup = false;\n\n constructor(private readonly opts: ChipiTransportOptions) {\n this.url = opts.walletUrl.replace(/\\/$/, \"\") + \"/connect\";\n this.walletOrigin = new URL(opts.walletUrl).origin;\n }\n\n on(event: EventName, handler: EventHandler): void {\n (this.handlers.get(event) ?? this.handlers.set(event, new Set()).get(event)!).add(handler);\n }\n\n off(event: EventName, handler: EventHandler): void {\n this.handlers.get(event)?.delete(handler);\n }\n\n private ensureListener(): void {\n if (this.listening || typeof window === \"undefined\") return;\n window.addEventListener(\"message\", this.onMessage);\n this.listening = true;\n }\n\n private onMessage = (e: MessageEvent): void => {\n if (e.origin !== this.walletOrigin || !isChipiWalletMessage(e.data)) return;\n // Isolate to OUR wallet window: without this, a second Chipi popup (another\n // dApp, same origin) could leak its `ready`/`event` into this transport.\n // With no target (before open / after close) nothing is ours: ignore it all,\n // so a stray `ready` can't flip state and a stray `event` can't fire.\n if (!this.target || e.source !== this.target) return;\n const msg = e.data as ChipiWalletMessage;\n if (msg.type === \"ready\") {\n this.ready = true;\n this.readyDeferred?.resolve();\n this.readyDeferred = null;\n // A fresh /connect re-announces \"ready\": e.g. after the user signs in,\n // which reloads the popup onto a new page. The request we already sent went\n // to the previous page, which is gone. Re-send the requests that are still\n // unanswered (`pending` only holds those) so they reach the new page.\n // Contract: the hosted wallet MUST de-dupe by request id, because a repeat\n // `ready` (e.g. the popup's multi-post ready) re-sends the same request.\n for (const p of this.pending.values()) {\n this.target.postMessage(p.message, this.walletOrigin);\n }\n return;\n }\n if (msg.type === \"rpc-result\") {\n const p = this.pending.get(msg.id);\n if (!p) return;\n this.pending.delete(msg.id);\n if (p.timer) clearTimeout(p.timer);\n if (msg.ok) p.resolve(msg.result);\n else p.reject(Object.assign(new Error(msg.error.message), { code: msg.error.code }));\n return;\n }\n if (msg.type === \"event\") {\n this.handlers.get(msg.event)?.forEach((h) => h(msg.data));\n }\n };\n\n /** Resolve \"auto\" → \"parent\" when iframed, else \"popup\". */\n private resolveMode(): \"popup\" | \"parent\" {\n const mode = this.opts.mode ?? \"popup\";\n if (mode !== \"auto\") return mode;\n return typeof window !== \"undefined\" && window.parent !== window ? \"parent\" : \"popup\";\n }\n\n /** Open (or reuse) the wallet (popup window OR the parent frame) and wait for\n * its ready handshake. Concurrent calls share ONE handshake. */\n async open(): Promise<void> {\n if (typeof window === \"undefined\") throw new Error(\"chipi_connector_requires_browser\");\n this.ensureListener();\n const isParent = this.resolveMode() === \"parent\";\n if (this.ready && this.target && (isParent || !this.target.closed)) return;\n if (this.openPromise) return this.openPromise;\n this.openPromise = this.doOpen(isParent);\n try {\n await this.openPromise;\n } finally {\n this.openPromise = null;\n }\n }\n\n private async doOpen(isParent: boolean): Promise<void> {\n if (isParent) {\n if (window.parent === window) throw new Error(\"chipi_not_in_iframe\");\n this.target = window.parent;\n this.ownsTarget = false;\n } else {\n this.ready = false;\n // Unique per-open window name so a reconnect can never reuse a stale popup\n // that still holds a previous session's pending approval.\n const name = this.opts.windowName ?? `chipi-wallet-${randomId()}`;\n this.target = window.open(\n this.url,\n name,\n this.opts.windowFeatures ?? \"popup=yes,width=420,height=680\"\n );\n this.ownsTarget = true;\n if (!this.target) throw Object.assign(new Error(\"Popup blocked\"), { code: \"popup_blocked\" });\n this.hadPopup = true;\n }\n const opened = this.target;\n this.readyDeferred = deferred<void>();\n try {\n await this.awaitReady();\n } catch (err) {\n // Handshake stalled: close the popup we opened and reset, so a stale\n // window can't answer later and the next open() starts from scratch.\n // (Skip if close() already replaced the target in the meantime.)\n if (this.target === opened) this.resetTarget();\n throw err;\n }\n }\n\n /** Close the popup (if we own one) and forget the target + ready state. */\n private resetTarget(): void {\n try {\n if (this.ownsTarget) this.target?.close();\n } catch {\n // ignore\n }\n this.target = null;\n this.ready = false;\n this.readyDeferred = null;\n }\n\n private async awaitReady(): Promise<void> {\n // Generous: a cold login (Clerk / passkey) can take a while. We only reject\n // here on an outright stall: the popup-closed watcher handles the real\n // \"user gave up / closed it\" case quickly.\n const timeoutMs = this.opts.openTimeoutMs ?? 180_000;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(\"wallet_open_timeout\")), timeoutMs);\n });\n try {\n await Promise.race([this.readyDeferred!.promise, timeout]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n\n /** Reject every in-flight request (popup closed / disconnected). */\n private rejectAllPending(message: string): void {\n for (const [, p] of this.pending) {\n if (p.timer) clearTimeout(p.timer);\n p.reject(Object.assign(new Error(message), { code: 4001 }));\n }\n this.pending.clear();\n }\n\n /** While requests are in flight, watch for the user closing the popup and\n * reject them: otherwise the dApp's promise would hang forever. */\n private startCloseWatch(): void {\n if (this.closeWatch || !this.ownsTarget) return;\n this.closeWatch = setInterval(() => {\n if (this.target?.closed) {\n this.ready = false;\n this.target = null;\n this.rejectAllPending(\"User closed the wallet\");\n this.stopCloseWatch();\n } else if (this.pending.size === 0) {\n this.stopCloseWatch();\n }\n }, 500);\n }\n\n private stopCloseWatch(): void {\n if (this.closeWatch) {\n clearInterval(this.closeWatch);\n this.closeWatch = null;\n }\n }\n\n /**\n * Forward a get-starknet RPC call to the wallet, awaiting its response.\n *\n * The first request may open the popup. Once a popup has been opened, a\n * request made after it was closed rejects with `code: \"POPUP_CLOSED\"`\n * instead of calling `window.open` again: requests usually run outside a\n * click, where browsers block popups. Reopen via `connect()` / `open()`\n * from a click.\n */\n async request(call: ChipiRpcCall): Promise<unknown> {\n if (this.hadPopup && this.resolveMode() === \"popup\" && (!this.target || this.target.closed)) {\n throw transportError(\n \"POPUP_CLOSED\",\n \"The Chipi wallet window was closed. Call connect() again from a click.\"\n );\n }\n await this.open();\n if (this.ownsTarget) this.target?.focus();\n const id = randomId();\n const message: ChipiRpcRequestMessage = {\n channel: CHIPI_WC,\n type: \"rpc\",\n id,\n origin: window.location.origin,\n call: stripUndefined(call),\n };\n const timeoutMs = this.opts.requestTimeoutMs ?? 120_000;\n return new Promise<unknown>((resolve, reject) => {\n const entry: {\n resolve: (v: unknown) => void;\n reject: (e: unknown) => void;\n message: ChipiRpcRequestMessage;\n timer?: ReturnType<typeof setTimeout>;\n } = { resolve, reject, message };\n if (timeoutMs > 0 && Number.isFinite(timeoutMs)) {\n entry.timer = setTimeout(() => {\n if (this.pending.get(id) !== entry) return;\n this.pending.delete(id);\n reject(\n transportError(\n \"REQUEST_TIMEOUT\",\n `The Chipi wallet did not answer \"${call.type}\" within ${timeoutMs} ms.`\n )\n );\n }, timeoutMs);\n }\n this.pending.set(id, entry);\n this.target!.postMessage(message, this.walletOrigin);\n this.startCloseWatch();\n });\n }\n\n /** Close the popup (if we own one) + reject in-flight requests. */\n close(): void {\n this.stopCloseWatch();\n // Unblock an in-flight open() instead of leaving it to the ready timeout.\n this.readyDeferred?.reject(Object.assign(new Error(\"disconnected\"), { code: 4001 }));\n this.resetTarget();\n this.rejectAllPending(\"disconnected\");\n if (this.listening && typeof window !== \"undefined\") {\n window.removeEventListener(\"message\", this.onMessage);\n this.listening = false;\n }\n }\n}\n","import type { StarknetWindowObject } from \"@starknet-io/types-js\";\n\n/** Window key get-starknet discovers by scanning for `starknet*` properties. */\nexport const CHIPI_WINDOW_KEY = \"starknet_chipi\";\n\nexport interface ChipiRegistration {\n /** Remove `window.starknet_chipi` + the announce listener. */\n dispose: () => void;\n}\n\n/**\n * Make a Chipi `StarknetWindowObject` discoverable to any get-starknet /\n * starknet-react / starknetkit dApp on the page: WITHOUT an upstream PR and\n * WITHOUT whitelisting. This self-registration covers the apps that scan for\n * wallets rather than importing our connector explicitly.\n *\n * Discovery is announced two ways for maximum reach:\n * 1. **window scan**: set `window.starknet_chipi`. get-starknet v4's\n * `getAvailableWallets()` finds every `window` key starting with `starknet`.\n * 2. **event announce**: dispatch `starknet:announceWallet` now and again on\n * the dApp's `starknet:requestWallets` (the EIP-6963-style, timing-robust\n * Starknet Wallet Standard discovery path).\n *\n * SSR-safe (no-ops when there's no `window`) and idempotent per (target, wallet).\n */\nexport function registerChipiWallet(\n wallet: StarknetWindowObject,\n target: (Window & typeof globalThis) | undefined = typeof window !== \"undefined\"\n ? window\n : undefined\n): ChipiRegistration {\n if (!target) return { dispose: () => {} };\n\n const store = target as unknown as Record<string, unknown>;\n // 1. Classic window-scan discovery.\n store[CHIPI_WINDOW_KEY] = wallet;\n\n // 2. Event-based discovery (announce now + whenever a dApp asks).\n const announce = () =>\n target.dispatchEvent(new CustomEvent(\"starknet:announceWallet\", { detail: wallet }));\n target.addEventListener(\"starknet:requestWallets\", announce);\n announce();\n\n return {\n dispose: () => {\n target.removeEventListener(\"starknet:requestWallets\", announce);\n // Only remove our own object: never clobber a newer injector's wallet.\n if (store[CHIPI_WINDOW_KEY] === wallet) delete store[CHIPI_WINDOW_KEY];\n },\n };\n}\n","// Chipi brand wallet icon: the current luchador mark on a transparent\n// background, 48x48 PNG (same asset used by the browser extension's\n// toolbar icon). A data-URI is what get-starknet / wallet pickers render.\nexport const CHIPI_ICON = \"data:image/png;base64,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\";\n","/**\n * `ChipiConnector`: a starknet-react / get-starknet connector for the Chipi\n * hosted smart-account wallet. A self-contained connector package any dApp\n * adds to its `connectors` array (`new ChipiConnector()`) directly: no\n * whitelisting, no dependency on a third-party wallet kit, and NO browser\n * extension required. Clicking \"Connect with Chipi\" opens our hosted wallet\n * (passkey + gasless paymaster) in a popup; the dApp's `wallet_*` RPC calls are\n * forwarded over postMessage and answered after the user approves in Chipi's\n * own (already-built) approval UI.\n */\nimport { Connector } from \"@starknet-react/core\";\nimport { WalletAccount, constants } from \"starknet\";\nimport type { AccountInterface, ProviderInterface } from \"starknet\";\nimport type {\n RpcMessage,\n RequestFnCall,\n RpcTypeToMessageMap,\n StarknetWindowObject,\n} from \"@starknet-io/types-js\";\nimport { ChipiPopupTransport, type ChipiTransportOptions } from \"./transport.js\";\nimport { registerChipiWallet, type ChipiRegistration } from \"./register.js\";\nimport { CHIPI_ICON } from \"./icon.js\";\n\n// @starknet-react/core declares these internally but doesn't export them; mirror\n// the shapes (ConnectorIcons === get-starknet's StarknetWindowObject[\"icon\"]).\ntype ConnectorIcons = StarknetWindowObject[\"icon\"];\ntype ConnectorData = { account?: string; chainId?: bigint };\n/** Mirrors starknet-react's `ConnectArgs` (not exported by every version). */\ntype ConnectArgs = { chainIdHint?: bigint };\n\n/** Starknet mainnet chain id (felt of the shortstring \"SN_MAIN\"). */\nconst SN_MAIN = BigInt(constants.StarknetChainId.SN_MAIN);\n\n/** Parse a wallet-sent chain id (hex/decimal string, bigint or number). */\nfunction toChainId(value: unknown): bigint | undefined {\n if (typeof value === \"bigint\") return value;\n if (typeof value === \"number\" || typeof value === \"string\") {\n try {\n return BigInt(value);\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\nexport interface ChipiConnectorOptions {\n /** Hosted wallet base URL. Defaults to `https://wallet.chipipay.com`. */\n walletUrl?: string;\n /** Override the connector id / display name / icon if embedding. */\n id?: string;\n name?: string;\n icon?: ConnectorIcons;\n transport?: ChipiTransportOptions;\n /**\n * Self-register the wallet on `window` (set `window.starknet_chipi` + announce\n * via `starknet:announceWallet`) so dApps that *scan* for wallets, raw\n * get-starknet / Wallet-Standard consumers that don't import this connector,\n * also discover \"Connect with Chipi\". Defaults to `true` in a browser; pass\n * `false` to opt out (e.g. to avoid a double entry in a picker that already\n * lists the connector explicitly). No-op during SSR.\n */\n register?: boolean;\n // NOTE: the in-app-browser (\"parent\") transport mode is implemented in the\n // transport but NOT yet supported by the hosted wallet side, so it's not\n // exposed here in v1. Use popup (external dApps) only.\n}\n\nexport class ChipiConnector extends Connector {\n private readonly transport: ChipiPopupTransport;\n private readonly _id: string;\n private readonly _name: string;\n private readonly _icon: ConnectorIcons;\n private _account: string | null = null;\n private _swo: StarknetWindowObject | null = null;\n private _registration: ChipiRegistration | null = null;\n private readonly _autoRegister: boolean;\n\n constructor(options: ChipiConnectorOptions = {}) {\n super();\n const walletUrl =\n options.walletUrl ?? options.transport?.walletUrl ?? \"https://wallet.chipipay.com\";\n this.transport = new ChipiPopupTransport({\n ...options.transport,\n walletUrl,\n mode: \"popup\", // v1: external-dApp popup only (parent host not yet built)\n });\n this._id = options.id ?? \"chipi\";\n this._name = options.name ?? \"Connect with Chipi\";\n this._icon = options.icon ?? CHIPI_ICON;\n this._autoRegister = options.register !== false;\n if (this._autoRegister) this.register();\n }\n\n /**\n * Announce this wallet to scanning dApps (`window.starknet_chipi` +\n * `starknet:announceWallet`). Called automatically from the constructor\n * unless `register: false`. Idempotent and SSR-safe.\n */\n register(): void {\n if (this._registration) return;\n this._registration = registerChipiWallet(this.swo());\n }\n\n /** Undo {@link register}: remove the window object + announce listener. */\n unregister(): void {\n this._registration?.dispose();\n this._registration = null;\n }\n\n get id(): string {\n return this._id;\n }\n\n get name(): string {\n return this._name;\n }\n\n get icon(): ConnectorIcons {\n return this._icon;\n }\n\n /** Hosted wallet: always available (no extension to detect). */\n available(): boolean {\n return true;\n }\n\n /** No silent reconnect in v1: the user re-approves the popup each session. */\n async ready(): Promise<boolean> {\n return this._account !== null;\n }\n\n /** Lazily build the postMessage-backed get-starknet window object. */\n private swo(): StarknetWindowObject {\n if (this._swo) return this._swo;\n const transport = this.transport;\n const request = (async (call: RpcMessage) =>\n transport.request(call)) as StarknetWindowObject[\"request\"];\n this._swo = {\n id: this._id,\n name: this._name,\n version: \"1.0.0\",\n icon: typeof this._icon === \"string\" ? this._icon : (this._icon?.dark ?? \"\"),\n request,\n on: ((event: string, handler: (data: unknown) => void) => {\n if (event === \"accountsChanged\" || event === \"networkChanged\") transport.on(event, handler);\n }) as StarknetWindowObject[\"on\"],\n off: ((event: string, handler: (data: unknown) => void) => {\n if (event === \"accountsChanged\" || event === \"networkChanged\")\n transport.off(event, handler);\n }) as StarknetWindowObject[\"off\"],\n };\n return this._swo;\n }\n\n /**\n * Open the hosted wallet (call from a click: it opens a popup) and request\n * the account. Chipi is mainnet-only: a `chainIdHint` other than SN_MAIN\n * rejects before any popup opens.\n */\n async connect(args: ConnectArgs = {}): Promise<ConnectorData> {\n if (args.chainIdHint !== undefined && BigInt(args.chainIdHint) !== SN_MAIN) {\n throw Object.assign(\n new Error(\n `Chipi is mainnet-only: chainIdHint 0x${BigInt(args.chainIdHint).toString(16)} is not SN_MAIN.`\n ),\n { code: \"UNSUPPORTED_CHAIN\" }\n );\n }\n // Re-announce if a previous disconnect() disposed the registration.\n if (this._autoRegister) this.register();\n this.subscribe();\n await this.transport.open();\n const accounts = (await this.transport.request({ type: \"wallet_requestAccounts\" })) as string[];\n const account = accounts?.[0];\n if (!account) throw new Error(\"chipi_no_account\");\n this._account = account;\n const data: ConnectorData = { account, chainId: SN_MAIN };\n this.emitEvent(\"connect\", data);\n return data;\n }\n\n async disconnect(): Promise<void> {\n this.unsubscribe();\n this.transport.close();\n this._account = null;\n // Drop `window.starknet_chipi` so scanners don't keep a stale object; the\n // next connect() registers a fresh one.\n this.unregister();\n this._swo = null;\n this.emitEvent(\"disconnect\");\n }\n\n /** Forward the wallet's account/network events as starknet-react events. */\n private subscribe(): void {\n this.unsubscribe(); // idempotent across repeated connect() calls\n this.transport.on(\"accountsChanged\", this.onAccountsChanged);\n this.transport.on(\"networkChanged\", this.onNetworkChanged);\n }\n\n private unsubscribe(): void {\n this.transport.off(\"accountsChanged\", this.onAccountsChanged);\n this.transport.off(\"networkChanged\", this.onNetworkChanged);\n }\n\n private onAccountsChanged = (data: unknown): void => {\n const accounts = Array.isArray(data) ? (data as unknown[]) : [];\n const account = accounts[0];\n if (typeof account === \"string\" && account) {\n this._account = account;\n this.emitEvent(\"change\", { account, chainId: SN_MAIN });\n } else {\n this._account = null;\n this.emitEvent(\"disconnect\");\n }\n };\n\n private onNetworkChanged = (data: unknown): void => {\n // The wallet may send the chain id alone or `{ chainId, accounts }`.\n const payload =\n typeof data === \"object\" && data !== null && !Array.isArray(data)\n ? (data as { chainId?: unknown; accounts?: unknown })\n : { chainId: data };\n const chainId = toChainId(payload.chainId);\n const accounts = Array.isArray(payload.accounts) ? payload.accounts : [];\n const next = typeof accounts[0] === \"string\" && accounts[0] ? accounts[0] : this._account;\n if (next) this._account = next;\n const change: ConnectorData = {};\n if (chainId !== undefined) change.chainId = chainId;\n if (next) change.account = next;\n this.emitEvent(\"change\", change);\n };\n\n // `Connector` extends eventemitter3's EventEmitter, but the bundled .d.ts\n // doesn't surface `emit` cleanly through the abstract class: reach it via a\n // narrow cast rather than fight the upstream typing.\n private emitEvent(event: \"connect\" | \"change\", data: ConnectorData): void;\n private emitEvent(event: \"disconnect\"): void;\n private emitEvent(event: \"connect\" | \"change\" | \"disconnect\", data?: ConnectorData): void {\n const emitter = this as unknown as { emit: (e: string, d?: ConnectorData) => void };\n if (data === undefined) emitter.emit(event);\n else emitter.emit(event, data);\n }\n\n async account(provider: ProviderInterface): Promise<AccountInterface> {\n if (!this._account) throw new Error(\"chipi_not_connected\");\n // WalletAccount routes execute()/signMessage() through the SWO's request(),\n // i.e. over our postMessage channel to the hosted wallet.\n return WalletAccount.connect(provider, this.swo());\n }\n\n async chainId(): Promise<bigint> {\n return SN_MAIN;\n }\n\n async request<T extends RpcMessage[\"type\"]>(\n call: RequestFnCall<T>\n ): Promise<RpcTypeToMessageMap[T][\"result\"]> {\n return this.transport.request(call) as Promise<RpcTypeToMessageMap[T][\"result\"]>;\n }\n}\n","import { ChipiConnector, type ChipiConnectorOptions } from \"./connector.js\";\n\n/**\n * Plain-function form of {@link ChipiConnector}, for parity with\n * `@starknet-react/core`'s built-in factories (`ready()`, `braavos()`):\n *\n * const connectors = [chipi(), ready(), braavos()];\n *\n * Equivalent to `new ChipiConnector(options)`: use whichever reads better\n * in your `connectors` array.\n */\nexport function chipi(options?: ChipiConnectorOptions): ChipiConnector {\n return new ChipiConnector(options);\n}\n","/**\n * Chipi as a Wallet Standard wallet with Starknet features\n * (`WalletWithStarknetFeatures` from `@starknet-io/get-starknet-wallet-standard`),\n * so dApps on get-starknet v5+/v6 discovery (`@starknet-io/get-starknet-discovery`,\n * `@starknet-start/react`, anything that listens for\n * `wallet-standard:register-wallet`) list \"Chipi\" without importing this\n * package's connector.\n *\n * Backed by the same popup transport as {@link ChipiConnector}. The types\n * below mirror the upstream interfaces structurally so this package keeps no\n * runtime (or type) dependency on `@wallet-standard/*`.\n */\nimport type { RequestFn } from \"@starknet-io/types-js\";\nimport { ChipiPopupTransport, type ChipiTransportOptions } from \"./transport.js\";\nimport { CHIPI_ICON } from \"./icon.js\";\n\n/** Wallet Standard chain id for Starknet mainnet: `starknet:` + hex of \"SN_MAIN\"\n * (same as `WELL_KNOWN_STARKNET_CHAINS[0]` in get-starknet-wallet-standard). */\nexport const CHIPI_STARKNET_MAINNET_CHAIN = \"starknet:0x534e5f4d41494e\" as const;\n\n/** `starknet:0x...` chain identifier. */\nexport type ChipiStarknetChain = `starknet:0x${string}`;\n\n/** Data-URI icon, as Wallet Standard requires. */\nexport type ChipiWalletIcon = `data:image/${\"svg+xml\" | \"webp\" | \"png\" | \"gif\"};base64,${string}`;\n\n/** Mirrors `@wallet-standard/base` `WalletAccount`. */\nexport interface ChipiStandardWalletAccount {\n readonly address: string;\n readonly publicKey: Uint8Array;\n readonly chains: readonly ChipiStarknetChain[];\n readonly features: readonly `${string}:${string}`[];\n}\n\n/** Mirrors `@wallet-standard/features` `StandardEventsChangeProperties`. */\nexport interface ChipiStandardChangeProperties {\n readonly chains?: readonly ChipiStarknetChain[];\n readonly accounts?: readonly ChipiStandardWalletAccount[];\n}\n\n/** Mirrors `StarknetFeatures` from `@starknet-io/get-starknet-wallet-standard`.\n * (A type alias, not an interface, so it satisfies Wallet Standard's\n * `IdentifierRecord` index signature.) */\nexport type ChipiStandardWalletFeatures = {\n readonly \"starknet:walletApi\": {\n readonly version: \"1.0.0\";\n readonly request: RequestFn;\n readonly walletVersion: string;\n readonly id: string;\n };\n readonly \"standard:connect\": {\n readonly version: \"1.0.0\";\n readonly connect: (input?: {\n readonly silent?: boolean;\n }) => Promise<{ readonly accounts: readonly ChipiStandardWalletAccount[] }>;\n };\n readonly \"standard:disconnect\": {\n readonly version: \"1.0.0\";\n readonly disconnect: () => Promise<void>;\n };\n readonly \"standard:events\": {\n readonly version: \"1.0.0\";\n readonly on: <E extends \"change\">(\n event: E,\n listener: (properties: ChipiStandardChangeProperties) => void\n ) => () => void;\n };\n};\n\n/** Structurally a `WalletWithStarknetFeatures`. */\nexport interface ChipiStandardWallet {\n readonly version: \"1.0.0\";\n readonly name: string;\n readonly icon: ChipiWalletIcon;\n readonly chains: readonly ChipiStarknetChain[];\n readonly accounts: readonly ChipiStandardWalletAccount[];\n readonly features: ChipiStandardWalletFeatures;\n}\n\nexport interface ChipiStandardWalletOptions {\n /** Hosted wallet base URL. Defaults to `https://wallet.chipipay.com`. */\n walletUrl?: string;\n /** Display name. Defaults to `\"Chipi\"`. */\n name?: string;\n /** Data-URI icon. Defaults to the Chipi icon. */\n icon?: ChipiWalletIcon;\n /** Popup transport tuning (window name/features, timeouts). */\n transport?: Omit<ChipiTransportOptions, \"walletUrl\" | \"mode\">;\n}\n\n/** Same shape as a Wallet Standard `register-wallet` event detail callback. */\ntype RegisterApi = { register: (wallet: ChipiStandardWallet) => () => void };\n\nfunction toStarknetChain(value: unknown): ChipiStarknetChain | undefined {\n if (typeof value !== \"string\" && typeof value !== \"bigint\" && typeof value !== \"number\") {\n return undefined;\n }\n try {\n return `starknet:0x${BigInt(value).toString(16)}`;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Build the Chipi Wallet Standard wallet (without registering it). `connect`\n * opens the popup, so dApps call it from a click; `connect({ silent: true })`\n * never opens a popup and returns the current accounts (empty if not\n * connected).\n */\nexport function createChipiStandardWallet(\n options: ChipiStandardWalletOptions = {}\n): ChipiStandardWallet {\n const transport = new ChipiPopupTransport({\n ...options.transport,\n walletUrl: options.walletUrl ?? \"https://wallet.chipipay.com\",\n mode: \"popup\",\n });\n const listeners = new Set<(properties: ChipiStandardChangeProperties) => void>();\n let current: { address: string; chain: ChipiStarknetChain } | null = null;\n\n const accounts = (): ChipiStandardWalletAccount[] =>\n current\n ? [\n {\n address: current.address,\n publicKey: new Uint8Array(),\n chains: [current.chain],\n features: [],\n },\n ]\n : [];\n const emitChange = () => {\n const properties: ChipiStandardChangeProperties = { accounts: accounts() };\n for (const listener of [...listeners]) listener(properties);\n };\n const setDisconnected = () => {\n if (!current) return;\n current = null;\n emitChange();\n };\n\n const onAccountsChanged = (data: unknown) => {\n const list = Array.isArray(data) ? (data as unknown[]) : [];\n const address = list[0];\n if (typeof address !== \"string\" || !address) return setDisconnected();\n if (!current) return; // not connected through this wallet: ignore\n current = { ...current, address };\n emitChange();\n };\n const onNetworkChanged = (data: unknown) => {\n const payload =\n typeof data === \"object\" && data !== null && !Array.isArray(data)\n ? (data as { chainId?: unknown; accounts?: unknown })\n : { chainId: data };\n const chain = toStarknetChain(payload.chainId);\n if (!chain) return setDisconnected();\n if (!current) return;\n const list = Array.isArray(payload.accounts) ? (payload.accounts as unknown[]) : [];\n const address = typeof list[0] === \"string\" && list[0] ? list[0] : current.address;\n current = { address, chain };\n emitChange();\n };\n transport.on(\"accountsChanged\", onAccountsChanged);\n transport.on(\"networkChanged\", onNetworkChanged);\n\n const request = ((call: Parameters<RequestFn>[0]) => transport.request(call)) as RequestFn;\n\n const features: ChipiStandardWalletFeatures = {\n \"starknet:walletApi\": {\n version: \"1.0.0\",\n request,\n walletVersion: \"1.0.0\",\n id: \"chipi\",\n },\n \"standard:connect\": {\n version: \"1.0.0\",\n connect: async (input) => {\n if (current || input?.silent) return { accounts: accounts() };\n await transport.open();\n // No params: never forward `{ silent_mode: undefined }` to the wallet.\n const result = (await transport.request({ type: \"wallet_requestAccounts\" })) as unknown;\n const list = Array.isArray(result) ? (result as unknown[]) : [];\n const address = list[0];\n if (typeof address !== \"string\" || !address) return { accounts: [] };\n current = { address, chain: CHIPI_STARKNET_MAINNET_CHAIN };\n emitChange();\n return { accounts: accounts() };\n },\n },\n \"standard:disconnect\": {\n version: \"1.0.0\",\n disconnect: async () => {\n transport.close();\n setDisconnected();\n },\n },\n \"standard:events\": {\n version: \"1.0.0\",\n on: (_event, listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n },\n };\n\n return {\n version: \"1.0.0\",\n name: options.name ?? \"Chipi\",\n icon: options.icon ?? (CHIPI_ICON as ChipiWalletIcon),\n chains: [CHIPI_STARKNET_MAINNET_CHAIN],\n get accounts() {\n return accounts();\n },\n features,\n };\n}\n\n/**\n * Register Chipi with every Wallet Standard app on the page: dispatches\n * `wallet-standard:register-wallet` now and answers later\n * `wallet-standard:app-ready` events (the `@wallet-standard/wallet`\n * `registerWallet` protocol, implemented here without the dependency).\n *\n * Returns an unregister function that removes the listener and unregisters\n * from every app that accepted the wallet. SSR-safe: a no-op without `window`.\n */\nexport function registerChipiStandardWallet(\n options: ChipiStandardWalletOptions = {},\n target: (Window & typeof globalThis) | undefined = typeof window !== \"undefined\"\n ? window\n : undefined\n): () => void {\n if (!target) return () => {};\n const wallet = createChipiStandardWallet(options);\n const unregisters: Array<() => void> = [];\n const callback = ({ register }: RegisterApi) => {\n unregisters.push(register(wallet));\n };\n const onAppReady = (event: Event) => {\n const api = (event as CustomEvent<RegisterApi>).detail;\n if (api && typeof api.register === \"function\") callback(api);\n };\n try {\n target.dispatchEvent(\n new CustomEvent(\"wallet-standard:register-wallet\", {\n detail: callback,\n bubbles: false,\n cancelable: false,\n composed: false,\n })\n );\n } catch (error) {\n console.error(\"wallet-standard:register-wallet event could not be dispatched\\n\", error);\n }\n target.addEventListener(\"wallet-standard:app-ready\", onAppReady);\n return () => {\n target.removeEventListener(\"wallet-standard:app-ready\", onAppReady);\n for (const unregister of unregisters.splice(0)) unregister();\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/protocol.ts","../src/transport.ts","../src/register.ts","../src/icon.ts","../src/connector.ts","../src/factory.ts","../src/standard.ts"],"names":["constants","Connector","WalletAccount"],"mappings":";;;;;;;;AAkBO,IAAM,QAAA,GAAW;AAwCjB,SAAS,qBAAqB,IAAA,EAA2C;AAC9E,EAAA,OACE,OAAO,IAAA,KAAS,QAAA,IAChB,IAAA,KAAS,IAAA,IACR,KAA+B,OAAA,KAAY,QAAA;AAEhD;AAGO,SAAS,mBAAmB,IAAA,EAAyC;AAC1E,EAAA,OACE,OAAO,SAAS,QAAA,IAChB,IAAA,KAAS,QACR,IAAA,CAA+B,OAAA,KAAY,QAAA,IAC3C,IAAA,CAA4B,IAAA,KAAS,KAAA;AAE1C;;;ACzBA,SAAS,cAAA,CAAe,MAA+B,OAAA,EAAwB;AAC7E,EAAA,MAAM,GAAA,GAAM,OAAO,MAAA,CAAO,IAAI,MAAM,OAAO,CAAA,EAAG,EAAE,IAAA,EAAM,CAAA;AACtD,EAAA,GAAA,CAAI,IAAA,GAAO,IAAA;AACX,EAAA,OAAO,GAAA;AACT;AAMA,SAAS,eAAkB,KAAA,EAAa;AACtC,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,cAAA,CAAe,CAAC,CAAC,CAAA;AACnE,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,UAAU,OAAO,KAAA;AACxD,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,cAAA,CAAe,KAAK,CAAA;AACzC,EAAA,IAAI,KAAA,KAAU,MAAA,CAAO,SAAA,IAAa,KAAA,KAAU,MAAM,OAAO,KAAA;AACzD,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAgC,CAAA,EAAG;AACrE,IAAA,IAAI,MAAM,MAAA,EAAW,GAAA,CAAI,CAAC,CAAA,GAAI,eAAe,CAAC,CAAA;AAAA,EAChD;AACA,EAAA,OAAO,GAAA;AACT;AAKA,SAAS,QAAA,GAAc;AACrB,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,MAAA;AACJ,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAW,CAAC,KAAK,GAAA,KAAQ;AAC3C,IAAA,OAAA,GAAU,GAAA;AACV,IAAA,MAAA,GAAS,GAAA;AAAA,EACX,CAAC,CAAA;AACD,EAAA,OAAO,EAAE,OAAA,EAAS,OAAA,EAAS,MAAA,EAAO;AACpC;AAGA,IAAM,WAAA,GAAc,kBAAA;AAWpB,SAAS,cAAc,IAAA,EAAoD;AACzE,EAAA,QAAQ,KAAK,IAAA;AAAM,IACjB,KAAK,uBAAA;AACH,MAAA,OAAO,EAAE,KAAA,EAAO,EAAC,EAAE;AAAA,IACrB,KAAK,wBAAA,EAA0B;AAC7B,MAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,MAAA,OAAO,QAAQ,WAAA,KAAgB,IAAA,GAAO,EAAE,KAAA,EAAO,IAAG,GAAI,MAAA;AAAA,IACxD;AAAA,IACA,KAAK,uBAAA;AACH,MAAA,OAAO,EAAE,OAAO,WAAA,EAAY;AAAA,IAC9B;AACE,MAAA,OAAO,MAAA;AAAA;AAEb;AAEA,SAAS,QAAA,GAAmB;AAE1B,EAAA,OAAO,GAAG,IAAA,CAAK,GAAA,EAAI,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,GAAS,QAAA,CAAS,EAAE,EAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA,CAAA;AAC9E;AAEO,IAAM,sBAAN,MAA0B;AAAA,EAwB/B,YAA6B,IAAA,EAA6B;AAA7B,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AArB7B,IAAA,IAAA,CAAQ,MAAA,GAAwB,IAAA;AAChC,IAAA,IAAA,CAAQ,UAAA,GAAa,KAAA;AACrB,IAAA,IAAA,CAAQ,KAAA,GAAQ,KAAA;AAChB,IAAA,IAAA,CAAQ,SAAA,GAAY,KAAA;AACpB,IAAA,IAAA,CAAiB,OAAA,uBAAc,GAAA,EAQ7B;AACF,IAAA,IAAA,CAAiB,QAAA,uBAAe,GAAA,EAAkC;AAClE,IAAA,IAAA,CAAQ,aAAA,GAA0D,IAAA;AAClE,IAAA,IAAA,CAAQ,WAAA,GAAoC,IAAA;AAC5C,IAAA,IAAA,CAAQ,UAAA,GAAoD,IAAA;AAG5D;AAAA;AAAA,IAAA,IAAA,CAAQ,QAAA,GAAW,KAAA;AAqBnB,IAAA,IAAA,CAAQ,SAAA,GAAY,CAAC,CAAA,KAA0B;AAC7C,MAAA,IAAI,CAAA,CAAE,WAAW,IAAA,CAAK,YAAA,IAAgB,CAAC,oBAAA,CAAqB,CAAA,CAAE,IAAI,CAAA,EAAG;AAKrE,MAAA,IAAI,CAAC,IAAA,CAAK,MAAA,IAAU,CAAA,CAAE,MAAA,KAAW,KAAK,MAAA,EAAQ;AAC9C,MAAA,MAAM,MAAM,CAAA,CAAE,IAAA;AACd,MAAA,IAAI,GAAA,CAAI,SAAS,OAAA,EAAS;AACxB,QAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,QAAA,IAAA,CAAK,eAAe,OAAA,EAAQ;AAC5B,QAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AAOrB,QAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAO,EAAG;AACrC,UAAA,IAAA,CAAK,MAAA,CAAO,WAAA,CAAY,CAAA,CAAE,OAAA,EAAS,KAAK,YAAY,CAAA;AAAA,QACtD;AACA,QAAA;AAAA,MACF;AACA,MAAA,IAAI,GAAA,CAAI,SAAS,YAAA,EAAc;AAC7B,QAAA,MAAM,CAAA,GAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,IAAI,EAAE,CAAA;AACjC,QAAA,IAAI,CAAC,CAAA,EAAG;AACR,QAAA,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,GAAA,CAAI,EAAE,CAAA;AAC1B,QAAA,IAAI,CAAA,CAAE,KAAA,EAAO,YAAA,CAAa,CAAA,CAAE,KAAK,CAAA;AACjC,QAAA,IAAI,GAAA,CAAI,EAAA,EAAI,CAAA,CAAE,OAAA,CAAQ,IAAI,MAAM,CAAA;AAAA,eACzB,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,IAAI,MAAM,GAAA,CAAI,KAAA,CAAM,OAAO,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,CAAI,KAAA,CAAM,IAAA,EAAM,CAAC,CAAA;AACnF,QAAA;AAAA,MACF;AACA,MAAA,IAAI,GAAA,CAAI,SAAS,OAAA,EAAS;AACxB,QAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA,EAAG,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,GAAA,CAAI,IAAI,CAAC,CAAA;AAAA,MAC1D;AAAA,IACF,CAAA;AArDE,IAAA,IAAA,CAAK,MAAM,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,GAAI,UAAA;AAC/C,IAAA,IAAA,CAAK,YAAA,GAAe,IAAI,GAAA,CAAI,IAAA,CAAK,SAAS,CAAA,CAAE,MAAA;AAAA,EAC9C;AAAA,EAEA,EAAA,CAAG,OAAkB,OAAA,EAA6B;AAChD,IAAA,CAAC,KAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA,IAAK,KAAK,QAAA,CAAS,GAAA,CAAI,KAAA,kBAAO,IAAI,KAAK,CAAA,CAAE,IAAI,KAAK,CAAA,EAAI,IAAI,OAAO,CAAA;AAAA,EAC3F;AAAA,EAEA,GAAA,CAAI,OAAkB,OAAA,EAA6B;AACjD,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA,EAAG,OAAO,OAAO,CAAA;AAAA,EAC1C;AAAA,EAEQ,cAAA,GAAuB;AAC7B,IAAA,IAAI,IAAA,CAAK,SAAA,IAAa,OAAO,MAAA,KAAW,WAAA,EAAa;AACrD,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAA,EAAW,IAAA,CAAK,SAAS,CAAA;AACjD,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,EACnB;AAAA;AAAA,EAwCQ,WAAA,GAAkC;AACxC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,IAAA,IAAQ,OAAA;AAC/B,IAAA,IAAI,IAAA,KAAS,QAAQ,OAAO,IAAA;AAC5B,IAAA,OAAO,OAAO,MAAA,KAAW,WAAA,IAAe,MAAA,CAAO,MAAA,KAAW,SAAS,QAAA,GAAW,OAAA;AAAA,EAChF;AAAA;AAAA;AAAA,EAIA,MAAM,IAAA,GAAsB;AAC1B,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,MAAM,IAAI,MAAM,kCAAkC,CAAA;AACrF,IAAA,IAAA,CAAK,cAAA,EAAe;AACpB,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,WAAA,EAAY,KAAM,QAAA;AACxC,IAAA,IAAI,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA,KAAW,YAAY,CAAC,IAAA,CAAK,OAAO,MAAA,CAAA,EAAS;AACpE,IAAA,IAAI,IAAA,CAAK,WAAA,EAAa,OAAO,IAAA,CAAK,WAAA;AAClC,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA,CAAK,MAAA,CAAO,QAAQ,CAAA;AACvC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,WAAA;AAAA,IACb,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAc,OAAO,QAAA,EAAkC;AACrD,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,IAAI,OAAO,MAAA,KAAW,MAAA,EAAQ,MAAM,IAAI,MAAM,qBAAqB,CAAA;AACnE,MAAA,IAAA,CAAK,SAAS,MAAA,CAAO,MAAA;AACrB,MAAA,IAAA,CAAK,UAAA,GAAa,KAAA;AAAA,IACpB,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAGb,MAAA,MAAM,OAAO,IAAA,CAAK,IAAA,CAAK,UAAA,IAAc,CAAA,aAAA,EAAgB,UAAU,CAAA,CAAA;AAC/D,MAAA,IAAA,CAAK,SAAS,MAAA,CAAO,IAAA;AAAA,QACnB,IAAA,CAAK,GAAA;AAAA,QACL,IAAA;AAAA,QACA,IAAA,CAAK,KAAK,cAAA,IAAkB;AAAA,OAC9B;AACA,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAClB,MAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,MAAM,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,eAAe,CAAA,EAAG,EAAE,IAAA,EAAM,iBAAiB,CAAA;AAC3F,MAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAA,IAClB;AACA,IAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,IAAA,IAAA,CAAK,gBAAgB,QAAA,EAAe;AACpC,IAAA,IAAI;AACF,MAAA,MAAM,KAAK,UAAA,EAAW;AAAA,IACxB,SAAS,GAAA,EAAK;AAIZ,MAAA,IAAI,IAAA,CAAK,MAAA,KAAW,MAAA,EAAQ,IAAA,CAAK,WAAA,EAAY;AAC7C,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA,EAGQ,WAAA,GAAoB;AAC1B,IAAA,IAAI;AACF,MAAA,IAAI,IAAA,CAAK,UAAA,EAAY,IAAA,CAAK,MAAA,EAAQ,KAAA,EAAM;AAAA,IAC1C,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AAAA,EACvB;AAAA,EAEA,MAAc,UAAA,GAA4B;AAIxC,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,IAAA,CAAK,aAAA,IAAiB,IAAA;AAC7C,IAAA,IAAI,KAAA;AACJ,IAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAe,CAAC,GAAG,MAAA,KAAW;AAChD,MAAA,KAAA,GAAQ,UAAA,CAAW,MAAM,MAAA,CAAO,IAAI,MAAM,qBAAqB,CAAC,GAAG,SAAS,CAAA;AAAA,IAC9E,CAAC,CAAA;AACD,IAAA,IAAI;AACF,MAAA,MAAM,QAAQ,IAAA,CAAK,CAAC,KAAK,aAAA,CAAe,OAAA,EAAS,OAAO,CAAC,CAAA;AAAA,IAC3D,CAAA,SAAE;AACA,MAAA,IAAI,KAAA,eAAoB,KAAK,CAAA;AAAA,IAC/B;AAAA,EACF;AAAA;AAAA,EAGQ,iBAAiB,OAAA,EAAuB;AAC9C,IAAA,KAAA,MAAW,GAAG,CAAC,CAAA,IAAK,KAAK,OAAA,EAAS;AAChC,MAAA,IAAI,CAAA,CAAE,KAAA,EAAO,YAAA,CAAa,CAAA,CAAE,KAAK,CAAA;AACjC,MAAA,CAAA,CAAE,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG,EAAE,IAAA,EAAM,IAAA,EAAM,CAAC,CAAA;AAAA,IAC5D;AACA,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AAAA,EACrB;AAAA;AAAA;AAAA,EAIQ,eAAA,GAAwB;AAC9B,IAAA,IAAI,IAAA,CAAK,UAAA,IAAc,CAAC,IAAA,CAAK,UAAA,EAAY;AACzC,IAAA,IAAA,CAAK,UAAA,GAAa,YAAY,MAAM;AAClC,MAAA,IAAI,IAAA,CAAK,QAAQ,MAAA,EAAQ;AACvB,QAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,QAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,QAAA,IAAA,CAAK,iBAAiB,wBAAwB,CAAA;AAC9C,QAAA,IAAA,CAAK,cAAA,EAAe;AAAA,MACtB,CAAA,MAAA,IAAW,IAAA,CAAK,OAAA,CAAQ,IAAA,KAAS,CAAA,EAAG;AAClC,QAAA,IAAA,CAAK,cAAA,EAAe;AAAA,MACtB;AAAA,IACF,GAAG,GAAG,CAAA;AAAA,EACR;AAAA,EAEQ,cAAA,GAAuB;AAC7B,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,aAAA,CAAc,KAAK,UAAU,CAAA;AAC7B,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,IACpB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,QAAQ,IAAA,EAAsC;AAGlD,IAAA,IAAI,IAAA,CAAK,aAAY,KAAM,OAAA,KAAY,CAAC,IAAA,CAAK,MAAA,IAAU,IAAA,CAAK,MAAA,CAAO,MAAA,CAAA,EAAS;AAC1E,MAAA,MAAM,OAAA,GAAU,cAAc,IAAI,CAAA;AAClC,MAAA,IAAI,OAAA,SAAgB,OAAA,CAAQ,KAAA;AAAA,IAC9B;AACA,IAAA,IAAI,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,WAAA,EAAY,KAAM,OAAA,KAAY,CAAC,IAAA,CAAK,MAAA,IAAU,IAAA,CAAK,MAAA,CAAO,MAAA,CAAA,EAAS;AAC3F,MAAA,MAAM,cAAA;AAAA,QACJ,cAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AACA,IAAA,MAAM,KAAK,IAAA,EAAK;AAChB,IAAA,IAAI,IAAA,CAAK,UAAA,EAAY,IAAA,CAAK,MAAA,EAAQ,KAAA,EAAM;AACxC,IAAA,MAAM,KAAK,QAAA,EAAS;AACpB,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,OAAA,EAAS,QAAA;AAAA,MACT,IAAA,EAAM,KAAA;AAAA,MACN,EAAA;AAAA,MACA,MAAA,EAAQ,OAAO,QAAA,CAAS,MAAA;AAAA,MACxB,IAAA,EAAM,eAAe,IAAI;AAAA,KAC3B;AACA,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,IAAA,CAAK,gBAAA,IAAoB,IAAA;AAChD,IAAA,OAAO,IAAI,OAAA,CAAiB,CAAC,OAAA,EAAS,MAAA,KAAW;AAC/C,MAAA,MAAM,KAAA,GAKF,EAAE,OAAA,EAAS,MAAA,EAAQ,OAAA,EAAQ;AAC/B,MAAA,IAAI,SAAA,GAAY,CAAA,IAAK,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,EAAG;AAC/C,QAAA,KAAA,CAAM,KAAA,GAAQ,WAAW,MAAM;AAC7B,UAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAE,MAAM,KAAA,EAAO;AACpC,UAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,EAAE,CAAA;AACtB,UAAA,MAAA;AAAA,YACE,cAAA;AAAA,cACE,iBAAA;AAAA,cACA,CAAA,iCAAA,EAAoC,IAAA,CAAK,IAAI,CAAA,SAAA,EAAY,SAAS,CAAA,IAAA;AAAA;AACpE,WACF;AAAA,QACF,GAAG,SAAS,CAAA;AAAA,MACd;AACA,MAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAA,EAAI,KAAK,CAAA;AAC1B,MAAA,IAAA,CAAK,MAAA,CAAQ,WAAA,CAAY,OAAA,EAAS,IAAA,CAAK,YAAY,CAAA;AACnD,MAAA,IAAA,CAAK,eAAA,EAAgB;AAAA,IACvB,CAAC,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,cAAA,EAAe;AAEpB,IAAA,IAAA,CAAK,aAAA,EAAe,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,cAAc,CAAA,EAAG,EAAE,IAAA,EAAM,IAAA,EAAM,CAAC,CAAA;AACnF,IAAA,IAAA,CAAK,WAAA,EAAY;AACjB,IAAA,IAAA,CAAK,iBAAiB,cAAc,CAAA;AACpC,IAAA,IAAI,IAAA,CAAK,SAAA,IAAa,OAAO,MAAA,KAAW,WAAA,EAAa;AACnD,MAAA,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,IAAA,CAAK,SAAS,CAAA;AACpD,MAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AAAA,IACnB;AAAA,EACF;AACF;;;AC9XO,IAAM,gBAAA,GAAmB;AAsBzB,SAAS,oBACd,MAAA,EACA,MAAA,GAAmD,OAAO,MAAA,KAAW,WAAA,GACjE,SACA,MAAA,EACe;AACnB,EAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,EAAE,SAAS,MAAM;AAAA,EAAC,CAAA,EAAE;AAExC,EAAA,MAAM,KAAA,GAAQ,MAAA;AAEd,EAAA,KAAA,CAAM,gBAAgB,CAAA,GAAI,MAAA;AAG1B,EAAA,MAAM,QAAA,GAAW,MACf,MAAA,CAAO,aAAA,CAAc,IAAI,WAAA,CAAY,yBAAA,EAA2B,EAAE,MAAA,EAAQ,MAAA,EAAQ,CAAC,CAAA;AACrF,EAAA,MAAA,CAAO,gBAAA,CAAiB,2BAA2B,QAAQ,CAAA;AAC3D,EAAA,QAAA,EAAS;AAET,EAAA,OAAO;AAAA,IACL,SAAS,MAAM;AACb,MAAA,MAAA,CAAO,mBAAA,CAAoB,2BAA2B,QAAQ,CAAA;AAE9D,MAAA,IAAI,MAAM,gBAAgB,CAAA,KAAM,MAAA,EAAQ,OAAO,MAAM,gBAAgB,CAAA;AAAA,IACvE;AAAA,GACF;AACF;;;AC/CO,IAAM,UAAA,GACX,w1QAAA;;;AC2BF,IAAM,OAAA,GAAU,MAAA,CAAOA,kBAAA,CAAU,eAAA,CAAgB,OAAO,CAAA;AAGxD,SAAS,UAAU,KAAA,EAAoC;AACrD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,KAAA;AACtC,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,OAAO,UAAU,QAAA,EAAU;AAC1D,IAAA,IAAI;AACF,MAAA,OAAO,OAAO,KAAK,CAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AA6BO,IAAM,cAAA,GAAN,cAA6BC,cAAA,CAAU;AAAA,EAU5C,WAAA,CAAY,OAAA,GAAiC,EAAC,EAAG;AAC/C,IAAA,KAAA,EAAM;AANR,IAAA,IAAA,CAAQ,QAAA,GAA0B,IAAA;AAClC,IAAA,IAAA,CAAQ,IAAA,GAAoC,IAAA;AAC5C,IAAA,IAAA,CAAQ,aAAA,GAA0C,IAAA;AAkIlD,IAAA,IAAA,CAAQ,iBAAA,GAAoB,CAAC,IAAA,KAAwB;AACnD,MAAA,MAAM,WAAW,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,GAAK,OAAqB,EAAC;AAC9D,MAAA,MAAM,OAAA,GAAU,SAAS,CAAC,CAAA;AAC1B,MAAA,IAAI,OAAO,OAAA,KAAY,QAAA,IAAY,OAAA,EAAS;AAC1C,QAAA,IAAA,CAAK,QAAA,GAAW,OAAA;AAChB,QAAA,IAAA,CAAK,UAAU,QAAA,EAAU,EAAE,OAAA,EAAS,OAAA,EAAS,SAAS,CAAA;AAAA,MACxD,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,QAAA,IAAA,CAAK,UAAU,YAAY,CAAA;AAAA,MAC7B;AAAA,IACF,CAAA;AAEA,IAAA,IAAA,CAAQ,gBAAA,GAAmB,CAAC,IAAA,KAAwB;AAElD,MAAA,MAAM,OAAA,GACJ,OAAO,IAAA,KAAS,QAAA,IAAY,SAAS,IAAA,IAAQ,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,GAC3D,IAAA,GACD,EAAE,SAAS,IAAA,EAAK;AACtB,MAAA,MAAM,OAAA,GAAU,SAAA,CAAU,OAAA,CAAQ,OAAO,CAAA;AACzC,MAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,OAAA,CAAQ,QAAQ,CAAA,GAAI,OAAA,CAAQ,WAAW,EAAC;AACvE,MAAA,MAAM,IAAA,GAAO,OAAO,QAAA,CAAS,CAAC,CAAA,KAAM,QAAA,IAAY,QAAA,CAAS,CAAC,CAAA,GAAI,QAAA,CAAS,CAAC,CAAA,GAAI,IAAA,CAAK,QAAA;AACjF,MAAA,IAAI,IAAA,OAAW,QAAA,GAAW,IAAA;AAC1B,MAAA,MAAM,SAAwB,EAAC;AAC/B,MAAA,IAAI,OAAA,KAAY,MAAA,EAAW,MAAA,CAAO,OAAA,GAAU,OAAA;AAC5C,MAAA,IAAI,IAAA,SAAa,OAAA,GAAU,IAAA;AAC3B,MAAA,IAAA,CAAK,SAAA,CAAU,UAAU,MAAM,CAAA;AAAA,IACjC,CAAA;AAvJE,IAAA,MAAM,SAAA,GACJ,OAAA,CAAQ,SAAA,IAAa,OAAA,CAAQ,WAAW,SAAA,IAAa,6BAAA;AACvD,IAAA,IAAA,CAAK,SAAA,GAAY,IAAI,mBAAA,CAAoB;AAAA,MACvC,GAAG,OAAA,CAAQ,SAAA;AAAA,MACX,SAAA;AAAA,MACA,IAAA,EAAM;AAAA;AAAA,KACP,CAAA;AACD,IAAA,IAAA,CAAK,GAAA,GAAM,QAAQ,EAAA,IAAM,OAAA;AACzB,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAQ,IAAA,IAAQ,oBAAA;AAC7B,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAQ,IAAA,IAAQ,UAAA;AAC7B,IAAA,IAAA,CAAK,aAAA,GAAgB,QAAQ,QAAA,KAAa,KAAA;AAC1C,IAAA,IAAI,IAAA,CAAK,aAAA,EAAe,IAAA,CAAK,QAAA,EAAS;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAA,GAAiB;AACf,IAAA,IAAI,KAAK,aAAA,EAAe;AACxB,IAAA,IAAA,CAAK,aAAA,GAAgB,mBAAA,CAAoB,IAAA,CAAK,GAAA,EAAK,CAAA;AAAA,EACrD;AAAA;AAAA,EAGA,UAAA,GAAmB;AACjB,IAAA,IAAA,CAAK,eAAe,OAAA,EAAQ;AAC5B,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AAAA,EACvB;AAAA,EAEA,IAAI,EAAA,GAAa;AACf,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,EACd;AAAA,EAEA,IAAI,IAAA,GAAe;AACjB,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA,EAEA,IAAI,IAAA,GAAuB;AACzB,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA;AAAA,EAGA,SAAA,GAAqB;AACnB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,KAAA,GAA0B;AAC9B,IAAA,OAAO,KAAK,QAAA,KAAa,IAAA;AAAA,EAC3B;AAAA;AAAA,EAGQ,GAAA,GAA4B;AAClC,IAAA,IAAI,IAAA,CAAK,IAAA,EAAM,OAAO,IAAA,CAAK,IAAA;AAC3B,IAAA,MAAM,YAAY,IAAA,CAAK,SAAA;AACvB,IAAA,MAAM,OAAA,IAAW,OAAO,IAAA,KACtB,SAAA,CAAU,QAAQ,IAAI,CAAA,CAAA;AACxB,IAAA,IAAA,CAAK,IAAA,GAAO;AAAA,MACV,IAAI,IAAA,CAAK,GAAA;AAAA,MACT,MAAM,IAAA,CAAK,KAAA;AAAA,MACX,OAAA,EAAS,OAAA;AAAA,MACT,IAAA,EAAM,OAAO,IAAA,CAAK,KAAA,KAAU,WAAW,IAAA,CAAK,KAAA,GAAS,IAAA,CAAK,KAAA,EAAO,IAAA,IAAQ,EAAA;AAAA,MACzE,OAAA;AAAA,MACA,EAAA,GAAK,CAAC,KAAA,EAAe,OAAA,KAAqC;AACxD,QAAA,IAAI,UAAU,iBAAA,IAAqB,KAAA,KAAU,kBAAkB,SAAA,CAAU,EAAA,CAAG,OAAO,OAAO,CAAA;AAAA,MAC5F,CAAA,CAAA;AAAA,MACA,GAAA,GAAM,CAAC,KAAA,EAAe,OAAA,KAAqC;AACzD,QAAA,IAAI,KAAA,KAAU,qBAAqB,KAAA,KAAU,gBAAA;AAC3C,UAAA,SAAA,CAAU,GAAA,CAAI,OAAO,OAAO,CAAA;AAAA,MAChC,CAAA;AAAA,KACF;AACA,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAA,CAAQ,IAAA,GAAoB,EAAC,EAA2B;AAC5D,IAAA,IAAI,KAAK,WAAA,KAAgB,MAAA,IAAa,OAAO,IAAA,CAAK,WAAW,MAAM,OAAA,EAAS;AAC1E,MAAA,MAAM,MAAA,CAAO,MAAA;AAAA,QACX,IAAI,KAAA;AAAA,UACF,wCAAwC,MAAA,CAAO,IAAA,CAAK,WAAW,CAAA,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,gBAAA;AAAA,SAC/E;AAAA,QACA,EAAE,MAAM,mBAAA;AAAoB,OAC9B;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,CAAK,aAAA,EAAe,IAAA,CAAK,QAAA,EAAS;AACtC,IAAA,IAAA,CAAK,SAAA,EAAU;AACf,IAAA,MAAM,IAAA,CAAK,UAAU,IAAA,EAAK;AAC1B,IAAA,MAAM,QAAA,GAAY,MAAM,IAAA,CAAK,SAAA,CAAU,QAAQ,EAAE,IAAA,EAAM,0BAA0B,CAAA;AACjF,IAAA,MAAM,OAAA,GAAU,WAAW,CAAC,CAAA;AAC5B,IAAA,IAAI,CAAC,OAAA,EAAS,MAAM,IAAI,MAAM,kBAAkB,CAAA;AAChD,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA;AAChB,IAAA,MAAM,IAAA,GAAsB,EAAE,OAAA,EAAS,OAAA,EAAS,OAAA,EAAQ;AACxD,IAAA,IAAA,CAAK,SAAA,CAAU,WAAW,IAAI,CAAA;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,UAAA,GAA4B;AAChC,IAAA,IAAA,CAAK,WAAA,EAAY;AACjB,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AACrB,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAGhB,IAAA,IAAA,CAAK,UAAA,EAAW;AAChB,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,UAAU,YAAY,CAAA;AAAA,EAC7B;AAAA;AAAA,EAGQ,SAAA,GAAkB;AACxB,IAAA,IAAA,CAAK,WAAA,EAAY;AACjB,IAAA,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,iBAAA,EAAmB,IAAA,CAAK,iBAAiB,CAAA;AAC3D,IAAA,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,gBAAA,EAAkB,IAAA,CAAK,gBAAgB,CAAA;AAAA,EAC3D;AAAA,EAEQ,WAAA,GAAoB;AAC1B,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,iBAAA,EAAmB,IAAA,CAAK,iBAAiB,CAAA;AAC5D,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,gBAAA,EAAkB,IAAA,CAAK,gBAAgB,CAAA;AAAA,EAC5D;AAAA,EAmCQ,SAAA,CAAU,OAA4C,IAAA,EAA4B;AACxF,IAAA,MAAM,OAAA,GAAU,IAAA;AAChB,IAAA,IAAI,IAAA,KAAS,MAAA,EAAW,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA;AAAA,SACrC,OAAA,CAAQ,IAAA,CAAK,KAAA,EAAO,IAAI,CAAA;AAAA,EAC/B;AAAA,EAEA,MAAM,QAAQ,QAAA,EAAwD;AACpE,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,EAAU,MAAM,IAAI,MAAM,qBAAqB,CAAA;AAGzD,IAAA,OAAOC,sBAAA,CAAc,OAAA,CAAQ,QAAA,EAAU,IAAA,CAAK,KAAK,CAAA;AAAA,EACnD;AAAA,EAEA,MAAM,OAAA,GAA2B;AAC/B,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAM,QACJ,IAAA,EAC2C;AAC3C,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,IAAI,CAAA;AAAA,EACpC;AACF;;;AC9PO,SAAS,MAAM,OAAA,EAAiD;AACrE,EAAA,OAAO,IAAI,eAAe,OAAO,CAAA;AACnC;;;ACKO,IAAM,4BAAA,GAA+B;AA2E5C,SAAS,gBAAgB,KAAA,EAAgD;AACvE,EAAA,IAAI,OAAO,UAAU,QAAA,IAAY,OAAO,UAAU,QAAA,IAAY,OAAO,UAAU,QAAA,EAAU;AACvF,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI;AACF,IAAA,OAAO,cAAc,MAAA,CAAO,KAAK,CAAA,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA;AAAA,EACjD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAQO,SAAS,yBAAA,CACd,OAAA,GAAsC,EAAC,EAClB;AACrB,EAAA,MAAM,SAAA,GAAY,IAAI,mBAAA,CAAoB;AAAA,IACxC,GAAG,OAAA,CAAQ,SAAA;AAAA,IACX,SAAA,EAAW,QAAQ,SAAA,IAAa,6BAAA;AAAA,IAChC,IAAA,EAAM;AAAA,GACP,CAAA;AACD,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAyD;AAC/E,EAAA,IAAI,OAAA,GAAiE,IAAA;AAErE,EAAA,MAAM,QAAA,GAAW,MACf,OAAA,GACI;AAAA,IACE;AAAA,MACE,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,SAAA,EAAW,IAAI,UAAA,EAAW;AAAA,MAC1B,MAAA,EAAQ,CAAC,OAAA,CAAQ,KAAK,CAAA;AAAA,MACtB,UAAU;AAAC;AACb,MAEF,EAAC;AACP,EAAA,MAAM,aAAa,MAAM;AACvB,IAAA,MAAM,UAAA,GAA4C,EAAE,QAAA,EAAU,QAAA,EAAS,EAAE;AACzE,IAAA,KAAA,MAAW,YAAY,CAAC,GAAG,SAAS,CAAA,WAAY,UAAU,CAAA;AAAA,EAC5D,CAAA;AACA,EAAA,MAAM,kBAAkB,MAAM;AAC5B,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,OAAA,GAAU,IAAA;AACV,IAAA,UAAA,EAAW;AAAA,EACb,CAAA;AAEA,EAAA,MAAM,iBAAA,GAAoB,CAAC,IAAA,KAAkB;AAC3C,IAAA,MAAM,OAAO,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,GAAK,OAAqB,EAAC;AAC1D,IAAA,MAAM,OAAA,GAAU,KAAK,CAAC,CAAA;AACtB,IAAA,IAAI,OAAO,OAAA,KAAY,QAAA,IAAY,CAAC,OAAA,SAAgB,eAAA,EAAgB;AACpE,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,OAAA,GAAU,EAAE,GAAG,OAAA,EAAS,OAAA,EAAQ;AAChC,IAAA,UAAA,EAAW;AAAA,EACb,CAAA;AACA,EAAA,MAAM,gBAAA,GAAmB,CAAC,IAAA,KAAkB;AAC1C,IAAA,MAAM,OAAA,GACJ,OAAO,IAAA,KAAS,QAAA,IAAY,SAAS,IAAA,IAAQ,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,GAC3D,IAAA,GACD,EAAE,SAAS,IAAA,EAAK;AACtB,IAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,OAAA,CAAQ,OAAO,CAAA;AAC7C,IAAA,IAAI,CAAC,KAAA,EAAO,OAAO,eAAA,EAAgB;AACnC,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,OAAA,CAAQ,QAAQ,CAAA,GAAK,OAAA,CAAQ,WAAyB,EAAC;AAClF,IAAA,MAAM,OAAA,GAAU,OAAO,IAAA,CAAK,CAAC,CAAA,KAAM,QAAA,IAAY,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA,CAAK,CAAC,CAAA,GAAI,OAAA,CAAQ,OAAA;AAC3E,IAAA,OAAA,GAAU,EAAE,SAAS,KAAA,EAAM;AAC3B,IAAA,UAAA,EAAW;AAAA,EACb,CAAA;AACA,EAAA,SAAA,CAAU,EAAA,CAAG,mBAAmB,iBAAiB,CAAA;AACjD,EAAA,SAAA,CAAU,EAAA,CAAG,kBAAkB,gBAAgB,CAAA;AAE/C,EAAA,MAAM,OAAA,IAAW,CAAC,IAAA,KAAmC,SAAA,CAAU,QAAQ,IAAI,CAAA,CAAA;AAE3E,EAAA,MAAM,QAAA,GAAwC;AAAA,IAC5C,oBAAA,EAAsB;AAAA,MACpB,OAAA,EAAS,OAAA;AAAA,MACT,OAAA;AAAA,MACA,aAAA,EAAe,OAAA;AAAA,MACf,EAAA,EAAI;AAAA,KACN;AAAA,IACA,kBAAA,EAAoB;AAAA,MAClB,OAAA,EAAS,OAAA;AAAA,MACT,OAAA,EAAS,OAAO,KAAA,KAAU;AACxB,QAAA,IAAI,WAAW,KAAA,EAAO,MAAA,SAAe,EAAE,QAAA,EAAU,UAAS,EAAE;AAC5D,QAAA,MAAM,UAAU,IAAA,EAAK;AAErB,QAAA,MAAM,SAAU,MAAM,SAAA,CAAU,QAAQ,EAAE,IAAA,EAAM,0BAA0B,CAAA;AAC1E,QAAA,MAAM,OAAO,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,GAAK,SAAuB,EAAC;AAC9D,QAAA,MAAM,OAAA,GAAU,KAAK,CAAC,CAAA;AACtB,QAAA,IAAI,OAAO,YAAY,QAAA,IAAY,CAAC,SAAS,OAAO,EAAE,QAAA,EAAU,EAAC,EAAE;AACnE,QAAA,OAAA,GAAU,EAAE,OAAA,EAAS,KAAA,EAAO,4BAAA,EAA6B;AACzD,QAAA,UAAA,EAAW;AACX,QAAA,OAAO,EAAE,QAAA,EAAU,QAAA,EAAS,EAAE;AAAA,MAChC;AAAA,KACF;AAAA,IACA,qBAAA,EAAuB;AAAA,MACrB,OAAA,EAAS,OAAA;AAAA,MACT,YAAY,YAAY;AACtB,QAAA,SAAA,CAAU,KAAA,EAAM;AAChB,QAAA,eAAA,EAAgB;AAAA,MAClB;AAAA,KACF;AAAA,IACA,iBAAA,EAAmB;AAAA,MACjB,OAAA,EAAS,OAAA;AAAA,MACT,EAAA,EAAI,CAAC,MAAA,EAAQ,QAAA,KAAa;AACxB,QAAA,SAAA,CAAU,IAAI,QAAQ,CAAA;AACtB,QAAA,OAAO,MAAM;AACX,UAAA,SAAA,CAAU,OAAO,QAAQ,CAAA;AAAA,QAC3B,CAAA;AAAA,MACF;AAAA;AACF,GACF;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,OAAA;AAAA,IACT,IAAA,EAAM,QAAQ,IAAA,IAAQ,OAAA;AAAA,IACtB,IAAA,EAAM,QAAQ,IAAA,IAAS,UAAA;AAAA,IACvB,MAAA,EAAQ,CAAC,4BAA4B,CAAA;AAAA,IACrC,IAAI,QAAA,GAAW;AACb,MAAA,OAAO,QAAA,EAAS;AAAA,IAClB,CAAA;AAAA,IACA;AAAA,GACF;AACF;AAWO,SAAS,2BAAA,CACd,UAAsC,EAAC,EACvC,SAAmD,OAAO,MAAA,KAAW,WAAA,GACjE,MAAA,GACA,MAAA,EACQ;AACZ,EAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,MAAM;AAAA,EAAC,CAAA;AAC3B,EAAA,MAAM,MAAA,GAAS,0BAA0B,OAAO,CAAA;AAChD,EAAA,MAAM,cAAiC,EAAC;AACxC,EAAA,MAAM,QAAA,GAAW,CAAC,EAAE,QAAA,EAAS,KAAmB;AAC9C,IAAA,WAAA,CAAY,IAAA,CAAK,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA,EACnC,CAAA;AACA,EAAA,MAAM,UAAA,GAAa,CAAC,KAAA,KAAiB;AACnC,IAAA,MAAM,MAAO,KAAA,CAAmC,MAAA;AAChD,IAAA,IAAI,OAAO,OAAO,GAAA,CAAI,QAAA,KAAa,UAAA,WAAqB,GAAG,CAAA;AAAA,EAC7D,CAAA;AACA,EAAA,IAAI;AACF,IAAA,MAAA,CAAO,aAAA;AAAA,MACL,IAAI,YAAY,iCAAA,EAAmC;AAAA,QACjD,MAAA,EAAQ,QAAA;AAAA,QACR,OAAA,EAAS,KAAA;AAAA,QACT,UAAA,EAAY,KAAA;AAAA,QACZ,QAAA,EAAU;AAAA,OACX;AAAA,KACH;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,mEAAmE,KAAK,CAAA;AAAA,EACxF;AACA,EAAA,MAAA,CAAO,gBAAA,CAAiB,6BAA6B,UAAU,CAAA;AAC/D,EAAA,OAAO,MAAM;AACX,IAAA,MAAA,CAAO,mBAAA,CAAoB,6BAA6B,UAAU,CAAA;AAClE,IAAA,KAAA,MAAW,UAAA,IAAc,WAAA,CAAY,MAAA,CAAO,CAAC,GAAG,UAAA,EAAW;AAAA,EAC7D,CAAA;AACF","file":"index.cjs","sourcesContent":["/**\n * Wire protocol between the \"Connect with Chipi\" connector (running in the dApp)\n * and the Chipi hosted wallet (running at `wallet.chipipay.com` in a popup).\n *\n * Both sides import these shapes so the contract stays in lock-step. The\n * transport is `window.postMessage`: the dApp opens the wallet in a popup,\n * forwards get-starknet `wallet_*` RPC calls over the channel, and the wallet\n * answers after the user approves in its own (already-built) approval UI.\n */\n/** A get-starknet RPC call as sent over the wire: just the discriminant +\n * optional params (the full typed `RpcMessage` carries result/errors we don't\n * serialize). */\nexport interface ChipiRpcCall {\n type: string;\n params?: unknown;\n}\n\n/** Namespace tag on every message so we ignore unrelated postMessages. */\nexport const CHIPI_WC = \"chipi-connect/v1\" as const;\n\n/** wallet → dApp: the hosted wallet page finished loading and is listening. */\nexport interface ChipiReadyMessage {\n channel: typeof CHIPI_WC;\n type: \"ready\";\n}\n\n/** dApp → wallet: forward a get-starknet `wallet_*` RPC call. */\nexport interface ChipiRpcRequestMessage {\n channel: typeof CHIPI_WC;\n type: \"rpc\";\n id: string;\n /** The dApp origin, so the wallet can show it + enforce Verify checks. */\n origin: string;\n call: ChipiRpcCall;\n}\n\n/** wallet → dApp: the result (or error) for a given request id. */\nexport type ChipiRpcResultMessage =\n | { channel: typeof CHIPI_WC; type: \"rpc-result\"; id: string; ok: true; result: unknown }\n | {\n channel: typeof CHIPI_WC;\n type: \"rpc-result\";\n id: string;\n ok: false;\n error: { code: number; message: string };\n };\n\n/** wallet → dApp: an account/network change to propagate to the dApp. */\nexport interface ChipiEventMessage {\n channel: typeof CHIPI_WC;\n type: \"event\";\n event: \"accountsChanged\" | \"networkChanged\";\n data: unknown;\n}\n\nexport type ChipiWalletMessage = ChipiReadyMessage | ChipiRpcResultMessage | ChipiEventMessage;\nexport type ChipiDappMessage = ChipiRpcRequestMessage;\n\nexport function isChipiWalletMessage(data: unknown): data is ChipiWalletMessage {\n return (\n typeof data === \"object\" &&\n data !== null &&\n (data as { channel?: unknown }).channel === CHIPI_WC\n );\n}\n\n/** Type guard for a dApp→wallet message (used by the hosted wallet side). */\nexport function isChipiDappMessage(data: unknown): data is ChipiDappMessage {\n return (\n typeof data === \"object\" &&\n data !== null &&\n (data as { channel?: unknown }).channel === CHIPI_WC &&\n (data as { type?: unknown }).type === \"rpc\"\n );\n}\n","/**\n * Client-side (dApp) transport: opens the Chipi hosted wallet in a popup,\n * performs the ready handshake, and forwards get-starknet `wallet_*` RPC calls\n * over `postMessage`, correlating responses by id. The popup is reused across\n * requests. If the user closes it, later requests reject with `POPUP_CLOSED`\n * instead of reopening it: `window.open` outside a click is blocked by\n * browsers, so the dApp must call `connect()` (or `open()`) again from a click.\n */\nimport {\n CHIPI_WC,\n isChipiWalletMessage,\n type ChipiRpcCall,\n type ChipiRpcRequestMessage,\n type ChipiWalletMessage,\n} from \"./protocol.js\";\n\nexport interface ChipiTransportOptions {\n /** Hosted wallet base URL, e.g. `https://wallet.chipipay.com`. */\n walletUrl: string;\n /**\n * Transport mode:\n * - `\"popup\"` (default): open the hosted wallet in a popup window: the\n * universal model, works for any external dApp.\n * - `\"parent\"`: the dApp is embedded in an iframe INSIDE the Chipi wallet\n * (in-app browser); talk to `window.parent` instead of opening a popup, so\n * approval renders inline in the wallet. Only works when the dApp is\n * actually iframed by the Chipi host.\n * - `\"auto\"`: use `\"parent\"` when running inside an iframe, else `\"popup\"`.\n */\n mode?: \"popup\" | \"parent\" | \"auto\";\n /** Popup window name. */\n windowName?: string;\n /** Popup window features. */\n windowFeatures?: string;\n /** Ready-handshake timeout (ms). Defaults to 180_000. On timeout the popup is\n * closed and the transport resets, so the next `open()` starts clean. */\n openTimeoutMs?: number;\n /**\n * Per-request timeout (ms), counted from when the request is posted to the\n * wallet. Defaults to 120_000. A request that gets no answer in time rejects\n * with an Error whose `code` (and `name`) is `\"REQUEST_TIMEOUT\"`. Pass `0` to\n * disable.\n */\n requestTimeoutMs?: number;\n}\n\n/** Error codes the transport attaches to `Error.code` (besides wallet codes). */\nexport type ChipiTransportErrorCode = \"REQUEST_TIMEOUT\" | \"POPUP_CLOSED\";\n\nfunction transportError(code: ChipiTransportErrorCode, message: string): Error {\n const err = Object.assign(new Error(message), { code });\n err.name = code;\n return err;\n}\n\n/** Drop `undefined` values from plain objects (recursively) so the wallet never\n * receives `{ key: undefined }`: a strict schema on the host side would reject\n * it, and `postMessage` would otherwise preserve the key. Arrays keep their\n * positions. */\nfunction stripUndefined<T>(value: T): T {\n if (Array.isArray(value)) return value.map((v) => stripUndefined(v)) as T;\n if (value === null || typeof value !== \"object\") return value;\n const proto = Object.getPrototypeOf(value);\n if (proto !== Object.prototype && proto !== null) return value;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (v !== undefined) out[k] = stripUndefined(v);\n }\n return out as T;\n}\n\ntype EventName = \"accountsChanged\" | \"networkChanged\";\ntype EventHandler = (data: unknown) => void;\n\nfunction deferred<T>() {\n let resolve!: (v: T) => void;\n let reject!: (e: unknown) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n return { promise, resolve, reject };\n}\n\n/** Starknet mainnet chain id, hex of the short string \"SN_MAIN\". Chipi is mainnet-only. */\nconst SN_MAIN_HEX = \"0x534e5f4d41494e\";\n\n/**\n * Answer for a passive call (one that must never prompt) while no wallet window\n * is open, or `undefined` when the call needs the wallet. Wallet scanners such\n * as get-starknet v4 send these to every `window.starknet*` object at page\n * load; forwarding them would call `window.open` outside a click.\n * - `wallet_getPermissions`: `[]` (this page has not connected).\n * - `wallet_requestAccounts` with `silent_mode: true`: `[]` (never prompts).\n * - `wallet_requestChainId`: SN_MAIN.\n */\nfunction passiveAnswer(call: ChipiRpcCall): { value: unknown } | undefined {\n switch (call.type) {\n case \"wallet_getPermissions\":\n return { value: [] };\n case \"wallet_requestAccounts\": {\n const params = call.params as { silent_mode?: unknown } | undefined;\n return params?.silent_mode === true ? { value: [] } : undefined;\n }\n case \"wallet_requestChainId\":\n return { value: SN_MAIN_HEX };\n default:\n return undefined;\n }\n}\n\nfunction randomId(): string {\n // App-runtime ids; uniqueness only needs to hold within one open popup.\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport class ChipiPopupTransport {\n private readonly walletOrigin: string;\n private readonly url: string;\n private target: Window | null = null;\n private ownsTarget = false;\n private ready = false;\n private listening = false;\n private readonly pending = new Map<\n string,\n {\n resolve: (v: unknown) => void;\n reject: (e: unknown) => void;\n message: ChipiRpcRequestMessage;\n timer?: ReturnType<typeof setTimeout>;\n }\n >();\n private readonly handlers = new Map<EventName, Set<EventHandler>>();\n private readyDeferred: ReturnType<typeof deferred<void>> | null = null;\n private openPromise: Promise<void> | null = null;\n private closeWatch: ReturnType<typeof setInterval> | null = null;\n /** True once this transport opened a popup. A later request with no live\n * popup means the user closed it: reject instead of reopening off-gesture. */\n private hadPopup = false;\n\n constructor(private readonly opts: ChipiTransportOptions) {\n this.url = opts.walletUrl.replace(/\\/$/, \"\") + \"/connect\";\n this.walletOrigin = new URL(opts.walletUrl).origin;\n }\n\n on(event: EventName, handler: EventHandler): void {\n (this.handlers.get(event) ?? this.handlers.set(event, new Set()).get(event)!).add(handler);\n }\n\n off(event: EventName, handler: EventHandler): void {\n this.handlers.get(event)?.delete(handler);\n }\n\n private ensureListener(): void {\n if (this.listening || typeof window === \"undefined\") return;\n window.addEventListener(\"message\", this.onMessage);\n this.listening = true;\n }\n\n private onMessage = (e: MessageEvent): void => {\n if (e.origin !== this.walletOrigin || !isChipiWalletMessage(e.data)) return;\n // Isolate to OUR wallet window: without this, a second Chipi popup (another\n // dApp, same origin) could leak its `ready`/`event` into this transport.\n // With no target (before open / after close) nothing is ours: ignore it all,\n // so a stray `ready` can't flip state and a stray `event` can't fire.\n if (!this.target || e.source !== this.target) return;\n const msg = e.data as ChipiWalletMessage;\n if (msg.type === \"ready\") {\n this.ready = true;\n this.readyDeferred?.resolve();\n this.readyDeferred = null;\n // A fresh /connect re-announces \"ready\": e.g. after the user signs in,\n // which reloads the popup onto a new page. The request we already sent went\n // to the previous page, which is gone. Re-send the requests that are still\n // unanswered (`pending` only holds those) so they reach the new page.\n // Contract: the hosted wallet MUST de-dupe by request id, because a repeat\n // `ready` (e.g. the popup's multi-post ready) re-sends the same request.\n for (const p of this.pending.values()) {\n this.target.postMessage(p.message, this.walletOrigin);\n }\n return;\n }\n if (msg.type === \"rpc-result\") {\n const p = this.pending.get(msg.id);\n if (!p) return;\n this.pending.delete(msg.id);\n if (p.timer) clearTimeout(p.timer);\n if (msg.ok) p.resolve(msg.result);\n else p.reject(Object.assign(new Error(msg.error.message), { code: msg.error.code }));\n return;\n }\n if (msg.type === \"event\") {\n this.handlers.get(msg.event)?.forEach((h) => h(msg.data));\n }\n };\n\n /** Resolve \"auto\" → \"parent\" when iframed, else \"popup\". */\n private resolveMode(): \"popup\" | \"parent\" {\n const mode = this.opts.mode ?? \"popup\";\n if (mode !== \"auto\") return mode;\n return typeof window !== \"undefined\" && window.parent !== window ? \"parent\" : \"popup\";\n }\n\n /** Open (or reuse) the wallet (popup window OR the parent frame) and wait for\n * its ready handshake. Concurrent calls share ONE handshake. */\n async open(): Promise<void> {\n if (typeof window === \"undefined\") throw new Error(\"chipi_connector_requires_browser\");\n this.ensureListener();\n const isParent = this.resolveMode() === \"parent\";\n if (this.ready && this.target && (isParent || !this.target.closed)) return;\n if (this.openPromise) return this.openPromise;\n this.openPromise = this.doOpen(isParent);\n try {\n await this.openPromise;\n } finally {\n this.openPromise = null;\n }\n }\n\n private async doOpen(isParent: boolean): Promise<void> {\n if (isParent) {\n if (window.parent === window) throw new Error(\"chipi_not_in_iframe\");\n this.target = window.parent;\n this.ownsTarget = false;\n } else {\n this.ready = false;\n // Unique per-open window name so a reconnect can never reuse a stale popup\n // that still holds a previous session's pending approval.\n const name = this.opts.windowName ?? `chipi-wallet-${randomId()}`;\n this.target = window.open(\n this.url,\n name,\n this.opts.windowFeatures ?? \"popup=yes,width=420,height=680\"\n );\n this.ownsTarget = true;\n if (!this.target) throw Object.assign(new Error(\"Popup blocked\"), { code: \"popup_blocked\" });\n this.hadPopup = true;\n }\n const opened = this.target;\n this.readyDeferred = deferred<void>();\n try {\n await this.awaitReady();\n } catch (err) {\n // Handshake stalled: close the popup we opened and reset, so a stale\n // window can't answer later and the next open() starts from scratch.\n // (Skip if close() already replaced the target in the meantime.)\n if (this.target === opened) this.resetTarget();\n throw err;\n }\n }\n\n /** Close the popup (if we own one) and forget the target + ready state. */\n private resetTarget(): void {\n try {\n if (this.ownsTarget) this.target?.close();\n } catch {\n // ignore\n }\n this.target = null;\n this.ready = false;\n this.readyDeferred = null;\n }\n\n private async awaitReady(): Promise<void> {\n // Generous: a cold login (Clerk / passkey) can take a while. We only reject\n // here on an outright stall: the popup-closed watcher handles the real\n // \"user gave up / closed it\" case quickly.\n const timeoutMs = this.opts.openTimeoutMs ?? 180_000;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(\"wallet_open_timeout\")), timeoutMs);\n });\n try {\n await Promise.race([this.readyDeferred!.promise, timeout]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n\n /** Reject every in-flight request (popup closed / disconnected). */\n private rejectAllPending(message: string): void {\n for (const [, p] of this.pending) {\n if (p.timer) clearTimeout(p.timer);\n p.reject(Object.assign(new Error(message), { code: 4001 }));\n }\n this.pending.clear();\n }\n\n /** While requests are in flight, watch for the user closing the popup and\n * reject them: otherwise the dApp's promise would hang forever. */\n private startCloseWatch(): void {\n if (this.closeWatch || !this.ownsTarget) return;\n this.closeWatch = setInterval(() => {\n if (this.target?.closed) {\n this.ready = false;\n this.target = null;\n this.rejectAllPending(\"User closed the wallet\");\n this.stopCloseWatch();\n } else if (this.pending.size === 0) {\n this.stopCloseWatch();\n }\n }, 500);\n }\n\n private stopCloseWatch(): void {\n if (this.closeWatch) {\n clearInterval(this.closeWatch);\n this.closeWatch = null;\n }\n }\n\n /**\n * Forward a get-starknet RPC call to the wallet, awaiting its response.\n *\n * With no wallet window open, passive calls are answered locally and never\n * open it: `wallet_getPermissions` → `[]`, `wallet_requestAccounts` with\n * `silent_mode: true` → `[]`, `wallet_requestChainId` → SN_MAIN.\n *\n * The first request may open the popup. Once a popup has been opened, a\n * request made after it was closed rejects with `code: \"POPUP_CLOSED\"`\n * instead of calling `window.open` again: requests usually run outside a\n * click, where browsers block popups. Reopen via `connect()` / `open()`\n * from a click.\n */\n async request(call: ChipiRpcCall): Promise<unknown> {\n // Passive calls never open the popup: with no wallet window open (or\n // opening), answer them here. Once connected they go to the wallet.\n if (this.resolveMode() === \"popup\" && (!this.target || this.target.closed)) {\n const passive = passiveAnswer(call);\n if (passive) return passive.value;\n }\n if (this.hadPopup && this.resolveMode() === \"popup\" && (!this.target || this.target.closed)) {\n throw transportError(\n \"POPUP_CLOSED\",\n \"The Chipi wallet window was closed. Call connect() again from a click.\"\n );\n }\n await this.open();\n if (this.ownsTarget) this.target?.focus();\n const id = randomId();\n const message: ChipiRpcRequestMessage = {\n channel: CHIPI_WC,\n type: \"rpc\",\n id,\n origin: window.location.origin,\n call: stripUndefined(call),\n };\n const timeoutMs = this.opts.requestTimeoutMs ?? 120_000;\n return new Promise<unknown>((resolve, reject) => {\n const entry: {\n resolve: (v: unknown) => void;\n reject: (e: unknown) => void;\n message: ChipiRpcRequestMessage;\n timer?: ReturnType<typeof setTimeout>;\n } = { resolve, reject, message };\n if (timeoutMs > 0 && Number.isFinite(timeoutMs)) {\n entry.timer = setTimeout(() => {\n if (this.pending.get(id) !== entry) return;\n this.pending.delete(id);\n reject(\n transportError(\n \"REQUEST_TIMEOUT\",\n `The Chipi wallet did not answer \"${call.type}\" within ${timeoutMs} ms.`\n )\n );\n }, timeoutMs);\n }\n this.pending.set(id, entry);\n this.target!.postMessage(message, this.walletOrigin);\n this.startCloseWatch();\n });\n }\n\n /** Close the popup (if we own one) + reject in-flight requests. */\n close(): void {\n this.stopCloseWatch();\n // Unblock an in-flight open() instead of leaving it to the ready timeout.\n this.readyDeferred?.reject(Object.assign(new Error(\"disconnected\"), { code: 4001 }));\n this.resetTarget();\n this.rejectAllPending(\"disconnected\");\n if (this.listening && typeof window !== \"undefined\") {\n window.removeEventListener(\"message\", this.onMessage);\n this.listening = false;\n }\n }\n}\n","import type { StarknetWindowObject } from \"@starknet-io/types-js\";\n\n/** Window key get-starknet discovers by scanning for `starknet*` properties. */\nexport const CHIPI_WINDOW_KEY = \"starknet_chipi\";\n\nexport interface ChipiRegistration {\n /** Remove `window.starknet_chipi` + the announce listener. */\n dispose: () => void;\n}\n\n/**\n * Make a Chipi `StarknetWindowObject` discoverable to any get-starknet /\n * starknet-react / starknetkit dApp on the page: WITHOUT an upstream PR and\n * WITHOUT whitelisting. This self-registration covers the apps that scan for\n * wallets rather than importing our connector explicitly.\n *\n * Discovery is announced two ways for maximum reach:\n * 1. **window scan**: set `window.starknet_chipi`. get-starknet v4's\n * `getAvailableWallets()` finds every `window` key starting with `starknet`.\n * 2. **event announce**: dispatch `starknet:announceWallet` now and again on\n * the dApp's `starknet:requestWallets` (the EIP-6963-style, timing-robust\n * Starknet Wallet Standard discovery path).\n *\n * SSR-safe (no-ops when there's no `window`) and idempotent per (target, wallet).\n */\nexport function registerChipiWallet(\n wallet: StarknetWindowObject,\n target: (Window & typeof globalThis) | undefined = typeof window !== \"undefined\"\n ? window\n : undefined\n): ChipiRegistration {\n if (!target) return { dispose: () => {} };\n\n const store = target as unknown as Record<string, unknown>;\n // 1. Classic window-scan discovery.\n store[CHIPI_WINDOW_KEY] = wallet;\n\n // 2. Event-based discovery (announce now + whenever a dApp asks).\n const announce = () =>\n target.dispatchEvent(new CustomEvent(\"starknet:announceWallet\", { detail: wallet }));\n target.addEventListener(\"starknet:requestWallets\", announce);\n announce();\n\n return {\n dispose: () => {\n target.removeEventListener(\"starknet:requestWallets\", announce);\n // Only remove our own object: never clobber a newer injector's wallet.\n if (store[CHIPI_WINDOW_KEY] === wallet) delete store[CHIPI_WINDOW_KEY];\n },\n };\n}\n","// Chipi brand wallet icon: the current luchador mark on a transparent\n// background, 48x48 PNG (same asset used by the browser extension's\n// toolbar icon). A data-URI is what get-starknet / wallet pickers render.\nexport const CHIPI_ICON =\n \"data:image/png;base64,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\";\n","/**\n * `ChipiConnector`: a starknet-react / get-starknet connector for the Chipi\n * hosted smart-account wallet. A self-contained connector package any dApp\n * adds to its `connectors` array (`new ChipiConnector()`) directly: no\n * whitelisting, no dependency on a third-party wallet kit, and NO browser\n * extension required. Clicking \"Connect with Chipi\" opens our hosted wallet\n * (passkey + gasless paymaster) in a popup; the dApp's `wallet_*` RPC calls are\n * forwarded over postMessage and answered after the user approves in Chipi's\n * own (already-built) approval UI.\n */\nimport { Connector } from \"@starknet-react/core\";\nimport { WalletAccount, constants } from \"starknet\";\nimport type { AccountInterface, ProviderInterface } from \"starknet\";\nimport type {\n RpcMessage,\n RequestFnCall,\n RpcTypeToMessageMap,\n StarknetWindowObject,\n} from \"@starknet-io/types-js\";\nimport { ChipiPopupTransport, type ChipiTransportOptions } from \"./transport.js\";\nimport { registerChipiWallet, type ChipiRegistration } from \"./register.js\";\nimport { CHIPI_ICON } from \"./icon.js\";\n\n// @starknet-react/core declares these internally but doesn't export them; mirror\n// the shapes (ConnectorIcons === get-starknet's StarknetWindowObject[\"icon\"]).\ntype ConnectorIcons = StarknetWindowObject[\"icon\"];\ntype ConnectorData = { account?: string; chainId?: bigint };\n/** Mirrors starknet-react's `ConnectArgs` (not exported by every version). */\ntype ConnectArgs = { chainIdHint?: bigint };\n\n/** Starknet mainnet chain id (felt of the shortstring \"SN_MAIN\"). */\nconst SN_MAIN = BigInt(constants.StarknetChainId.SN_MAIN);\n\n/** Parse a wallet-sent chain id (hex/decimal string, bigint or number). */\nfunction toChainId(value: unknown): bigint | undefined {\n if (typeof value === \"bigint\") return value;\n if (typeof value === \"number\" || typeof value === \"string\") {\n try {\n return BigInt(value);\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\nexport interface ChipiConnectorOptions {\n /** Hosted wallet base URL. Defaults to `https://wallet.chipipay.com`. */\n walletUrl?: string;\n /** Override the connector id / display name / icon if embedding. */\n id?: string;\n name?: string;\n icon?: ConnectorIcons;\n /**\n * Popup transport tuning: `windowName`, `windowFeatures`, `openTimeoutMs`,\n * `requestTimeoutMs`. `walletUrl` is optional here (the top-level\n * `walletUrl` wins) and `mode` is always `\"popup\"`.\n */\n transport?: Omit<ChipiTransportOptions, \"walletUrl\"> & { walletUrl?: string };\n /**\n * Self-register the wallet on `window` (set `window.starknet_chipi` + announce\n * via `starknet:announceWallet`) so dApps that *scan* `window.starknet*`\n * (get-starknet v4, get-starknet-discovery's injected scan) and don't import\n * this connector also discover \"Connect with Chipi\". Defaults to `true` in a browser; pass\n * `false` to opt out (e.g. to avoid a double entry in a picker that already\n * lists the connector explicitly). No-op during SSR.\n */\n register?: boolean;\n // NOTE: the in-app-browser (\"parent\") transport mode is implemented in the\n // transport but NOT yet supported by the hosted wallet side, so it's not\n // exposed here in v1. Use popup (external dApps) only.\n}\n\nexport class ChipiConnector extends Connector {\n private readonly transport: ChipiPopupTransport;\n private readonly _id: string;\n private readonly _name: string;\n private readonly _icon: ConnectorIcons;\n private _account: string | null = null;\n private _swo: StarknetWindowObject | null = null;\n private _registration: ChipiRegistration | null = null;\n private readonly _autoRegister: boolean;\n\n constructor(options: ChipiConnectorOptions = {}) {\n super();\n const walletUrl =\n options.walletUrl ?? options.transport?.walletUrl ?? \"https://wallet.chipipay.com\";\n this.transport = new ChipiPopupTransport({\n ...options.transport,\n walletUrl,\n mode: \"popup\", // v1: external-dApp popup only (parent host not yet built)\n });\n this._id = options.id ?? \"chipi\";\n this._name = options.name ?? \"Connect with Chipi\";\n this._icon = options.icon ?? CHIPI_ICON;\n this._autoRegister = options.register !== false;\n if (this._autoRegister) this.register();\n }\n\n /**\n * Announce this wallet to scanning dApps (`window.starknet_chipi` +\n * `starknet:announceWallet`). Called automatically from the constructor\n * unless `register: false`. Idempotent and SSR-safe.\n */\n register(): void {\n if (this._registration) return;\n this._registration = registerChipiWallet(this.swo());\n }\n\n /** Undo {@link register}: remove the window object + announce listener. */\n unregister(): void {\n this._registration?.dispose();\n this._registration = null;\n }\n\n get id(): string {\n return this._id;\n }\n\n get name(): string {\n return this._name;\n }\n\n get icon(): ConnectorIcons {\n return this._icon;\n }\n\n /** Hosted wallet: always available (no extension to detect). */\n available(): boolean {\n return true;\n }\n\n /** No silent reconnect in v1: the user re-approves the popup each session. */\n async ready(): Promise<boolean> {\n return this._account !== null;\n }\n\n /** Lazily build the postMessage-backed get-starknet window object. */\n private swo(): StarknetWindowObject {\n if (this._swo) return this._swo;\n const transport = this.transport;\n const request = (async (call: RpcMessage) =>\n transport.request(call)) as StarknetWindowObject[\"request\"];\n this._swo = {\n id: this._id,\n name: this._name,\n version: \"1.0.0\",\n icon: typeof this._icon === \"string\" ? this._icon : (this._icon?.dark ?? \"\"),\n request,\n on: ((event: string, handler: (data: unknown) => void) => {\n if (event === \"accountsChanged\" || event === \"networkChanged\") transport.on(event, handler);\n }) as StarknetWindowObject[\"on\"],\n off: ((event: string, handler: (data: unknown) => void) => {\n if (event === \"accountsChanged\" || event === \"networkChanged\")\n transport.off(event, handler);\n }) as StarknetWindowObject[\"off\"],\n };\n return this._swo;\n }\n\n /**\n * Open the hosted wallet (call from a click: it opens a popup) and request\n * the account. Chipi is mainnet-only: a `chainIdHint` other than SN_MAIN\n * rejects before any popup opens.\n */\n async connect(args: ConnectArgs = {}): Promise<ConnectorData> {\n if (args.chainIdHint !== undefined && BigInt(args.chainIdHint) !== SN_MAIN) {\n throw Object.assign(\n new Error(\n `Chipi is mainnet-only: chainIdHint 0x${BigInt(args.chainIdHint).toString(16)} is not SN_MAIN.`\n ),\n { code: \"UNSUPPORTED_CHAIN\" }\n );\n }\n // Re-announce if a previous disconnect() disposed the registration.\n if (this._autoRegister) this.register();\n this.subscribe();\n await this.transport.open();\n const accounts = (await this.transport.request({ type: \"wallet_requestAccounts\" })) as string[];\n const account = accounts?.[0];\n if (!account) throw new Error(\"chipi_no_account\");\n this._account = account;\n const data: ConnectorData = { account, chainId: SN_MAIN };\n this.emitEvent(\"connect\", data);\n return data;\n }\n\n async disconnect(): Promise<void> {\n this.unsubscribe();\n this.transport.close();\n this._account = null;\n // Drop `window.starknet_chipi` so scanners don't keep a stale object; the\n // next connect() registers a fresh one.\n this.unregister();\n this._swo = null;\n this.emitEvent(\"disconnect\");\n }\n\n /** Forward the wallet's account/network events as starknet-react events. */\n private subscribe(): void {\n this.unsubscribe(); // idempotent across repeated connect() calls\n this.transport.on(\"accountsChanged\", this.onAccountsChanged);\n this.transport.on(\"networkChanged\", this.onNetworkChanged);\n }\n\n private unsubscribe(): void {\n this.transport.off(\"accountsChanged\", this.onAccountsChanged);\n this.transport.off(\"networkChanged\", this.onNetworkChanged);\n }\n\n private onAccountsChanged = (data: unknown): void => {\n const accounts = Array.isArray(data) ? (data as unknown[]) : [];\n const account = accounts[0];\n if (typeof account === \"string\" && account) {\n this._account = account;\n this.emitEvent(\"change\", { account, chainId: SN_MAIN });\n } else {\n this._account = null;\n this.emitEvent(\"disconnect\");\n }\n };\n\n private onNetworkChanged = (data: unknown): void => {\n // The wallet may send the chain id alone or `{ chainId, accounts }`.\n const payload =\n typeof data === \"object\" && data !== null && !Array.isArray(data)\n ? (data as { chainId?: unknown; accounts?: unknown })\n : { chainId: data };\n const chainId = toChainId(payload.chainId);\n const accounts = Array.isArray(payload.accounts) ? payload.accounts : [];\n const next = typeof accounts[0] === \"string\" && accounts[0] ? accounts[0] : this._account;\n if (next) this._account = next;\n const change: ConnectorData = {};\n if (chainId !== undefined) change.chainId = chainId;\n if (next) change.account = next;\n this.emitEvent(\"change\", change);\n };\n\n // `Connector` extends eventemitter3's EventEmitter, but the bundled .d.ts\n // doesn't surface `emit` cleanly through the abstract class: reach it via a\n // narrow cast rather than fight the upstream typing.\n private emitEvent(event: \"connect\" | \"change\", data: ConnectorData): void;\n private emitEvent(event: \"disconnect\"): void;\n private emitEvent(event: \"connect\" | \"change\" | \"disconnect\", data?: ConnectorData): void {\n const emitter = this as unknown as { emit: (e: string, d?: ConnectorData) => void };\n if (data === undefined) emitter.emit(event);\n else emitter.emit(event, data);\n }\n\n async account(provider: ProviderInterface): Promise<AccountInterface> {\n if (!this._account) throw new Error(\"chipi_not_connected\");\n // WalletAccount routes execute()/signMessage() through the SWO's request(),\n // i.e. over our postMessage channel to the hosted wallet.\n return WalletAccount.connect(provider, this.swo());\n }\n\n async chainId(): Promise<bigint> {\n return SN_MAIN;\n }\n\n async request<T extends RpcMessage[\"type\"]>(\n call: RequestFnCall<T>\n ): Promise<RpcTypeToMessageMap[T][\"result\"]> {\n return this.transport.request(call) as Promise<RpcTypeToMessageMap[T][\"result\"]>;\n }\n}\n","import { ChipiConnector, type ChipiConnectorOptions } from \"./connector.js\";\n\n/**\n * Plain-function form of {@link ChipiConnector}, for parity with\n * `@starknet-react/core`'s built-in factories (`ready()`, `braavos()`):\n *\n * const connectors = [chipi(), ready(), braavos()];\n *\n * Equivalent to `new ChipiConnector(options)`: use whichever reads better\n * in your `connectors` array.\n */\nexport function chipi(options?: ChipiConnectorOptions): ChipiConnector {\n return new ChipiConnector(options);\n}\n","/**\n * Chipi as a Wallet Standard wallet with Starknet features\n * (`WalletWithStarknetFeatures` from `@starknet-io/get-starknet-wallet-standard`),\n * so dApps on get-starknet v5+/v6 discovery (`@starknet-io/get-starknet-discovery`,\n * `@starknet-start/react`, anything that listens for\n * `wallet-standard:register-wallet`) list \"Chipi\" without importing this\n * package's connector.\n *\n * Backed by the same popup transport as {@link ChipiConnector}. The types\n * below mirror the upstream interfaces structurally so this package keeps no\n * runtime (or type) dependency on `@wallet-standard/*`.\n */\nimport type { RequestFn } from \"@starknet-io/types-js\";\nimport { ChipiPopupTransport, type ChipiTransportOptions } from \"./transport.js\";\nimport { CHIPI_ICON } from \"./icon.js\";\n\n/** Wallet Standard chain id for Starknet mainnet: `starknet:` + hex of \"SN_MAIN\"\n * (same as `WELL_KNOWN_STARKNET_CHAINS[0]` in get-starknet-wallet-standard). */\nexport const CHIPI_STARKNET_MAINNET_CHAIN = \"starknet:0x534e5f4d41494e\" as const;\n\n/** `starknet:0x...` chain identifier. */\nexport type ChipiStarknetChain = `starknet:0x${string}`;\n\n/** Data-URI icon, as Wallet Standard requires. */\nexport type ChipiWalletIcon = `data:image/${\"svg+xml\" | \"webp\" | \"png\" | \"gif\"};base64,${string}`;\n\n/** Mirrors `@wallet-standard/base` `WalletAccount`. */\nexport interface ChipiStandardWalletAccount {\n readonly address: string;\n readonly publicKey: Uint8Array;\n readonly chains: readonly ChipiStarknetChain[];\n readonly features: readonly `${string}:${string}`[];\n}\n\n/** Mirrors `@wallet-standard/features` `StandardEventsChangeProperties`. */\nexport interface ChipiStandardChangeProperties {\n readonly chains?: readonly ChipiStarknetChain[];\n readonly accounts?: readonly ChipiStandardWalletAccount[];\n}\n\n/** Mirrors `StarknetFeatures` from `@starknet-io/get-starknet-wallet-standard`.\n * (A type alias, not an interface, so it satisfies Wallet Standard's\n * `IdentifierRecord` index signature.) */\nexport type ChipiStandardWalletFeatures = {\n readonly \"starknet:walletApi\": {\n readonly version: \"1.0.0\";\n readonly request: RequestFn;\n readonly walletVersion: string;\n readonly id: string;\n };\n readonly \"standard:connect\": {\n readonly version: \"1.0.0\";\n readonly connect: (input?: {\n readonly silent?: boolean;\n }) => Promise<{ readonly accounts: readonly ChipiStandardWalletAccount[] }>;\n };\n readonly \"standard:disconnect\": {\n readonly version: \"1.0.0\";\n readonly disconnect: () => Promise<void>;\n };\n readonly \"standard:events\": {\n readonly version: \"1.0.0\";\n readonly on: <E extends \"change\">(\n event: E,\n listener: (properties: ChipiStandardChangeProperties) => void\n ) => () => void;\n };\n};\n\n/** Structurally a `WalletWithStarknetFeatures`. */\nexport interface ChipiStandardWallet {\n readonly version: \"1.0.0\";\n readonly name: string;\n readonly icon: ChipiWalletIcon;\n readonly chains: readonly ChipiStarknetChain[];\n readonly accounts: readonly ChipiStandardWalletAccount[];\n readonly features: ChipiStandardWalletFeatures;\n}\n\nexport interface ChipiStandardWalletOptions {\n /** Hosted wallet base URL. Defaults to `https://wallet.chipipay.com`. */\n walletUrl?: string;\n /** Display name. Defaults to `\"Chipi\"`. */\n name?: string;\n /** Data-URI icon. Defaults to the Chipi icon. */\n icon?: ChipiWalletIcon;\n /** Popup transport tuning (window name/features, timeouts). */\n transport?: Omit<ChipiTransportOptions, \"walletUrl\" | \"mode\">;\n}\n\n/** Same shape as a Wallet Standard `register-wallet` event detail callback. */\ntype RegisterApi = { register: (wallet: ChipiStandardWallet) => () => void };\n\nfunction toStarknetChain(value: unknown): ChipiStarknetChain | undefined {\n if (typeof value !== \"string\" && typeof value !== \"bigint\" && typeof value !== \"number\") {\n return undefined;\n }\n try {\n return `starknet:0x${BigInt(value).toString(16)}`;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Build the Chipi Wallet Standard wallet (without registering it). `connect`\n * opens the popup, so dApps call it from a click; `connect({ silent: true })`\n * never opens a popup and returns the current accounts (empty if not\n * connected).\n */\nexport function createChipiStandardWallet(\n options: ChipiStandardWalletOptions = {}\n): ChipiStandardWallet {\n const transport = new ChipiPopupTransport({\n ...options.transport,\n walletUrl: options.walletUrl ?? \"https://wallet.chipipay.com\",\n mode: \"popup\",\n });\n const listeners = new Set<(properties: ChipiStandardChangeProperties) => void>();\n let current: { address: string; chain: ChipiStarknetChain } | null = null;\n\n const accounts = (): ChipiStandardWalletAccount[] =>\n current\n ? [\n {\n address: current.address,\n publicKey: new Uint8Array(),\n chains: [current.chain],\n features: [],\n },\n ]\n : [];\n const emitChange = () => {\n const properties: ChipiStandardChangeProperties = { accounts: accounts() };\n for (const listener of [...listeners]) listener(properties);\n };\n const setDisconnected = () => {\n if (!current) return;\n current = null;\n emitChange();\n };\n\n const onAccountsChanged = (data: unknown) => {\n const list = Array.isArray(data) ? (data as unknown[]) : [];\n const address = list[0];\n if (typeof address !== \"string\" || !address) return setDisconnected();\n if (!current) return; // not connected through this wallet: ignore\n current = { ...current, address };\n emitChange();\n };\n const onNetworkChanged = (data: unknown) => {\n const payload =\n typeof data === \"object\" && data !== null && !Array.isArray(data)\n ? (data as { chainId?: unknown; accounts?: unknown })\n : { chainId: data };\n const chain = toStarknetChain(payload.chainId);\n if (!chain) return setDisconnected();\n if (!current) return;\n const list = Array.isArray(payload.accounts) ? (payload.accounts as unknown[]) : [];\n const address = typeof list[0] === \"string\" && list[0] ? list[0] : current.address;\n current = { address, chain };\n emitChange();\n };\n transport.on(\"accountsChanged\", onAccountsChanged);\n transport.on(\"networkChanged\", onNetworkChanged);\n\n const request = ((call: Parameters<RequestFn>[0]) => transport.request(call)) as RequestFn;\n\n const features: ChipiStandardWalletFeatures = {\n \"starknet:walletApi\": {\n version: \"1.0.0\",\n request,\n walletVersion: \"1.0.0\",\n id: \"chipi\",\n },\n \"standard:connect\": {\n version: \"1.0.0\",\n connect: async (input) => {\n if (current || input?.silent) return { accounts: accounts() };\n await transport.open();\n // No params: never forward `{ silent_mode: undefined }` to the wallet.\n const result = (await transport.request({ type: \"wallet_requestAccounts\" })) as unknown;\n const list = Array.isArray(result) ? (result as unknown[]) : [];\n const address = list[0];\n if (typeof address !== \"string\" || !address) return { accounts: [] };\n current = { address, chain: CHIPI_STARKNET_MAINNET_CHAIN };\n emitChange();\n return { accounts: accounts() };\n },\n },\n \"standard:disconnect\": {\n version: \"1.0.0\",\n disconnect: async () => {\n transport.close();\n setDisconnected();\n },\n },\n \"standard:events\": {\n version: \"1.0.0\",\n on: (_event, listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n },\n };\n\n return {\n version: \"1.0.0\",\n name: options.name ?? \"Chipi\",\n icon: options.icon ?? (CHIPI_ICON as ChipiWalletIcon),\n chains: [CHIPI_STARKNET_MAINNET_CHAIN],\n get accounts() {\n return accounts();\n },\n features,\n };\n}\n\n/**\n * Register Chipi with every Wallet Standard app on the page: dispatches\n * `wallet-standard:register-wallet` now and answers later\n * `wallet-standard:app-ready` events (the `@wallet-standard/wallet`\n * `registerWallet` protocol, implemented here without the dependency).\n *\n * Returns an unregister function that removes the listener and unregisters\n * from every app that accepted the wallet. SSR-safe: a no-op without `window`.\n */\nexport function registerChipiStandardWallet(\n options: ChipiStandardWalletOptions = {},\n target: (Window & typeof globalThis) | undefined = typeof window !== \"undefined\"\n ? window\n : undefined\n): () => void {\n if (!target) return () => {};\n const wallet = createChipiStandardWallet(options);\n const unregisters: Array<() => void> = [];\n const callback = ({ register }: RegisterApi) => {\n unregisters.push(register(wallet));\n };\n const onAppReady = (event: Event) => {\n const api = (event as CustomEvent<RegisterApi>).detail;\n if (api && typeof api.register === \"function\") callback(api);\n };\n try {\n target.dispatchEvent(\n new CustomEvent(\"wallet-standard:register-wallet\", {\n detail: callback,\n bubbles: false,\n cancelable: false,\n composed: false,\n })\n );\n } catch (error) {\n console.error(\"wallet-standard:register-wallet event could not be dispatched\\n\", error);\n }\n target.addEventListener(\"wallet-standard:app-ready\", onAppReady);\n return () => {\n target.removeEventListener(\"wallet-standard:app-ready\", onAppReady);\n for (const unregister of unregisters.splice(0)) unregister();\n };\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -145,6 +145,10 @@ declare class ChipiPopupTransport {
145
145
  /**
146
146
  * Forward a get-starknet RPC call to the wallet, awaiting its response.
147
147
  *
148
+ * With no wallet window open, passive calls are answered locally and never
149
+ * open it: `wallet_getPermissions` → `[]`, `wallet_requestAccounts` with
150
+ * `silent_mode: true` → `[]`, `wallet_requestChainId` → SN_MAIN.
151
+ *
148
152
  * The first request may open the popup. Once a popup has been opened, a
149
153
  * request made after it was closed rejects with `code: "POPUP_CLOSED"`
150
154
  * instead of calling `window.open` again: requests usually run outside a
@@ -183,12 +187,19 @@ interface ChipiConnectorOptions {
183
187
  id?: string;
184
188
  name?: string;
185
189
  icon?: ConnectorIcons;
186
- transport?: ChipiTransportOptions;
190
+ /**
191
+ * Popup transport tuning: `windowName`, `windowFeatures`, `openTimeoutMs`,
192
+ * `requestTimeoutMs`. `walletUrl` is optional here (the top-level
193
+ * `walletUrl` wins) and `mode` is always `"popup"`.
194
+ */
195
+ transport?: Omit<ChipiTransportOptions, "walletUrl"> & {
196
+ walletUrl?: string;
197
+ };
187
198
  /**
188
199
  * 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
200
+ * via `starknet:announceWallet`) so dApps that *scan* `window.starknet*`
201
+ * (get-starknet v4, get-starknet-discovery's injected scan) and don't import
202
+ * this connector also discover "Connect with Chipi". Defaults to `true` in a browser; pass
192
203
  * `false` to opt out (e.g. to avoid a double entry in a picker that already
193
204
  * lists the connector explicitly). No-op during SSR.
194
205
  */
package/dist/index.d.ts CHANGED
@@ -145,6 +145,10 @@ declare class ChipiPopupTransport {
145
145
  /**
146
146
  * Forward a get-starknet RPC call to the wallet, awaiting its response.
147
147
  *
148
+ * With no wallet window open, passive calls are answered locally and never
149
+ * open it: `wallet_getPermissions` → `[]`, `wallet_requestAccounts` with
150
+ * `silent_mode: true` → `[]`, `wallet_requestChainId` → SN_MAIN.
151
+ *
148
152
  * The first request may open the popup. Once a popup has been opened, a
149
153
  * request made after it was closed rejects with `code: "POPUP_CLOSED"`
150
154
  * instead of calling `window.open` again: requests usually run outside a
@@ -183,12 +187,19 @@ interface ChipiConnectorOptions {
183
187
  id?: string;
184
188
  name?: string;
185
189
  icon?: ConnectorIcons;
186
- transport?: ChipiTransportOptions;
190
+ /**
191
+ * Popup transport tuning: `windowName`, `windowFeatures`, `openTimeoutMs`,
192
+ * `requestTimeoutMs`. `walletUrl` is optional here (the top-level
193
+ * `walletUrl` wins) and `mode` is always `"popup"`.
194
+ */
195
+ transport?: Omit<ChipiTransportOptions, "walletUrl"> & {
196
+ walletUrl?: string;
197
+ };
187
198
  /**
188
199
  * 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
200
+ * via `starknet:announceWallet`) so dApps that *scan* `window.starknet*`
201
+ * (get-starknet v4, get-starknet-discovery's injected scan) and don't import
202
+ * this connector also discover "Connect with Chipi". Defaults to `true` in a browser; pass
192
203
  * `false` to opt out (e.g. to avoid a double entry in a picker that already
193
204
  * lists the connector explicitly). No-op during SSR.
194
205
  */
package/dist/index.js CHANGED
@@ -38,6 +38,21 @@ function deferred() {
38
38
  });
39
39
  return { promise, resolve, reject };
40
40
  }
41
+ var SN_MAIN_HEX = "0x534e5f4d41494e";
42
+ function passiveAnswer(call) {
43
+ switch (call.type) {
44
+ case "wallet_getPermissions":
45
+ return { value: [] };
46
+ case "wallet_requestAccounts": {
47
+ const params = call.params;
48
+ return params?.silent_mode === true ? { value: [] } : void 0;
49
+ }
50
+ case "wallet_requestChainId":
51
+ return { value: SN_MAIN_HEX };
52
+ default:
53
+ return void 0;
54
+ }
55
+ }
41
56
  function randomId() {
42
57
  return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
43
58
  }
@@ -197,6 +212,10 @@ var ChipiPopupTransport = class {
197
212
  /**
198
213
  * Forward a get-starknet RPC call to the wallet, awaiting its response.
199
214
  *
215
+ * With no wallet window open, passive calls are answered locally and never
216
+ * open it: `wallet_getPermissions` → `[]`, `wallet_requestAccounts` with
217
+ * `silent_mode: true` → `[]`, `wallet_requestChainId` → SN_MAIN.
218
+ *
200
219
  * The first request may open the popup. Once a popup has been opened, a
201
220
  * request made after it was closed rejects with `code: "POPUP_CLOSED"`
202
221
  * instead of calling `window.open` again: requests usually run outside a
@@ -204,6 +223,10 @@ var ChipiPopupTransport = class {
204
223
  * from a click.
205
224
  */
206
225
  async request(call) {
226
+ if (this.resolveMode() === "popup" && (!this.target || this.target.closed)) {
227
+ const passive = passiveAnswer(call);
228
+ if (passive) return passive.value;
229
+ }
207
230
  if (this.hadPopup && this.resolveMode() === "popup" && (!this.target || this.target.closed)) {
208
231
  throw transportError(
209
232
  "POPUP_CLOSED",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/protocol.ts","../src/transport.ts","../src/register.ts","../src/icon.ts","../src/connector.ts","../src/factory.ts","../src/standard.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Wire protocol between the \"Connect with Chipi\" connector (running in the dApp)\n * and the Chipi hosted wallet (running at `wallet.chipipay.com` in a popup).\n *\n * Both sides import these shapes so the contract stays in lock-step. The\n * transport is `window.postMessage`: the dApp opens the wallet in a popup,\n * forwards get-starknet `wallet_*` RPC calls over the channel, and the wallet\n * answers after the user approves in its own (already-built) approval UI.\n */\n/** A get-starknet RPC call as sent over the wire: just the discriminant +\n * optional params (the full typed `RpcMessage` carries result/errors we don't\n * serialize). */\nexport interface ChipiRpcCall {\n type: string;\n params?: unknown;\n}\n\n/** Namespace tag on every message so we ignore unrelated postMessages. */\nexport const CHIPI_WC = \"chipi-connect/v1\" as const;\n\n/** wallet → dApp: the hosted wallet page finished loading and is listening. */\nexport interface ChipiReadyMessage {\n channel: typeof CHIPI_WC;\n type: \"ready\";\n}\n\n/** dApp → wallet: forward a get-starknet `wallet_*` RPC call. */\nexport interface ChipiRpcRequestMessage {\n channel: typeof CHIPI_WC;\n type: \"rpc\";\n id: string;\n /** The dApp origin, so the wallet can show it + enforce Verify checks. */\n origin: string;\n call: ChipiRpcCall;\n}\n\n/** wallet → dApp: the result (or error) for a given request id. */\nexport type ChipiRpcResultMessage =\n | { channel: typeof CHIPI_WC; type: \"rpc-result\"; id: string; ok: true; result: unknown }\n | {\n channel: typeof CHIPI_WC;\n type: \"rpc-result\";\n id: string;\n ok: false;\n error: { code: number; message: string };\n };\n\n/** wallet → dApp: an account/network change to propagate to the dApp. */\nexport interface ChipiEventMessage {\n channel: typeof CHIPI_WC;\n type: \"event\";\n event: \"accountsChanged\" | \"networkChanged\";\n data: unknown;\n}\n\nexport type ChipiWalletMessage = ChipiReadyMessage | ChipiRpcResultMessage | ChipiEventMessage;\nexport type ChipiDappMessage = ChipiRpcRequestMessage;\n\nexport function isChipiWalletMessage(data: unknown): data is ChipiWalletMessage {\n return (\n typeof data === \"object\" &&\n data !== null &&\n (data as { channel?: unknown }).channel === CHIPI_WC\n );\n}\n\n/** Type guard for a dApp→wallet message (used by the hosted wallet side). */\nexport function isChipiDappMessage(data: unknown): data is ChipiDappMessage {\n return (\n typeof data === \"object\" &&\n data !== null &&\n (data as { channel?: unknown }).channel === CHIPI_WC &&\n (data as { type?: unknown }).type === \"rpc\"\n );\n}\n","/**\n * Client-side (dApp) transport: opens the Chipi hosted wallet in a popup,\n * performs the ready handshake, and forwards get-starknet `wallet_*` RPC calls\n * over `postMessage`, correlating responses by id. The popup is reused across\n * requests. If the user closes it, later requests reject with `POPUP_CLOSED`\n * instead of reopening it: `window.open` outside a click is blocked by\n * browsers, so the dApp must call `connect()` (or `open()`) again from a click.\n */\nimport {\n CHIPI_WC,\n isChipiWalletMessage,\n type ChipiRpcCall,\n type ChipiRpcRequestMessage,\n type ChipiWalletMessage,\n} from \"./protocol.js\";\n\nexport interface ChipiTransportOptions {\n /** Hosted wallet base URL, e.g. `https://wallet.chipipay.com`. */\n walletUrl: string;\n /**\n * Transport mode:\n * - `\"popup\"` (default): open the hosted wallet in a popup window: the\n * universal model, works for any external dApp.\n * - `\"parent\"`: the dApp is embedded in an iframe INSIDE the Chipi wallet\n * (in-app browser); talk to `window.parent` instead of opening a popup, so\n * approval renders inline in the wallet. Only works when the dApp is\n * actually iframed by the Chipi host.\n * - `\"auto\"`: use `\"parent\"` when running inside an iframe, else `\"popup\"`.\n */\n mode?: \"popup\" | \"parent\" | \"auto\";\n /** Popup window name. */\n windowName?: string;\n /** Popup window features. */\n windowFeatures?: string;\n /** Ready-handshake timeout (ms). Defaults to 180_000. On timeout the popup is\n * closed and the transport resets, so the next `open()` starts clean. */\n openTimeoutMs?: number;\n /**\n * Per-request timeout (ms), counted from when the request is posted to the\n * wallet. Defaults to 120_000. A request that gets no answer in time rejects\n * with an Error whose `code` (and `name`) is `\"REQUEST_TIMEOUT\"`. Pass `0` to\n * disable.\n */\n requestTimeoutMs?: number;\n}\n\n/** Error codes the transport attaches to `Error.code` (besides wallet codes). */\nexport type ChipiTransportErrorCode = \"REQUEST_TIMEOUT\" | \"POPUP_CLOSED\";\n\nfunction transportError(code: ChipiTransportErrorCode, message: string): Error {\n const err = Object.assign(new Error(message), { code });\n err.name = code;\n return err;\n}\n\n/** Drop `undefined` values from plain objects (recursively) so the wallet never\n * receives `{ key: undefined }`: a strict schema on the host side would reject\n * it, and `postMessage` would otherwise preserve the key. Arrays keep their\n * positions. */\nfunction stripUndefined<T>(value: T): T {\n if (Array.isArray(value)) return value.map((v) => stripUndefined(v)) as T;\n if (value === null || typeof value !== \"object\") return value;\n const proto = Object.getPrototypeOf(value);\n if (proto !== Object.prototype && proto !== null) return value;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (v !== undefined) out[k] = stripUndefined(v);\n }\n return out as T;\n}\n\ntype EventName = \"accountsChanged\" | \"networkChanged\";\ntype EventHandler = (data: unknown) => void;\n\nfunction deferred<T>() {\n let resolve!: (v: T) => void;\n let reject!: (e: unknown) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n return { promise, resolve, reject };\n}\n\nfunction randomId(): string {\n // App-runtime ids; uniqueness only needs to hold within one open popup.\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport class ChipiPopupTransport {\n private readonly walletOrigin: string;\n private readonly url: string;\n private target: Window | null = null;\n private ownsTarget = false;\n private ready = false;\n private listening = false;\n private readonly pending = new Map<\n string,\n {\n resolve: (v: unknown) => void;\n reject: (e: unknown) => void;\n message: ChipiRpcRequestMessage;\n timer?: ReturnType<typeof setTimeout>;\n }\n >();\n private readonly handlers = new Map<EventName, Set<EventHandler>>();\n private readyDeferred: ReturnType<typeof deferred<void>> | null = null;\n private openPromise: Promise<void> | null = null;\n private closeWatch: ReturnType<typeof setInterval> | null = null;\n /** True once this transport opened a popup. A later request with no live\n * popup means the user closed it: reject instead of reopening off-gesture. */\n private hadPopup = false;\n\n constructor(private readonly opts: ChipiTransportOptions) {\n this.url = opts.walletUrl.replace(/\\/$/, \"\") + \"/connect\";\n this.walletOrigin = new URL(opts.walletUrl).origin;\n }\n\n on(event: EventName, handler: EventHandler): void {\n (this.handlers.get(event) ?? this.handlers.set(event, new Set()).get(event)!).add(handler);\n }\n\n off(event: EventName, handler: EventHandler): void {\n this.handlers.get(event)?.delete(handler);\n }\n\n private ensureListener(): void {\n if (this.listening || typeof window === \"undefined\") return;\n window.addEventListener(\"message\", this.onMessage);\n this.listening = true;\n }\n\n private onMessage = (e: MessageEvent): void => {\n if (e.origin !== this.walletOrigin || !isChipiWalletMessage(e.data)) return;\n // Isolate to OUR wallet window: without this, a second Chipi popup (another\n // dApp, same origin) could leak its `ready`/`event` into this transport.\n // With no target (before open / after close) nothing is ours: ignore it all,\n // so a stray `ready` can't flip state and a stray `event` can't fire.\n if (!this.target || e.source !== this.target) return;\n const msg = e.data as ChipiWalletMessage;\n if (msg.type === \"ready\") {\n this.ready = true;\n this.readyDeferred?.resolve();\n this.readyDeferred = null;\n // A fresh /connect re-announces \"ready\": e.g. after the user signs in,\n // which reloads the popup onto a new page. The request we already sent went\n // to the previous page, which is gone. Re-send the requests that are still\n // unanswered (`pending` only holds those) so they reach the new page.\n // Contract: the hosted wallet MUST de-dupe by request id, because a repeat\n // `ready` (e.g. the popup's multi-post ready) re-sends the same request.\n for (const p of this.pending.values()) {\n this.target.postMessage(p.message, this.walletOrigin);\n }\n return;\n }\n if (msg.type === \"rpc-result\") {\n const p = this.pending.get(msg.id);\n if (!p) return;\n this.pending.delete(msg.id);\n if (p.timer) clearTimeout(p.timer);\n if (msg.ok) p.resolve(msg.result);\n else p.reject(Object.assign(new Error(msg.error.message), { code: msg.error.code }));\n return;\n }\n if (msg.type === \"event\") {\n this.handlers.get(msg.event)?.forEach((h) => h(msg.data));\n }\n };\n\n /** Resolve \"auto\" → \"parent\" when iframed, else \"popup\". */\n private resolveMode(): \"popup\" | \"parent\" {\n const mode = this.opts.mode ?? \"popup\";\n if (mode !== \"auto\") return mode;\n return typeof window !== \"undefined\" && window.parent !== window ? \"parent\" : \"popup\";\n }\n\n /** Open (or reuse) the wallet (popup window OR the parent frame) and wait for\n * its ready handshake. Concurrent calls share ONE handshake. */\n async open(): Promise<void> {\n if (typeof window === \"undefined\") throw new Error(\"chipi_connector_requires_browser\");\n this.ensureListener();\n const isParent = this.resolveMode() === \"parent\";\n if (this.ready && this.target && (isParent || !this.target.closed)) return;\n if (this.openPromise) return this.openPromise;\n this.openPromise = this.doOpen(isParent);\n try {\n await this.openPromise;\n } finally {\n this.openPromise = null;\n }\n }\n\n private async doOpen(isParent: boolean): Promise<void> {\n if (isParent) {\n if (window.parent === window) throw new Error(\"chipi_not_in_iframe\");\n this.target = window.parent;\n this.ownsTarget = false;\n } else {\n this.ready = false;\n // Unique per-open window name so a reconnect can never reuse a stale popup\n // that still holds a previous session's pending approval.\n const name = this.opts.windowName ?? `chipi-wallet-${randomId()}`;\n this.target = window.open(\n this.url,\n name,\n this.opts.windowFeatures ?? \"popup=yes,width=420,height=680\"\n );\n this.ownsTarget = true;\n if (!this.target) throw Object.assign(new Error(\"Popup blocked\"), { code: \"popup_blocked\" });\n this.hadPopup = true;\n }\n const opened = this.target;\n this.readyDeferred = deferred<void>();\n try {\n await this.awaitReady();\n } catch (err) {\n // Handshake stalled: close the popup we opened and reset, so a stale\n // window can't answer later and the next open() starts from scratch.\n // (Skip if close() already replaced the target in the meantime.)\n if (this.target === opened) this.resetTarget();\n throw err;\n }\n }\n\n /** Close the popup (if we own one) and forget the target + ready state. */\n private resetTarget(): void {\n try {\n if (this.ownsTarget) this.target?.close();\n } catch {\n // ignore\n }\n this.target = null;\n this.ready = false;\n this.readyDeferred = null;\n }\n\n private async awaitReady(): Promise<void> {\n // Generous: a cold login (Clerk / passkey) can take a while. We only reject\n // here on an outright stall: the popup-closed watcher handles the real\n // \"user gave up / closed it\" case quickly.\n const timeoutMs = this.opts.openTimeoutMs ?? 180_000;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(\"wallet_open_timeout\")), timeoutMs);\n });\n try {\n await Promise.race([this.readyDeferred!.promise, timeout]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n\n /** Reject every in-flight request (popup closed / disconnected). */\n private rejectAllPending(message: string): void {\n for (const [, p] of this.pending) {\n if (p.timer) clearTimeout(p.timer);\n p.reject(Object.assign(new Error(message), { code: 4001 }));\n }\n this.pending.clear();\n }\n\n /** While requests are in flight, watch for the user closing the popup and\n * reject them: otherwise the dApp's promise would hang forever. */\n private startCloseWatch(): void {\n if (this.closeWatch || !this.ownsTarget) return;\n this.closeWatch = setInterval(() => {\n if (this.target?.closed) {\n this.ready = false;\n this.target = null;\n this.rejectAllPending(\"User closed the wallet\");\n this.stopCloseWatch();\n } else if (this.pending.size === 0) {\n this.stopCloseWatch();\n }\n }, 500);\n }\n\n private stopCloseWatch(): void {\n if (this.closeWatch) {\n clearInterval(this.closeWatch);\n this.closeWatch = null;\n }\n }\n\n /**\n * Forward a get-starknet RPC call to the wallet, awaiting its response.\n *\n * The first request may open the popup. Once a popup has been opened, a\n * request made after it was closed rejects with `code: \"POPUP_CLOSED\"`\n * instead of calling `window.open` again: requests usually run outside a\n * click, where browsers block popups. Reopen via `connect()` / `open()`\n * from a click.\n */\n async request(call: ChipiRpcCall): Promise<unknown> {\n if (this.hadPopup && this.resolveMode() === \"popup\" && (!this.target || this.target.closed)) {\n throw transportError(\n \"POPUP_CLOSED\",\n \"The Chipi wallet window was closed. Call connect() again from a click.\"\n );\n }\n await this.open();\n if (this.ownsTarget) this.target?.focus();\n const id = randomId();\n const message: ChipiRpcRequestMessage = {\n channel: CHIPI_WC,\n type: \"rpc\",\n id,\n origin: window.location.origin,\n call: stripUndefined(call),\n };\n const timeoutMs = this.opts.requestTimeoutMs ?? 120_000;\n return new Promise<unknown>((resolve, reject) => {\n const entry: {\n resolve: (v: unknown) => void;\n reject: (e: unknown) => void;\n message: ChipiRpcRequestMessage;\n timer?: ReturnType<typeof setTimeout>;\n } = { resolve, reject, message };\n if (timeoutMs > 0 && Number.isFinite(timeoutMs)) {\n entry.timer = setTimeout(() => {\n if (this.pending.get(id) !== entry) return;\n this.pending.delete(id);\n reject(\n transportError(\n \"REQUEST_TIMEOUT\",\n `The Chipi wallet did not answer \"${call.type}\" within ${timeoutMs} ms.`\n )\n );\n }, timeoutMs);\n }\n this.pending.set(id, entry);\n this.target!.postMessage(message, this.walletOrigin);\n this.startCloseWatch();\n });\n }\n\n /** Close the popup (if we own one) + reject in-flight requests. */\n close(): void {\n this.stopCloseWatch();\n // Unblock an in-flight open() instead of leaving it to the ready timeout.\n this.readyDeferred?.reject(Object.assign(new Error(\"disconnected\"), { code: 4001 }));\n this.resetTarget();\n this.rejectAllPending(\"disconnected\");\n if (this.listening && typeof window !== \"undefined\") {\n window.removeEventListener(\"message\", this.onMessage);\n this.listening = false;\n }\n }\n}\n","import type { StarknetWindowObject } from \"@starknet-io/types-js\";\n\n/** Window key get-starknet discovers by scanning for `starknet*` properties. */\nexport const CHIPI_WINDOW_KEY = \"starknet_chipi\";\n\nexport interface ChipiRegistration {\n /** Remove `window.starknet_chipi` + the announce listener. */\n dispose: () => void;\n}\n\n/**\n * Make a Chipi `StarknetWindowObject` discoverable to any get-starknet /\n * starknet-react / starknetkit dApp on the page: WITHOUT an upstream PR and\n * WITHOUT whitelisting. This self-registration covers the apps that scan for\n * wallets rather than importing our connector explicitly.\n *\n * Discovery is announced two ways for maximum reach:\n * 1. **window scan**: set `window.starknet_chipi`. get-starknet v4's\n * `getAvailableWallets()` finds every `window` key starting with `starknet`.\n * 2. **event announce**: dispatch `starknet:announceWallet` now and again on\n * the dApp's `starknet:requestWallets` (the EIP-6963-style, timing-robust\n * Starknet Wallet Standard discovery path).\n *\n * SSR-safe (no-ops when there's no `window`) and idempotent per (target, wallet).\n */\nexport function registerChipiWallet(\n wallet: StarknetWindowObject,\n target: (Window & typeof globalThis) | undefined = typeof window !== \"undefined\"\n ? window\n : undefined\n): ChipiRegistration {\n if (!target) return { dispose: () => {} };\n\n const store = target as unknown as Record<string, unknown>;\n // 1. Classic window-scan discovery.\n store[CHIPI_WINDOW_KEY] = wallet;\n\n // 2. Event-based discovery (announce now + whenever a dApp asks).\n const announce = () =>\n target.dispatchEvent(new CustomEvent(\"starknet:announceWallet\", { detail: wallet }));\n target.addEventListener(\"starknet:requestWallets\", announce);\n announce();\n\n return {\n dispose: () => {\n target.removeEventListener(\"starknet:requestWallets\", announce);\n // Only remove our own object: never clobber a newer injector's wallet.\n if (store[CHIPI_WINDOW_KEY] === wallet) delete store[CHIPI_WINDOW_KEY];\n },\n };\n}\n","// Chipi brand wallet icon: the current luchador mark on a transparent\n// background, 48x48 PNG (same asset used by the browser extension's\n// toolbar icon). A data-URI is what get-starknet / wallet pickers render.\nexport const CHIPI_ICON = \"data:image/png;base64,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\";\n","/**\n * `ChipiConnector`: a starknet-react / get-starknet connector for the Chipi\n * hosted smart-account wallet. A self-contained connector package any dApp\n * adds to its `connectors` array (`new ChipiConnector()`) directly: no\n * whitelisting, no dependency on a third-party wallet kit, and NO browser\n * extension required. Clicking \"Connect with Chipi\" opens our hosted wallet\n * (passkey + gasless paymaster) in a popup; the dApp's `wallet_*` RPC calls are\n * forwarded over postMessage and answered after the user approves in Chipi's\n * own (already-built) approval UI.\n */\nimport { Connector } from \"@starknet-react/core\";\nimport { WalletAccount, constants } from \"starknet\";\nimport type { AccountInterface, ProviderInterface } from \"starknet\";\nimport type {\n RpcMessage,\n RequestFnCall,\n RpcTypeToMessageMap,\n StarknetWindowObject,\n} from \"@starknet-io/types-js\";\nimport { ChipiPopupTransport, type ChipiTransportOptions } from \"./transport.js\";\nimport { registerChipiWallet, type ChipiRegistration } from \"./register.js\";\nimport { CHIPI_ICON } from \"./icon.js\";\n\n// @starknet-react/core declares these internally but doesn't export them; mirror\n// the shapes (ConnectorIcons === get-starknet's StarknetWindowObject[\"icon\"]).\ntype ConnectorIcons = StarknetWindowObject[\"icon\"];\ntype ConnectorData = { account?: string; chainId?: bigint };\n/** Mirrors starknet-react's `ConnectArgs` (not exported by every version). */\ntype ConnectArgs = { chainIdHint?: bigint };\n\n/** Starknet mainnet chain id (felt of the shortstring \"SN_MAIN\"). */\nconst SN_MAIN = BigInt(constants.StarknetChainId.SN_MAIN);\n\n/** Parse a wallet-sent chain id (hex/decimal string, bigint or number). */\nfunction toChainId(value: unknown): bigint | undefined {\n if (typeof value === \"bigint\") return value;\n if (typeof value === \"number\" || typeof value === \"string\") {\n try {\n return BigInt(value);\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\nexport interface ChipiConnectorOptions {\n /** Hosted wallet base URL. Defaults to `https://wallet.chipipay.com`. */\n walletUrl?: string;\n /** Override the connector id / display name / icon if embedding. */\n id?: string;\n name?: string;\n icon?: ConnectorIcons;\n transport?: ChipiTransportOptions;\n /**\n * Self-register the wallet on `window` (set `window.starknet_chipi` + announce\n * via `starknet:announceWallet`) so dApps that *scan* for wallets, raw\n * get-starknet / Wallet-Standard consumers that don't import this connector,\n * also discover \"Connect with Chipi\". Defaults to `true` in a browser; pass\n * `false` to opt out (e.g. to avoid a double entry in a picker that already\n * lists the connector explicitly). No-op during SSR.\n */\n register?: boolean;\n // NOTE: the in-app-browser (\"parent\") transport mode is implemented in the\n // transport but NOT yet supported by the hosted wallet side, so it's not\n // exposed here in v1. Use popup (external dApps) only.\n}\n\nexport class ChipiConnector extends Connector {\n private readonly transport: ChipiPopupTransport;\n private readonly _id: string;\n private readonly _name: string;\n private readonly _icon: ConnectorIcons;\n private _account: string | null = null;\n private _swo: StarknetWindowObject | null = null;\n private _registration: ChipiRegistration | null = null;\n private readonly _autoRegister: boolean;\n\n constructor(options: ChipiConnectorOptions = {}) {\n super();\n const walletUrl =\n options.walletUrl ?? options.transport?.walletUrl ?? \"https://wallet.chipipay.com\";\n this.transport = new ChipiPopupTransport({\n ...options.transport,\n walletUrl,\n mode: \"popup\", // v1: external-dApp popup only (parent host not yet built)\n });\n this._id = options.id ?? \"chipi\";\n this._name = options.name ?? \"Connect with Chipi\";\n this._icon = options.icon ?? CHIPI_ICON;\n this._autoRegister = options.register !== false;\n if (this._autoRegister) this.register();\n }\n\n /**\n * Announce this wallet to scanning dApps (`window.starknet_chipi` +\n * `starknet:announceWallet`). Called automatically from the constructor\n * unless `register: false`. Idempotent and SSR-safe.\n */\n register(): void {\n if (this._registration) return;\n this._registration = registerChipiWallet(this.swo());\n }\n\n /** Undo {@link register}: remove the window object + announce listener. */\n unregister(): void {\n this._registration?.dispose();\n this._registration = null;\n }\n\n get id(): string {\n return this._id;\n }\n\n get name(): string {\n return this._name;\n }\n\n get icon(): ConnectorIcons {\n return this._icon;\n }\n\n /** Hosted wallet: always available (no extension to detect). */\n available(): boolean {\n return true;\n }\n\n /** No silent reconnect in v1: the user re-approves the popup each session. */\n async ready(): Promise<boolean> {\n return this._account !== null;\n }\n\n /** Lazily build the postMessage-backed get-starknet window object. */\n private swo(): StarknetWindowObject {\n if (this._swo) return this._swo;\n const transport = this.transport;\n const request = (async (call: RpcMessage) =>\n transport.request(call)) as StarknetWindowObject[\"request\"];\n this._swo = {\n id: this._id,\n name: this._name,\n version: \"1.0.0\",\n icon: typeof this._icon === \"string\" ? this._icon : (this._icon?.dark ?? \"\"),\n request,\n on: ((event: string, handler: (data: unknown) => void) => {\n if (event === \"accountsChanged\" || event === \"networkChanged\") transport.on(event, handler);\n }) as StarknetWindowObject[\"on\"],\n off: ((event: string, handler: (data: unknown) => void) => {\n if (event === \"accountsChanged\" || event === \"networkChanged\")\n transport.off(event, handler);\n }) as StarknetWindowObject[\"off\"],\n };\n return this._swo;\n }\n\n /**\n * Open the hosted wallet (call from a click: it opens a popup) and request\n * the account. Chipi is mainnet-only: a `chainIdHint` other than SN_MAIN\n * rejects before any popup opens.\n */\n async connect(args: ConnectArgs = {}): Promise<ConnectorData> {\n if (args.chainIdHint !== undefined && BigInt(args.chainIdHint) !== SN_MAIN) {\n throw Object.assign(\n new Error(\n `Chipi is mainnet-only: chainIdHint 0x${BigInt(args.chainIdHint).toString(16)} is not SN_MAIN.`\n ),\n { code: \"UNSUPPORTED_CHAIN\" }\n );\n }\n // Re-announce if a previous disconnect() disposed the registration.\n if (this._autoRegister) this.register();\n this.subscribe();\n await this.transport.open();\n const accounts = (await this.transport.request({ type: \"wallet_requestAccounts\" })) as string[];\n const account = accounts?.[0];\n if (!account) throw new Error(\"chipi_no_account\");\n this._account = account;\n const data: ConnectorData = { account, chainId: SN_MAIN };\n this.emitEvent(\"connect\", data);\n return data;\n }\n\n async disconnect(): Promise<void> {\n this.unsubscribe();\n this.transport.close();\n this._account = null;\n // Drop `window.starknet_chipi` so scanners don't keep a stale object; the\n // next connect() registers a fresh one.\n this.unregister();\n this._swo = null;\n this.emitEvent(\"disconnect\");\n }\n\n /** Forward the wallet's account/network events as starknet-react events. */\n private subscribe(): void {\n this.unsubscribe(); // idempotent across repeated connect() calls\n this.transport.on(\"accountsChanged\", this.onAccountsChanged);\n this.transport.on(\"networkChanged\", this.onNetworkChanged);\n }\n\n private unsubscribe(): void {\n this.transport.off(\"accountsChanged\", this.onAccountsChanged);\n this.transport.off(\"networkChanged\", this.onNetworkChanged);\n }\n\n private onAccountsChanged = (data: unknown): void => {\n const accounts = Array.isArray(data) ? (data as unknown[]) : [];\n const account = accounts[0];\n if (typeof account === \"string\" && account) {\n this._account = account;\n this.emitEvent(\"change\", { account, chainId: SN_MAIN });\n } else {\n this._account = null;\n this.emitEvent(\"disconnect\");\n }\n };\n\n private onNetworkChanged = (data: unknown): void => {\n // The wallet may send the chain id alone or `{ chainId, accounts }`.\n const payload =\n typeof data === \"object\" && data !== null && !Array.isArray(data)\n ? (data as { chainId?: unknown; accounts?: unknown })\n : { chainId: data };\n const chainId = toChainId(payload.chainId);\n const accounts = Array.isArray(payload.accounts) ? payload.accounts : [];\n const next = typeof accounts[0] === \"string\" && accounts[0] ? accounts[0] : this._account;\n if (next) this._account = next;\n const change: ConnectorData = {};\n if (chainId !== undefined) change.chainId = chainId;\n if (next) change.account = next;\n this.emitEvent(\"change\", change);\n };\n\n // `Connector` extends eventemitter3's EventEmitter, but the bundled .d.ts\n // doesn't surface `emit` cleanly through the abstract class: reach it via a\n // narrow cast rather than fight the upstream typing.\n private emitEvent(event: \"connect\" | \"change\", data: ConnectorData): void;\n private emitEvent(event: \"disconnect\"): void;\n private emitEvent(event: \"connect\" | \"change\" | \"disconnect\", data?: ConnectorData): void {\n const emitter = this as unknown as { emit: (e: string, d?: ConnectorData) => void };\n if (data === undefined) emitter.emit(event);\n else emitter.emit(event, data);\n }\n\n async account(provider: ProviderInterface): Promise<AccountInterface> {\n if (!this._account) throw new Error(\"chipi_not_connected\");\n // WalletAccount routes execute()/signMessage() through the SWO's request(),\n // i.e. over our postMessage channel to the hosted wallet.\n return WalletAccount.connect(provider, this.swo());\n }\n\n async chainId(): Promise<bigint> {\n return SN_MAIN;\n }\n\n async request<T extends RpcMessage[\"type\"]>(\n call: RequestFnCall<T>\n ): Promise<RpcTypeToMessageMap[T][\"result\"]> {\n return this.transport.request(call) as Promise<RpcTypeToMessageMap[T][\"result\"]>;\n }\n}\n","import { ChipiConnector, type ChipiConnectorOptions } from \"./connector.js\";\n\n/**\n * Plain-function form of {@link ChipiConnector}, for parity with\n * `@starknet-react/core`'s built-in factories (`ready()`, `braavos()`):\n *\n * const connectors = [chipi(), ready(), braavos()];\n *\n * Equivalent to `new ChipiConnector(options)`: use whichever reads better\n * in your `connectors` array.\n */\nexport function chipi(options?: ChipiConnectorOptions): ChipiConnector {\n return new ChipiConnector(options);\n}\n","/**\n * Chipi as a Wallet Standard wallet with Starknet features\n * (`WalletWithStarknetFeatures` from `@starknet-io/get-starknet-wallet-standard`),\n * so dApps on get-starknet v5+/v6 discovery (`@starknet-io/get-starknet-discovery`,\n * `@starknet-start/react`, anything that listens for\n * `wallet-standard:register-wallet`) list \"Chipi\" without importing this\n * package's connector.\n *\n * Backed by the same popup transport as {@link ChipiConnector}. The types\n * below mirror the upstream interfaces structurally so this package keeps no\n * runtime (or type) dependency on `@wallet-standard/*`.\n */\nimport type { RequestFn } from \"@starknet-io/types-js\";\nimport { ChipiPopupTransport, type ChipiTransportOptions } from \"./transport.js\";\nimport { CHIPI_ICON } from \"./icon.js\";\n\n/** Wallet Standard chain id for Starknet mainnet: `starknet:` + hex of \"SN_MAIN\"\n * (same as `WELL_KNOWN_STARKNET_CHAINS[0]` in get-starknet-wallet-standard). */\nexport const CHIPI_STARKNET_MAINNET_CHAIN = \"starknet:0x534e5f4d41494e\" as const;\n\n/** `starknet:0x...` chain identifier. */\nexport type ChipiStarknetChain = `starknet:0x${string}`;\n\n/** Data-URI icon, as Wallet Standard requires. */\nexport type ChipiWalletIcon = `data:image/${\"svg+xml\" | \"webp\" | \"png\" | \"gif\"};base64,${string}`;\n\n/** Mirrors `@wallet-standard/base` `WalletAccount`. */\nexport interface ChipiStandardWalletAccount {\n readonly address: string;\n readonly publicKey: Uint8Array;\n readonly chains: readonly ChipiStarknetChain[];\n readonly features: readonly `${string}:${string}`[];\n}\n\n/** Mirrors `@wallet-standard/features` `StandardEventsChangeProperties`. */\nexport interface ChipiStandardChangeProperties {\n readonly chains?: readonly ChipiStarknetChain[];\n readonly accounts?: readonly ChipiStandardWalletAccount[];\n}\n\n/** Mirrors `StarknetFeatures` from `@starknet-io/get-starknet-wallet-standard`.\n * (A type alias, not an interface, so it satisfies Wallet Standard's\n * `IdentifierRecord` index signature.) */\nexport type ChipiStandardWalletFeatures = {\n readonly \"starknet:walletApi\": {\n readonly version: \"1.0.0\";\n readonly request: RequestFn;\n readonly walletVersion: string;\n readonly id: string;\n };\n readonly \"standard:connect\": {\n readonly version: \"1.0.0\";\n readonly connect: (input?: {\n readonly silent?: boolean;\n }) => Promise<{ readonly accounts: readonly ChipiStandardWalletAccount[] }>;\n };\n readonly \"standard:disconnect\": {\n readonly version: \"1.0.0\";\n readonly disconnect: () => Promise<void>;\n };\n readonly \"standard:events\": {\n readonly version: \"1.0.0\";\n readonly on: <E extends \"change\">(\n event: E,\n listener: (properties: ChipiStandardChangeProperties) => void\n ) => () => void;\n };\n};\n\n/** Structurally a `WalletWithStarknetFeatures`. */\nexport interface ChipiStandardWallet {\n readonly version: \"1.0.0\";\n readonly name: string;\n readonly icon: ChipiWalletIcon;\n readonly chains: readonly ChipiStarknetChain[];\n readonly accounts: readonly ChipiStandardWalletAccount[];\n readonly features: ChipiStandardWalletFeatures;\n}\n\nexport interface ChipiStandardWalletOptions {\n /** Hosted wallet base URL. Defaults to `https://wallet.chipipay.com`. */\n walletUrl?: string;\n /** Display name. Defaults to `\"Chipi\"`. */\n name?: string;\n /** Data-URI icon. Defaults to the Chipi icon. */\n icon?: ChipiWalletIcon;\n /** Popup transport tuning (window name/features, timeouts). */\n transport?: Omit<ChipiTransportOptions, \"walletUrl\" | \"mode\">;\n}\n\n/** Same shape as a Wallet Standard `register-wallet` event detail callback. */\ntype RegisterApi = { register: (wallet: ChipiStandardWallet) => () => void };\n\nfunction toStarknetChain(value: unknown): ChipiStarknetChain | undefined {\n if (typeof value !== \"string\" && typeof value !== \"bigint\" && typeof value !== \"number\") {\n return undefined;\n }\n try {\n return `starknet:0x${BigInt(value).toString(16)}`;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Build the Chipi Wallet Standard wallet (without registering it). `connect`\n * opens the popup, so dApps call it from a click; `connect({ silent: true })`\n * never opens a popup and returns the current accounts (empty if not\n * connected).\n */\nexport function createChipiStandardWallet(\n options: ChipiStandardWalletOptions = {}\n): ChipiStandardWallet {\n const transport = new ChipiPopupTransport({\n ...options.transport,\n walletUrl: options.walletUrl ?? \"https://wallet.chipipay.com\",\n mode: \"popup\",\n });\n const listeners = new Set<(properties: ChipiStandardChangeProperties) => void>();\n let current: { address: string; chain: ChipiStarknetChain } | null = null;\n\n const accounts = (): ChipiStandardWalletAccount[] =>\n current\n ? [\n {\n address: current.address,\n publicKey: new Uint8Array(),\n chains: [current.chain],\n features: [],\n },\n ]\n : [];\n const emitChange = () => {\n const properties: ChipiStandardChangeProperties = { accounts: accounts() };\n for (const listener of [...listeners]) listener(properties);\n };\n const setDisconnected = () => {\n if (!current) return;\n current = null;\n emitChange();\n };\n\n const onAccountsChanged = (data: unknown) => {\n const list = Array.isArray(data) ? (data as unknown[]) : [];\n const address = list[0];\n if (typeof address !== \"string\" || !address) return setDisconnected();\n if (!current) return; // not connected through this wallet: ignore\n current = { ...current, address };\n emitChange();\n };\n const onNetworkChanged = (data: unknown) => {\n const payload =\n typeof data === \"object\" && data !== null && !Array.isArray(data)\n ? (data as { chainId?: unknown; accounts?: unknown })\n : { chainId: data };\n const chain = toStarknetChain(payload.chainId);\n if (!chain) return setDisconnected();\n if (!current) return;\n const list = Array.isArray(payload.accounts) ? (payload.accounts as unknown[]) : [];\n const address = typeof list[0] === \"string\" && list[0] ? list[0] : current.address;\n current = { address, chain };\n emitChange();\n };\n transport.on(\"accountsChanged\", onAccountsChanged);\n transport.on(\"networkChanged\", onNetworkChanged);\n\n const request = ((call: Parameters<RequestFn>[0]) => transport.request(call)) as RequestFn;\n\n const features: ChipiStandardWalletFeatures = {\n \"starknet:walletApi\": {\n version: \"1.0.0\",\n request,\n walletVersion: \"1.0.0\",\n id: \"chipi\",\n },\n \"standard:connect\": {\n version: \"1.0.0\",\n connect: async (input) => {\n if (current || input?.silent) return { accounts: accounts() };\n await transport.open();\n // No params: never forward `{ silent_mode: undefined }` to the wallet.\n const result = (await transport.request({ type: \"wallet_requestAccounts\" })) as unknown;\n const list = Array.isArray(result) ? (result as unknown[]) : [];\n const address = list[0];\n if (typeof address !== \"string\" || !address) return { accounts: [] };\n current = { address, chain: CHIPI_STARKNET_MAINNET_CHAIN };\n emitChange();\n return { accounts: accounts() };\n },\n },\n \"standard:disconnect\": {\n version: \"1.0.0\",\n disconnect: async () => {\n transport.close();\n setDisconnected();\n },\n },\n \"standard:events\": {\n version: \"1.0.0\",\n on: (_event, listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n },\n };\n\n return {\n version: \"1.0.0\",\n name: options.name ?? \"Chipi\",\n icon: options.icon ?? (CHIPI_ICON as ChipiWalletIcon),\n chains: [CHIPI_STARKNET_MAINNET_CHAIN],\n get accounts() {\n return accounts();\n },\n features,\n };\n}\n\n/**\n * Register Chipi with every Wallet Standard app on the page: dispatches\n * `wallet-standard:register-wallet` now and answers later\n * `wallet-standard:app-ready` events (the `@wallet-standard/wallet`\n * `registerWallet` protocol, implemented here without the dependency).\n *\n * Returns an unregister function that removes the listener and unregisters\n * from every app that accepted the wallet. SSR-safe: a no-op without `window`.\n */\nexport function registerChipiStandardWallet(\n options: ChipiStandardWalletOptions = {},\n target: (Window & typeof globalThis) | undefined = typeof window !== \"undefined\"\n ? window\n : undefined\n): () => void {\n if (!target) return () => {};\n const wallet = createChipiStandardWallet(options);\n const unregisters: Array<() => void> = [];\n const callback = ({ register }: RegisterApi) => {\n unregisters.push(register(wallet));\n };\n const onAppReady = (event: Event) => {\n const api = (event as CustomEvent<RegisterApi>).detail;\n if (api && typeof api.register === \"function\") callback(api);\n };\n try {\n target.dispatchEvent(\n new CustomEvent(\"wallet-standard:register-wallet\", {\n detail: callback,\n bubbles: false,\n cancelable: false,\n composed: false,\n })\n );\n } catch (error) {\n console.error(\"wallet-standard:register-wallet event could not be dispatched\\n\", error);\n }\n target.addEventListener(\"wallet-standard:app-ready\", onAppReady);\n return () => {\n target.removeEventListener(\"wallet-standard:app-ready\", onAppReady);\n for (const unregister of unregisters.splice(0)) unregister();\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/protocol.ts","../src/transport.ts","../src/register.ts","../src/icon.ts","../src/connector.ts","../src/factory.ts","../src/standard.ts"],"names":[],"mappings":";;;;;;AAkBO,IAAM,QAAA,GAAW;AAwCjB,SAAS,qBAAqB,IAAA,EAA2C;AAC9E,EAAA,OACE,OAAO,IAAA,KAAS,QAAA,IAChB,IAAA,KAAS,IAAA,IACR,KAA+B,OAAA,KAAY,QAAA;AAEhD;AAGO,SAAS,mBAAmB,IAAA,EAAyC;AAC1E,EAAA,OACE,OAAO,SAAS,QAAA,IAChB,IAAA,KAAS,QACR,IAAA,CAA+B,OAAA,KAAY,QAAA,IAC3C,IAAA,CAA4B,IAAA,KAAS,KAAA;AAE1C;;;ACzBA,SAAS,cAAA,CAAe,MAA+B,OAAA,EAAwB;AAC7E,EAAA,MAAM,GAAA,GAAM,OAAO,MAAA,CAAO,IAAI,MAAM,OAAO,CAAA,EAAG,EAAE,IAAA,EAAM,CAAA;AACtD,EAAA,GAAA,CAAI,IAAA,GAAO,IAAA;AACX,EAAA,OAAO,GAAA;AACT;AAMA,SAAS,eAAkB,KAAA,EAAa;AACtC,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,cAAA,CAAe,CAAC,CAAC,CAAA;AACnE,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,UAAU,OAAO,KAAA;AACxD,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,cAAA,CAAe,KAAK,CAAA;AACzC,EAAA,IAAI,KAAA,KAAU,MAAA,CAAO,SAAA,IAAa,KAAA,KAAU,MAAM,OAAO,KAAA;AACzD,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAgC,CAAA,EAAG;AACrE,IAAA,IAAI,MAAM,MAAA,EAAW,GAAA,CAAI,CAAC,CAAA,GAAI,eAAe,CAAC,CAAA;AAAA,EAChD;AACA,EAAA,OAAO,GAAA;AACT;AAKA,SAAS,QAAA,GAAc;AACrB,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,MAAA;AACJ,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAW,CAAC,KAAK,GAAA,KAAQ;AAC3C,IAAA,OAAA,GAAU,GAAA;AACV,IAAA,MAAA,GAAS,GAAA;AAAA,EACX,CAAC,CAAA;AACD,EAAA,OAAO,EAAE,OAAA,EAAS,OAAA,EAAS,MAAA,EAAO;AACpC;AAGA,IAAM,WAAA,GAAc,kBAAA;AAWpB,SAAS,cAAc,IAAA,EAAoD;AACzE,EAAA,QAAQ,KAAK,IAAA;AAAM,IACjB,KAAK,uBAAA;AACH,MAAA,OAAO,EAAE,KAAA,EAAO,EAAC,EAAE;AAAA,IACrB,KAAK,wBAAA,EAA0B;AAC7B,MAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,MAAA,OAAO,QAAQ,WAAA,KAAgB,IAAA,GAAO,EAAE,KAAA,EAAO,IAAG,GAAI,MAAA;AAAA,IACxD;AAAA,IACA,KAAK,uBAAA;AACH,MAAA,OAAO,EAAE,OAAO,WAAA,EAAY;AAAA,IAC9B;AACE,MAAA,OAAO,MAAA;AAAA;AAEb;AAEA,SAAS,QAAA,GAAmB;AAE1B,EAAA,OAAO,GAAG,IAAA,CAAK,GAAA,EAAI,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,GAAS,QAAA,CAAS,EAAE,EAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA,CAAA;AAC9E;AAEO,IAAM,sBAAN,MAA0B;AAAA,EAwB/B,YAA6B,IAAA,EAA6B;AAA7B,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AArB7B,IAAA,IAAA,CAAQ,MAAA,GAAwB,IAAA;AAChC,IAAA,IAAA,CAAQ,UAAA,GAAa,KAAA;AACrB,IAAA,IAAA,CAAQ,KAAA,GAAQ,KAAA;AAChB,IAAA,IAAA,CAAQ,SAAA,GAAY,KAAA;AACpB,IAAA,IAAA,CAAiB,OAAA,uBAAc,GAAA,EAQ7B;AACF,IAAA,IAAA,CAAiB,QAAA,uBAAe,GAAA,EAAkC;AAClE,IAAA,IAAA,CAAQ,aAAA,GAA0D,IAAA;AAClE,IAAA,IAAA,CAAQ,WAAA,GAAoC,IAAA;AAC5C,IAAA,IAAA,CAAQ,UAAA,GAAoD,IAAA;AAG5D;AAAA;AAAA,IAAA,IAAA,CAAQ,QAAA,GAAW,KAAA;AAqBnB,IAAA,IAAA,CAAQ,SAAA,GAAY,CAAC,CAAA,KAA0B;AAC7C,MAAA,IAAI,CAAA,CAAE,WAAW,IAAA,CAAK,YAAA,IAAgB,CAAC,oBAAA,CAAqB,CAAA,CAAE,IAAI,CAAA,EAAG;AAKrE,MAAA,IAAI,CAAC,IAAA,CAAK,MAAA,IAAU,CAAA,CAAE,MAAA,KAAW,KAAK,MAAA,EAAQ;AAC9C,MAAA,MAAM,MAAM,CAAA,CAAE,IAAA;AACd,MAAA,IAAI,GAAA,CAAI,SAAS,OAAA,EAAS;AACxB,QAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,QAAA,IAAA,CAAK,eAAe,OAAA,EAAQ;AAC5B,QAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AAOrB,QAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAO,EAAG;AACrC,UAAA,IAAA,CAAK,MAAA,CAAO,WAAA,CAAY,CAAA,CAAE,OAAA,EAAS,KAAK,YAAY,CAAA;AAAA,QACtD;AACA,QAAA;AAAA,MACF;AACA,MAAA,IAAI,GAAA,CAAI,SAAS,YAAA,EAAc;AAC7B,QAAA,MAAM,CAAA,GAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,IAAI,EAAE,CAAA;AACjC,QAAA,IAAI,CAAC,CAAA,EAAG;AACR,QAAA,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,GAAA,CAAI,EAAE,CAAA;AAC1B,QAAA,IAAI,CAAA,CAAE,KAAA,EAAO,YAAA,CAAa,CAAA,CAAE,KAAK,CAAA;AACjC,QAAA,IAAI,GAAA,CAAI,EAAA,EAAI,CAAA,CAAE,OAAA,CAAQ,IAAI,MAAM,CAAA;AAAA,eACzB,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,IAAI,MAAM,GAAA,CAAI,KAAA,CAAM,OAAO,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,CAAI,KAAA,CAAM,IAAA,EAAM,CAAC,CAAA;AACnF,QAAA;AAAA,MACF;AACA,MAAA,IAAI,GAAA,CAAI,SAAS,OAAA,EAAS;AACxB,QAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA,EAAG,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,GAAA,CAAI,IAAI,CAAC,CAAA;AAAA,MAC1D;AAAA,IACF,CAAA;AArDE,IAAA,IAAA,CAAK,MAAM,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,GAAI,UAAA;AAC/C,IAAA,IAAA,CAAK,YAAA,GAAe,IAAI,GAAA,CAAI,IAAA,CAAK,SAAS,CAAA,CAAE,MAAA;AAAA,EAC9C;AAAA,EAEA,EAAA,CAAG,OAAkB,OAAA,EAA6B;AAChD,IAAA,CAAC,KAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA,IAAK,KAAK,QAAA,CAAS,GAAA,CAAI,KAAA,kBAAO,IAAI,KAAK,CAAA,CAAE,IAAI,KAAK,CAAA,EAAI,IAAI,OAAO,CAAA;AAAA,EAC3F;AAAA,EAEA,GAAA,CAAI,OAAkB,OAAA,EAA6B;AACjD,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA,EAAG,OAAO,OAAO,CAAA;AAAA,EAC1C;AAAA,EAEQ,cAAA,GAAuB;AAC7B,IAAA,IAAI,IAAA,CAAK,SAAA,IAAa,OAAO,MAAA,KAAW,WAAA,EAAa;AACrD,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAA,EAAW,IAAA,CAAK,SAAS,CAAA;AACjD,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,EACnB;AAAA;AAAA,EAwCQ,WAAA,GAAkC;AACxC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,IAAA,IAAQ,OAAA;AAC/B,IAAA,IAAI,IAAA,KAAS,QAAQ,OAAO,IAAA;AAC5B,IAAA,OAAO,OAAO,MAAA,KAAW,WAAA,IAAe,MAAA,CAAO,MAAA,KAAW,SAAS,QAAA,GAAW,OAAA;AAAA,EAChF;AAAA;AAAA;AAAA,EAIA,MAAM,IAAA,GAAsB;AAC1B,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,MAAM,IAAI,MAAM,kCAAkC,CAAA;AACrF,IAAA,IAAA,CAAK,cAAA,EAAe;AACpB,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,WAAA,EAAY,KAAM,QAAA;AACxC,IAAA,IAAI,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA,KAAW,YAAY,CAAC,IAAA,CAAK,OAAO,MAAA,CAAA,EAAS;AACpE,IAAA,IAAI,IAAA,CAAK,WAAA,EAAa,OAAO,IAAA,CAAK,WAAA;AAClC,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA,CAAK,MAAA,CAAO,QAAQ,CAAA;AACvC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,WAAA;AAAA,IACb,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAc,OAAO,QAAA,EAAkC;AACrD,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,IAAI,OAAO,MAAA,KAAW,MAAA,EAAQ,MAAM,IAAI,MAAM,qBAAqB,CAAA;AACnE,MAAA,IAAA,CAAK,SAAS,MAAA,CAAO,MAAA;AACrB,MAAA,IAAA,CAAK,UAAA,GAAa,KAAA;AAAA,IACpB,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAGb,MAAA,MAAM,OAAO,IAAA,CAAK,IAAA,CAAK,UAAA,IAAc,CAAA,aAAA,EAAgB,UAAU,CAAA,CAAA;AAC/D,MAAA,IAAA,CAAK,SAAS,MAAA,CAAO,IAAA;AAAA,QACnB,IAAA,CAAK,GAAA;AAAA,QACL,IAAA;AAAA,QACA,IAAA,CAAK,KAAK,cAAA,IAAkB;AAAA,OAC9B;AACA,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAClB,MAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,MAAM,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,eAAe,CAAA,EAAG,EAAE,IAAA,EAAM,iBAAiB,CAAA;AAC3F,MAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAA,IAClB;AACA,IAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,IAAA,IAAA,CAAK,gBAAgB,QAAA,EAAe;AACpC,IAAA,IAAI;AACF,MAAA,MAAM,KAAK,UAAA,EAAW;AAAA,IACxB,SAAS,GAAA,EAAK;AAIZ,MAAA,IAAI,IAAA,CAAK,MAAA,KAAW,MAAA,EAAQ,IAAA,CAAK,WAAA,EAAY;AAC7C,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA,EAGQ,WAAA,GAAoB;AAC1B,IAAA,IAAI;AACF,MAAA,IAAI,IAAA,CAAK,UAAA,EAAY,IAAA,CAAK,MAAA,EAAQ,KAAA,EAAM;AAAA,IAC1C,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AAAA,EACvB;AAAA,EAEA,MAAc,UAAA,GAA4B;AAIxC,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,IAAA,CAAK,aAAA,IAAiB,IAAA;AAC7C,IAAA,IAAI,KAAA;AACJ,IAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAe,CAAC,GAAG,MAAA,KAAW;AAChD,MAAA,KAAA,GAAQ,UAAA,CAAW,MAAM,MAAA,CAAO,IAAI,MAAM,qBAAqB,CAAC,GAAG,SAAS,CAAA;AAAA,IAC9E,CAAC,CAAA;AACD,IAAA,IAAI;AACF,MAAA,MAAM,QAAQ,IAAA,CAAK,CAAC,KAAK,aAAA,CAAe,OAAA,EAAS,OAAO,CAAC,CAAA;AAAA,IAC3D,CAAA,SAAE;AACA,MAAA,IAAI,KAAA,eAAoB,KAAK,CAAA;AAAA,IAC/B;AAAA,EACF;AAAA;AAAA,EAGQ,iBAAiB,OAAA,EAAuB;AAC9C,IAAA,KAAA,MAAW,GAAG,CAAC,CAAA,IAAK,KAAK,OAAA,EAAS;AAChC,MAAA,IAAI,CAAA,CAAE,KAAA,EAAO,YAAA,CAAa,CAAA,CAAE,KAAK,CAAA;AACjC,MAAA,CAAA,CAAE,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG,EAAE,IAAA,EAAM,IAAA,EAAM,CAAC,CAAA;AAAA,IAC5D;AACA,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AAAA,EACrB;AAAA;AAAA;AAAA,EAIQ,eAAA,GAAwB;AAC9B,IAAA,IAAI,IAAA,CAAK,UAAA,IAAc,CAAC,IAAA,CAAK,UAAA,EAAY;AACzC,IAAA,IAAA,CAAK,UAAA,GAAa,YAAY,MAAM;AAClC,MAAA,IAAI,IAAA,CAAK,QAAQ,MAAA,EAAQ;AACvB,QAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,QAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,QAAA,IAAA,CAAK,iBAAiB,wBAAwB,CAAA;AAC9C,QAAA,IAAA,CAAK,cAAA,EAAe;AAAA,MACtB,CAAA,MAAA,IAAW,IAAA,CAAK,OAAA,CAAQ,IAAA,KAAS,CAAA,EAAG;AAClC,QAAA,IAAA,CAAK,cAAA,EAAe;AAAA,MACtB;AAAA,IACF,GAAG,GAAG,CAAA;AAAA,EACR;AAAA,EAEQ,cAAA,GAAuB;AAC7B,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,aAAA,CAAc,KAAK,UAAU,CAAA;AAC7B,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,IACpB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,QAAQ,IAAA,EAAsC;AAGlD,IAAA,IAAI,IAAA,CAAK,aAAY,KAAM,OAAA,KAAY,CAAC,IAAA,CAAK,MAAA,IAAU,IAAA,CAAK,MAAA,CAAO,MAAA,CAAA,EAAS;AAC1E,MAAA,MAAM,OAAA,GAAU,cAAc,IAAI,CAAA;AAClC,MAAA,IAAI,OAAA,SAAgB,OAAA,CAAQ,KAAA;AAAA,IAC9B;AACA,IAAA,IAAI,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,WAAA,EAAY,KAAM,OAAA,KAAY,CAAC,IAAA,CAAK,MAAA,IAAU,IAAA,CAAK,MAAA,CAAO,MAAA,CAAA,EAAS;AAC3F,MAAA,MAAM,cAAA;AAAA,QACJ,cAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AACA,IAAA,MAAM,KAAK,IAAA,EAAK;AAChB,IAAA,IAAI,IAAA,CAAK,UAAA,EAAY,IAAA,CAAK,MAAA,EAAQ,KAAA,EAAM;AACxC,IAAA,MAAM,KAAK,QAAA,EAAS;AACpB,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,OAAA,EAAS,QAAA;AAAA,MACT,IAAA,EAAM,KAAA;AAAA,MACN,EAAA;AAAA,MACA,MAAA,EAAQ,OAAO,QAAA,CAAS,MAAA;AAAA,MACxB,IAAA,EAAM,eAAe,IAAI;AAAA,KAC3B;AACA,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,IAAA,CAAK,gBAAA,IAAoB,IAAA;AAChD,IAAA,OAAO,IAAI,OAAA,CAAiB,CAAC,OAAA,EAAS,MAAA,KAAW;AAC/C,MAAA,MAAM,KAAA,GAKF,EAAE,OAAA,EAAS,MAAA,EAAQ,OAAA,EAAQ;AAC/B,MAAA,IAAI,SAAA,GAAY,CAAA,IAAK,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,EAAG;AAC/C,QAAA,KAAA,CAAM,KAAA,GAAQ,WAAW,MAAM;AAC7B,UAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAE,MAAM,KAAA,EAAO;AACpC,UAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,EAAE,CAAA;AACtB,UAAA,MAAA;AAAA,YACE,cAAA;AAAA,cACE,iBAAA;AAAA,cACA,CAAA,iCAAA,EAAoC,IAAA,CAAK,IAAI,CAAA,SAAA,EAAY,SAAS,CAAA,IAAA;AAAA;AACpE,WACF;AAAA,QACF,GAAG,SAAS,CAAA;AAAA,MACd;AACA,MAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAA,EAAI,KAAK,CAAA;AAC1B,MAAA,IAAA,CAAK,MAAA,CAAQ,WAAA,CAAY,OAAA,EAAS,IAAA,CAAK,YAAY,CAAA;AACnD,MAAA,IAAA,CAAK,eAAA,EAAgB;AAAA,IACvB,CAAC,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,cAAA,EAAe;AAEpB,IAAA,IAAA,CAAK,aAAA,EAAe,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,cAAc,CAAA,EAAG,EAAE,IAAA,EAAM,IAAA,EAAM,CAAC,CAAA;AACnF,IAAA,IAAA,CAAK,WAAA,EAAY;AACjB,IAAA,IAAA,CAAK,iBAAiB,cAAc,CAAA;AACpC,IAAA,IAAI,IAAA,CAAK,SAAA,IAAa,OAAO,MAAA,KAAW,WAAA,EAAa;AACnD,MAAA,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,IAAA,CAAK,SAAS,CAAA;AACpD,MAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AAAA,IACnB;AAAA,EACF;AACF;;;AC9XO,IAAM,gBAAA,GAAmB;AAsBzB,SAAS,oBACd,MAAA,EACA,MAAA,GAAmD,OAAO,MAAA,KAAW,WAAA,GACjE,SACA,MAAA,EACe;AACnB,EAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,EAAE,SAAS,MAAM;AAAA,EAAC,CAAA,EAAE;AAExC,EAAA,MAAM,KAAA,GAAQ,MAAA;AAEd,EAAA,KAAA,CAAM,gBAAgB,CAAA,GAAI,MAAA;AAG1B,EAAA,MAAM,QAAA,GAAW,MACf,MAAA,CAAO,aAAA,CAAc,IAAI,WAAA,CAAY,yBAAA,EAA2B,EAAE,MAAA,EAAQ,MAAA,EAAQ,CAAC,CAAA;AACrF,EAAA,MAAA,CAAO,gBAAA,CAAiB,2BAA2B,QAAQ,CAAA;AAC3D,EAAA,QAAA,EAAS;AAET,EAAA,OAAO;AAAA,IACL,SAAS,MAAM;AACb,MAAA,MAAA,CAAO,mBAAA,CAAoB,2BAA2B,QAAQ,CAAA;AAE9D,MAAA,IAAI,MAAM,gBAAgB,CAAA,KAAM,MAAA,EAAQ,OAAO,MAAM,gBAAgB,CAAA;AAAA,IACvE;AAAA,GACF;AACF;;;AC/CO,IAAM,UAAA,GACX,w1QAAA;;;AC2BF,IAAM,OAAA,GAAU,MAAA,CAAO,SAAA,CAAU,eAAA,CAAgB,OAAO,CAAA;AAGxD,SAAS,UAAU,KAAA,EAAoC;AACrD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,KAAA;AACtC,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,OAAO,UAAU,QAAA,EAAU;AAC1D,IAAA,IAAI;AACF,MAAA,OAAO,OAAO,KAAK,CAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AA6BO,IAAM,cAAA,GAAN,cAA6B,SAAA,CAAU;AAAA,EAU5C,WAAA,CAAY,OAAA,GAAiC,EAAC,EAAG;AAC/C,IAAA,KAAA,EAAM;AANR,IAAA,IAAA,CAAQ,QAAA,GAA0B,IAAA;AAClC,IAAA,IAAA,CAAQ,IAAA,GAAoC,IAAA;AAC5C,IAAA,IAAA,CAAQ,aAAA,GAA0C,IAAA;AAkIlD,IAAA,IAAA,CAAQ,iBAAA,GAAoB,CAAC,IAAA,KAAwB;AACnD,MAAA,MAAM,WAAW,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,GAAK,OAAqB,EAAC;AAC9D,MAAA,MAAM,OAAA,GAAU,SAAS,CAAC,CAAA;AAC1B,MAAA,IAAI,OAAO,OAAA,KAAY,QAAA,IAAY,OAAA,EAAS;AAC1C,QAAA,IAAA,CAAK,QAAA,GAAW,OAAA;AAChB,QAAA,IAAA,CAAK,UAAU,QAAA,EAAU,EAAE,OAAA,EAAS,OAAA,EAAS,SAAS,CAAA;AAAA,MACxD,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,QAAA,IAAA,CAAK,UAAU,YAAY,CAAA;AAAA,MAC7B;AAAA,IACF,CAAA;AAEA,IAAA,IAAA,CAAQ,gBAAA,GAAmB,CAAC,IAAA,KAAwB;AAElD,MAAA,MAAM,OAAA,GACJ,OAAO,IAAA,KAAS,QAAA,IAAY,SAAS,IAAA,IAAQ,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,GAC3D,IAAA,GACD,EAAE,SAAS,IAAA,EAAK;AACtB,MAAA,MAAM,OAAA,GAAU,SAAA,CAAU,OAAA,CAAQ,OAAO,CAAA;AACzC,MAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,OAAA,CAAQ,QAAQ,CAAA,GAAI,OAAA,CAAQ,WAAW,EAAC;AACvE,MAAA,MAAM,IAAA,GAAO,OAAO,QAAA,CAAS,CAAC,CAAA,KAAM,QAAA,IAAY,QAAA,CAAS,CAAC,CAAA,GAAI,QAAA,CAAS,CAAC,CAAA,GAAI,IAAA,CAAK,QAAA;AACjF,MAAA,IAAI,IAAA,OAAW,QAAA,GAAW,IAAA;AAC1B,MAAA,MAAM,SAAwB,EAAC;AAC/B,MAAA,IAAI,OAAA,KAAY,MAAA,EAAW,MAAA,CAAO,OAAA,GAAU,OAAA;AAC5C,MAAA,IAAI,IAAA,SAAa,OAAA,GAAU,IAAA;AAC3B,MAAA,IAAA,CAAK,SAAA,CAAU,UAAU,MAAM,CAAA;AAAA,IACjC,CAAA;AAvJE,IAAA,MAAM,SAAA,GACJ,OAAA,CAAQ,SAAA,IAAa,OAAA,CAAQ,WAAW,SAAA,IAAa,6BAAA;AACvD,IAAA,IAAA,CAAK,SAAA,GAAY,IAAI,mBAAA,CAAoB;AAAA,MACvC,GAAG,OAAA,CAAQ,SAAA;AAAA,MACX,SAAA;AAAA,MACA,IAAA,EAAM;AAAA;AAAA,KACP,CAAA;AACD,IAAA,IAAA,CAAK,GAAA,GAAM,QAAQ,EAAA,IAAM,OAAA;AACzB,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAQ,IAAA,IAAQ,oBAAA;AAC7B,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAQ,IAAA,IAAQ,UAAA;AAC7B,IAAA,IAAA,CAAK,aAAA,GAAgB,QAAQ,QAAA,KAAa,KAAA;AAC1C,IAAA,IAAI,IAAA,CAAK,aAAA,EAAe,IAAA,CAAK,QAAA,EAAS;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAA,GAAiB;AACf,IAAA,IAAI,KAAK,aAAA,EAAe;AACxB,IAAA,IAAA,CAAK,aAAA,GAAgB,mBAAA,CAAoB,IAAA,CAAK,GAAA,EAAK,CAAA;AAAA,EACrD;AAAA;AAAA,EAGA,UAAA,GAAmB;AACjB,IAAA,IAAA,CAAK,eAAe,OAAA,EAAQ;AAC5B,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AAAA,EACvB;AAAA,EAEA,IAAI,EAAA,GAAa;AACf,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,EACd;AAAA,EAEA,IAAI,IAAA,GAAe;AACjB,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA,EAEA,IAAI,IAAA,GAAuB;AACzB,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA;AAAA,EAGA,SAAA,GAAqB;AACnB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,KAAA,GAA0B;AAC9B,IAAA,OAAO,KAAK,QAAA,KAAa,IAAA;AAAA,EAC3B;AAAA;AAAA,EAGQ,GAAA,GAA4B;AAClC,IAAA,IAAI,IAAA,CAAK,IAAA,EAAM,OAAO,IAAA,CAAK,IAAA;AAC3B,IAAA,MAAM,YAAY,IAAA,CAAK,SAAA;AACvB,IAAA,MAAM,OAAA,IAAW,OAAO,IAAA,KACtB,SAAA,CAAU,QAAQ,IAAI,CAAA,CAAA;AACxB,IAAA,IAAA,CAAK,IAAA,GAAO;AAAA,MACV,IAAI,IAAA,CAAK,GAAA;AAAA,MACT,MAAM,IAAA,CAAK,KAAA;AAAA,MACX,OAAA,EAAS,OAAA;AAAA,MACT,IAAA,EAAM,OAAO,IAAA,CAAK,KAAA,KAAU,WAAW,IAAA,CAAK,KAAA,GAAS,IAAA,CAAK,KAAA,EAAO,IAAA,IAAQ,EAAA;AAAA,MACzE,OAAA;AAAA,MACA,EAAA,GAAK,CAAC,KAAA,EAAe,OAAA,KAAqC;AACxD,QAAA,IAAI,UAAU,iBAAA,IAAqB,KAAA,KAAU,kBAAkB,SAAA,CAAU,EAAA,CAAG,OAAO,OAAO,CAAA;AAAA,MAC5F,CAAA,CAAA;AAAA,MACA,GAAA,GAAM,CAAC,KAAA,EAAe,OAAA,KAAqC;AACzD,QAAA,IAAI,KAAA,KAAU,qBAAqB,KAAA,KAAU,gBAAA;AAC3C,UAAA,SAAA,CAAU,GAAA,CAAI,OAAO,OAAO,CAAA;AAAA,MAChC,CAAA;AAAA,KACF;AACA,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAA,CAAQ,IAAA,GAAoB,EAAC,EAA2B;AAC5D,IAAA,IAAI,KAAK,WAAA,KAAgB,MAAA,IAAa,OAAO,IAAA,CAAK,WAAW,MAAM,OAAA,EAAS;AAC1E,MAAA,MAAM,MAAA,CAAO,MAAA;AAAA,QACX,IAAI,KAAA;AAAA,UACF,wCAAwC,MAAA,CAAO,IAAA,CAAK,WAAW,CAAA,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,gBAAA;AAAA,SAC/E;AAAA,QACA,EAAE,MAAM,mBAAA;AAAoB,OAC9B;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,CAAK,aAAA,EAAe,IAAA,CAAK,QAAA,EAAS;AACtC,IAAA,IAAA,CAAK,SAAA,EAAU;AACf,IAAA,MAAM,IAAA,CAAK,UAAU,IAAA,EAAK;AAC1B,IAAA,MAAM,QAAA,GAAY,MAAM,IAAA,CAAK,SAAA,CAAU,QAAQ,EAAE,IAAA,EAAM,0BAA0B,CAAA;AACjF,IAAA,MAAM,OAAA,GAAU,WAAW,CAAC,CAAA;AAC5B,IAAA,IAAI,CAAC,OAAA,EAAS,MAAM,IAAI,MAAM,kBAAkB,CAAA;AAChD,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA;AAChB,IAAA,MAAM,IAAA,GAAsB,EAAE,OAAA,EAAS,OAAA,EAAS,OAAA,EAAQ;AACxD,IAAA,IAAA,CAAK,SAAA,CAAU,WAAW,IAAI,CAAA;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,UAAA,GAA4B;AAChC,IAAA,IAAA,CAAK,WAAA,EAAY;AACjB,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AACrB,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAGhB,IAAA,IAAA,CAAK,UAAA,EAAW;AAChB,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,UAAU,YAAY,CAAA;AAAA,EAC7B;AAAA;AAAA,EAGQ,SAAA,GAAkB;AACxB,IAAA,IAAA,CAAK,WAAA,EAAY;AACjB,IAAA,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,iBAAA,EAAmB,IAAA,CAAK,iBAAiB,CAAA;AAC3D,IAAA,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,gBAAA,EAAkB,IAAA,CAAK,gBAAgB,CAAA;AAAA,EAC3D;AAAA,EAEQ,WAAA,GAAoB;AAC1B,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,iBAAA,EAAmB,IAAA,CAAK,iBAAiB,CAAA;AAC5D,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,gBAAA,EAAkB,IAAA,CAAK,gBAAgB,CAAA;AAAA,EAC5D;AAAA,EAmCQ,SAAA,CAAU,OAA4C,IAAA,EAA4B;AACxF,IAAA,MAAM,OAAA,GAAU,IAAA;AAChB,IAAA,IAAI,IAAA,KAAS,MAAA,EAAW,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA;AAAA,SACrC,OAAA,CAAQ,IAAA,CAAK,KAAA,EAAO,IAAI,CAAA;AAAA,EAC/B;AAAA,EAEA,MAAM,QAAQ,QAAA,EAAwD;AACpE,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,EAAU,MAAM,IAAI,MAAM,qBAAqB,CAAA;AAGzD,IAAA,OAAO,aAAA,CAAc,OAAA,CAAQ,QAAA,EAAU,IAAA,CAAK,KAAK,CAAA;AAAA,EACnD;AAAA,EAEA,MAAM,OAAA,GAA2B;AAC/B,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAM,QACJ,IAAA,EAC2C;AAC3C,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,IAAI,CAAA;AAAA,EACpC;AACF;;;AC9PO,SAAS,MAAM,OAAA,EAAiD;AACrE,EAAA,OAAO,IAAI,eAAe,OAAO,CAAA;AACnC;;;ACKO,IAAM,4BAAA,GAA+B;AA2E5C,SAAS,gBAAgB,KAAA,EAAgD;AACvE,EAAA,IAAI,OAAO,UAAU,QAAA,IAAY,OAAO,UAAU,QAAA,IAAY,OAAO,UAAU,QAAA,EAAU;AACvF,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI;AACF,IAAA,OAAO,cAAc,MAAA,CAAO,KAAK,CAAA,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA;AAAA,EACjD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAQO,SAAS,yBAAA,CACd,OAAA,GAAsC,EAAC,EAClB;AACrB,EAAA,MAAM,SAAA,GAAY,IAAI,mBAAA,CAAoB;AAAA,IACxC,GAAG,OAAA,CAAQ,SAAA;AAAA,IACX,SAAA,EAAW,QAAQ,SAAA,IAAa,6BAAA;AAAA,IAChC,IAAA,EAAM;AAAA,GACP,CAAA;AACD,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAyD;AAC/E,EAAA,IAAI,OAAA,GAAiE,IAAA;AAErE,EAAA,MAAM,QAAA,GAAW,MACf,OAAA,GACI;AAAA,IACE;AAAA,MACE,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,SAAA,EAAW,IAAI,UAAA,EAAW;AAAA,MAC1B,MAAA,EAAQ,CAAC,OAAA,CAAQ,KAAK,CAAA;AAAA,MACtB,UAAU;AAAC;AACb,MAEF,EAAC;AACP,EAAA,MAAM,aAAa,MAAM;AACvB,IAAA,MAAM,UAAA,GAA4C,EAAE,QAAA,EAAU,QAAA,EAAS,EAAE;AACzE,IAAA,KAAA,MAAW,YAAY,CAAC,GAAG,SAAS,CAAA,WAAY,UAAU,CAAA;AAAA,EAC5D,CAAA;AACA,EAAA,MAAM,kBAAkB,MAAM;AAC5B,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,OAAA,GAAU,IAAA;AACV,IAAA,UAAA,EAAW;AAAA,EACb,CAAA;AAEA,EAAA,MAAM,iBAAA,GAAoB,CAAC,IAAA,KAAkB;AAC3C,IAAA,MAAM,OAAO,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,GAAK,OAAqB,EAAC;AAC1D,IAAA,MAAM,OAAA,GAAU,KAAK,CAAC,CAAA;AACtB,IAAA,IAAI,OAAO,OAAA,KAAY,QAAA,IAAY,CAAC,OAAA,SAAgB,eAAA,EAAgB;AACpE,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,OAAA,GAAU,EAAE,GAAG,OAAA,EAAS,OAAA,EAAQ;AAChC,IAAA,UAAA,EAAW;AAAA,EACb,CAAA;AACA,EAAA,MAAM,gBAAA,GAAmB,CAAC,IAAA,KAAkB;AAC1C,IAAA,MAAM,OAAA,GACJ,OAAO,IAAA,KAAS,QAAA,IAAY,SAAS,IAAA,IAAQ,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,GAC3D,IAAA,GACD,EAAE,SAAS,IAAA,EAAK;AACtB,IAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,OAAA,CAAQ,OAAO,CAAA;AAC7C,IAAA,IAAI,CAAC,KAAA,EAAO,OAAO,eAAA,EAAgB;AACnC,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,OAAA,CAAQ,QAAQ,CAAA,GAAK,OAAA,CAAQ,WAAyB,EAAC;AAClF,IAAA,MAAM,OAAA,GAAU,OAAO,IAAA,CAAK,CAAC,CAAA,KAAM,QAAA,IAAY,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA,CAAK,CAAC,CAAA,GAAI,OAAA,CAAQ,OAAA;AAC3E,IAAA,OAAA,GAAU,EAAE,SAAS,KAAA,EAAM;AAC3B,IAAA,UAAA,EAAW;AAAA,EACb,CAAA;AACA,EAAA,SAAA,CAAU,EAAA,CAAG,mBAAmB,iBAAiB,CAAA;AACjD,EAAA,SAAA,CAAU,EAAA,CAAG,kBAAkB,gBAAgB,CAAA;AAE/C,EAAA,MAAM,OAAA,IAAW,CAAC,IAAA,KAAmC,SAAA,CAAU,QAAQ,IAAI,CAAA,CAAA;AAE3E,EAAA,MAAM,QAAA,GAAwC;AAAA,IAC5C,oBAAA,EAAsB;AAAA,MACpB,OAAA,EAAS,OAAA;AAAA,MACT,OAAA;AAAA,MACA,aAAA,EAAe,OAAA;AAAA,MACf,EAAA,EAAI;AAAA,KACN;AAAA,IACA,kBAAA,EAAoB;AAAA,MAClB,OAAA,EAAS,OAAA;AAAA,MACT,OAAA,EAAS,OAAO,KAAA,KAAU;AACxB,QAAA,IAAI,WAAW,KAAA,EAAO,MAAA,SAAe,EAAE,QAAA,EAAU,UAAS,EAAE;AAC5D,QAAA,MAAM,UAAU,IAAA,EAAK;AAErB,QAAA,MAAM,SAAU,MAAM,SAAA,CAAU,QAAQ,EAAE,IAAA,EAAM,0BAA0B,CAAA;AAC1E,QAAA,MAAM,OAAO,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,GAAK,SAAuB,EAAC;AAC9D,QAAA,MAAM,OAAA,GAAU,KAAK,CAAC,CAAA;AACtB,QAAA,IAAI,OAAO,YAAY,QAAA,IAAY,CAAC,SAAS,OAAO,EAAE,QAAA,EAAU,EAAC,EAAE;AACnE,QAAA,OAAA,GAAU,EAAE,OAAA,EAAS,KAAA,EAAO,4BAAA,EAA6B;AACzD,QAAA,UAAA,EAAW;AACX,QAAA,OAAO,EAAE,QAAA,EAAU,QAAA,EAAS,EAAE;AAAA,MAChC;AAAA,KACF;AAAA,IACA,qBAAA,EAAuB;AAAA,MACrB,OAAA,EAAS,OAAA;AAAA,MACT,YAAY,YAAY;AACtB,QAAA,SAAA,CAAU,KAAA,EAAM;AAChB,QAAA,eAAA,EAAgB;AAAA,MAClB;AAAA,KACF;AAAA,IACA,iBAAA,EAAmB;AAAA,MACjB,OAAA,EAAS,OAAA;AAAA,MACT,EAAA,EAAI,CAAC,MAAA,EAAQ,QAAA,KAAa;AACxB,QAAA,SAAA,CAAU,IAAI,QAAQ,CAAA;AACtB,QAAA,OAAO,MAAM;AACX,UAAA,SAAA,CAAU,OAAO,QAAQ,CAAA;AAAA,QAC3B,CAAA;AAAA,MACF;AAAA;AACF,GACF;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,OAAA;AAAA,IACT,IAAA,EAAM,QAAQ,IAAA,IAAQ,OAAA;AAAA,IACtB,IAAA,EAAM,QAAQ,IAAA,IAAS,UAAA;AAAA,IACvB,MAAA,EAAQ,CAAC,4BAA4B,CAAA;AAAA,IACrC,IAAI,QAAA,GAAW;AACb,MAAA,OAAO,QAAA,EAAS;AAAA,IAClB,CAAA;AAAA,IACA;AAAA,GACF;AACF;AAWO,SAAS,2BAAA,CACd,UAAsC,EAAC,EACvC,SAAmD,OAAO,MAAA,KAAW,WAAA,GACjE,MAAA,GACA,MAAA,EACQ;AACZ,EAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,MAAM;AAAA,EAAC,CAAA;AAC3B,EAAA,MAAM,MAAA,GAAS,0BAA0B,OAAO,CAAA;AAChD,EAAA,MAAM,cAAiC,EAAC;AACxC,EAAA,MAAM,QAAA,GAAW,CAAC,EAAE,QAAA,EAAS,KAAmB;AAC9C,IAAA,WAAA,CAAY,IAAA,CAAK,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA,EACnC,CAAA;AACA,EAAA,MAAM,UAAA,GAAa,CAAC,KAAA,KAAiB;AACnC,IAAA,MAAM,MAAO,KAAA,CAAmC,MAAA;AAChD,IAAA,IAAI,OAAO,OAAO,GAAA,CAAI,QAAA,KAAa,UAAA,WAAqB,GAAG,CAAA;AAAA,EAC7D,CAAA;AACA,EAAA,IAAI;AACF,IAAA,MAAA,CAAO,aAAA;AAAA,MACL,IAAI,YAAY,iCAAA,EAAmC;AAAA,QACjD,MAAA,EAAQ,QAAA;AAAA,QACR,OAAA,EAAS,KAAA;AAAA,QACT,UAAA,EAAY,KAAA;AAAA,QACZ,QAAA,EAAU;AAAA,OACX;AAAA,KACH;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,mEAAmE,KAAK,CAAA;AAAA,EACxF;AACA,EAAA,MAAA,CAAO,gBAAA,CAAiB,6BAA6B,UAAU,CAAA;AAC/D,EAAA,OAAO,MAAM;AACX,IAAA,MAAA,CAAO,mBAAA,CAAoB,6BAA6B,UAAU,CAAA;AAClE,IAAA,KAAA,MAAW,UAAA,IAAc,WAAA,CAAY,MAAA,CAAO,CAAC,GAAG,UAAA,EAAW;AAAA,EAC7D,CAAA;AACF","file":"index.js","sourcesContent":["/**\n * Wire protocol between the \"Connect with Chipi\" connector (running in the dApp)\n * and the Chipi hosted wallet (running at `wallet.chipipay.com` in a popup).\n *\n * Both sides import these shapes so the contract stays in lock-step. The\n * transport is `window.postMessage`: the dApp opens the wallet in a popup,\n * forwards get-starknet `wallet_*` RPC calls over the channel, and the wallet\n * answers after the user approves in its own (already-built) approval UI.\n */\n/** A get-starknet RPC call as sent over the wire: just the discriminant +\n * optional params (the full typed `RpcMessage` carries result/errors we don't\n * serialize). */\nexport interface ChipiRpcCall {\n type: string;\n params?: unknown;\n}\n\n/** Namespace tag on every message so we ignore unrelated postMessages. */\nexport const CHIPI_WC = \"chipi-connect/v1\" as const;\n\n/** wallet → dApp: the hosted wallet page finished loading and is listening. */\nexport interface ChipiReadyMessage {\n channel: typeof CHIPI_WC;\n type: \"ready\";\n}\n\n/** dApp → wallet: forward a get-starknet `wallet_*` RPC call. */\nexport interface ChipiRpcRequestMessage {\n channel: typeof CHIPI_WC;\n type: \"rpc\";\n id: string;\n /** The dApp origin, so the wallet can show it + enforce Verify checks. */\n origin: string;\n call: ChipiRpcCall;\n}\n\n/** wallet → dApp: the result (or error) for a given request id. */\nexport type ChipiRpcResultMessage =\n | { channel: typeof CHIPI_WC; type: \"rpc-result\"; id: string; ok: true; result: unknown }\n | {\n channel: typeof CHIPI_WC;\n type: \"rpc-result\";\n id: string;\n ok: false;\n error: { code: number; message: string };\n };\n\n/** wallet → dApp: an account/network change to propagate to the dApp. */\nexport interface ChipiEventMessage {\n channel: typeof CHIPI_WC;\n type: \"event\";\n event: \"accountsChanged\" | \"networkChanged\";\n data: unknown;\n}\n\nexport type ChipiWalletMessage = ChipiReadyMessage | ChipiRpcResultMessage | ChipiEventMessage;\nexport type ChipiDappMessage = ChipiRpcRequestMessage;\n\nexport function isChipiWalletMessage(data: unknown): data is ChipiWalletMessage {\n return (\n typeof data === \"object\" &&\n data !== null &&\n (data as { channel?: unknown }).channel === CHIPI_WC\n );\n}\n\n/** Type guard for a dApp→wallet message (used by the hosted wallet side). */\nexport function isChipiDappMessage(data: unknown): data is ChipiDappMessage {\n return (\n typeof data === \"object\" &&\n data !== null &&\n (data as { channel?: unknown }).channel === CHIPI_WC &&\n (data as { type?: unknown }).type === \"rpc\"\n );\n}\n","/**\n * Client-side (dApp) transport: opens the Chipi hosted wallet in a popup,\n * performs the ready handshake, and forwards get-starknet `wallet_*` RPC calls\n * over `postMessage`, correlating responses by id. The popup is reused across\n * requests. If the user closes it, later requests reject with `POPUP_CLOSED`\n * instead of reopening it: `window.open` outside a click is blocked by\n * browsers, so the dApp must call `connect()` (or `open()`) again from a click.\n */\nimport {\n CHIPI_WC,\n isChipiWalletMessage,\n type ChipiRpcCall,\n type ChipiRpcRequestMessage,\n type ChipiWalletMessage,\n} from \"./protocol.js\";\n\nexport interface ChipiTransportOptions {\n /** Hosted wallet base URL, e.g. `https://wallet.chipipay.com`. */\n walletUrl: string;\n /**\n * Transport mode:\n * - `\"popup\"` (default): open the hosted wallet in a popup window: the\n * universal model, works for any external dApp.\n * - `\"parent\"`: the dApp is embedded in an iframe INSIDE the Chipi wallet\n * (in-app browser); talk to `window.parent` instead of opening a popup, so\n * approval renders inline in the wallet. Only works when the dApp is\n * actually iframed by the Chipi host.\n * - `\"auto\"`: use `\"parent\"` when running inside an iframe, else `\"popup\"`.\n */\n mode?: \"popup\" | \"parent\" | \"auto\";\n /** Popup window name. */\n windowName?: string;\n /** Popup window features. */\n windowFeatures?: string;\n /** Ready-handshake timeout (ms). Defaults to 180_000. On timeout the popup is\n * closed and the transport resets, so the next `open()` starts clean. */\n openTimeoutMs?: number;\n /**\n * Per-request timeout (ms), counted from when the request is posted to the\n * wallet. Defaults to 120_000. A request that gets no answer in time rejects\n * with an Error whose `code` (and `name`) is `\"REQUEST_TIMEOUT\"`. Pass `0` to\n * disable.\n */\n requestTimeoutMs?: number;\n}\n\n/** Error codes the transport attaches to `Error.code` (besides wallet codes). */\nexport type ChipiTransportErrorCode = \"REQUEST_TIMEOUT\" | \"POPUP_CLOSED\";\n\nfunction transportError(code: ChipiTransportErrorCode, message: string): Error {\n const err = Object.assign(new Error(message), { code });\n err.name = code;\n return err;\n}\n\n/** Drop `undefined` values from plain objects (recursively) so the wallet never\n * receives `{ key: undefined }`: a strict schema on the host side would reject\n * it, and `postMessage` would otherwise preserve the key. Arrays keep their\n * positions. */\nfunction stripUndefined<T>(value: T): T {\n if (Array.isArray(value)) return value.map((v) => stripUndefined(v)) as T;\n if (value === null || typeof value !== \"object\") return value;\n const proto = Object.getPrototypeOf(value);\n if (proto !== Object.prototype && proto !== null) return value;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (v !== undefined) out[k] = stripUndefined(v);\n }\n return out as T;\n}\n\ntype EventName = \"accountsChanged\" | \"networkChanged\";\ntype EventHandler = (data: unknown) => void;\n\nfunction deferred<T>() {\n let resolve!: (v: T) => void;\n let reject!: (e: unknown) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n return { promise, resolve, reject };\n}\n\n/** Starknet mainnet chain id, hex of the short string \"SN_MAIN\". Chipi is mainnet-only. */\nconst SN_MAIN_HEX = \"0x534e5f4d41494e\";\n\n/**\n * Answer for a passive call (one that must never prompt) while no wallet window\n * is open, or `undefined` when the call needs the wallet. Wallet scanners such\n * as get-starknet v4 send these to every `window.starknet*` object at page\n * load; forwarding them would call `window.open` outside a click.\n * - `wallet_getPermissions`: `[]` (this page has not connected).\n * - `wallet_requestAccounts` with `silent_mode: true`: `[]` (never prompts).\n * - `wallet_requestChainId`: SN_MAIN.\n */\nfunction passiveAnswer(call: ChipiRpcCall): { value: unknown } | undefined {\n switch (call.type) {\n case \"wallet_getPermissions\":\n return { value: [] };\n case \"wallet_requestAccounts\": {\n const params = call.params as { silent_mode?: unknown } | undefined;\n return params?.silent_mode === true ? { value: [] } : undefined;\n }\n case \"wallet_requestChainId\":\n return { value: SN_MAIN_HEX };\n default:\n return undefined;\n }\n}\n\nfunction randomId(): string {\n // App-runtime ids; uniqueness only needs to hold within one open popup.\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport class ChipiPopupTransport {\n private readonly walletOrigin: string;\n private readonly url: string;\n private target: Window | null = null;\n private ownsTarget = false;\n private ready = false;\n private listening = false;\n private readonly pending = new Map<\n string,\n {\n resolve: (v: unknown) => void;\n reject: (e: unknown) => void;\n message: ChipiRpcRequestMessage;\n timer?: ReturnType<typeof setTimeout>;\n }\n >();\n private readonly handlers = new Map<EventName, Set<EventHandler>>();\n private readyDeferred: ReturnType<typeof deferred<void>> | null = null;\n private openPromise: Promise<void> | null = null;\n private closeWatch: ReturnType<typeof setInterval> | null = null;\n /** True once this transport opened a popup. A later request with no live\n * popup means the user closed it: reject instead of reopening off-gesture. */\n private hadPopup = false;\n\n constructor(private readonly opts: ChipiTransportOptions) {\n this.url = opts.walletUrl.replace(/\\/$/, \"\") + \"/connect\";\n this.walletOrigin = new URL(opts.walletUrl).origin;\n }\n\n on(event: EventName, handler: EventHandler): void {\n (this.handlers.get(event) ?? this.handlers.set(event, new Set()).get(event)!).add(handler);\n }\n\n off(event: EventName, handler: EventHandler): void {\n this.handlers.get(event)?.delete(handler);\n }\n\n private ensureListener(): void {\n if (this.listening || typeof window === \"undefined\") return;\n window.addEventListener(\"message\", this.onMessage);\n this.listening = true;\n }\n\n private onMessage = (e: MessageEvent): void => {\n if (e.origin !== this.walletOrigin || !isChipiWalletMessage(e.data)) return;\n // Isolate to OUR wallet window: without this, a second Chipi popup (another\n // dApp, same origin) could leak its `ready`/`event` into this transport.\n // With no target (before open / after close) nothing is ours: ignore it all,\n // so a stray `ready` can't flip state and a stray `event` can't fire.\n if (!this.target || e.source !== this.target) return;\n const msg = e.data as ChipiWalletMessage;\n if (msg.type === \"ready\") {\n this.ready = true;\n this.readyDeferred?.resolve();\n this.readyDeferred = null;\n // A fresh /connect re-announces \"ready\": e.g. after the user signs in,\n // which reloads the popup onto a new page. The request we already sent went\n // to the previous page, which is gone. Re-send the requests that are still\n // unanswered (`pending` only holds those) so they reach the new page.\n // Contract: the hosted wallet MUST de-dupe by request id, because a repeat\n // `ready` (e.g. the popup's multi-post ready) re-sends the same request.\n for (const p of this.pending.values()) {\n this.target.postMessage(p.message, this.walletOrigin);\n }\n return;\n }\n if (msg.type === \"rpc-result\") {\n const p = this.pending.get(msg.id);\n if (!p) return;\n this.pending.delete(msg.id);\n if (p.timer) clearTimeout(p.timer);\n if (msg.ok) p.resolve(msg.result);\n else p.reject(Object.assign(new Error(msg.error.message), { code: msg.error.code }));\n return;\n }\n if (msg.type === \"event\") {\n this.handlers.get(msg.event)?.forEach((h) => h(msg.data));\n }\n };\n\n /** Resolve \"auto\" → \"parent\" when iframed, else \"popup\". */\n private resolveMode(): \"popup\" | \"parent\" {\n const mode = this.opts.mode ?? \"popup\";\n if (mode !== \"auto\") return mode;\n return typeof window !== \"undefined\" && window.parent !== window ? \"parent\" : \"popup\";\n }\n\n /** Open (or reuse) the wallet (popup window OR the parent frame) and wait for\n * its ready handshake. Concurrent calls share ONE handshake. */\n async open(): Promise<void> {\n if (typeof window === \"undefined\") throw new Error(\"chipi_connector_requires_browser\");\n this.ensureListener();\n const isParent = this.resolveMode() === \"parent\";\n if (this.ready && this.target && (isParent || !this.target.closed)) return;\n if (this.openPromise) return this.openPromise;\n this.openPromise = this.doOpen(isParent);\n try {\n await this.openPromise;\n } finally {\n this.openPromise = null;\n }\n }\n\n private async doOpen(isParent: boolean): Promise<void> {\n if (isParent) {\n if (window.parent === window) throw new Error(\"chipi_not_in_iframe\");\n this.target = window.parent;\n this.ownsTarget = false;\n } else {\n this.ready = false;\n // Unique per-open window name so a reconnect can never reuse a stale popup\n // that still holds a previous session's pending approval.\n const name = this.opts.windowName ?? `chipi-wallet-${randomId()}`;\n this.target = window.open(\n this.url,\n name,\n this.opts.windowFeatures ?? \"popup=yes,width=420,height=680\"\n );\n this.ownsTarget = true;\n if (!this.target) throw Object.assign(new Error(\"Popup blocked\"), { code: \"popup_blocked\" });\n this.hadPopup = true;\n }\n const opened = this.target;\n this.readyDeferred = deferred<void>();\n try {\n await this.awaitReady();\n } catch (err) {\n // Handshake stalled: close the popup we opened and reset, so a stale\n // window can't answer later and the next open() starts from scratch.\n // (Skip if close() already replaced the target in the meantime.)\n if (this.target === opened) this.resetTarget();\n throw err;\n }\n }\n\n /** Close the popup (if we own one) and forget the target + ready state. */\n private resetTarget(): void {\n try {\n if (this.ownsTarget) this.target?.close();\n } catch {\n // ignore\n }\n this.target = null;\n this.ready = false;\n this.readyDeferred = null;\n }\n\n private async awaitReady(): Promise<void> {\n // Generous: a cold login (Clerk / passkey) can take a while. We only reject\n // here on an outright stall: the popup-closed watcher handles the real\n // \"user gave up / closed it\" case quickly.\n const timeoutMs = this.opts.openTimeoutMs ?? 180_000;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(\"wallet_open_timeout\")), timeoutMs);\n });\n try {\n await Promise.race([this.readyDeferred!.promise, timeout]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n\n /** Reject every in-flight request (popup closed / disconnected). */\n private rejectAllPending(message: string): void {\n for (const [, p] of this.pending) {\n if (p.timer) clearTimeout(p.timer);\n p.reject(Object.assign(new Error(message), { code: 4001 }));\n }\n this.pending.clear();\n }\n\n /** While requests are in flight, watch for the user closing the popup and\n * reject them: otherwise the dApp's promise would hang forever. */\n private startCloseWatch(): void {\n if (this.closeWatch || !this.ownsTarget) return;\n this.closeWatch = setInterval(() => {\n if (this.target?.closed) {\n this.ready = false;\n this.target = null;\n this.rejectAllPending(\"User closed the wallet\");\n this.stopCloseWatch();\n } else if (this.pending.size === 0) {\n this.stopCloseWatch();\n }\n }, 500);\n }\n\n private stopCloseWatch(): void {\n if (this.closeWatch) {\n clearInterval(this.closeWatch);\n this.closeWatch = null;\n }\n }\n\n /**\n * Forward a get-starknet RPC call to the wallet, awaiting its response.\n *\n * With no wallet window open, passive calls are answered locally and never\n * open it: `wallet_getPermissions` → `[]`, `wallet_requestAccounts` with\n * `silent_mode: true` → `[]`, `wallet_requestChainId` → SN_MAIN.\n *\n * The first request may open the popup. Once a popup has been opened, a\n * request made after it was closed rejects with `code: \"POPUP_CLOSED\"`\n * instead of calling `window.open` again: requests usually run outside a\n * click, where browsers block popups. Reopen via `connect()` / `open()`\n * from a click.\n */\n async request(call: ChipiRpcCall): Promise<unknown> {\n // Passive calls never open the popup: with no wallet window open (or\n // opening), answer them here. Once connected they go to the wallet.\n if (this.resolveMode() === \"popup\" && (!this.target || this.target.closed)) {\n const passive = passiveAnswer(call);\n if (passive) return passive.value;\n }\n if (this.hadPopup && this.resolveMode() === \"popup\" && (!this.target || this.target.closed)) {\n throw transportError(\n \"POPUP_CLOSED\",\n \"The Chipi wallet window was closed. Call connect() again from a click.\"\n );\n }\n await this.open();\n if (this.ownsTarget) this.target?.focus();\n const id = randomId();\n const message: ChipiRpcRequestMessage = {\n channel: CHIPI_WC,\n type: \"rpc\",\n id,\n origin: window.location.origin,\n call: stripUndefined(call),\n };\n const timeoutMs = this.opts.requestTimeoutMs ?? 120_000;\n return new Promise<unknown>((resolve, reject) => {\n const entry: {\n resolve: (v: unknown) => void;\n reject: (e: unknown) => void;\n message: ChipiRpcRequestMessage;\n timer?: ReturnType<typeof setTimeout>;\n } = { resolve, reject, message };\n if (timeoutMs > 0 && Number.isFinite(timeoutMs)) {\n entry.timer = setTimeout(() => {\n if (this.pending.get(id) !== entry) return;\n this.pending.delete(id);\n reject(\n transportError(\n \"REQUEST_TIMEOUT\",\n `The Chipi wallet did not answer \"${call.type}\" within ${timeoutMs} ms.`\n )\n );\n }, timeoutMs);\n }\n this.pending.set(id, entry);\n this.target!.postMessage(message, this.walletOrigin);\n this.startCloseWatch();\n });\n }\n\n /** Close the popup (if we own one) + reject in-flight requests. */\n close(): void {\n this.stopCloseWatch();\n // Unblock an in-flight open() instead of leaving it to the ready timeout.\n this.readyDeferred?.reject(Object.assign(new Error(\"disconnected\"), { code: 4001 }));\n this.resetTarget();\n this.rejectAllPending(\"disconnected\");\n if (this.listening && typeof window !== \"undefined\") {\n window.removeEventListener(\"message\", this.onMessage);\n this.listening = false;\n }\n }\n}\n","import type { StarknetWindowObject } from \"@starknet-io/types-js\";\n\n/** Window key get-starknet discovers by scanning for `starknet*` properties. */\nexport const CHIPI_WINDOW_KEY = \"starknet_chipi\";\n\nexport interface ChipiRegistration {\n /** Remove `window.starknet_chipi` + the announce listener. */\n dispose: () => void;\n}\n\n/**\n * Make a Chipi `StarknetWindowObject` discoverable to any get-starknet /\n * starknet-react / starknetkit dApp on the page: WITHOUT an upstream PR and\n * WITHOUT whitelisting. This self-registration covers the apps that scan for\n * wallets rather than importing our connector explicitly.\n *\n * Discovery is announced two ways for maximum reach:\n * 1. **window scan**: set `window.starknet_chipi`. get-starknet v4's\n * `getAvailableWallets()` finds every `window` key starting with `starknet`.\n * 2. **event announce**: dispatch `starknet:announceWallet` now and again on\n * the dApp's `starknet:requestWallets` (the EIP-6963-style, timing-robust\n * Starknet Wallet Standard discovery path).\n *\n * SSR-safe (no-ops when there's no `window`) and idempotent per (target, wallet).\n */\nexport function registerChipiWallet(\n wallet: StarknetWindowObject,\n target: (Window & typeof globalThis) | undefined = typeof window !== \"undefined\"\n ? window\n : undefined\n): ChipiRegistration {\n if (!target) return { dispose: () => {} };\n\n const store = target as unknown as Record<string, unknown>;\n // 1. Classic window-scan discovery.\n store[CHIPI_WINDOW_KEY] = wallet;\n\n // 2. Event-based discovery (announce now + whenever a dApp asks).\n const announce = () =>\n target.dispatchEvent(new CustomEvent(\"starknet:announceWallet\", { detail: wallet }));\n target.addEventListener(\"starknet:requestWallets\", announce);\n announce();\n\n return {\n dispose: () => {\n target.removeEventListener(\"starknet:requestWallets\", announce);\n // Only remove our own object: never clobber a newer injector's wallet.\n if (store[CHIPI_WINDOW_KEY] === wallet) delete store[CHIPI_WINDOW_KEY];\n },\n };\n}\n","// Chipi brand wallet icon: the current luchador mark on a transparent\n// background, 48x48 PNG (same asset used by the browser extension's\n// toolbar icon). A data-URI is what get-starknet / wallet pickers render.\nexport const CHIPI_ICON =\n \"data:image/png;base64,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\";\n","/**\n * `ChipiConnector`: a starknet-react / get-starknet connector for the Chipi\n * hosted smart-account wallet. A self-contained connector package any dApp\n * adds to its `connectors` array (`new ChipiConnector()`) directly: no\n * whitelisting, no dependency on a third-party wallet kit, and NO browser\n * extension required. Clicking \"Connect with Chipi\" opens our hosted wallet\n * (passkey + gasless paymaster) in a popup; the dApp's `wallet_*` RPC calls are\n * forwarded over postMessage and answered after the user approves in Chipi's\n * own (already-built) approval UI.\n */\nimport { Connector } from \"@starknet-react/core\";\nimport { WalletAccount, constants } from \"starknet\";\nimport type { AccountInterface, ProviderInterface } from \"starknet\";\nimport type {\n RpcMessage,\n RequestFnCall,\n RpcTypeToMessageMap,\n StarknetWindowObject,\n} from \"@starknet-io/types-js\";\nimport { ChipiPopupTransport, type ChipiTransportOptions } from \"./transport.js\";\nimport { registerChipiWallet, type ChipiRegistration } from \"./register.js\";\nimport { CHIPI_ICON } from \"./icon.js\";\n\n// @starknet-react/core declares these internally but doesn't export them; mirror\n// the shapes (ConnectorIcons === get-starknet's StarknetWindowObject[\"icon\"]).\ntype ConnectorIcons = StarknetWindowObject[\"icon\"];\ntype ConnectorData = { account?: string; chainId?: bigint };\n/** Mirrors starknet-react's `ConnectArgs` (not exported by every version). */\ntype ConnectArgs = { chainIdHint?: bigint };\n\n/** Starknet mainnet chain id (felt of the shortstring \"SN_MAIN\"). */\nconst SN_MAIN = BigInt(constants.StarknetChainId.SN_MAIN);\n\n/** Parse a wallet-sent chain id (hex/decimal string, bigint or number). */\nfunction toChainId(value: unknown): bigint | undefined {\n if (typeof value === \"bigint\") return value;\n if (typeof value === \"number\" || typeof value === \"string\") {\n try {\n return BigInt(value);\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\nexport interface ChipiConnectorOptions {\n /** Hosted wallet base URL. Defaults to `https://wallet.chipipay.com`. */\n walletUrl?: string;\n /** Override the connector id / display name / icon if embedding. */\n id?: string;\n name?: string;\n icon?: ConnectorIcons;\n /**\n * Popup transport tuning: `windowName`, `windowFeatures`, `openTimeoutMs`,\n * `requestTimeoutMs`. `walletUrl` is optional here (the top-level\n * `walletUrl` wins) and `mode` is always `\"popup\"`.\n */\n transport?: Omit<ChipiTransportOptions, \"walletUrl\"> & { walletUrl?: string };\n /**\n * Self-register the wallet on `window` (set `window.starknet_chipi` + announce\n * via `starknet:announceWallet`) so dApps that *scan* `window.starknet*`\n * (get-starknet v4, get-starknet-discovery's injected scan) and don't import\n * this connector also discover \"Connect with Chipi\". Defaults to `true` in a browser; pass\n * `false` to opt out (e.g. to avoid a double entry in a picker that already\n * lists the connector explicitly). No-op during SSR.\n */\n register?: boolean;\n // NOTE: the in-app-browser (\"parent\") transport mode is implemented in the\n // transport but NOT yet supported by the hosted wallet side, so it's not\n // exposed here in v1. Use popup (external dApps) only.\n}\n\nexport class ChipiConnector extends Connector {\n private readonly transport: ChipiPopupTransport;\n private readonly _id: string;\n private readonly _name: string;\n private readonly _icon: ConnectorIcons;\n private _account: string | null = null;\n private _swo: StarknetWindowObject | null = null;\n private _registration: ChipiRegistration | null = null;\n private readonly _autoRegister: boolean;\n\n constructor(options: ChipiConnectorOptions = {}) {\n super();\n const walletUrl =\n options.walletUrl ?? options.transport?.walletUrl ?? \"https://wallet.chipipay.com\";\n this.transport = new ChipiPopupTransport({\n ...options.transport,\n walletUrl,\n mode: \"popup\", // v1: external-dApp popup only (parent host not yet built)\n });\n this._id = options.id ?? \"chipi\";\n this._name = options.name ?? \"Connect with Chipi\";\n this._icon = options.icon ?? CHIPI_ICON;\n this._autoRegister = options.register !== false;\n if (this._autoRegister) this.register();\n }\n\n /**\n * Announce this wallet to scanning dApps (`window.starknet_chipi` +\n * `starknet:announceWallet`). Called automatically from the constructor\n * unless `register: false`. Idempotent and SSR-safe.\n */\n register(): void {\n if (this._registration) return;\n this._registration = registerChipiWallet(this.swo());\n }\n\n /** Undo {@link register}: remove the window object + announce listener. */\n unregister(): void {\n this._registration?.dispose();\n this._registration = null;\n }\n\n get id(): string {\n return this._id;\n }\n\n get name(): string {\n return this._name;\n }\n\n get icon(): ConnectorIcons {\n return this._icon;\n }\n\n /** Hosted wallet: always available (no extension to detect). */\n available(): boolean {\n return true;\n }\n\n /** No silent reconnect in v1: the user re-approves the popup each session. */\n async ready(): Promise<boolean> {\n return this._account !== null;\n }\n\n /** Lazily build the postMessage-backed get-starknet window object. */\n private swo(): StarknetWindowObject {\n if (this._swo) return this._swo;\n const transport = this.transport;\n const request = (async (call: RpcMessage) =>\n transport.request(call)) as StarknetWindowObject[\"request\"];\n this._swo = {\n id: this._id,\n name: this._name,\n version: \"1.0.0\",\n icon: typeof this._icon === \"string\" ? this._icon : (this._icon?.dark ?? \"\"),\n request,\n on: ((event: string, handler: (data: unknown) => void) => {\n if (event === \"accountsChanged\" || event === \"networkChanged\") transport.on(event, handler);\n }) as StarknetWindowObject[\"on\"],\n off: ((event: string, handler: (data: unknown) => void) => {\n if (event === \"accountsChanged\" || event === \"networkChanged\")\n transport.off(event, handler);\n }) as StarknetWindowObject[\"off\"],\n };\n return this._swo;\n }\n\n /**\n * Open the hosted wallet (call from a click: it opens a popup) and request\n * the account. Chipi is mainnet-only: a `chainIdHint` other than SN_MAIN\n * rejects before any popup opens.\n */\n async connect(args: ConnectArgs = {}): Promise<ConnectorData> {\n if (args.chainIdHint !== undefined && BigInt(args.chainIdHint) !== SN_MAIN) {\n throw Object.assign(\n new Error(\n `Chipi is mainnet-only: chainIdHint 0x${BigInt(args.chainIdHint).toString(16)} is not SN_MAIN.`\n ),\n { code: \"UNSUPPORTED_CHAIN\" }\n );\n }\n // Re-announce if a previous disconnect() disposed the registration.\n if (this._autoRegister) this.register();\n this.subscribe();\n await this.transport.open();\n const accounts = (await this.transport.request({ type: \"wallet_requestAccounts\" })) as string[];\n const account = accounts?.[0];\n if (!account) throw new Error(\"chipi_no_account\");\n this._account = account;\n const data: ConnectorData = { account, chainId: SN_MAIN };\n this.emitEvent(\"connect\", data);\n return data;\n }\n\n async disconnect(): Promise<void> {\n this.unsubscribe();\n this.transport.close();\n this._account = null;\n // Drop `window.starknet_chipi` so scanners don't keep a stale object; the\n // next connect() registers a fresh one.\n this.unregister();\n this._swo = null;\n this.emitEvent(\"disconnect\");\n }\n\n /** Forward the wallet's account/network events as starknet-react events. */\n private subscribe(): void {\n this.unsubscribe(); // idempotent across repeated connect() calls\n this.transport.on(\"accountsChanged\", this.onAccountsChanged);\n this.transport.on(\"networkChanged\", this.onNetworkChanged);\n }\n\n private unsubscribe(): void {\n this.transport.off(\"accountsChanged\", this.onAccountsChanged);\n this.transport.off(\"networkChanged\", this.onNetworkChanged);\n }\n\n private onAccountsChanged = (data: unknown): void => {\n const accounts = Array.isArray(data) ? (data as unknown[]) : [];\n const account = accounts[0];\n if (typeof account === \"string\" && account) {\n this._account = account;\n this.emitEvent(\"change\", { account, chainId: SN_MAIN });\n } else {\n this._account = null;\n this.emitEvent(\"disconnect\");\n }\n };\n\n private onNetworkChanged = (data: unknown): void => {\n // The wallet may send the chain id alone or `{ chainId, accounts }`.\n const payload =\n typeof data === \"object\" && data !== null && !Array.isArray(data)\n ? (data as { chainId?: unknown; accounts?: unknown })\n : { chainId: data };\n const chainId = toChainId(payload.chainId);\n const accounts = Array.isArray(payload.accounts) ? payload.accounts : [];\n const next = typeof accounts[0] === \"string\" && accounts[0] ? accounts[0] : this._account;\n if (next) this._account = next;\n const change: ConnectorData = {};\n if (chainId !== undefined) change.chainId = chainId;\n if (next) change.account = next;\n this.emitEvent(\"change\", change);\n };\n\n // `Connector` extends eventemitter3's EventEmitter, but the bundled .d.ts\n // doesn't surface `emit` cleanly through the abstract class: reach it via a\n // narrow cast rather than fight the upstream typing.\n private emitEvent(event: \"connect\" | \"change\", data: ConnectorData): void;\n private emitEvent(event: \"disconnect\"): void;\n private emitEvent(event: \"connect\" | \"change\" | \"disconnect\", data?: ConnectorData): void {\n const emitter = this as unknown as { emit: (e: string, d?: ConnectorData) => void };\n if (data === undefined) emitter.emit(event);\n else emitter.emit(event, data);\n }\n\n async account(provider: ProviderInterface): Promise<AccountInterface> {\n if (!this._account) throw new Error(\"chipi_not_connected\");\n // WalletAccount routes execute()/signMessage() through the SWO's request(),\n // i.e. over our postMessage channel to the hosted wallet.\n return WalletAccount.connect(provider, this.swo());\n }\n\n async chainId(): Promise<bigint> {\n return SN_MAIN;\n }\n\n async request<T extends RpcMessage[\"type\"]>(\n call: RequestFnCall<T>\n ): Promise<RpcTypeToMessageMap[T][\"result\"]> {\n return this.transport.request(call) as Promise<RpcTypeToMessageMap[T][\"result\"]>;\n }\n}\n","import { ChipiConnector, type ChipiConnectorOptions } from \"./connector.js\";\n\n/**\n * Plain-function form of {@link ChipiConnector}, for parity with\n * `@starknet-react/core`'s built-in factories (`ready()`, `braavos()`):\n *\n * const connectors = [chipi(), ready(), braavos()];\n *\n * Equivalent to `new ChipiConnector(options)`: use whichever reads better\n * in your `connectors` array.\n */\nexport function chipi(options?: ChipiConnectorOptions): ChipiConnector {\n return new ChipiConnector(options);\n}\n","/**\n * Chipi as a Wallet Standard wallet with Starknet features\n * (`WalletWithStarknetFeatures` from `@starknet-io/get-starknet-wallet-standard`),\n * so dApps on get-starknet v5+/v6 discovery (`@starknet-io/get-starknet-discovery`,\n * `@starknet-start/react`, anything that listens for\n * `wallet-standard:register-wallet`) list \"Chipi\" without importing this\n * package's connector.\n *\n * Backed by the same popup transport as {@link ChipiConnector}. The types\n * below mirror the upstream interfaces structurally so this package keeps no\n * runtime (or type) dependency on `@wallet-standard/*`.\n */\nimport type { RequestFn } from \"@starknet-io/types-js\";\nimport { ChipiPopupTransport, type ChipiTransportOptions } from \"./transport.js\";\nimport { CHIPI_ICON } from \"./icon.js\";\n\n/** Wallet Standard chain id for Starknet mainnet: `starknet:` + hex of \"SN_MAIN\"\n * (same as `WELL_KNOWN_STARKNET_CHAINS[0]` in get-starknet-wallet-standard). */\nexport const CHIPI_STARKNET_MAINNET_CHAIN = \"starknet:0x534e5f4d41494e\" as const;\n\n/** `starknet:0x...` chain identifier. */\nexport type ChipiStarknetChain = `starknet:0x${string}`;\n\n/** Data-URI icon, as Wallet Standard requires. */\nexport type ChipiWalletIcon = `data:image/${\"svg+xml\" | \"webp\" | \"png\" | \"gif\"};base64,${string}`;\n\n/** Mirrors `@wallet-standard/base` `WalletAccount`. */\nexport interface ChipiStandardWalletAccount {\n readonly address: string;\n readonly publicKey: Uint8Array;\n readonly chains: readonly ChipiStarknetChain[];\n readonly features: readonly `${string}:${string}`[];\n}\n\n/** Mirrors `@wallet-standard/features` `StandardEventsChangeProperties`. */\nexport interface ChipiStandardChangeProperties {\n readonly chains?: readonly ChipiStarknetChain[];\n readonly accounts?: readonly ChipiStandardWalletAccount[];\n}\n\n/** Mirrors `StarknetFeatures` from `@starknet-io/get-starknet-wallet-standard`.\n * (A type alias, not an interface, so it satisfies Wallet Standard's\n * `IdentifierRecord` index signature.) */\nexport type ChipiStandardWalletFeatures = {\n readonly \"starknet:walletApi\": {\n readonly version: \"1.0.0\";\n readonly request: RequestFn;\n readonly walletVersion: string;\n readonly id: string;\n };\n readonly \"standard:connect\": {\n readonly version: \"1.0.0\";\n readonly connect: (input?: {\n readonly silent?: boolean;\n }) => Promise<{ readonly accounts: readonly ChipiStandardWalletAccount[] }>;\n };\n readonly \"standard:disconnect\": {\n readonly version: \"1.0.0\";\n readonly disconnect: () => Promise<void>;\n };\n readonly \"standard:events\": {\n readonly version: \"1.0.0\";\n readonly on: <E extends \"change\">(\n event: E,\n listener: (properties: ChipiStandardChangeProperties) => void\n ) => () => void;\n };\n};\n\n/** Structurally a `WalletWithStarknetFeatures`. */\nexport interface ChipiStandardWallet {\n readonly version: \"1.0.0\";\n readonly name: string;\n readonly icon: ChipiWalletIcon;\n readonly chains: readonly ChipiStarknetChain[];\n readonly accounts: readonly ChipiStandardWalletAccount[];\n readonly features: ChipiStandardWalletFeatures;\n}\n\nexport interface ChipiStandardWalletOptions {\n /** Hosted wallet base URL. Defaults to `https://wallet.chipipay.com`. */\n walletUrl?: string;\n /** Display name. Defaults to `\"Chipi\"`. */\n name?: string;\n /** Data-URI icon. Defaults to the Chipi icon. */\n icon?: ChipiWalletIcon;\n /** Popup transport tuning (window name/features, timeouts). */\n transport?: Omit<ChipiTransportOptions, \"walletUrl\" | \"mode\">;\n}\n\n/** Same shape as a Wallet Standard `register-wallet` event detail callback. */\ntype RegisterApi = { register: (wallet: ChipiStandardWallet) => () => void };\n\nfunction toStarknetChain(value: unknown): ChipiStarknetChain | undefined {\n if (typeof value !== \"string\" && typeof value !== \"bigint\" && typeof value !== \"number\") {\n return undefined;\n }\n try {\n return `starknet:0x${BigInt(value).toString(16)}`;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Build the Chipi Wallet Standard wallet (without registering it). `connect`\n * opens the popup, so dApps call it from a click; `connect({ silent: true })`\n * never opens a popup and returns the current accounts (empty if not\n * connected).\n */\nexport function createChipiStandardWallet(\n options: ChipiStandardWalletOptions = {}\n): ChipiStandardWallet {\n const transport = new ChipiPopupTransport({\n ...options.transport,\n walletUrl: options.walletUrl ?? \"https://wallet.chipipay.com\",\n mode: \"popup\",\n });\n const listeners = new Set<(properties: ChipiStandardChangeProperties) => void>();\n let current: { address: string; chain: ChipiStarknetChain } | null = null;\n\n const accounts = (): ChipiStandardWalletAccount[] =>\n current\n ? [\n {\n address: current.address,\n publicKey: new Uint8Array(),\n chains: [current.chain],\n features: [],\n },\n ]\n : [];\n const emitChange = () => {\n const properties: ChipiStandardChangeProperties = { accounts: accounts() };\n for (const listener of [...listeners]) listener(properties);\n };\n const setDisconnected = () => {\n if (!current) return;\n current = null;\n emitChange();\n };\n\n const onAccountsChanged = (data: unknown) => {\n const list = Array.isArray(data) ? (data as unknown[]) : [];\n const address = list[0];\n if (typeof address !== \"string\" || !address) return setDisconnected();\n if (!current) return; // not connected through this wallet: ignore\n current = { ...current, address };\n emitChange();\n };\n const onNetworkChanged = (data: unknown) => {\n const payload =\n typeof data === \"object\" && data !== null && !Array.isArray(data)\n ? (data as { chainId?: unknown; accounts?: unknown })\n : { chainId: data };\n const chain = toStarknetChain(payload.chainId);\n if (!chain) return setDisconnected();\n if (!current) return;\n const list = Array.isArray(payload.accounts) ? (payload.accounts as unknown[]) : [];\n const address = typeof list[0] === \"string\" && list[0] ? list[0] : current.address;\n current = { address, chain };\n emitChange();\n };\n transport.on(\"accountsChanged\", onAccountsChanged);\n transport.on(\"networkChanged\", onNetworkChanged);\n\n const request = ((call: Parameters<RequestFn>[0]) => transport.request(call)) as RequestFn;\n\n const features: ChipiStandardWalletFeatures = {\n \"starknet:walletApi\": {\n version: \"1.0.0\",\n request,\n walletVersion: \"1.0.0\",\n id: \"chipi\",\n },\n \"standard:connect\": {\n version: \"1.0.0\",\n connect: async (input) => {\n if (current || input?.silent) return { accounts: accounts() };\n await transport.open();\n // No params: never forward `{ silent_mode: undefined }` to the wallet.\n const result = (await transport.request({ type: \"wallet_requestAccounts\" })) as unknown;\n const list = Array.isArray(result) ? (result as unknown[]) : [];\n const address = list[0];\n if (typeof address !== \"string\" || !address) return { accounts: [] };\n current = { address, chain: CHIPI_STARKNET_MAINNET_CHAIN };\n emitChange();\n return { accounts: accounts() };\n },\n },\n \"standard:disconnect\": {\n version: \"1.0.0\",\n disconnect: async () => {\n transport.close();\n setDisconnected();\n },\n },\n \"standard:events\": {\n version: \"1.0.0\",\n on: (_event, listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n },\n };\n\n return {\n version: \"1.0.0\",\n name: options.name ?? \"Chipi\",\n icon: options.icon ?? (CHIPI_ICON as ChipiWalletIcon),\n chains: [CHIPI_STARKNET_MAINNET_CHAIN],\n get accounts() {\n return accounts();\n },\n features,\n };\n}\n\n/**\n * Register Chipi with every Wallet Standard app on the page: dispatches\n * `wallet-standard:register-wallet` now and answers later\n * `wallet-standard:app-ready` events (the `@wallet-standard/wallet`\n * `registerWallet` protocol, implemented here without the dependency).\n *\n * Returns an unregister function that removes the listener and unregisters\n * from every app that accepted the wallet. SSR-safe: a no-op without `window`.\n */\nexport function registerChipiStandardWallet(\n options: ChipiStandardWalletOptions = {},\n target: (Window & typeof globalThis) | undefined = typeof window !== \"undefined\"\n ? window\n : undefined\n): () => void {\n if (!target) return () => {};\n const wallet = createChipiStandardWallet(options);\n const unregisters: Array<() => void> = [];\n const callback = ({ register }: RegisterApi) => {\n unregisters.push(register(wallet));\n };\n const onAppReady = (event: Event) => {\n const api = (event as CustomEvent<RegisterApi>).detail;\n if (api && typeof api.register === \"function\") callback(api);\n };\n try {\n target.dispatchEvent(\n new CustomEvent(\"wallet-standard:register-wallet\", {\n detail: callback,\n bubbles: false,\n cancelable: false,\n composed: false,\n })\n );\n } catch (error) {\n console.error(\"wallet-standard:register-wallet event could not be dispatched\\n\", error);\n }\n target.addEventListener(\"wallet-standard:app-ready\", onAppReady);\n return () => {\n target.removeEventListener(\"wallet-standard:app-ready\", onAppReady);\n for (const unregister of unregisters.splice(0)) unregister();\n };\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@chipi-stack/starknet-connector",
3
- "version": "0.4.0",
4
- "description": "\"Connect with Chipi\" — a starknet-react / get-starknet connector that lets any Starknet dApp connect to a Chipi hosted smart-account wallet (passkey, gasless). No browser extension, no WalletConnect.",
3
+ "version": "0.5.0",
4
+ "description": "Connect with Chipi: a starknet-react / get-starknet connector and Wallet Standard wallet for the Chipi hosted smart-account wallet (passkey, gasless). Works next to injected wallets like Bramble, Ready and Braavos. No browser extension, no WalletConnect.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",
@@ -29,6 +29,8 @@
29
29
  "starknet",
30
30
  "starknet-react",
31
31
  "get-starknet",
32
+ "wallet-standard",
33
+ "bramble",
32
34
  "connector",
33
35
  "wallet",
34
36
  "smart-account",