@chipi-stack/starknet-connector 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -14
- package/dist/index.cjs +600 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +372 -0
- package/dist/index.d.ts +372 -10
- package/dist/index.js +587 -12
- package/dist/index.js.map +1 -1
- package/package.json +15 -6
- package/dist/connector.d.ts +0 -72
- package/dist/connector.d.ts.map +0 -1
- package/dist/connector.js +0 -128
- package/dist/connector.js.map +0 -1
- package/dist/factory.d.ts +0 -12
- package/dist/factory.d.ts.map +0 -1
- package/dist/factory.js +0 -14
- package/dist/factory.js.map +0 -1
- package/dist/icon.d.ts +0 -2
- package/dist/icon.d.ts.map +0 -1
- package/dist/icon.js +0 -5
- package/dist/icon.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/protocol.d.ts +0 -62
- package/dist/protocol.d.ts.map +0 -1
- package/dist/protocol.js +0 -15
- package/dist/protocol.js.map +0 -1
- package/dist/register.d.ts +0 -24
- package/dist/register.d.ts.map +0 -1
- package/dist/register.js +0 -39
- package/dist/register.js.map +0 -1
- package/dist/transport.d.ts +0 -68
- package/dist/transport.d.ts.map +0 -1
- package/dist/transport.js +0 -217
- package/dist/transport.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,13 +1,588 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import { Connector } from '@starknet-react/core';
|
|
2
|
+
import { constants, WalletAccount } from 'starknet';
|
|
3
|
+
|
|
4
|
+
// src/connector.ts
|
|
5
|
+
|
|
6
|
+
// src/protocol.ts
|
|
7
|
+
var CHIPI_WC = "chipi-connect/v1";
|
|
8
|
+
function isChipiWalletMessage(data) {
|
|
9
|
+
return typeof data === "object" && data !== null && data.channel === CHIPI_WC;
|
|
10
|
+
}
|
|
11
|
+
function isChipiDappMessage(data) {
|
|
12
|
+
return typeof data === "object" && data !== null && data.channel === CHIPI_WC && data.type === "rpc";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// src/transport.ts
|
|
16
|
+
function transportError(code, message) {
|
|
17
|
+
const err = Object.assign(new Error(message), { code });
|
|
18
|
+
err.name = code;
|
|
19
|
+
return err;
|
|
20
|
+
}
|
|
21
|
+
function stripUndefined(value) {
|
|
22
|
+
if (Array.isArray(value)) return value.map((v) => stripUndefined(v));
|
|
23
|
+
if (value === null || typeof value !== "object") return value;
|
|
24
|
+
const proto = Object.getPrototypeOf(value);
|
|
25
|
+
if (proto !== Object.prototype && proto !== null) return value;
|
|
26
|
+
const out = {};
|
|
27
|
+
for (const [k, v] of Object.entries(value)) {
|
|
28
|
+
if (v !== void 0) out[k] = stripUndefined(v);
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
function deferred() {
|
|
33
|
+
let resolve;
|
|
34
|
+
let reject;
|
|
35
|
+
const promise = new Promise((res, rej) => {
|
|
36
|
+
resolve = res;
|
|
37
|
+
reject = rej;
|
|
38
|
+
});
|
|
39
|
+
return { promise, resolve, reject };
|
|
40
|
+
}
|
|
41
|
+
function randomId() {
|
|
42
|
+
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
43
|
+
}
|
|
44
|
+
var ChipiPopupTransport = class {
|
|
45
|
+
constructor(opts) {
|
|
46
|
+
this.opts = opts;
|
|
47
|
+
this.target = null;
|
|
48
|
+
this.ownsTarget = false;
|
|
49
|
+
this.ready = false;
|
|
50
|
+
this.listening = false;
|
|
51
|
+
this.pending = /* @__PURE__ */ new Map();
|
|
52
|
+
this.handlers = /* @__PURE__ */ new Map();
|
|
53
|
+
this.readyDeferred = null;
|
|
54
|
+
this.openPromise = null;
|
|
55
|
+
this.closeWatch = null;
|
|
56
|
+
/** True once this transport opened a popup. A later request with no live
|
|
57
|
+
* popup means the user closed it: reject instead of reopening off-gesture. */
|
|
58
|
+
this.hadPopup = false;
|
|
59
|
+
this.onMessage = (e) => {
|
|
60
|
+
if (e.origin !== this.walletOrigin || !isChipiWalletMessage(e.data)) return;
|
|
61
|
+
if (!this.target || e.source !== this.target) return;
|
|
62
|
+
const msg = e.data;
|
|
63
|
+
if (msg.type === "ready") {
|
|
64
|
+
this.ready = true;
|
|
65
|
+
this.readyDeferred?.resolve();
|
|
66
|
+
this.readyDeferred = null;
|
|
67
|
+
for (const p of this.pending.values()) {
|
|
68
|
+
this.target.postMessage(p.message, this.walletOrigin);
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (msg.type === "rpc-result") {
|
|
73
|
+
const p = this.pending.get(msg.id);
|
|
74
|
+
if (!p) return;
|
|
75
|
+
this.pending.delete(msg.id);
|
|
76
|
+
if (p.timer) clearTimeout(p.timer);
|
|
77
|
+
if (msg.ok) p.resolve(msg.result);
|
|
78
|
+
else p.reject(Object.assign(new Error(msg.error.message), { code: msg.error.code }));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (msg.type === "event") {
|
|
82
|
+
this.handlers.get(msg.event)?.forEach((h) => h(msg.data));
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
this.url = opts.walletUrl.replace(/\/$/, "") + "/connect";
|
|
86
|
+
this.walletOrigin = new URL(opts.walletUrl).origin;
|
|
87
|
+
}
|
|
88
|
+
on(event, handler) {
|
|
89
|
+
(this.handlers.get(event) ?? this.handlers.set(event, /* @__PURE__ */ new Set()).get(event)).add(handler);
|
|
90
|
+
}
|
|
91
|
+
off(event, handler) {
|
|
92
|
+
this.handlers.get(event)?.delete(handler);
|
|
93
|
+
}
|
|
94
|
+
ensureListener() {
|
|
95
|
+
if (this.listening || typeof window === "undefined") return;
|
|
96
|
+
window.addEventListener("message", this.onMessage);
|
|
97
|
+
this.listening = true;
|
|
98
|
+
}
|
|
99
|
+
/** Resolve "auto" → "parent" when iframed, else "popup". */
|
|
100
|
+
resolveMode() {
|
|
101
|
+
const mode = this.opts.mode ?? "popup";
|
|
102
|
+
if (mode !== "auto") return mode;
|
|
103
|
+
return typeof window !== "undefined" && window.parent !== window ? "parent" : "popup";
|
|
104
|
+
}
|
|
105
|
+
/** Open (or reuse) the wallet (popup window OR the parent frame) and wait for
|
|
106
|
+
* its ready handshake. Concurrent calls share ONE handshake. */
|
|
107
|
+
async open() {
|
|
108
|
+
if (typeof window === "undefined") throw new Error("chipi_connector_requires_browser");
|
|
109
|
+
this.ensureListener();
|
|
110
|
+
const isParent = this.resolveMode() === "parent";
|
|
111
|
+
if (this.ready && this.target && (isParent || !this.target.closed)) return;
|
|
112
|
+
if (this.openPromise) return this.openPromise;
|
|
113
|
+
this.openPromise = this.doOpen(isParent);
|
|
114
|
+
try {
|
|
115
|
+
await this.openPromise;
|
|
116
|
+
} finally {
|
|
117
|
+
this.openPromise = null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async doOpen(isParent) {
|
|
121
|
+
if (isParent) {
|
|
122
|
+
if (window.parent === window) throw new Error("chipi_not_in_iframe");
|
|
123
|
+
this.target = window.parent;
|
|
124
|
+
this.ownsTarget = false;
|
|
125
|
+
} else {
|
|
126
|
+
this.ready = false;
|
|
127
|
+
const name = this.opts.windowName ?? `chipi-wallet-${randomId()}`;
|
|
128
|
+
this.target = window.open(
|
|
129
|
+
this.url,
|
|
130
|
+
name,
|
|
131
|
+
this.opts.windowFeatures ?? "popup=yes,width=420,height=680"
|
|
132
|
+
);
|
|
133
|
+
this.ownsTarget = true;
|
|
134
|
+
if (!this.target) throw Object.assign(new Error("Popup blocked"), { code: "popup_blocked" });
|
|
135
|
+
this.hadPopup = true;
|
|
136
|
+
}
|
|
137
|
+
const opened = this.target;
|
|
138
|
+
this.readyDeferred = deferred();
|
|
139
|
+
try {
|
|
140
|
+
await this.awaitReady();
|
|
141
|
+
} catch (err) {
|
|
142
|
+
if (this.target === opened) this.resetTarget();
|
|
143
|
+
throw err;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/** Close the popup (if we own one) and forget the target + ready state. */
|
|
147
|
+
resetTarget() {
|
|
148
|
+
try {
|
|
149
|
+
if (this.ownsTarget) this.target?.close();
|
|
150
|
+
} catch {
|
|
151
|
+
}
|
|
152
|
+
this.target = null;
|
|
153
|
+
this.ready = false;
|
|
154
|
+
this.readyDeferred = null;
|
|
155
|
+
}
|
|
156
|
+
async awaitReady() {
|
|
157
|
+
const timeoutMs = this.opts.openTimeoutMs ?? 18e4;
|
|
158
|
+
let timer;
|
|
159
|
+
const timeout = new Promise((_, reject) => {
|
|
160
|
+
timer = setTimeout(() => reject(new Error("wallet_open_timeout")), timeoutMs);
|
|
161
|
+
});
|
|
162
|
+
try {
|
|
163
|
+
await Promise.race([this.readyDeferred.promise, timeout]);
|
|
164
|
+
} finally {
|
|
165
|
+
if (timer) clearTimeout(timer);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/** Reject every in-flight request (popup closed / disconnected). */
|
|
169
|
+
rejectAllPending(message) {
|
|
170
|
+
for (const [, p] of this.pending) {
|
|
171
|
+
if (p.timer) clearTimeout(p.timer);
|
|
172
|
+
p.reject(Object.assign(new Error(message), { code: 4001 }));
|
|
173
|
+
}
|
|
174
|
+
this.pending.clear();
|
|
175
|
+
}
|
|
176
|
+
/** While requests are in flight, watch for the user closing the popup and
|
|
177
|
+
* reject them: otherwise the dApp's promise would hang forever. */
|
|
178
|
+
startCloseWatch() {
|
|
179
|
+
if (this.closeWatch || !this.ownsTarget) return;
|
|
180
|
+
this.closeWatch = setInterval(() => {
|
|
181
|
+
if (this.target?.closed) {
|
|
182
|
+
this.ready = false;
|
|
183
|
+
this.target = null;
|
|
184
|
+
this.rejectAllPending("User closed the wallet");
|
|
185
|
+
this.stopCloseWatch();
|
|
186
|
+
} else if (this.pending.size === 0) {
|
|
187
|
+
this.stopCloseWatch();
|
|
188
|
+
}
|
|
189
|
+
}, 500);
|
|
190
|
+
}
|
|
191
|
+
stopCloseWatch() {
|
|
192
|
+
if (this.closeWatch) {
|
|
193
|
+
clearInterval(this.closeWatch);
|
|
194
|
+
this.closeWatch = null;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Forward a get-starknet RPC call to the wallet, awaiting its response.
|
|
199
|
+
*
|
|
200
|
+
* The first request may open the popup. Once a popup has been opened, a
|
|
201
|
+
* request made after it was closed rejects with `code: "POPUP_CLOSED"`
|
|
202
|
+
* instead of calling `window.open` again: requests usually run outside a
|
|
203
|
+
* click, where browsers block popups. Reopen via `connect()` / `open()`
|
|
204
|
+
* from a click.
|
|
205
|
+
*/
|
|
206
|
+
async request(call) {
|
|
207
|
+
if (this.hadPopup && this.resolveMode() === "popup" && (!this.target || this.target.closed)) {
|
|
208
|
+
throw transportError(
|
|
209
|
+
"POPUP_CLOSED",
|
|
210
|
+
"The Chipi wallet window was closed. Call connect() again from a click."
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
await this.open();
|
|
214
|
+
if (this.ownsTarget) this.target?.focus();
|
|
215
|
+
const id = randomId();
|
|
216
|
+
const message = {
|
|
217
|
+
channel: CHIPI_WC,
|
|
218
|
+
type: "rpc",
|
|
219
|
+
id,
|
|
220
|
+
origin: window.location.origin,
|
|
221
|
+
call: stripUndefined(call)
|
|
222
|
+
};
|
|
223
|
+
const timeoutMs = this.opts.requestTimeoutMs ?? 12e4;
|
|
224
|
+
return new Promise((resolve, reject) => {
|
|
225
|
+
const entry = { resolve, reject, message };
|
|
226
|
+
if (timeoutMs > 0 && Number.isFinite(timeoutMs)) {
|
|
227
|
+
entry.timer = setTimeout(() => {
|
|
228
|
+
if (this.pending.get(id) !== entry) return;
|
|
229
|
+
this.pending.delete(id);
|
|
230
|
+
reject(
|
|
231
|
+
transportError(
|
|
232
|
+
"REQUEST_TIMEOUT",
|
|
233
|
+
`The Chipi wallet did not answer "${call.type}" within ${timeoutMs} ms.`
|
|
234
|
+
)
|
|
235
|
+
);
|
|
236
|
+
}, timeoutMs);
|
|
237
|
+
}
|
|
238
|
+
this.pending.set(id, entry);
|
|
239
|
+
this.target.postMessage(message, this.walletOrigin);
|
|
240
|
+
this.startCloseWatch();
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
/** Close the popup (if we own one) + reject in-flight requests. */
|
|
244
|
+
close() {
|
|
245
|
+
this.stopCloseWatch();
|
|
246
|
+
this.readyDeferred?.reject(Object.assign(new Error("disconnected"), { code: 4001 }));
|
|
247
|
+
this.resetTarget();
|
|
248
|
+
this.rejectAllPending("disconnected");
|
|
249
|
+
if (this.listening && typeof window !== "undefined") {
|
|
250
|
+
window.removeEventListener("message", this.onMessage);
|
|
251
|
+
this.listening = false;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
// src/register.ts
|
|
257
|
+
var CHIPI_WINDOW_KEY = "starknet_chipi";
|
|
258
|
+
function registerChipiWallet(wallet, target = typeof window !== "undefined" ? window : void 0) {
|
|
259
|
+
if (!target) return { dispose: () => {
|
|
260
|
+
} };
|
|
261
|
+
const store = target;
|
|
262
|
+
store[CHIPI_WINDOW_KEY] = wallet;
|
|
263
|
+
const announce = () => target.dispatchEvent(new CustomEvent("starknet:announceWallet", { detail: wallet }));
|
|
264
|
+
target.addEventListener("starknet:requestWallets", announce);
|
|
265
|
+
announce();
|
|
266
|
+
return {
|
|
267
|
+
dispose: () => {
|
|
268
|
+
target.removeEventListener("starknet:requestWallets", announce);
|
|
269
|
+
if (store[CHIPI_WINDOW_KEY] === wallet) delete store[CHIPI_WINDOW_KEY];
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// src/icon.ts
|
|
275
|
+
var CHIPI_ICON = "data:image/png;base64,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";
|
|
276
|
+
|
|
277
|
+
// src/connector.ts
|
|
278
|
+
var SN_MAIN = BigInt(constants.StarknetChainId.SN_MAIN);
|
|
279
|
+
function toChainId(value) {
|
|
280
|
+
if (typeof value === "bigint") return value;
|
|
281
|
+
if (typeof value === "number" || typeof value === "string") {
|
|
282
|
+
try {
|
|
283
|
+
return BigInt(value);
|
|
284
|
+
} catch {
|
|
285
|
+
return void 0;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return void 0;
|
|
289
|
+
}
|
|
290
|
+
var ChipiConnector = class extends Connector {
|
|
291
|
+
constructor(options = {}) {
|
|
292
|
+
super();
|
|
293
|
+
this._account = null;
|
|
294
|
+
this._swo = null;
|
|
295
|
+
this._registration = null;
|
|
296
|
+
this.onAccountsChanged = (data) => {
|
|
297
|
+
const accounts = Array.isArray(data) ? data : [];
|
|
298
|
+
const account = accounts[0];
|
|
299
|
+
if (typeof account === "string" && account) {
|
|
300
|
+
this._account = account;
|
|
301
|
+
this.emitEvent("change", { account, chainId: SN_MAIN });
|
|
302
|
+
} else {
|
|
303
|
+
this._account = null;
|
|
304
|
+
this.emitEvent("disconnect");
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
this.onNetworkChanged = (data) => {
|
|
308
|
+
const payload = typeof data === "object" && data !== null && !Array.isArray(data) ? data : { chainId: data };
|
|
309
|
+
const chainId = toChainId(payload.chainId);
|
|
310
|
+
const accounts = Array.isArray(payload.accounts) ? payload.accounts : [];
|
|
311
|
+
const next = typeof accounts[0] === "string" && accounts[0] ? accounts[0] : this._account;
|
|
312
|
+
if (next) this._account = next;
|
|
313
|
+
const change = {};
|
|
314
|
+
if (chainId !== void 0) change.chainId = chainId;
|
|
315
|
+
if (next) change.account = next;
|
|
316
|
+
this.emitEvent("change", change);
|
|
317
|
+
};
|
|
318
|
+
const walletUrl = options.walletUrl ?? options.transport?.walletUrl ?? "https://wallet.chipipay.com";
|
|
319
|
+
this.transport = new ChipiPopupTransport({
|
|
320
|
+
...options.transport,
|
|
321
|
+
walletUrl,
|
|
322
|
+
mode: "popup"
|
|
323
|
+
// v1: external-dApp popup only (parent host not yet built)
|
|
324
|
+
});
|
|
325
|
+
this._id = options.id ?? "chipi";
|
|
326
|
+
this._name = options.name ?? "Connect with Chipi";
|
|
327
|
+
this._icon = options.icon ?? CHIPI_ICON;
|
|
328
|
+
this._autoRegister = options.register !== false;
|
|
329
|
+
if (this._autoRegister) this.register();
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Announce this wallet to scanning dApps (`window.starknet_chipi` +
|
|
333
|
+
* `starknet:announceWallet`). Called automatically from the constructor
|
|
334
|
+
* unless `register: false`. Idempotent and SSR-safe.
|
|
335
|
+
*/
|
|
336
|
+
register() {
|
|
337
|
+
if (this._registration) return;
|
|
338
|
+
this._registration = registerChipiWallet(this.swo());
|
|
339
|
+
}
|
|
340
|
+
/** Undo {@link register}: remove the window object + announce listener. */
|
|
341
|
+
unregister() {
|
|
342
|
+
this._registration?.dispose();
|
|
343
|
+
this._registration = null;
|
|
344
|
+
}
|
|
345
|
+
get id() {
|
|
346
|
+
return this._id;
|
|
347
|
+
}
|
|
348
|
+
get name() {
|
|
349
|
+
return this._name;
|
|
350
|
+
}
|
|
351
|
+
get icon() {
|
|
352
|
+
return this._icon;
|
|
353
|
+
}
|
|
354
|
+
/** Hosted wallet: always available (no extension to detect). */
|
|
355
|
+
available() {
|
|
356
|
+
return true;
|
|
357
|
+
}
|
|
358
|
+
/** No silent reconnect in v1: the user re-approves the popup each session. */
|
|
359
|
+
async ready() {
|
|
360
|
+
return this._account !== null;
|
|
361
|
+
}
|
|
362
|
+
/** Lazily build the postMessage-backed get-starknet window object. */
|
|
363
|
+
swo() {
|
|
364
|
+
if (this._swo) return this._swo;
|
|
365
|
+
const transport = this.transport;
|
|
366
|
+
const request = (async (call) => transport.request(call));
|
|
367
|
+
this._swo = {
|
|
368
|
+
id: this._id,
|
|
369
|
+
name: this._name,
|
|
370
|
+
version: "1.0.0",
|
|
371
|
+
icon: typeof this._icon === "string" ? this._icon : this._icon?.dark ?? "",
|
|
372
|
+
request,
|
|
373
|
+
on: ((event, handler) => {
|
|
374
|
+
if (event === "accountsChanged" || event === "networkChanged") transport.on(event, handler);
|
|
375
|
+
}),
|
|
376
|
+
off: ((event, handler) => {
|
|
377
|
+
if (event === "accountsChanged" || event === "networkChanged")
|
|
378
|
+
transport.off(event, handler);
|
|
379
|
+
})
|
|
380
|
+
};
|
|
381
|
+
return this._swo;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Open the hosted wallet (call from a click: it opens a popup) and request
|
|
385
|
+
* the account. Chipi is mainnet-only: a `chainIdHint` other than SN_MAIN
|
|
386
|
+
* rejects before any popup opens.
|
|
387
|
+
*/
|
|
388
|
+
async connect(args = {}) {
|
|
389
|
+
if (args.chainIdHint !== void 0 && BigInt(args.chainIdHint) !== SN_MAIN) {
|
|
390
|
+
throw Object.assign(
|
|
391
|
+
new Error(
|
|
392
|
+
`Chipi is mainnet-only: chainIdHint 0x${BigInt(args.chainIdHint).toString(16)} is not SN_MAIN.`
|
|
393
|
+
),
|
|
394
|
+
{ code: "UNSUPPORTED_CHAIN" }
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
if (this._autoRegister) this.register();
|
|
398
|
+
this.subscribe();
|
|
399
|
+
await this.transport.open();
|
|
400
|
+
const accounts = await this.transport.request({ type: "wallet_requestAccounts" });
|
|
401
|
+
const account = accounts?.[0];
|
|
402
|
+
if (!account) throw new Error("chipi_no_account");
|
|
403
|
+
this._account = account;
|
|
404
|
+
const data = { account, chainId: SN_MAIN };
|
|
405
|
+
this.emitEvent("connect", data);
|
|
406
|
+
return data;
|
|
407
|
+
}
|
|
408
|
+
async disconnect() {
|
|
409
|
+
this.unsubscribe();
|
|
410
|
+
this.transport.close();
|
|
411
|
+
this._account = null;
|
|
412
|
+
this.unregister();
|
|
413
|
+
this._swo = null;
|
|
414
|
+
this.emitEvent("disconnect");
|
|
415
|
+
}
|
|
416
|
+
/** Forward the wallet's account/network events as starknet-react events. */
|
|
417
|
+
subscribe() {
|
|
418
|
+
this.unsubscribe();
|
|
419
|
+
this.transport.on("accountsChanged", this.onAccountsChanged);
|
|
420
|
+
this.transport.on("networkChanged", this.onNetworkChanged);
|
|
421
|
+
}
|
|
422
|
+
unsubscribe() {
|
|
423
|
+
this.transport.off("accountsChanged", this.onAccountsChanged);
|
|
424
|
+
this.transport.off("networkChanged", this.onNetworkChanged);
|
|
425
|
+
}
|
|
426
|
+
emitEvent(event, data) {
|
|
427
|
+
const emitter = this;
|
|
428
|
+
if (data === void 0) emitter.emit(event);
|
|
429
|
+
else emitter.emit(event, data);
|
|
430
|
+
}
|
|
431
|
+
async account(provider) {
|
|
432
|
+
if (!this._account) throw new Error("chipi_not_connected");
|
|
433
|
+
return WalletAccount.connect(provider, this.swo());
|
|
434
|
+
}
|
|
435
|
+
async chainId() {
|
|
436
|
+
return SN_MAIN;
|
|
437
|
+
}
|
|
438
|
+
async request(call) {
|
|
439
|
+
return this.transport.request(call);
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
// src/factory.ts
|
|
444
|
+
function chipi(options) {
|
|
445
|
+
return new ChipiConnector(options);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// src/standard.ts
|
|
449
|
+
var CHIPI_STARKNET_MAINNET_CHAIN = "starknet:0x534e5f4d41494e";
|
|
450
|
+
function toStarknetChain(value) {
|
|
451
|
+
if (typeof value !== "string" && typeof value !== "bigint" && typeof value !== "number") {
|
|
452
|
+
return void 0;
|
|
453
|
+
}
|
|
454
|
+
try {
|
|
455
|
+
return `starknet:0x${BigInt(value).toString(16)}`;
|
|
456
|
+
} catch {
|
|
457
|
+
return void 0;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
function createChipiStandardWallet(options = {}) {
|
|
461
|
+
const transport = new ChipiPopupTransport({
|
|
462
|
+
...options.transport,
|
|
463
|
+
walletUrl: options.walletUrl ?? "https://wallet.chipipay.com",
|
|
464
|
+
mode: "popup"
|
|
465
|
+
});
|
|
466
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
467
|
+
let current = null;
|
|
468
|
+
const accounts = () => current ? [
|
|
469
|
+
{
|
|
470
|
+
address: current.address,
|
|
471
|
+
publicKey: new Uint8Array(),
|
|
472
|
+
chains: [current.chain],
|
|
473
|
+
features: []
|
|
474
|
+
}
|
|
475
|
+
] : [];
|
|
476
|
+
const emitChange = () => {
|
|
477
|
+
const properties = { accounts: accounts() };
|
|
478
|
+
for (const listener of [...listeners]) listener(properties);
|
|
479
|
+
};
|
|
480
|
+
const setDisconnected = () => {
|
|
481
|
+
if (!current) return;
|
|
482
|
+
current = null;
|
|
483
|
+
emitChange();
|
|
484
|
+
};
|
|
485
|
+
const onAccountsChanged = (data) => {
|
|
486
|
+
const list = Array.isArray(data) ? data : [];
|
|
487
|
+
const address = list[0];
|
|
488
|
+
if (typeof address !== "string" || !address) return setDisconnected();
|
|
489
|
+
if (!current) return;
|
|
490
|
+
current = { ...current, address };
|
|
491
|
+
emitChange();
|
|
492
|
+
};
|
|
493
|
+
const onNetworkChanged = (data) => {
|
|
494
|
+
const payload = typeof data === "object" && data !== null && !Array.isArray(data) ? data : { chainId: data };
|
|
495
|
+
const chain = toStarknetChain(payload.chainId);
|
|
496
|
+
if (!chain) return setDisconnected();
|
|
497
|
+
if (!current) return;
|
|
498
|
+
const list = Array.isArray(payload.accounts) ? payload.accounts : [];
|
|
499
|
+
const address = typeof list[0] === "string" && list[0] ? list[0] : current.address;
|
|
500
|
+
current = { address, chain };
|
|
501
|
+
emitChange();
|
|
502
|
+
};
|
|
503
|
+
transport.on("accountsChanged", onAccountsChanged);
|
|
504
|
+
transport.on("networkChanged", onNetworkChanged);
|
|
505
|
+
const request = ((call) => transport.request(call));
|
|
506
|
+
const features = {
|
|
507
|
+
"starknet:walletApi": {
|
|
508
|
+
version: "1.0.0",
|
|
509
|
+
request,
|
|
510
|
+
walletVersion: "1.0.0",
|
|
511
|
+
id: "chipi"
|
|
512
|
+
},
|
|
513
|
+
"standard:connect": {
|
|
514
|
+
version: "1.0.0",
|
|
515
|
+
connect: async (input) => {
|
|
516
|
+
if (current || input?.silent) return { accounts: accounts() };
|
|
517
|
+
await transport.open();
|
|
518
|
+
const result = await transport.request({ type: "wallet_requestAccounts" });
|
|
519
|
+
const list = Array.isArray(result) ? result : [];
|
|
520
|
+
const address = list[0];
|
|
521
|
+
if (typeof address !== "string" || !address) return { accounts: [] };
|
|
522
|
+
current = { address, chain: CHIPI_STARKNET_MAINNET_CHAIN };
|
|
523
|
+
emitChange();
|
|
524
|
+
return { accounts: accounts() };
|
|
525
|
+
}
|
|
526
|
+
},
|
|
527
|
+
"standard:disconnect": {
|
|
528
|
+
version: "1.0.0",
|
|
529
|
+
disconnect: async () => {
|
|
530
|
+
transport.close();
|
|
531
|
+
setDisconnected();
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
"standard:events": {
|
|
535
|
+
version: "1.0.0",
|
|
536
|
+
on: (_event, listener) => {
|
|
537
|
+
listeners.add(listener);
|
|
538
|
+
return () => {
|
|
539
|
+
listeners.delete(listener);
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
return {
|
|
545
|
+
version: "1.0.0",
|
|
546
|
+
name: options.name ?? "Chipi",
|
|
547
|
+
icon: options.icon ?? CHIPI_ICON,
|
|
548
|
+
chains: [CHIPI_STARKNET_MAINNET_CHAIN],
|
|
549
|
+
get accounts() {
|
|
550
|
+
return accounts();
|
|
551
|
+
},
|
|
552
|
+
features
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
function registerChipiStandardWallet(options = {}, target = typeof window !== "undefined" ? window : void 0) {
|
|
556
|
+
if (!target) return () => {
|
|
557
|
+
};
|
|
558
|
+
const wallet = createChipiStandardWallet(options);
|
|
559
|
+
const unregisters = [];
|
|
560
|
+
const callback = ({ register }) => {
|
|
561
|
+
unregisters.push(register(wallet));
|
|
562
|
+
};
|
|
563
|
+
const onAppReady = (event) => {
|
|
564
|
+
const api = event.detail;
|
|
565
|
+
if (api && typeof api.register === "function") callback(api);
|
|
566
|
+
};
|
|
567
|
+
try {
|
|
568
|
+
target.dispatchEvent(
|
|
569
|
+
new CustomEvent("wallet-standard:register-wallet", {
|
|
570
|
+
detail: callback,
|
|
571
|
+
bubbles: false,
|
|
572
|
+
cancelable: false,
|
|
573
|
+
composed: false
|
|
574
|
+
})
|
|
575
|
+
);
|
|
576
|
+
} catch (error) {
|
|
577
|
+
console.error("wallet-standard:register-wallet event could not be dispatched\n", error);
|
|
578
|
+
}
|
|
579
|
+
target.addEventListener("wallet-standard:app-ready", onAppReady);
|
|
580
|
+
return () => {
|
|
581
|
+
target.removeEventListener("wallet-standard:app-ready", onAppReady);
|
|
582
|
+
for (const unregister of unregisters.splice(0)) unregister();
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
export { CHIPI_STARKNET_MAINNET_CHAIN, CHIPI_WC, CHIPI_WINDOW_KEY, ChipiConnector, ChipiPopupTransport, chipi, createChipiStandardWallet, isChipiDappMessage, isChipiWalletMessage, registerChipiStandardWallet, registerChipiWallet };
|
|
587
|
+
//# sourceMappingURL=index.js.map
|
|
13
588
|
//# sourceMappingURL=index.js.map
|