@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 +199 -88
- package/dist/index.cjs +23 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -4
- package/dist/index.d.ts +15 -4
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,35 +1,41 @@
|
|
|
1
1
|
# @chipi-stack/starknet-connector
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[get-starknet](https://github.com/starknet-io/get-starknet) connector that
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
14
|
-
|
|
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
|
-
|
|
17
|
+
Offer Chipi next to Bramble, Ready and Braavos:
|
|
20
18
|
|
|
21
19
|
```tsx
|
|
22
|
-
import {
|
|
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
|
-
|
|
33
|
+
new InjectedConnector({ options: { id: "bramble", name: "Bramble" } }),
|
|
34
|
+
ready(), // Ready (formerly Argent X)
|
|
29
35
|
braavos(),
|
|
30
36
|
];
|
|
31
37
|
|
|
32
|
-
export function
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
- `
|
|
64
|
-
|
|
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/
|
|
74
|
-
register: true, //
|
|
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
|
-
|
|
77
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
224
|
+
The connector rejects with an `Error`. Check `err.code` first, then `err.message`.
|
|
101
225
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
-
|
|
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",
|
package/dist/index.cjs.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":["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":"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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\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
|
-
|
|
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*
|
|
190
|
-
* get-starknet
|
|
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
|
-
|
|
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*
|
|
190
|
-
* get-starknet
|
|
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":"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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\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
|
-
"description": "
|
|
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",
|