@chipi-stack/starknet-connector 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,24 +0,0 @@
1
- import type { StarknetWindowObject } from "@starknet-io/types-js";
2
- /** Window key get-starknet discovers by scanning for `starknet*` properties. */
3
- export declare const CHIPI_WINDOW_KEY = "starknet_chipi";
4
- export interface ChipiRegistration {
5
- /** Remove `window.starknet_chipi` + the announce listener. */
6
- dispose: () => void;
7
- }
8
- /**
9
- * Make a Chipi `StarknetWindowObject` discoverable to any get-starknet /
10
- * starknet-react / starknetkit dApp on the page — WITHOUT an upstream PR and
11
- * WITHOUT whitelisting. This self-registration covers the apps that scan for
12
- * wallets rather than importing our connector explicitly.
13
- *
14
- * Discovery is announced two ways for maximum reach:
15
- * 1. **window scan** — set `window.starknet_chipi`. get-starknet v4's
16
- * `getAvailableWallets()` finds every `window` key starting with `starknet`.
17
- * 2. **event announce** — dispatch `starknet:announceWallet` now and again on
18
- * the dApp's `starknet:requestWallets` (the EIP-6963-style, timing-robust
19
- * Starknet Wallet Standard discovery path).
20
- *
21
- * SSR-safe (no-ops when there's no `window`) and idempotent per (target, wallet).
22
- */
23
- export declare function registerChipiWallet(wallet: StarknetWindowObject, target?: (Window & typeof globalThis) | undefined): ChipiRegistration;
24
- //# sourceMappingURL=register.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IAChC,8DAA8D;IAC9D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,oBAAoB,EAC5B,MAAM,GAAE,CAAC,MAAM,GAAG,OAAO,UAAU,CAAC,GAAG,SAE1B,GACZ,iBAAiB,CAoBnB"}
package/dist/register.js DELETED
@@ -1,39 +0,0 @@
1
- /** Window key get-starknet discovers by scanning for `starknet*` properties. */
2
- export const CHIPI_WINDOW_KEY = "starknet_chipi";
3
- /**
4
- * Make a Chipi `StarknetWindowObject` discoverable to any get-starknet /
5
- * starknet-react / starknetkit dApp on the page — WITHOUT an upstream PR and
6
- * WITHOUT whitelisting. This self-registration covers the apps that scan for
7
- * wallets rather than importing our connector explicitly.
8
- *
9
- * Discovery is announced two ways for maximum reach:
10
- * 1. **window scan** — set `window.starknet_chipi`. get-starknet v4's
11
- * `getAvailableWallets()` finds every `window` key starting with `starknet`.
12
- * 2. **event announce** — dispatch `starknet:announceWallet` now and again on
13
- * the dApp's `starknet:requestWallets` (the EIP-6963-style, timing-robust
14
- * Starknet Wallet Standard discovery path).
15
- *
16
- * SSR-safe (no-ops when there's no `window`) and idempotent per (target, wallet).
17
- */
18
- export function registerChipiWallet(wallet, target = typeof window !== "undefined"
19
- ? window
20
- : undefined) {
21
- if (!target)
22
- return { dispose: () => { } };
23
- const store = target;
24
- // 1. Classic window-scan discovery.
25
- store[CHIPI_WINDOW_KEY] = wallet;
26
- // 2. Event-based discovery (announce now + whenever a dApp asks).
27
- const announce = () => target.dispatchEvent(new CustomEvent("starknet:announceWallet", { detail: wallet }));
28
- target.addEventListener("starknet:requestWallets", announce);
29
- announce();
30
- return {
31
- dispose: () => {
32
- target.removeEventListener("starknet:requestWallets", announce);
33
- // Only remove our own object — never clobber a newer injector's wallet.
34
- if (store[CHIPI_WINDOW_KEY] === wallet)
35
- delete store[CHIPI_WINDOW_KEY];
36
- },
37
- };
38
- }
39
- //# sourceMappingURL=register.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAEA,gFAAgF;AAChF,MAAM,CAAC,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAOjD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAA4B,EAC5B,SAAmD,OAAO,MAAM,KAAK,WAAW;IAC9E,CAAC,CAAC,MAAM;IACR,CAAC,CAAC,SAAS;IAEb,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC;IAE1C,MAAM,KAAK,GAAG,MAA4C,CAAC;IAC3D,oCAAoC;IACpC,KAAK,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAAC;IAEjC,kEAAkE;IAClE,MAAM,QAAQ,GAAG,GAAG,EAAE,CACpB,MAAM,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,yBAAyB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IACvF,MAAM,CAAC,gBAAgB,CAAC,yBAAyB,EAAE,QAAQ,CAAC,CAAC;IAC7D,QAAQ,EAAE,CAAC;IAEX,OAAO;QACL,OAAO,EAAE,GAAG,EAAE;YACZ,MAAM,CAAC,mBAAmB,CAAC,yBAAyB,EAAE,QAAQ,CAAC,CAAC;YAChE,wEAAwE;YACxE,IAAI,KAAK,CAAC,gBAAgB,CAAC,KAAK,MAAM;gBAAE,OAAO,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACzE,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,68 +0,0 @@
1
- /**
2
- * Client-side (dApp) transport: opens the Chipi hosted wallet in a popup,
3
- * performs the ready handshake, and forwards get-starknet `wallet_*` RPC calls
4
- * over `postMessage`, correlating responses by id. The popup is reused across
5
- * requests; if the user closed it, the next request reopens it.
6
- */
7
- import { type ChipiRpcCall } from "./protocol.js";
8
- export interface ChipiTransportOptions {
9
- /** Hosted wallet base URL, e.g. `https://wallet.chipipay.com`. */
10
- walletUrl: string;
11
- /**
12
- * Transport mode:
13
- * - `"popup"` (default): open the hosted wallet in a popup window — the
14
- * universal model, works for any external dApp.
15
- * - `"parent"`: the dApp is embedded in an iframe INSIDE the Chipi wallet
16
- * (in-app browser); talk to `window.parent` instead of opening a popup, so
17
- * approval renders inline in the wallet. Only works when the dApp is
18
- * actually iframed by the Chipi host.
19
- * - `"auto"`: use `"parent"` when running inside an iframe, else `"popup"`.
20
- */
21
- mode?: "popup" | "parent" | "auto";
22
- /** Popup window name. */
23
- windowName?: string;
24
- /** Popup window features. */
25
- windowFeatures?: string;
26
- /** Ready-handshake timeout (ms). */
27
- openTimeoutMs?: number;
28
- }
29
- type EventName = "accountsChanged" | "networkChanged";
30
- type EventHandler = (data: unknown) => void;
31
- export declare class ChipiPopupTransport {
32
- private readonly opts;
33
- private readonly walletOrigin;
34
- private readonly url;
35
- private target;
36
- private ownsTarget;
37
- private ready;
38
- private listening;
39
- private readonly pending;
40
- private readonly handlers;
41
- private readyDeferred;
42
- private openPromise;
43
- private closeWatch;
44
- constructor(opts: ChipiTransportOptions);
45
- on(event: EventName, handler: EventHandler): void;
46
- off(event: EventName, handler: EventHandler): void;
47
- private ensureListener;
48
- private onMessage;
49
- /** Resolve "auto" → "parent" when iframed, else "popup". */
50
- private resolveMode;
51
- /** Open (or reuse) the wallet (popup window OR the parent frame) and wait for
52
- * its ready handshake. Concurrent calls share ONE handshake. */
53
- open(): Promise<void>;
54
- private doOpen;
55
- private awaitReady;
56
- /** Reject every in-flight request (popup closed / disconnected). */
57
- private rejectAllPending;
58
- /** While requests are in flight, watch for the user closing the popup and
59
- * reject them — otherwise the dApp's promise would hang forever. */
60
- private startCloseWatch;
61
- private stopCloseWatch;
62
- /** Forward a get-starknet RPC call to the wallet, awaiting its response. */
63
- request(call: ChipiRpcCall): Promise<unknown>;
64
- /** Close the popup (if we own one) + reject in-flight requests. */
65
- close(): void;
66
- }
67
- export {};
68
- //# sourceMappingURL=transport.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAGL,KAAK,YAAY,EAGlB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,qBAAqB;IACpC,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACnC,yBAAyB;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,KAAK,SAAS,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AACtD,KAAK,YAAY,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;AAiB5C,qBAAa,mBAAmB;IAoBlB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAnBjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAOpB;IACJ,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2C;IACpE,OAAO,CAAC,aAAa,CAAkD;IACvE,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,UAAU,CAA+C;gBAEpC,IAAI,EAAE,qBAAqB;IAKxD,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAIjD,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAIlD,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,SAAS,CAiCf;IAEF,4DAA4D;IAC5D,OAAO,CAAC,WAAW;IAMnB;oEACgE;IAC1D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAcb,MAAM;YAsBN,UAAU;IAgBxB,oEAAoE;IACpE,OAAO,CAAC,gBAAgB;IAKxB;wEACoE;IACpE,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,cAAc;IAOtB,4EAA4E;IACtE,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAkBnD,mEAAmE;IACnE,KAAK,IAAI,IAAI;CAed"}
package/dist/transport.js DELETED
@@ -1,217 +0,0 @@
1
- /**
2
- * Client-side (dApp) transport: opens the Chipi hosted wallet in a popup,
3
- * performs the ready handshake, and forwards get-starknet `wallet_*` RPC calls
4
- * over `postMessage`, correlating responses by id. The popup is reused across
5
- * requests; if the user closed it, the next request reopens it.
6
- */
7
- import { CHIPI_WC, isChipiWalletMessage, } from "./protocol.js";
8
- function deferred() {
9
- let resolve;
10
- let reject;
11
- const promise = new Promise((res, rej) => {
12
- resolve = res;
13
- reject = rej;
14
- });
15
- return { promise, resolve, reject };
16
- }
17
- function randomId() {
18
- // App-runtime ids; uniqueness only needs to hold within one open popup.
19
- return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
20
- }
21
- export class ChipiPopupTransport {
22
- constructor(opts) {
23
- this.opts = opts;
24
- this.target = null;
25
- this.ownsTarget = false;
26
- this.ready = false;
27
- this.listening = false;
28
- this.pending = new Map();
29
- this.handlers = new Map();
30
- this.readyDeferred = null;
31
- this.openPromise = null;
32
- this.closeWatch = null;
33
- this.onMessage = (e) => {
34
- if (e.origin !== this.walletOrigin || !isChipiWalletMessage(e.data))
35
- return;
36
- // Isolate to OUR wallet window — without this, a second Chipi popup (another
37
- // dApp, same origin) could leak its `ready`/`event` into this transport.
38
- if (this.target && e.source !== this.target)
39
- return;
40
- const msg = e.data;
41
- if (msg.type === "ready") {
42
- this.ready = true;
43
- this.readyDeferred?.resolve();
44
- this.readyDeferred = null;
45
- // A fresh /connect re-announces "ready" — e.g. after the user signs in,
46
- // which reloads the popup onto a new page. The request we already sent went
47
- // to the previous page, which is gone. Re-send any in-flight requests so
48
- // they reach the new page. The hosted wallet de-dupes by request id, so a
49
- // repeat (e.g. from the popup's multi-post ready) is harmless.
50
- if (this.target) {
51
- for (const p of this.pending.values()) {
52
- this.target.postMessage(p.message, this.walletOrigin);
53
- }
54
- }
55
- return;
56
- }
57
- if (msg.type === "rpc-result") {
58
- const p = this.pending.get(msg.id);
59
- if (!p)
60
- return;
61
- this.pending.delete(msg.id);
62
- if (msg.ok)
63
- p.resolve(msg.result);
64
- else
65
- p.reject(Object.assign(new Error(msg.error.message), { code: msg.error.code }));
66
- return;
67
- }
68
- if (msg.type === "event") {
69
- this.handlers.get(msg.event)?.forEach((h) => h(msg.data));
70
- }
71
- };
72
- this.url = opts.walletUrl.replace(/\/$/, "") + "/connect";
73
- this.walletOrigin = new URL(opts.walletUrl).origin;
74
- }
75
- on(event, handler) {
76
- (this.handlers.get(event) ?? this.handlers.set(event, new Set()).get(event)).add(handler);
77
- }
78
- off(event, handler) {
79
- this.handlers.get(event)?.delete(handler);
80
- }
81
- ensureListener() {
82
- if (this.listening || typeof window === "undefined")
83
- return;
84
- window.addEventListener("message", this.onMessage);
85
- this.listening = true;
86
- }
87
- /** Resolve "auto" → "parent" when iframed, else "popup". */
88
- resolveMode() {
89
- const mode = this.opts.mode ?? "popup";
90
- if (mode !== "auto")
91
- return mode;
92
- return typeof window !== "undefined" && window.parent !== window ? "parent" : "popup";
93
- }
94
- /** Open (or reuse) the wallet (popup window OR the parent frame) and wait for
95
- * its ready handshake. Concurrent calls share ONE handshake. */
96
- async open() {
97
- if (typeof window === "undefined")
98
- throw new Error("chipi_connector_requires_browser");
99
- this.ensureListener();
100
- const isParent = this.resolveMode() === "parent";
101
- if (this.ready && this.target && (isParent || !this.target.closed))
102
- return;
103
- if (this.openPromise)
104
- return this.openPromise;
105
- this.openPromise = this.doOpen(isParent);
106
- try {
107
- await this.openPromise;
108
- }
109
- finally {
110
- this.openPromise = null;
111
- }
112
- }
113
- async doOpen(isParent) {
114
- if (isParent) {
115
- if (window.parent === window)
116
- throw new Error("chipi_not_in_iframe");
117
- this.target = window.parent;
118
- this.ownsTarget = false;
119
- }
120
- else {
121
- this.ready = false;
122
- // Unique per-open window name so a reconnect can never reuse a stale popup
123
- // that still holds a previous session's pending approval.
124
- const name = this.opts.windowName ?? `chipi-wallet-${randomId()}`;
125
- this.target = window.open(this.url, name, this.opts.windowFeatures ?? "popup=yes,width=420,height=680");
126
- this.ownsTarget = true;
127
- if (!this.target)
128
- throw Object.assign(new Error("Popup blocked"), { code: "popup_blocked" });
129
- }
130
- this.readyDeferred = deferred();
131
- await this.awaitReady();
132
- }
133
- async awaitReady() {
134
- // Generous: a cold login (Clerk / passkey) can take a while. We only reject
135
- // here on an outright stall — the popup-closed watcher handles the real
136
- // "user gave up / closed it" case quickly.
137
- const timeoutMs = this.opts.openTimeoutMs ?? 180000;
138
- let timer;
139
- const timeout = new Promise((_, reject) => {
140
- timer = setTimeout(() => reject(new Error("wallet_open_timeout")), timeoutMs);
141
- });
142
- try {
143
- await Promise.race([this.readyDeferred.promise, timeout]);
144
- }
145
- finally {
146
- if (timer)
147
- clearTimeout(timer);
148
- }
149
- }
150
- /** Reject every in-flight request (popup closed / disconnected). */
151
- rejectAllPending(message) {
152
- for (const [, p] of this.pending)
153
- p.reject(Object.assign(new Error(message), { code: 4001 }));
154
- this.pending.clear();
155
- }
156
- /** While requests are in flight, watch for the user closing the popup and
157
- * reject them — otherwise the dApp's promise would hang forever. */
158
- startCloseWatch() {
159
- if (this.closeWatch || !this.ownsTarget)
160
- return;
161
- this.closeWatch = setInterval(() => {
162
- if (this.target?.closed) {
163
- this.ready = false;
164
- this.target = null;
165
- this.rejectAllPending("User closed the wallet");
166
- this.stopCloseWatch();
167
- }
168
- else if (this.pending.size === 0) {
169
- this.stopCloseWatch();
170
- }
171
- }, 500);
172
- }
173
- stopCloseWatch() {
174
- if (this.closeWatch) {
175
- clearInterval(this.closeWatch);
176
- this.closeWatch = null;
177
- }
178
- }
179
- /** Forward a get-starknet RPC call to the wallet, awaiting its response. */
180
- async request(call) {
181
- await this.open();
182
- if (this.ownsTarget)
183
- this.target?.focus();
184
- const id = randomId();
185
- const message = {
186
- channel: CHIPI_WC,
187
- type: "rpc",
188
- id,
189
- origin: window.location.origin,
190
- call,
191
- };
192
- return new Promise((resolve, reject) => {
193
- this.pending.set(id, { resolve, reject, message });
194
- this.target.postMessage(message, this.walletOrigin);
195
- this.startCloseWatch();
196
- });
197
- }
198
- /** Close the popup (if we own one) + reject in-flight requests. */
199
- close() {
200
- this.stopCloseWatch();
201
- try {
202
- if (this.ownsTarget)
203
- this.target?.close();
204
- }
205
- catch {
206
- // ignore
207
- }
208
- this.target = null;
209
- this.ready = false;
210
- this.rejectAllPending("disconnected");
211
- if (this.listening && typeof window !== "undefined") {
212
- window.removeEventListener("message", this.onMessage);
213
- this.listening = false;
214
- }
215
- }
216
- }
217
- //# sourceMappingURL=transport.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}