@chipi-stack/starknet-connector 0.3.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 +41 -0
- package/dist/index.cjs +286 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +142 -6
- package/dist/index.d.ts +142 -6
- package/dist/index.js +285 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Connector } from '@starknet-react/core';
|
|
2
2
|
import { ProviderInterface, AccountInterface } from 'starknet';
|
|
3
|
-
import { StarknetWindowObject, RpcMessage, RequestFnCall, RpcTypeToMessageMap } from '@starknet-io/types-js';
|
|
3
|
+
import { StarknetWindowObject, RpcMessage, RequestFnCall, RpcTypeToMessageMap, RequestFn } from '@starknet-io/types-js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Wire protocol between the "Connect with Chipi" connector (running in the dApp)
|
|
@@ -68,7 +68,9 @@ declare function isChipiDappMessage(data: unknown): data is ChipiDappMessage;
|
|
|
68
68
|
* Client-side (dApp) transport: opens the Chipi hosted wallet in a popup,
|
|
69
69
|
* performs the ready handshake, and forwards get-starknet `wallet_*` RPC calls
|
|
70
70
|
* over `postMessage`, correlating responses by id. The popup is reused across
|
|
71
|
-
* requests
|
|
71
|
+
* requests. If the user closes it, later requests reject with `POPUP_CLOSED`
|
|
72
|
+
* instead of reopening it: `window.open` outside a click is blocked by
|
|
73
|
+
* browsers, so the dApp must call `connect()` (or `open()`) again from a click.
|
|
72
74
|
*/
|
|
73
75
|
|
|
74
76
|
interface ChipiTransportOptions {
|
|
@@ -89,9 +91,19 @@ interface ChipiTransportOptions {
|
|
|
89
91
|
windowName?: string;
|
|
90
92
|
/** Popup window features. */
|
|
91
93
|
windowFeatures?: string;
|
|
92
|
-
/** Ready-handshake timeout (ms).
|
|
94
|
+
/** Ready-handshake timeout (ms). Defaults to 180_000. On timeout the popup is
|
|
95
|
+
* closed and the transport resets, so the next `open()` starts clean. */
|
|
93
96
|
openTimeoutMs?: number;
|
|
97
|
+
/**
|
|
98
|
+
* Per-request timeout (ms), counted from when the request is posted to the
|
|
99
|
+
* wallet. Defaults to 120_000. A request that gets no answer in time rejects
|
|
100
|
+
* with an Error whose `code` (and `name`) is `"REQUEST_TIMEOUT"`. Pass `0` to
|
|
101
|
+
* disable.
|
|
102
|
+
*/
|
|
103
|
+
requestTimeoutMs?: number;
|
|
94
104
|
}
|
|
105
|
+
/** Error codes the transport attaches to `Error.code` (besides wallet codes). */
|
|
106
|
+
type ChipiTransportErrorCode = "REQUEST_TIMEOUT" | "POPUP_CLOSED";
|
|
95
107
|
type EventName = "accountsChanged" | "networkChanged";
|
|
96
108
|
type EventHandler = (data: unknown) => void;
|
|
97
109
|
declare class ChipiPopupTransport {
|
|
@@ -107,6 +119,9 @@ declare class ChipiPopupTransport {
|
|
|
107
119
|
private readyDeferred;
|
|
108
120
|
private openPromise;
|
|
109
121
|
private closeWatch;
|
|
122
|
+
/** True once this transport opened a popup. A later request with no live
|
|
123
|
+
* popup means the user closed it: reject instead of reopening off-gesture. */
|
|
124
|
+
private hadPopup;
|
|
110
125
|
constructor(opts: ChipiTransportOptions);
|
|
111
126
|
on(event: EventName, handler: EventHandler): void;
|
|
112
127
|
off(event: EventName, handler: EventHandler): void;
|
|
@@ -118,6 +133,8 @@ declare class ChipiPopupTransport {
|
|
|
118
133
|
* its ready handshake. Concurrent calls share ONE handshake. */
|
|
119
134
|
open(): Promise<void>;
|
|
120
135
|
private doOpen;
|
|
136
|
+
/** Close the popup (if we own one) and forget the target + ready state. */
|
|
137
|
+
private resetTarget;
|
|
121
138
|
private awaitReady;
|
|
122
139
|
/** Reject every in-flight request (popup closed / disconnected). */
|
|
123
140
|
private rejectAllPending;
|
|
@@ -125,7 +142,15 @@ declare class ChipiPopupTransport {
|
|
|
125
142
|
* reject them: otherwise the dApp's promise would hang forever. */
|
|
126
143
|
private startCloseWatch;
|
|
127
144
|
private stopCloseWatch;
|
|
128
|
-
/**
|
|
145
|
+
/**
|
|
146
|
+
* Forward a get-starknet RPC call to the wallet, awaiting its response.
|
|
147
|
+
*
|
|
148
|
+
* The first request may open the popup. Once a popup has been opened, a
|
|
149
|
+
* request made after it was closed rejects with `code: "POPUP_CLOSED"`
|
|
150
|
+
* instead of calling `window.open` again: requests usually run outside a
|
|
151
|
+
* click, where browsers block popups. Reopen via `connect()` / `open()`
|
|
152
|
+
* from a click.
|
|
153
|
+
*/
|
|
129
154
|
request(call: ChipiRpcCall): Promise<unknown>;
|
|
130
155
|
/** Close the popup (if we own one) + reject in-flight requests. */
|
|
131
156
|
close(): void;
|
|
@@ -147,6 +172,10 @@ type ConnectorData = {
|
|
|
147
172
|
account?: string;
|
|
148
173
|
chainId?: bigint;
|
|
149
174
|
};
|
|
175
|
+
/** Mirrors starknet-react's `ConnectArgs` (not exported by every version). */
|
|
176
|
+
type ConnectArgs = {
|
|
177
|
+
chainIdHint?: bigint;
|
|
178
|
+
};
|
|
150
179
|
interface ChipiConnectorOptions {
|
|
151
180
|
/** Hosted wallet base URL. Defaults to `https://wallet.chipipay.com`. */
|
|
152
181
|
walletUrl?: string;
|
|
@@ -173,6 +202,7 @@ declare class ChipiConnector extends Connector {
|
|
|
173
202
|
private _account;
|
|
174
203
|
private _swo;
|
|
175
204
|
private _registration;
|
|
205
|
+
private readonly _autoRegister;
|
|
176
206
|
constructor(options?: ChipiConnectorOptions);
|
|
177
207
|
/**
|
|
178
208
|
* Announce this wallet to scanning dApps (`window.starknet_chipi` +
|
|
@@ -191,8 +221,18 @@ declare class ChipiConnector extends Connector {
|
|
|
191
221
|
ready(): Promise<boolean>;
|
|
192
222
|
/** Lazily build the postMessage-backed get-starknet window object. */
|
|
193
223
|
private swo;
|
|
194
|
-
|
|
224
|
+
/**
|
|
225
|
+
* Open the hosted wallet (call from a click: it opens a popup) and request
|
|
226
|
+
* the account. Chipi is mainnet-only: a `chainIdHint` other than SN_MAIN
|
|
227
|
+
* rejects before any popup opens.
|
|
228
|
+
*/
|
|
229
|
+
connect(args?: ConnectArgs): Promise<ConnectorData>;
|
|
195
230
|
disconnect(): Promise<void>;
|
|
231
|
+
/** Forward the wallet's account/network events as starknet-react events. */
|
|
232
|
+
private subscribe;
|
|
233
|
+
private unsubscribe;
|
|
234
|
+
private onAccountsChanged;
|
|
235
|
+
private onNetworkChanged;
|
|
196
236
|
private emitEvent;
|
|
197
237
|
account(provider: ProviderInterface): Promise<AccountInterface>;
|
|
198
238
|
chainId(): Promise<bigint>;
|
|
@@ -233,4 +273,100 @@ interface ChipiRegistration {
|
|
|
233
273
|
*/
|
|
234
274
|
declare function registerChipiWallet(wallet: StarknetWindowObject, target?: (Window & typeof globalThis) | undefined): ChipiRegistration;
|
|
235
275
|
|
|
236
|
-
|
|
276
|
+
/**
|
|
277
|
+
* Chipi as a Wallet Standard wallet with Starknet features
|
|
278
|
+
* (`WalletWithStarknetFeatures` from `@starknet-io/get-starknet-wallet-standard`),
|
|
279
|
+
* so dApps on get-starknet v5+/v6 discovery (`@starknet-io/get-starknet-discovery`,
|
|
280
|
+
* `@starknet-start/react`, anything that listens for
|
|
281
|
+
* `wallet-standard:register-wallet`) list "Chipi" without importing this
|
|
282
|
+
* package's connector.
|
|
283
|
+
*
|
|
284
|
+
* Backed by the same popup transport as {@link ChipiConnector}. The types
|
|
285
|
+
* below mirror the upstream interfaces structurally so this package keeps no
|
|
286
|
+
* runtime (or type) dependency on `@wallet-standard/*`.
|
|
287
|
+
*/
|
|
288
|
+
|
|
289
|
+
/** Wallet Standard chain id for Starknet mainnet: `starknet:` + hex of "SN_MAIN"
|
|
290
|
+
* (same as `WELL_KNOWN_STARKNET_CHAINS[0]` in get-starknet-wallet-standard). */
|
|
291
|
+
declare const CHIPI_STARKNET_MAINNET_CHAIN: "starknet:0x534e5f4d41494e";
|
|
292
|
+
/** `starknet:0x...` chain identifier. */
|
|
293
|
+
type ChipiStarknetChain = `starknet:0x${string}`;
|
|
294
|
+
/** Data-URI icon, as Wallet Standard requires. */
|
|
295
|
+
type ChipiWalletIcon = `data:image/${"svg+xml" | "webp" | "png" | "gif"};base64,${string}`;
|
|
296
|
+
/** Mirrors `@wallet-standard/base` `WalletAccount`. */
|
|
297
|
+
interface ChipiStandardWalletAccount {
|
|
298
|
+
readonly address: string;
|
|
299
|
+
readonly publicKey: Uint8Array;
|
|
300
|
+
readonly chains: readonly ChipiStarknetChain[];
|
|
301
|
+
readonly features: readonly `${string}:${string}`[];
|
|
302
|
+
}
|
|
303
|
+
/** Mirrors `@wallet-standard/features` `StandardEventsChangeProperties`. */
|
|
304
|
+
interface ChipiStandardChangeProperties {
|
|
305
|
+
readonly chains?: readonly ChipiStarknetChain[];
|
|
306
|
+
readonly accounts?: readonly ChipiStandardWalletAccount[];
|
|
307
|
+
}
|
|
308
|
+
/** Mirrors `StarknetFeatures` from `@starknet-io/get-starknet-wallet-standard`.
|
|
309
|
+
* (A type alias, not an interface, so it satisfies Wallet Standard's
|
|
310
|
+
* `IdentifierRecord` index signature.) */
|
|
311
|
+
type ChipiStandardWalletFeatures = {
|
|
312
|
+
readonly "starknet:walletApi": {
|
|
313
|
+
readonly version: "1.0.0";
|
|
314
|
+
readonly request: RequestFn;
|
|
315
|
+
readonly walletVersion: string;
|
|
316
|
+
readonly id: string;
|
|
317
|
+
};
|
|
318
|
+
readonly "standard:connect": {
|
|
319
|
+
readonly version: "1.0.0";
|
|
320
|
+
readonly connect: (input?: {
|
|
321
|
+
readonly silent?: boolean;
|
|
322
|
+
}) => Promise<{
|
|
323
|
+
readonly accounts: readonly ChipiStandardWalletAccount[];
|
|
324
|
+
}>;
|
|
325
|
+
};
|
|
326
|
+
readonly "standard:disconnect": {
|
|
327
|
+
readonly version: "1.0.0";
|
|
328
|
+
readonly disconnect: () => Promise<void>;
|
|
329
|
+
};
|
|
330
|
+
readonly "standard:events": {
|
|
331
|
+
readonly version: "1.0.0";
|
|
332
|
+
readonly on: <E extends "change">(event: E, listener: (properties: ChipiStandardChangeProperties) => void) => () => void;
|
|
333
|
+
};
|
|
334
|
+
};
|
|
335
|
+
/** Structurally a `WalletWithStarknetFeatures`. */
|
|
336
|
+
interface ChipiStandardWallet {
|
|
337
|
+
readonly version: "1.0.0";
|
|
338
|
+
readonly name: string;
|
|
339
|
+
readonly icon: ChipiWalletIcon;
|
|
340
|
+
readonly chains: readonly ChipiStarknetChain[];
|
|
341
|
+
readonly accounts: readonly ChipiStandardWalletAccount[];
|
|
342
|
+
readonly features: ChipiStandardWalletFeatures;
|
|
343
|
+
}
|
|
344
|
+
interface ChipiStandardWalletOptions {
|
|
345
|
+
/** Hosted wallet base URL. Defaults to `https://wallet.chipipay.com`. */
|
|
346
|
+
walletUrl?: string;
|
|
347
|
+
/** Display name. Defaults to `"Chipi"`. */
|
|
348
|
+
name?: string;
|
|
349
|
+
/** Data-URI icon. Defaults to the Chipi icon. */
|
|
350
|
+
icon?: ChipiWalletIcon;
|
|
351
|
+
/** Popup transport tuning (window name/features, timeouts). */
|
|
352
|
+
transport?: Omit<ChipiTransportOptions, "walletUrl" | "mode">;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Build the Chipi Wallet Standard wallet (without registering it). `connect`
|
|
356
|
+
* opens the popup, so dApps call it from a click; `connect({ silent: true })`
|
|
357
|
+
* never opens a popup and returns the current accounts (empty if not
|
|
358
|
+
* connected).
|
|
359
|
+
*/
|
|
360
|
+
declare function createChipiStandardWallet(options?: ChipiStandardWalletOptions): ChipiStandardWallet;
|
|
361
|
+
/**
|
|
362
|
+
* Register Chipi with every Wallet Standard app on the page: dispatches
|
|
363
|
+
* `wallet-standard:register-wallet` now and answers later
|
|
364
|
+
* `wallet-standard:app-ready` events (the `@wallet-standard/wallet`
|
|
365
|
+
* `registerWallet` protocol, implemented here without the dependency).
|
|
366
|
+
*
|
|
367
|
+
* Returns an unregister function that removes the listener and unregisters
|
|
368
|
+
* from every app that accepted the wallet. SSR-safe: a no-op without `window`.
|
|
369
|
+
*/
|
|
370
|
+
declare function registerChipiStandardWallet(options?: ChipiStandardWalletOptions, target?: (Window & typeof globalThis) | undefined): () => void;
|
|
371
|
+
|
|
372
|
+
export { CHIPI_STARKNET_MAINNET_CHAIN, CHIPI_WC, CHIPI_WINDOW_KEY, ChipiConnector, type ChipiConnectorOptions, type ChipiDappMessage, type ChipiEventMessage, ChipiPopupTransport, type ChipiReadyMessage, type ChipiRegistration, type ChipiRpcCall, type ChipiRpcRequestMessage, type ChipiRpcResultMessage, type ChipiStandardChangeProperties, type ChipiStandardWallet, type ChipiStandardWalletAccount, type ChipiStandardWalletFeatures, type ChipiStandardWalletOptions, type ChipiStarknetChain, type ChipiTransportErrorCode, type ChipiTransportOptions, type ChipiWalletIcon, type ChipiWalletMessage, chipi, createChipiStandardWallet, isChipiDappMessage, isChipiWalletMessage, registerChipiStandardWallet, registerChipiWallet };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Connector } from '@starknet-react/core';
|
|
2
|
-
import { WalletAccount } from 'starknet';
|
|
2
|
+
import { constants, WalletAccount } from 'starknet';
|
|
3
3
|
|
|
4
4
|
// src/connector.ts
|
|
5
5
|
|
|
@@ -13,6 +13,22 @@ function isChipiDappMessage(data) {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
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
|
+
}
|
|
16
32
|
function deferred() {
|
|
17
33
|
let resolve;
|
|
18
34
|
let reject;
|
|
@@ -37,18 +53,19 @@ var ChipiPopupTransport = class {
|
|
|
37
53
|
this.readyDeferred = null;
|
|
38
54
|
this.openPromise = null;
|
|
39
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;
|
|
40
59
|
this.onMessage = (e) => {
|
|
41
60
|
if (e.origin !== this.walletOrigin || !isChipiWalletMessage(e.data)) return;
|
|
42
|
-
if (this.target
|
|
61
|
+
if (!this.target || e.source !== this.target) return;
|
|
43
62
|
const msg = e.data;
|
|
44
63
|
if (msg.type === "ready") {
|
|
45
64
|
this.ready = true;
|
|
46
65
|
this.readyDeferred?.resolve();
|
|
47
66
|
this.readyDeferred = null;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
this.target.postMessage(p.message, this.walletOrigin);
|
|
51
|
-
}
|
|
67
|
+
for (const p of this.pending.values()) {
|
|
68
|
+
this.target.postMessage(p.message, this.walletOrigin);
|
|
52
69
|
}
|
|
53
70
|
return;
|
|
54
71
|
}
|
|
@@ -56,6 +73,7 @@ var ChipiPopupTransport = class {
|
|
|
56
73
|
const p = this.pending.get(msg.id);
|
|
57
74
|
if (!p) return;
|
|
58
75
|
this.pending.delete(msg.id);
|
|
76
|
+
if (p.timer) clearTimeout(p.timer);
|
|
59
77
|
if (msg.ok) p.resolve(msg.result);
|
|
60
78
|
else p.reject(Object.assign(new Error(msg.error.message), { code: msg.error.code }));
|
|
61
79
|
return;
|
|
@@ -114,9 +132,26 @@ var ChipiPopupTransport = class {
|
|
|
114
132
|
);
|
|
115
133
|
this.ownsTarget = true;
|
|
116
134
|
if (!this.target) throw Object.assign(new Error("Popup blocked"), { code: "popup_blocked" });
|
|
135
|
+
this.hadPopup = true;
|
|
117
136
|
}
|
|
137
|
+
const opened = this.target;
|
|
118
138
|
this.readyDeferred = deferred();
|
|
119
|
-
|
|
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;
|
|
120
155
|
}
|
|
121
156
|
async awaitReady() {
|
|
122
157
|
const timeoutMs = this.opts.openTimeoutMs ?? 18e4;
|
|
@@ -132,7 +167,10 @@ var ChipiPopupTransport = class {
|
|
|
132
167
|
}
|
|
133
168
|
/** Reject every in-flight request (popup closed / disconnected). */
|
|
134
169
|
rejectAllPending(message) {
|
|
135
|
-
for (const [, p] of this.pending)
|
|
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
|
+
}
|
|
136
174
|
this.pending.clear();
|
|
137
175
|
}
|
|
138
176
|
/** While requests are in flight, watch for the user closing the popup and
|
|
@@ -156,8 +194,22 @@ var ChipiPopupTransport = class {
|
|
|
156
194
|
this.closeWatch = null;
|
|
157
195
|
}
|
|
158
196
|
}
|
|
159
|
-
/**
|
|
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
|
+
*/
|
|
160
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
|
+
}
|
|
161
213
|
await this.open();
|
|
162
214
|
if (this.ownsTarget) this.target?.focus();
|
|
163
215
|
const id = randomId();
|
|
@@ -166,10 +218,24 @@ var ChipiPopupTransport = class {
|
|
|
166
218
|
type: "rpc",
|
|
167
219
|
id,
|
|
168
220
|
origin: window.location.origin,
|
|
169
|
-
call
|
|
221
|
+
call: stripUndefined(call)
|
|
170
222
|
};
|
|
223
|
+
const timeoutMs = this.opts.requestTimeoutMs ?? 12e4;
|
|
171
224
|
return new Promise((resolve, reject) => {
|
|
172
|
-
|
|
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);
|
|
173
239
|
this.target.postMessage(message, this.walletOrigin);
|
|
174
240
|
this.startCloseWatch();
|
|
175
241
|
});
|
|
@@ -177,12 +243,8 @@ var ChipiPopupTransport = class {
|
|
|
177
243
|
/** Close the popup (if we own one) + reject in-flight requests. */
|
|
178
244
|
close() {
|
|
179
245
|
this.stopCloseWatch();
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
} catch {
|
|
183
|
-
}
|
|
184
|
-
this.target = null;
|
|
185
|
-
this.ready = false;
|
|
246
|
+
this.readyDeferred?.reject(Object.assign(new Error("disconnected"), { code: 4001 }));
|
|
247
|
+
this.resetTarget();
|
|
186
248
|
this.rejectAllPending("disconnected");
|
|
187
249
|
if (this.listening && typeof window !== "undefined") {
|
|
188
250
|
window.removeEventListener("message", this.onMessage);
|
|
@@ -213,13 +275,46 @@ function registerChipiWallet(wallet, target = typeof window !== "undefined" ? wi
|
|
|
213
275
|
var CHIPI_ICON = "data:image/png;base64,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";
|
|
214
276
|
|
|
215
277
|
// src/connector.ts
|
|
216
|
-
var SN_MAIN = BigInt(
|
|
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
|
+
}
|
|
217
290
|
var ChipiConnector = class extends Connector {
|
|
218
291
|
constructor(options = {}) {
|
|
219
292
|
super();
|
|
220
293
|
this._account = null;
|
|
221
294
|
this._swo = null;
|
|
222
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
|
+
};
|
|
223
318
|
const walletUrl = options.walletUrl ?? options.transport?.walletUrl ?? "https://wallet.chipipay.com";
|
|
224
319
|
this.transport = new ChipiPopupTransport({
|
|
225
320
|
...options.transport,
|
|
@@ -230,7 +325,8 @@ var ChipiConnector = class extends Connector {
|
|
|
230
325
|
this._id = options.id ?? "chipi";
|
|
231
326
|
this._name = options.name ?? "Connect with Chipi";
|
|
232
327
|
this._icon = options.icon ?? CHIPI_ICON;
|
|
233
|
-
|
|
328
|
+
this._autoRegister = options.register !== false;
|
|
329
|
+
if (this._autoRegister) this.register();
|
|
234
330
|
}
|
|
235
331
|
/**
|
|
236
332
|
* Announce this wallet to scanning dApps (`window.starknet_chipi` +
|
|
@@ -284,7 +380,22 @@ var ChipiConnector = class extends Connector {
|
|
|
284
380
|
};
|
|
285
381
|
return this._swo;
|
|
286
382
|
}
|
|
287
|
-
|
|
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();
|
|
288
399
|
await this.transport.open();
|
|
289
400
|
const accounts = await this.transport.request({ type: "wallet_requestAccounts" });
|
|
290
401
|
const account = accounts?.[0];
|
|
@@ -295,16 +406,27 @@ var ChipiConnector = class extends Connector {
|
|
|
295
406
|
return data;
|
|
296
407
|
}
|
|
297
408
|
async disconnect() {
|
|
409
|
+
this.unsubscribe();
|
|
298
410
|
this.transport.close();
|
|
299
411
|
this._account = null;
|
|
412
|
+
this.unregister();
|
|
300
413
|
this._swo = null;
|
|
301
414
|
this.emitEvent("disconnect");
|
|
302
415
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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
|
+
}
|
|
306
426
|
emitEvent(event, data) {
|
|
307
|
-
this
|
|
427
|
+
const emitter = this;
|
|
428
|
+
if (data === void 0) emitter.emit(event);
|
|
429
|
+
else emitter.emit(event, data);
|
|
308
430
|
}
|
|
309
431
|
async account(provider) {
|
|
310
432
|
if (!this._account) throw new Error("chipi_not_connected");
|
|
@@ -323,6 +445,144 @@ function chipi(options) {
|
|
|
323
445
|
return new ChipiConnector(options);
|
|
324
446
|
}
|
|
325
447
|
|
|
326
|
-
|
|
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 };
|
|
327
587
|
//# sourceMappingURL=index.js.map
|
|
328
588
|
//# sourceMappingURL=index.js.map
|