@ckb-ccc/connector 0.0.5-alpha.1 → 0.0.5-alpha.10

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.
Files changed (45) hide show
  1. package/dist/assets/chains/ckb.sm.svg.d.ts +2 -0
  2. package/dist/assets/chains/ckb.sm.svg.d.ts.map +1 -0
  3. package/dist/assets/chains/ckb.sm.svg.js +2 -0
  4. package/dist/assets/copy.svg.d.ts +2 -0
  5. package/dist/assets/copy.svg.d.ts.map +1 -0
  6. package/dist/assets/copy.svg.js +2 -0
  7. package/dist/assets/diconnect.svg.d.ts +2 -0
  8. package/dist/assets/diconnect.svg.d.ts.map +1 -0
  9. package/dist/assets/diconnect.svg.js +2 -0
  10. package/dist/assets/swap.svg.d.ts +2 -0
  11. package/dist/assets/swap.svg.d.ts.map +1 -0
  12. package/dist/assets/swap.svg.js +2 -0
  13. package/dist/connector/index.d.ts +6 -2
  14. package/dist/connector/index.d.ts.map +1 -1
  15. package/dist/connector/index.js +276 -84
  16. package/dist/events/index.d.ts +3 -0
  17. package/dist/events/index.d.ts.map +1 -1
  18. package/dist/events/index.js +5 -0
  19. package/dist/scenes/connected.d.ts +4 -0
  20. package/dist/scenes/connected.d.ts.map +1 -0
  21. package/dist/scenes/connected.js +71 -0
  22. package/dist/scenes/connecting.d.ts +1 -1
  23. package/dist/scenes/connecting.d.ts.map +1 -1
  24. package/dist/scenes/connecting.js +9 -3
  25. package/dist/scenes/networks.d.ts +3 -0
  26. package/dist/scenes/networks.d.ts.map +1 -0
  27. package/dist/scenes/networks.js +38 -0
  28. package/dist/scenes/signers.d.ts.map +1 -1
  29. package/dist/scenes/signers.js +5 -2
  30. package/dist/scenes/wallets.d.ts +1 -1
  31. package/dist/scenes/wallets.d.ts.map +1 -1
  32. package/dist/scenes/wallets.js +9 -44
  33. package/package.json +3 -3
  34. package/src/assets/chains/ckb.sm.svg.ts +5 -0
  35. package/src/assets/copy.svg.ts +5 -0
  36. package/src/assets/diconnect.svg.ts +5 -0
  37. package/src/assets/swap.svg.ts +5 -0
  38. package/src/connector/index.ts +328 -108
  39. package/src/events/index.ts +6 -0
  40. package/src/scenes/connected.ts +87 -0
  41. package/src/scenes/connecting.ts +9 -2
  42. package/src/scenes/networks.ts +47 -0
  43. package/src/scenes/signers.ts +5 -2
  44. package/src/scenes/wallets.ts +20 -63
  45. package/dist.commonjs/tsconfig.commonjs.tsbuildinfo +0 -1
@@ -5,14 +5,17 @@ import { Ref, createRef, ref } from "lit/directives/ref.js";
5
5
  import { CLOSE_SVG } from "../assets/close.svg";
6
6
  import { JOY_ID_SVG } from "../assets/joy-id.svg";
7
7
  import { LEFT_SVG } from "../assets/left.svg";
8
+ import { METAMASK_SVG } from "../assets/metamask.svg";
8
9
  import { OKX_SVG } from "../assets/okx.svg";
9
10
  import { UNI_SAT_SVG } from "../assets/uni-sat.svg";
10
- import { WillUpdateEvent } from "../events";
11
+ import { ClosedEvent, WillUpdateEvent } from "../events";
11
12
  import {
12
13
  generateConnectingScene,
13
14
  generateSignersScene,
14
15
  generateWalletsScene,
15
16
  } from "../scenes";
17
+ import { generateConnectedScene } from "../scenes/connected";
18
+ import { generateNetworksScene } from "../scenes/networks";
16
19
  import { WalletWithSigners } from "../types";
17
20
 
18
21
  enum Scene {
@@ -20,21 +23,21 @@ enum Scene {
20
23
  SelectingSigners = "SelectingSigners",
21
24
  Connecting = "Connecting",
22
25
  Connected = "Connected",
26
+ SwitchingNetworks = "SwitchingNetworks",
23
27
  }
24
28
 
25
29
  @customElement("ccc-connector")
26
30
  export class WebComponentConnector extends LitElement {
27
31
  @state()
28
32
  private wallets: WalletWithSigners[] = [];
33
+ @property()
34
+ public signerFilter?: (
35
+ signerInfo: ccc.SignerInfo,
36
+ wallet: ccc.Wallet,
37
+ ) => Promise<boolean>;
29
38
 
30
39
  private resetListeners: (() => void)[] = [];
31
40
 
32
- @state()
33
- public isOpen: boolean = false;
34
- public setIsOpen(isOpen: boolean) {
35
- this.isOpen = isOpen;
36
- }
37
-
38
41
  @property()
39
42
  public name?: string;
40
43
  @property()
@@ -52,6 +55,8 @@ export class WebComponentConnector extends LitElement {
52
55
  private selectedWallet?: WalletWithSigners;
53
56
  @state()
54
57
  private selectedSigner?: ccc.SignerInfo;
58
+ @state()
59
+ private connectingError?: string;
55
60
 
56
61
  @state()
57
62
  private walletName?: string;
@@ -61,17 +66,34 @@ export class WebComponentConnector extends LitElement {
61
66
  public wallet?: ccc.Wallet;
62
67
  @state()
63
68
  public signer?: ccc.SignerInfo;
64
- private prepareSigner() {
65
- (async () => {
66
- if (this.signer && (await this.signer.signer.isConnected())) {
67
- this.scene = Scene.Connected;
68
- return;
69
- }
70
69
 
71
- this.wallet = undefined;
72
- this.signer = undefined;
73
- this.scene = Scene.SelectingWallets;
74
- })();
70
+ @state()
71
+ private recommendAddress?: string;
72
+ @state()
73
+ private internalAddress?: string;
74
+ @state()
75
+ private balance?: ccc.Num;
76
+
77
+ private async updateSignerInfo() {
78
+ const signer = this.signer?.signer;
79
+ if (!signer) {
80
+ return;
81
+ }
82
+ this.recommendAddress = await signer.getRecommendedAddress();
83
+ this.internalAddress = await signer.getInternalAddress();
84
+ this.balance = await signer.getBalance();
85
+ }
86
+
87
+ private async prepareSigner() {
88
+ if (this.signer && (await this.signer.signer.isConnected())) {
89
+ await this.updateSignerInfo();
90
+ this.scene = Scene.Connected;
91
+ return;
92
+ }
93
+
94
+ this.wallet = undefined;
95
+ this.signer = undefined;
96
+ this.scene = Scene.SelectingWallets;
75
97
  }
76
98
 
77
99
  public disconnect() {
@@ -79,6 +101,7 @@ export class WebComponentConnector extends LitElement {
79
101
  this.walletName = undefined;
80
102
  this.signerName = undefined;
81
103
  this.saveConnection();
104
+ this.closedHandler();
82
105
  }
83
106
 
84
107
  private loadConnection() {
@@ -110,23 +133,33 @@ export class WebComponentConnector extends LitElement {
110
133
  }
111
134
 
112
135
  willUpdate(changedProperties: PropertyValues): void {
113
- if (changedProperties.has("client")) {
114
- this.reloadSigners();
115
- }
116
136
  if (
117
- changedProperties.has("walletName") ||
118
- changedProperties.has("wallets")
137
+ changedProperties.has("client") ||
138
+ changedProperties.has("signerFilter")
119
139
  ) {
120
- this.wallet = this.wallets.find(({ name }) => name === this.walletName);
140
+ this.reloadSigners();
121
141
  }
122
142
  if (
123
- changedProperties.has("signerName") ||
124
- changedProperties.has("wallet")
143
+ (changedProperties.has("scene") && this.scene === Scene.Connected) ||
144
+ changedProperties.has("wallets") ||
145
+ changedProperties.has("walletName") ||
146
+ changedProperties.has("signerName")
125
147
  ) {
126
- const wallet = this.wallets.find(({ name }) => name === this.walletName);
127
- this.signer = wallet?.signers.find(
128
- ({ name }) => name === this.signerName,
129
- );
148
+ (async () => {
149
+ const wallet = this.wallets.find(
150
+ ({ name }) => name === this.walletName,
151
+ );
152
+ const signer = wallet?.signers.find(
153
+ ({ name }) => name === this.signerName,
154
+ );
155
+ if (signer && (await signer.signer.isConnected())) {
156
+ this.wallet = wallet;
157
+ this.signer = signer;
158
+ } else {
159
+ this.wallet = undefined;
160
+ this.signer = undefined;
161
+ }
162
+ })();
130
163
  }
131
164
  if (changedProperties.has("signer")) {
132
165
  this.prepareSigner();
@@ -139,13 +172,15 @@ export class WebComponentConnector extends LitElement {
139
172
  this.wallets = [];
140
173
 
141
174
  (async () => {
142
- if (!this.signer) {
175
+ const signer = this.signer;
176
+ if (!signer) {
143
177
  return;
144
178
  }
145
179
 
180
+ await signer.signer.replaceClient(this.client);
181
+
146
182
  this.signer = {
147
- ...this.signer,
148
- signer: await this.signer.signer.replaceClient(this.client),
183
+ ...signer,
149
184
  };
150
185
  })();
151
186
 
@@ -159,31 +194,19 @@ export class WebComponentConnector extends LitElement {
159
194
  (document.querySelector('link[rel="icon"]') as HTMLLinkElement).href;
160
195
 
161
196
  ccc.JoyId.getJoyIdSigners(this.client, name, icon).forEach(
162
- ({ signer, type, name }) => {
163
- this.addSigner("JoyID", name, JOY_ID_SVG, type, signer);
197
+ ({ signer, name }) => {
198
+ this.addSigner("JoyID", name, JOY_ID_SVG, signer);
164
199
  },
165
200
  );
166
201
 
167
202
  const uniSatSigner = ccc.UniSat.getUniSatSigner(this.client);
168
203
  if (uniSatSigner) {
169
- this.addSigner(
170
- "UniSat",
171
- "BTC",
172
- UNI_SAT_SVG,
173
- ccc.SignerType.BTC,
174
- uniSatSigner,
175
- );
204
+ this.addSigner("UniSat", "BTC", UNI_SAT_SVG, uniSatSigner);
176
205
  }
177
206
 
178
207
  const okxBitcoinSigner = ccc.Okx.getOKXBitcoinSigner(this.client);
179
208
  if (okxBitcoinSigner) {
180
- this.addSigner(
181
- "OKX Wallet",
182
- "BTC",
183
- OKX_SVG,
184
- ccc.SignerType.BTC,
185
- okxBitcoinSigner,
186
- );
209
+ this.addSigner("OKX Wallet", "BTC", OKX_SVG, okxBitcoinSigner);
187
210
  }
188
211
 
189
212
  const eip6963Manager = new ccc.Eip6963.SignerFactory(this.client);
@@ -193,20 +216,64 @@ export class WebComponentConnector extends LitElement {
193
216
  `${signer.detail.info.name}`,
194
217
  "EVM",
195
218
  signer.detail.info.icon,
196
- ccc.SignerType.EVM,
197
219
  signer,
198
220
  );
199
221
  }),
200
222
  );
223
+
224
+ // === Dummy signers ===
225
+ this.addSigner(
226
+ "MetaMask",
227
+ "EVM",
228
+ METAMASK_SVG,
229
+ new ccc.SignerOpenLink(
230
+ this.client,
231
+ ccc.SignerType.EVM,
232
+ `https://metamask.app.link/dapp/${window.location.href}`,
233
+ ),
234
+ );
235
+ [ccc.SignerType.EVM, ccc.SignerType.BTC].forEach((type) => {
236
+ this.addSigner(
237
+ "OKX Wallet",
238
+ type,
239
+ OKX_SVG,
240
+ new ccc.SignerOpenLink(
241
+ this.client,
242
+ type,
243
+ "https://www.okx.com/download?deeplink=" +
244
+ encodeURIComponent(
245
+ "okx://wallet/dapp/url?dappUrl=" +
246
+ encodeURIComponent(window.location.href),
247
+ ),
248
+ ),
249
+ );
250
+ });
251
+ this.addSigner(
252
+ "UniSat",
253
+ ccc.SignerType.BTC,
254
+ UNI_SAT_SVG,
255
+ new ccc.SignerOpenLink(
256
+ this.client,
257
+ ccc.SignerType.BTC,
258
+ "https://unisat.io/download",
259
+ ),
260
+ );
261
+ // ===
201
262
  }
202
263
 
203
- private addSigner(
264
+ private async addSigner(
204
265
  walletName: string,
205
266
  signerName: string,
206
267
  icon: string,
207
- type: ccc.SignerType,
208
268
  signer: ccc.Signer,
209
269
  ) {
270
+ const signerInfo = { name: signerName, signer };
271
+ if (
272
+ this.signerFilter &&
273
+ !(await this.signerFilter(signerInfo, { name: walletName, icon }))
274
+ ) {
275
+ return;
276
+ }
210
277
  let updated = false;
211
278
  const wallets = this.wallets.map((wallet) => {
212
279
  if (wallet.name !== walletName) {
@@ -214,9 +281,13 @@ export class WebComponentConnector extends LitElement {
214
281
  }
215
282
 
216
283
  updated = true;
284
+ const allSigners = [...wallet.signers, signerInfo];
285
+ const signers = allSigners.filter(
286
+ ({ signer }) => !(signer instanceof ccc.SignerDummy),
287
+ );
217
288
  return {
218
289
  ...wallet,
219
- signers: [...wallet.signers, { type, name: signerName, signer }],
290
+ signers: signers.length !== 0 ? signers : [signerInfo],
220
291
  };
221
292
  });
222
293
 
@@ -224,7 +295,7 @@ export class WebComponentConnector extends LitElement {
224
295
  wallets.push({
225
296
  name: walletName,
226
297
  icon,
227
- signers: [{ type, name: signerName, signer }],
298
+ signers: [signerInfo],
228
299
  });
229
300
  }
230
301
 
@@ -237,6 +308,25 @@ export class WebComponentConnector extends LitElement {
237
308
 
238
309
  render() {
239
310
  const [title, body] = (() => {
311
+ if (this.scene === Scene.Connected && this.wallet && this.signer) {
312
+ return generateConnectedScene(
313
+ this.wallet,
314
+ this.signer,
315
+ this.recommendAddress,
316
+ this.internalAddress,
317
+ this.balance,
318
+ this.disconnect.bind(this),
319
+ () => {
320
+ this.scene = Scene.SwitchingNetworks;
321
+ },
322
+ );
323
+ }
324
+ if (this.scene === Scene.SwitchingNetworks) {
325
+ return generateNetworksScene(this.client, (client) => {
326
+ this.setClient(client);
327
+ this.closedHandler();
328
+ });
329
+ }
240
330
  if (this.scene === Scene.SelectingWallets || !this.selectedWallet) {
241
331
  return generateWalletsScene(
242
332
  this.wallets,
@@ -256,57 +346,59 @@ export class WebComponentConnector extends LitElement {
256
346
  return generateConnectingScene(
257
347
  this.selectedWallet,
258
348
  this.selectedSigner,
349
+ this.connectingError,
259
350
  this.signerSelectedHandler,
260
351
  );
261
352
  })();
262
353
 
263
- const canBack = [Scene.SelectingSigners, Scene.Connecting].includes(
264
- this.scene,
265
- );
266
-
267
- return html`<style>
268
- :host {
269
- ${this.isOpen ? "" : "display: none;"}
270
- --background: #fff;
271
- --divider: #eee;
272
- --btn-primary: #f8f8f8;
273
- --btn-primary-hover: #efeeee;
274
- --btn-secondary: #ddd;
275
- color: #1e1e1e;
276
- --tip-color: #666;
354
+ const canBack = [
355
+ Scene.SelectingSigners,
356
+ Scene.Connecting,
357
+ Scene.SwitchingNetworks,
358
+ ].includes(this.scene);
359
+
360
+ return html` <div
361
+ class="background"
362
+ @click=${(event: Event) => {
363
+ if (event.target === event.currentTarget) {
364
+ this.closedHandler();
277
365
  }
278
- </style>
279
- <div
280
- class="background"
281
- @click=${(event: Event) => {
282
- if (event.target === event.currentTarget) {
283
- this.closedHandler();
284
- }
285
- }}
286
- >
287
- <div class="main" ${ref(this.mainRef)}>
288
- <div class="header text-bold fs-big" ${ref(this.headerRef)}>
289
- <img
290
- class="back ${canBack ? "active" : ""}"
291
- src=${LEFT_SVG}
292
- @click=${() => {
293
- if (this.scene === Scene.Connecting) {
294
- this.scene = Scene.SelectingSigners;
295
- } else if (this.scene === Scene.SelectingSigners) {
366
+ }}
367
+ >
368
+ <div class="main" ${ref(this.mainRef)}>
369
+ <div
370
+ class="header text-bold fs-lg ${title == null
371
+ ? ""
372
+ : "header-divider"}"
373
+ ${ref(this.headerRef)}
374
+ >
375
+ <img
376
+ class="back ${canBack ? "active" : ""}"
377
+ src=${LEFT_SVG}
378
+ @click=${() => {
379
+ if (this.scene === Scene.Connecting) {
380
+ if ((this.selectedWallet?.signers.length ?? 0) <= 1) {
296
381
  this.scene = Scene.SelectingWallets;
382
+ } else {
383
+ this.scene = Scene.SelectingSigners;
297
384
  }
298
- }}
299
- />
300
- ${title}
301
- <img
302
- class="close active"
303
- src=${CLOSE_SVG}
304
- @click=${this.closedHandler}
305
- />
306
- </div>
307
- <div class="body" ${ref(this.bodyRef)}>${body}</div>
385
+ } else if (this.scene === Scene.SelectingSigners) {
386
+ this.scene = Scene.SelectingWallets;
387
+ } else if (this.scene === Scene.SwitchingNetworks) {
388
+ this.scene = Scene.Connected;
389
+ }
390
+ }}
391
+ />
392
+ ${title}
393
+ <img
394
+ class="close active"
395
+ src=${CLOSE_SVG}
396
+ @click=${this.closedHandler}
397
+ />
308
398
  </div>
309
- </div>`;
399
+ <div class="body" ${ref(this.bodyRef)}>${body}</div>
400
+ </div>
401
+ </div>`;
310
402
  }
311
403
 
312
404
  updated() {
@@ -330,27 +422,49 @@ export class WebComponentConnector extends LitElement {
330
422
  this.scene = Scene.SelectingWallets;
331
423
  this.selectedSigner = undefined;
332
424
  this.selectedWallet = undefined;
425
+ } else if ([Scene.SwitchingNetworks].includes(this.scene)) {
426
+ this.scene = Scene.Connected;
333
427
  }
334
- this.isOpen = false;
428
+
429
+ this.dispatchEvent(new ClosedEvent());
335
430
  };
336
431
 
337
432
  private signerSelectedHandler = (
338
433
  wallet: WalletWithSigners,
339
- signer: ccc.SignerInfo,
434
+ signerInfo: ccc.SignerInfo,
340
435
  ) => {
341
436
  this.scene = Scene.Connecting;
437
+ this.connectingError = undefined;
342
438
  this.selectedWallet = wallet;
343
- this.selectedSigner = signer;
439
+ this.selectedSigner = signerInfo;
344
440
  (async () => {
345
- await signer.signer.connect();
346
- if (!(await signer.signer.isConnected())) {
441
+ const { signer } = signerInfo;
442
+ try {
443
+ await signer.connect();
444
+ } catch (error) {
445
+ if (typeof error === "object") {
446
+ const message = (error as { message: unknown })?.message;
447
+ if (typeof message === "string") {
448
+ this.connectingError = message;
449
+ } else {
450
+ this.connectingError = JSON.stringify(message);
451
+ }
452
+ return;
453
+ }
454
+
455
+ this.connectingError = JSON.stringify(error);
456
+ }
457
+ if (!(await signer.isConnected())) {
347
458
  return;
348
459
  }
349
460
  this.scene = Scene.Connected;
350
461
  this.walletName = wallet.name;
351
- this.signerName = signer.name;
462
+ this.signerName = signerInfo.name;
352
463
  this.saveConnection();
353
464
  this.closedHandler();
465
+ this.internalAddress = await signer.getInternalAddress();
466
+ this.recommendAddress = await signer.getRecommendedAddress();
467
+ this.balance = await signer.getBalance();
354
468
  })();
355
469
  };
356
470
 
@@ -381,9 +495,18 @@ export class WebComponentConnector extends LitElement {
381
495
  color: var(--tip-color);
382
496
  }
383
497
 
384
- .fs-big {
498
+ .fs-sm {
499
+ font-size: 0.8rem;
500
+ }
501
+ .fs-md {
502
+ font-size: 1rem;
503
+ }
504
+ .fs-lg {
385
505
  font-size: 1.2rem;
386
506
  }
507
+ .fs-xl {
508
+ font-size: 1.5rem;
509
+ }
387
510
 
388
511
  .mb-1 {
389
512
  margin-bottom: 0.7rem;
@@ -397,6 +520,18 @@ export class WebComponentConnector extends LitElement {
397
520
  .mt-2 {
398
521
  margin-top: 1rem;
399
522
  }
523
+ .ml-1 {
524
+ margin-left: 0.7rem;
525
+ }
526
+ .ml-2 {
527
+ margin-left: 1em;
528
+ }
529
+ .mr-1 {
530
+ margin-right: 0.7rem;
531
+ }
532
+ .mr-2 {
533
+ margin-right: 1rem;
534
+ }
400
535
 
401
536
  .background {
402
537
  width: 100%;
@@ -419,8 +554,13 @@ export class WebComponentConnector extends LitElement {
419
554
  display: flex;
420
555
  justify-content: space-between;
421
556
  align-items: center;
422
- padding: 1rem 1.3rem;
557
+ padding: 1rem 1.3rem 0.5rem;
558
+ }
559
+
560
+ .header-divider {
561
+ padding-bottom: 1rem;
423
562
  border-bottom: 1px solid var(--divider);
563
+ margin-bottom: 1rem;
424
564
  }
425
565
 
426
566
  .close,
@@ -438,7 +578,7 @@ export class WebComponentConnector extends LitElement {
438
578
  }
439
579
 
440
580
  .body {
441
- padding: 1.4rem 1.3rem;
581
+ padding: 0 1.3rem 1.4rem;
442
582
  min-width: 20rem;
443
583
  display: flex;
444
584
  flex-direction: column;
@@ -455,17 +595,21 @@ export class WebComponentConnector extends LitElement {
455
595
  border-radius: 0.4rem;
456
596
  transition: background 0.15s ease-in-out;
457
597
  }
458
-
459
598
  .btn-primary img {
460
599
  width: 2rem;
461
600
  height: 2rem;
462
601
  margin-right: 1rem;
463
602
  border-radius: 0.4rem;
464
603
  }
465
-
466
604
  .btn-primary:hover {
467
605
  background: var(--btn-primary-hover);
468
606
  }
607
+ .btn-primary:disabled {
608
+ cursor: not-allowed;
609
+ }
610
+ .btn-primary:disabled:hover {
611
+ background: var(--btn-primary);
612
+ }
469
613
 
470
614
  .btn-secondary {
471
615
  display: flex;
@@ -475,12 +619,20 @@ export class WebComponentConnector extends LitElement {
475
619
  border-radius: 9999px;
476
620
  transition: background 0.15s ease-in-out;
477
621
  }
478
-
479
622
  .btn-secondary img {
480
623
  width: 0.8rem;
481
624
  height: 0.8rem;
482
625
  margin-right: 0.5rem;
483
626
  }
627
+ .btn-secondary:hover {
628
+ background: var(--btn-secondary-hover);
629
+ }
630
+ .btn-secondary:disabled {
631
+ cursor: not-allowed;
632
+ }
633
+ .btn-secondary:disabled:hover {
634
+ background: var(--btn-secondary);
635
+ }
484
636
 
485
637
  .wallet-icon {
486
638
  width: 4rem;
@@ -494,5 +646,73 @@ export class WebComponentConnector extends LitElement {
494
646
  height: 5rem;
495
647
  border-radius: 1rem;
496
648
  }
649
+
650
+ .position-relative {
651
+ position: relative;
652
+ }
653
+ .position-absolute {
654
+ position: absolute;
655
+ }
656
+
657
+ .connected-type-icon {
658
+ position: absolute;
659
+ width: 1.5rem;
660
+ height: 1.5rem;
661
+ right: -0.5rem;
662
+ bottom: -0.5rem;
663
+ }
664
+
665
+ .text-center {
666
+ text-align: center;
667
+ }
668
+
669
+ .cursor-pointer {
670
+ cursor: pointer;
671
+ }
672
+
673
+ .flex {
674
+ display: flex;
675
+ }
676
+ .justify-center {
677
+ justify-content: center;
678
+ }
679
+ .justify-between {
680
+ justify-content: space-between;
681
+ }
682
+ .align-center {
683
+ align-items: center;
684
+ }
685
+
686
+ .switch-btn-container {
687
+ width: 100%;
688
+ padding: 1rem;
689
+ }
690
+
691
+ .switch-line {
692
+ flex: 1;
693
+ height: 1px;
694
+ background-color: var(--divider);
695
+ }
696
+
697
+ .switching-status-dot {
698
+ width: 0.5rem;
699
+ height: 0.5rem;
700
+ background: #0f0;
701
+ border-radius: 50%;
702
+ }
703
+
704
+ .copy-btn {
705
+ width: 1.5rem;
706
+ height: 1.5rem;
707
+ }
708
+
709
+ .copy-btn-sm {
710
+ width: 1rem;
711
+ height: 1rem;
712
+ }
713
+
714
+ .sm-chain-logo {
715
+ width: 1.125rem;
716
+ }
497
717
  `;
498
718
  }
@@ -3,3 +3,9 @@ export class WillUpdateEvent extends Event {
3
3
  super("willUpdate", { composed: true });
4
4
  }
5
5
  }
6
+
7
+ export class ClosedEvent extends Event {
8
+ constructor() {
9
+ super("closed", { composed: true });
10
+ }
11
+ }