@ckb-ccc/connector 0.0.4 → 0.0.5-alpha.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.
Files changed (38) hide show
  1. package/README.md +6 -0
  2. package/dist/assets/chains/ckb.svg.d.ts +2 -0
  3. package/dist/assets/chains/ckb.svg.d.ts.map +1 -0
  4. package/dist/assets/chains/ckb.svg.js +2 -0
  5. package/dist/assets/chains/index.d.ts +1 -0
  6. package/dist/assets/chains/index.d.ts.map +1 -1
  7. package/dist/assets/chains/index.js +1 -0
  8. package/dist/assets/joy-id.svg.d.ts +2 -0
  9. package/dist/assets/joy-id.svg.d.ts.map +1 -0
  10. package/dist/assets/joy-id.svg.js +2 -0
  11. package/dist/assets/metamask.svg.d.ts +2 -0
  12. package/dist/assets/metamask.svg.d.ts.map +1 -0
  13. package/dist/assets/metamask.svg.js +2 -0
  14. package/dist/connector/index.d.ts +4 -7
  15. package/dist/connector/index.d.ts.map +1 -1
  16. package/dist/connector/index.js +76 -68
  17. package/dist/scenes/connecting.d.ts +2 -1
  18. package/dist/scenes/connecting.d.ts.map +1 -1
  19. package/dist/scenes/signers.d.ts +1 -1
  20. package/dist/scenes/signers.d.ts.map +1 -1
  21. package/dist/scenes/signers.js +3 -2
  22. package/dist/scenes/wallets.d.ts +1 -1
  23. package/dist/scenes/wallets.d.ts.map +1 -1
  24. package/dist/scenes/wallets.js +44 -9
  25. package/dist/types/index.d.ts +5 -0
  26. package/dist/types/index.d.ts.map +1 -1
  27. package/package.json +3 -3
  28. package/src/assets/chains/ckb.svg.ts +5 -0
  29. package/src/assets/chains/index.ts +1 -0
  30. package/src/assets/joy-id.svg.ts +5 -0
  31. package/src/assets/metamask.svg.ts +5 -0
  32. package/src/connector/index.ts +90 -75
  33. package/src/scenes/connecting.ts +3 -2
  34. package/src/scenes/signers.ts +4 -3
  35. package/src/scenes/wallets.ts +68 -22
  36. package/src/types/index.ts +6 -0
  37. package/tsconfig.base.json +0 -21
  38. package/tsconfig.commonjs.json +0 -8
package/README.md CHANGED
@@ -1,3 +1,9 @@
1
+ <p align="center">
2
+ <a href="https://ckbccc-demo.vercel.app/">
3
+ <img alt="Logo" src="https://raw.githubusercontent.com/ckb-ecofund/ccc/master/assets/logo.svg" width="20%" />
4
+ </a>
5
+ </p>
6
+
1
7
  <h1 align="center" style="font-size: 48px;">
2
8
  CCC Connector
3
9
  </h1>
@@ -0,0 +1,2 @@
1
+ export declare const CKB_SVG: string;
2
+ //# sourceMappingURL=ckb.svg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ckb.svg.d.ts","sourceRoot":"","sources":["../../../src/assets/chains/ckb.svg.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,QAEnB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { encodeSvgToImgSrc } from "../utils";
2
+ export const CKB_SVG = encodeSvgToImgSrc('<svg width="668" height="666.66669" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"><polygon points="170.265,206.318 223.416,206.318 223.416,93.897 264.161,93.897 170.265,0 " transform="matrix(1.8256046,0,0,1.8256046,-166.4037,144.47964)" /><polygon points="324.79,112.422 284.046,112.422 377.941,206.318 377.941,0 324.79,0 " transform="matrix(1.8256046,0,0,1.8256046,-166.4037,144.47964)" /></svg>');
@@ -1,3 +1,4 @@
1
1
  export * from "./btc.svg";
2
+ export * from "./ckb.svg";
2
3
  export * from "./eth.svg";
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/assets/chains/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/assets/chains/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC"}
@@ -1,2 +1,3 @@
1
1
  export * from "./btc.svg";
2
+ export * from "./ckb.svg";
2
3
  export * from "./eth.svg";
@@ -0,0 +1,2 @@
1
+ export declare const JOY_ID_SVG: string;
2
+ //# sourceMappingURL=joy-id.svg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"joy-id.svg.d.ts","sourceRoot":"","sources":["../../src/assets/joy-id.svg.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,UAAU,QAEtB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { encodeSvgToImgSrc } from "./utils";
2
+ export const JOY_ID_SVG = encodeSvgToImgSrc('<svg xmlns="http://www.w3.org/2000/svg" width="420" height="420" viewBox="0 0 420 420" fill="none"><circle cx="210" cy="210" r="210" fill="#333333"/><path d="M271.127 204.419C279.096 204.419 285.555 197.959 285.555 189.991C285.555 182.022 279.096 175.562 271.127 175.562C263.159 175.562 256.699 182.022 256.699 189.991C256.699 197.959 263.159 204.419 271.127 204.419Z" fill="#8CDD00"/><path d="M173.995 175.562C166.773 175.562 160.91 181.425 160.91 188.648C160.91 195.87 166.773 201.733 173.995 201.733C181.218 201.733 187.081 195.87 187.081 188.648C187.064 181.425 181.218 175.562 173.995 175.562Z" fill="#8CDD00"/><path d="M213.43 164.836L198.969 233.586C197.626 240.006 191.878 244.657 185.327 244.657C181.086 244.657 177.139 242.757 174.47 239.465C172.39 236.894 171.342 233.734 171.391 230.491L145.27 237.238C146.383 244.084 149.2 250.618 153.687 256.203C161.434 265.816 172.963 271.335 185.311 271.335C204.407 271.335 221.111 257.775 225.041 239.089L240.665 164.852H213.43V164.836Z" fill="#C1C1C1"/><path d="M335.83 115.983C327.068 105.19 314.065 99 300.161 99H267.981L262.363 125.662H300.161C305.991 125.662 311.445 128.249 315.113 132.786C318.782 137.306 320.207 143.185 319.011 148.884L313.394 175.562H340.645L345.116 154.387C347.965 140.778 344.592 126.775 335.83 115.983Z" fill="#8CDD00"/><path d="M295.216 261.999C291.285 280.669 274.597 294.212 255.518 294.212H226.875L221.258 320.874H255.518C287.126 320.874 314.803 298.421 321.304 267.485L326.021 245.049H298.77L295.216 261.999Z" fill="#8CDD00"/><path d="M98.8061 152.39L93.9258 175.58H121.177L124.894 157.892C128.825 139.223 145.513 125.679 164.592 125.679H192.04L197.657 99.0176H164.592C132.985 99.0012 105.308 121.454 98.8061 152.39Z" fill="#8CDD00"/><path d="M104.998 287.072C101.33 282.552 99.9049 276.673 101.1 270.974L106.079 247.342L77.2555 254.777L74.9956 265.487C72.1296 279.097 75.5196 293.099 84.2813 303.891C93.0429 314.684 106.046 320.874 119.95 320.874H150.935L156.553 294.212H119.95C114.12 294.196 108.666 291.608 104.998 287.072Z" fill="#8CDD00"/></svg>');
@@ -0,0 +1,2 @@
1
+ export declare const METAMASK_SVG: string;
2
+ //# sourceMappingURL=metamask.svg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metamask.svg.d.ts","sourceRoot":"","sources":["../../src/assets/metamask.svg.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,QAExB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { encodeSvgToImgSrc } from "./utils";
2
+ export const METAMASK_SVG = encodeSvgToImgSrc(`<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" id="Layer_1" x="0" y="0" version="1.1" viewBox="0 0 318.6 318.6"><style>.st1,.st6{fill:#e4761b;stroke:#e4761b;stroke-linecap:round;stroke-linejoin:round}.st6{fill:#f6851b;stroke:#f6851b}</style><path fill="#e2761b" stroke="#e2761b" stroke-linecap="round" stroke-linejoin="round" d="m274.1 35.5-99.5 73.9L193 65.8z"/><path d="m44.4 35.5 98.7 74.6-17.5-44.3zm193.9 171.3-26.5 40.6 56.7 15.6 16.3-55.3zm-204.4.9L50.1 263l56.7-15.6-26.5-40.6z" class="st1"/><path d="m103.6 138.2-15.8 23.9 56.3 2.5-2-60.5zm111.3 0-39-34.8-1.3 61.2 56.2-2.5zM106.8 247.4l33.8-16.5-29.2-22.8zm71.1-16.5 33.9 16.5-4.7-39.3z" class="st1"/><path fill="#d7c1b3" stroke="#d7c1b3" stroke-linecap="round" stroke-linejoin="round" d="m211.8 247.4-33.9-16.5 2.7 22.1-.3 9.3zm-105 0 31.5 14.9-.2-9.3 2.5-22.1z"/><path fill="#233447" stroke="#233447" stroke-linecap="round" stroke-linejoin="round" d="m138.8 193.5-28.2-8.3 19.9-9.1zm40.9 0 8.3-17.4 20 9.1z"/><path fill="#cd6116" stroke="#cd6116" stroke-linecap="round" stroke-linejoin="round" d="m106.8 247.4 4.8-40.6-31.3.9zM207 206.8l4.8 40.6 26.5-39.7zm23.8-44.7-56.2 2.5 5.2 28.9 8.3-17.4 20 9.1zm-120.2 23.1 20-9.1 8.2 17.4 5.3-28.9-56.3-2.5z"/><path fill="#e4751f" stroke="#e4751f" stroke-linecap="round" stroke-linejoin="round" d="m87.8 162.1 23.6 46-.8-22.9zm120.3 23.1-1 22.9 23.7-46zm-64-20.6-5.3 28.9 6.6 34.1 1.5-44.9zm30.5 0-2.7 18 1.2 45 6.7-34.1z"/><path d="m179.8 193.5-6.7 34.1 4.8 3.3 29.2-22.8 1-22.9zm-69.2-8.3.8 22.9 29.2 22.8 4.8-3.3-6.6-34.1z" class="st6"/><path fill="#c0ad9e" stroke="#c0ad9e" stroke-linecap="round" stroke-linejoin="round" d="m180.3 262.3.3-9.3-2.5-2.2h-37.7l-2.3 2.2.2 9.3-31.5-14.9 11 9 22.3 15.5h38.3l22.4-15.5 11-9z"/><path fill="#161616" stroke="#161616" stroke-linecap="round" stroke-linejoin="round" d="m177.9 230.9-4.8-3.3h-27.7l-4.8 3.3-2.5 22.1 2.3-2.2h37.7l2.5 2.2z"/><path fill="#763d16" stroke="#763d16" stroke-linecap="round" stroke-linejoin="round" d="m278.3 114.2 8.5-40.8-12.7-37.9-96.2 71.4 37 31.3 52.3 15.3 11.6-13.5-5-3.6 8-7.3-6.2-4.8 8-6.1zM31.8 73.4l8.5 40.8-5.4 4 8 6.1-6.1 4.8 8 7.3-5 3.6 11.5 13.5 52.3-15.3 37-31.3-96.2-71.4z"/><path d="m267.2 153.5-52.3-15.3 15.9 23.9-23.7 46 31.2-.4h46.5zm-163.6-15.3-52.3 15.3-17.4 54.2h46.4l31.1.4-23.6-46zm71 26.4 3.3-57.7 15.2-41.1h-67.5l15 41.1 3.5 57.7 1.2 18.2.1 44.8h27.7l.2-44.8z" class="st6"/><script xmlns=""/></svg>`);
@@ -1,6 +1,5 @@
1
1
  import { ccc } from "@ckb-ccc/ccc";
2
2
  import { LitElement, PropertyValues } from "lit";
3
- import { WalletWithSigners } from "../types";
4
3
  export declare class WebComponentConnector extends LitElement {
5
4
  private wallets;
6
5
  private resetListeners;
@@ -8,15 +7,13 @@ export declare class WebComponentConnector extends LitElement {
8
7
  setIsOpen(isOpen: boolean): void;
9
8
  client: ccc.Client;
10
9
  setClient(client: ccc.Client): void;
11
- private walletName?;
12
- private signerType?;
10
+ private scene;
13
11
  private selectedWallet?;
14
- private updateWallet;
15
12
  private selectedSigner?;
16
- private updateSigner;
17
- wallet?: WalletWithSigners;
13
+ private walletName?;
14
+ private signerName?;
15
+ wallet?: ccc.Wallet;
18
16
  signer?: ccc.SignerInfo;
19
- private canConnect;
20
17
  private prepareSigner;
21
18
  disconnect(): void;
22
19
  private loadConnection;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/connector/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAa,MAAM,KAAK,CAAC;AAW5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,qBACa,qBAAsB,SAAQ,UAAU;IAEnD,OAAO,CAAC,OAAO,CAA2B;IAE1C,OAAO,CAAC,cAAc,CAAsB;IAGrC,MAAM,EAAE,OAAO,CAAS;IACxB,SAAS,CAAC,MAAM,EAAE,OAAO;IAKzB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAiC;IACnD,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM;IAKnC,OAAO,CAAC,UAAU,CAAC,CAAS;IAE5B,OAAO,CAAC,UAAU,CAAC,CAAiB;IAEpC,OAAO,CAAC,cAAc,CAAC,CAAoB;IAC3C,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,YAAY;IAMb,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAE3B,MAAM,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC;IAC/B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa;IAuBd,UAAU;IAQjB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,cAAc;IAUtB,iBAAiB,IAAI,IAAI;IAMzB,UAAU,CAAC,iBAAiB,EAAE,cAAc,GAAG,IAAI;IAuBnD,OAAO,CAAC,aAAa;IAoDrB,OAAO,CAAC,SAAS;IA8BjB,MAAM;IAsDN,OAAO,CAAC,aAAa,CAKnB;IAEF,OAAO,CAAC,qBAAqB,CAO3B;IAEF,MAAM,CAAC,MAAM,0BAqIX;CACH"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/connector/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAa,MAAM,KAAK,CAAC;AAqB5D,qBACa,qBAAsB,SAAQ,UAAU;IAEnD,OAAO,CAAC,OAAO,CAA2B;IAE1C,OAAO,CAAC,cAAc,CAAsB;IAGrC,MAAM,EAAE,OAAO,CAAS;IACxB,SAAS,CAAC,MAAM,EAAE,OAAO;IAKzB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAiC;IACnD,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM;IAKnC,OAAO,CAAC,KAAK,CAAiC;IAE9C,OAAO,CAAC,cAAc,CAAC,CAAoB;IAE3C,OAAO,CAAC,cAAc,CAAC,CAAiB;IAGxC,OAAO,CAAC,UAAU,CAAC,CAAS;IAE5B,OAAO,CAAC,UAAU,CAAC,CAAS;IAErB,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC;IAEpB,MAAM,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC;IAC/B,OAAO,CAAC,aAAa;IAad,UAAU;IAOjB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,cAAc;IAUtB,iBAAiB,IAAI,IAAI;IAMzB,UAAU,CAAC,iBAAiB,EAAE,cAAc,GAAG,IAAI;IA0BnD,OAAO,CAAC,aAAa;IAyDrB,OAAO,CAAC,SAAS;IA+BjB,MAAM;IAwDN,OAAO,CAAC,aAAa,CAanB;IAEF,OAAO,CAAC,qBAAqB,CAkB3B;IAEF,MAAM,CAAC,MAAM,0BAiIX;CACH"}
@@ -8,10 +8,18 @@ import { ccc } from "@ckb-ccc/ccc";
8
8
  import { LitElement, css, html } from "lit";
9
9
  import { customElement, property, state } from "lit/decorators.js";
10
10
  import { CLOSE_SVG } from "../assets/close.svg";
11
+ import { JOY_ID_SVG } from "../assets/joy-id.svg";
11
12
  import { OKX_SVG } from "../assets/okx.svg";
12
13
  import { UNI_SAT_SVG } from "../assets/uni-sat.svg";
13
14
  import { WillUpdateEvent } from "../events";
14
15
  import { generateConnectingScene, generateSignersScene, generateWalletsScene, } from "../scenes";
16
+ var Scene;
17
+ (function (Scene) {
18
+ Scene["SelectingWallets"] = "SelectingWallets";
19
+ Scene["SelectingSigners"] = "SelectingSigners";
20
+ Scene["Connecting"] = "Connecting";
21
+ Scene["Connected"] = "Connected";
22
+ })(Scene || (Scene = {}));
15
23
  let WebComponentConnector = class WebComponentConnector extends LitElement {
16
24
  constructor() {
17
25
  super(...arguments);
@@ -19,17 +27,34 @@ let WebComponentConnector = class WebComponentConnector extends LitElement {
19
27
  this.resetListeners = [];
20
28
  this.isOpen = false;
21
29
  this.client = new ccc.ClientPublicTestnet();
22
- this.canConnect = false;
30
+ this.scene = Scene.SelectingWallets;
23
31
  this.closedHandler = () => {
24
- if (this.signer === undefined) {
25
- this.disconnect();
32
+ if ([
33
+ Scene.SelectingSigners,
34
+ Scene.SelectingWallets,
35
+ Scene.Connecting,
36
+ ].includes(this.scene)) {
37
+ this.scene = Scene.SelectingWallets;
38
+ this.selectedSigner = undefined;
39
+ this.selectedWallet = undefined;
26
40
  }
27
41
  this.isOpen = false;
28
42
  };
29
43
  this.signerSelectedHandler = (wallet, signer) => {
30
- this.walletName = wallet?.name;
31
- this.signerType = signer?.type;
32
- this.canConnect = true;
44
+ this.scene = Scene.Connecting;
45
+ this.selectedWallet = wallet;
46
+ this.selectedSigner = signer;
47
+ (async () => {
48
+ await signer.signer.connect();
49
+ if (!(await signer.signer.isConnected())) {
50
+ return;
51
+ }
52
+ this.scene = Scene.Connected;
53
+ this.walletName = wallet.name;
54
+ this.signerName = signer.name;
55
+ this.saveConnection();
56
+ this.closedHandler();
57
+ })();
33
58
  };
34
59
  }
35
60
  setIsOpen(isOpen) {
@@ -38,47 +63,31 @@ let WebComponentConnector = class WebComponentConnector extends LitElement {
38
63
  setClient(client) {
39
64
  this.client = client;
40
65
  }
41
- updateWallet() {
42
- this.selectedWallet = this.wallets.find((wallet) => this.walletName === wallet.name);
43
- }
44
- updateSigner() {
45
- this.selectedSigner = this.selectedWallet?.signers.find(({ type }) => type === this.signerType);
46
- }
47
66
  prepareSigner() {
48
67
  (async () => {
49
- if (!this.selectedSigner) {
50
- this.wallet = undefined;
51
- this.signer = undefined;
68
+ if (this.signer && (await this.signer.signer.isConnected())) {
69
+ this.scene = Scene.Connected;
52
70
  return;
53
71
  }
54
- if (!(await this.selectedSigner.signer.isConnected())) {
55
- if (!this.canConnect) {
56
- this.disconnect();
57
- return;
58
- }
59
- await this.selectedSigner.signer.connect();
60
- }
61
- this.saveConnection();
62
- this.wallet = this.selectedWallet;
63
- this.signer = this.selectedSigner;
64
- this.closedHandler();
72
+ this.wallet = undefined;
73
+ this.signer = undefined;
74
+ this.scene = Scene.SelectingWallets;
65
75
  })();
66
76
  }
67
77
  disconnect() {
78
+ this.signer?.signer?.disconnect();
68
79
  this.walletName = undefined;
69
- this.wallet = undefined;
70
- this.signerType = undefined;
71
- this.signer = undefined;
80
+ this.signerName = undefined;
72
81
  this.saveConnection();
73
82
  }
74
83
  loadConnection() {
75
- const { signerType, walletName, } = JSON.parse(window.localStorage.getItem("ccc-connection-info") ?? "{}");
76
- this.signerType = signerType;
84
+ const { signerName, walletName, } = JSON.parse(window.localStorage.getItem("ccc-connection-info") ?? "{}");
85
+ this.signerName = signerName;
77
86
  this.walletName = walletName;
78
87
  }
79
88
  saveConnection() {
80
89
  window.localStorage.setItem("ccc-connection-info", JSON.stringify({
81
- signerType: this.signerType,
90
+ signerName: this.signerName,
82
91
  walletName: this.walletName,
83
92
  }));
84
93
  }
@@ -93,13 +102,14 @@ let WebComponentConnector = class WebComponentConnector extends LitElement {
93
102
  }
94
103
  if (changedProperties.has("walletName") ||
95
104
  changedProperties.has("wallets")) {
96
- this.updateWallet();
105
+ this.wallet = this.wallets.find(({ name }) => name === this.walletName);
97
106
  }
98
- if (changedProperties.has("signerType") ||
99
- changedProperties.has("selectedWallet")) {
100
- this.updateSigner();
107
+ if (changedProperties.has("signerName") ||
108
+ changedProperties.has("wallet")) {
109
+ const wallet = this.wallets.find(({ name }) => name === this.walletName);
110
+ this.signer = wallet?.signers.find(({ name }) => name === this.signerName);
101
111
  }
102
- if (changedProperties.has("selectedSigner")) {
112
+ if (changedProperties.has("signer")) {
103
113
  this.prepareSigner();
104
114
  }
105
115
  this.dispatchEvent(new WillUpdateEvent());
@@ -107,62 +117,62 @@ let WebComponentConnector = class WebComponentConnector extends LitElement {
107
117
  reloadSigners() {
108
118
  this.wallets = [];
109
119
  (async () => {
110
- if (!this.selectedSigner) {
120
+ if (!this.signer) {
111
121
  return;
112
122
  }
113
- const newSigner = await this.selectedSigner.signer.replaceClient(this.client);
114
- if (newSigner) {
115
- this.selectedSigner = {
116
- ...this.selectedSigner,
117
- signer: newSigner,
118
- };
119
- }
120
- else {
121
- this.disconnect();
122
- }
123
+ this.signer = {
124
+ ...this.signer,
125
+ signer: await this.signer.signer.replaceClient(this.client),
126
+ };
123
127
  })();
124
128
  this.resetListeners.forEach((listener) => listener());
125
129
  this.resetListeners = [];
130
+ ccc.JoyId.getJoyIdSigners(this.client).forEach(({ signer, type, name }) => {
131
+ this.addSigner("JoyID", name, JOY_ID_SVG, type, signer);
132
+ });
126
133
  const uniSatSigner = ccc.UniSat.getUniSatSigner(this.client);
127
134
  if (uniSatSigner) {
128
- this.addSigner("UniSat", UNI_SAT_SVG, ccc.SignerType.BTC, uniSatSigner);
135
+ this.addSigner("UniSat", "BTC", UNI_SAT_SVG, ccc.SignerType.BTC, uniSatSigner);
129
136
  }
130
137
  const okxBitcoinSigner = ccc.Okx.getOKXBitcoinSigner(this.client);
131
138
  if (okxBitcoinSigner) {
132
- this.addSigner("OKX Wallet", OKX_SVG, ccc.SignerType.BTC, okxBitcoinSigner);
139
+ this.addSigner("OKX Wallet", "BTC", OKX_SVG, ccc.SignerType.BTC, okxBitcoinSigner);
133
140
  }
134
141
  const eip6963Manager = new ccc.Eip6963.SignerFactory(this.client);
135
142
  this.resetListeners.push(eip6963Manager.subscribeSigners((signer) => {
136
- this.addSigner(`${signer.detail.info.name}`, signer.detail.info.icon, ccc.SignerType.EVM, signer);
143
+ this.addSigner(`${signer.detail.info.name}`, "EVM", signer.detail.info.icon, ccc.SignerType.EVM, signer);
137
144
  }));
138
145
  }
139
- addSigner(name, icon, type, signer) {
146
+ addSigner(walletName, signerName, icon, type, signer) {
140
147
  let updated = false;
141
148
  const wallets = this.wallets.map((wallet) => {
142
- if (wallet.name !== name) {
149
+ if (wallet.name !== walletName) {
143
150
  return wallet;
144
151
  }
145
152
  updated = true;
146
153
  return {
147
154
  ...wallet,
148
- signers: [...wallet.signers, { type, signer }],
155
+ signers: [...wallet.signers, { type, name: signerName, signer }],
149
156
  };
150
157
  });
151
158
  if (!updated) {
152
159
  wallets.push({
153
- name,
160
+ name: walletName,
154
161
  icon,
155
- signers: [{ type, signer }],
162
+ signers: [{ type, name: signerName, signer }],
156
163
  });
157
164
  }
158
165
  this.wallets = wallets;
159
166
  }
160
167
  render() {
161
168
  const [title, body] = (() => {
162
- if (!this.selectedWallet) {
163
- return generateWalletsScene(this.wallets, this.signerSelectedHandler, this.signerSelectedHandler);
169
+ if (this.scene === Scene.SelectingWallets || !this.selectedWallet) {
170
+ return generateWalletsScene(this.wallets, (wallet) => {
171
+ this.selectedWallet = wallet;
172
+ this.scene = Scene.SelectingSigners;
173
+ }, this.signerSelectedHandler);
164
174
  }
165
- if (!this.selectedSigner) {
175
+ if (this.scene === Scene.SelectingSigners || !this.selectedSigner) {
166
176
  return generateSignersScene(this.selectedWallet, this.signerSelectedHandler);
167
177
  }
168
178
  return generateConnectingScene(this.selectedWallet, this.selectedSigner, this.signerSelectedHandler);
@@ -175,7 +185,6 @@ let WebComponentConnector = class WebComponentConnector extends LitElement {
175
185
  --btn-primary: #f8f8f8;
176
186
  --btn-primary-hover: #efeeee;
177
187
  --btn-secondary: #ddd;
178
- --btn-icon: #e9e4de;
179
188
  color: #1e1e1e;
180
189
  --tip-color: #666;
181
190
  }
@@ -296,8 +305,6 @@ WebComponentConnector.styles = css `
296
305
  width: 2rem;
297
306
  height: 2rem;
298
307
  margin-right: 1rem;
299
- border-radius: 0.4rem;
300
- background: var(--btn-icon);
301
308
  }
302
309
 
303
310
  .btn-primary:hover {
@@ -323,8 +330,6 @@ WebComponentConnector.styles = css `
323
330
  width: 4rem;
324
331
  height: 4rem;
325
332
  margin-bottom: 0.5rem;
326
- border-radius: 0.8rem;
327
- background: var(--btn-icon);
328
333
  }
329
334
 
330
335
  .connecting-wallet-icon {
@@ -344,16 +349,19 @@ __decorate([
344
349
  ], WebComponentConnector.prototype, "client", void 0);
345
350
  __decorate([
346
351
  state()
347
- ], WebComponentConnector.prototype, "walletName", void 0);
348
- __decorate([
349
- state()
350
- ], WebComponentConnector.prototype, "signerType", void 0);
352
+ ], WebComponentConnector.prototype, "scene", void 0);
351
353
  __decorate([
352
354
  state()
353
355
  ], WebComponentConnector.prototype, "selectedWallet", void 0);
354
356
  __decorate([
355
357
  state()
356
358
  ], WebComponentConnector.prototype, "selectedSigner", void 0);
359
+ __decorate([
360
+ state()
361
+ ], WebComponentConnector.prototype, "walletName", void 0);
362
+ __decorate([
363
+ state()
364
+ ], WebComponentConnector.prototype, "signerName", void 0);
357
365
  __decorate([
358
366
  state()
359
367
  ], WebComponentConnector.prototype, "wallet", void 0);
@@ -1,3 +1,4 @@
1
1
  import { ccc } from "@ckb-ccc/ccc";
2
- export declare function generateConnectingScene(wallet: ccc.Wallet, signer: ccc.SignerInfo, onSignerSelected: (wallet: ccc.Wallet | undefined, signer: ccc.SignerInfo) => unknown): (string | import("lit").TemplateResult<1>)[];
2
+ import { WalletWithSigners } from "../types";
3
+ export declare function generateConnectingScene(wallet: WalletWithSigners, signer: ccc.SignerInfo, onSignerSelected: (wallet: WalletWithSigners, signer: ccc.SignerInfo) => unknown): (string | import("lit").TemplateResult<1>)[];
3
4
  //# sourceMappingURL=connecting.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connecting.d.ts","sourceRoot":"","sources":["../../src/scenes/connecting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAInC,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,GAAG,CAAC,MAAM,EAClB,MAAM,EAAE,GAAG,CAAC,UAAU,EACtB,gBAAgB,EAAE,CAChB,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,SAAS,EAC9B,MAAM,EAAE,GAAG,CAAC,UAAU,KACnB,OAAO,gDAqBb"}
1
+ {"version":3,"file":"connecting.d.ts","sourceRoot":"","sources":["../../src/scenes/connecting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,GAAG,CAAC,UAAU,EACtB,gBAAgB,EAAE,CAChB,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,GAAG,CAAC,UAAU,KACnB,OAAO,gDAqBb"}
@@ -1,5 +1,5 @@
1
1
  import { ccc } from "@ckb-ccc/ccc";
2
2
  import { WalletWithSigners } from "../types";
3
3
  export declare function signerTypeToIcon(type: ccc.SignerType): string;
4
- export declare function generateSignersScene(wallet: WalletWithSigners, onSignerSelected: (wallet: ccc.Wallet | undefined, signer: ccc.SignerInfo) => unknown): (string | import("lit").TemplateResult<1>)[];
4
+ export declare function generateSignersScene(wallet: WalletWithSigners, onSignerSelected: (wallet: WalletWithSigners, signer: ccc.SignerInfo) => unknown): (string | import("lit").TemplateResult<1>)[];
5
5
  //# sourceMappingURL=signers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"signers.d.ts","sourceRoot":"","sources":["../../src/scenes/signers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAInC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC,UAAU,GAAG,MAAM,CAK7D;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,iBAAiB,EACzB,gBAAgB,EAAE,CAChB,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,SAAS,EAC9B,MAAM,EAAE,GAAG,CAAC,UAAU,KACnB,OAAO,gDAyBb"}
1
+ {"version":3,"file":"signers.d.ts","sourceRoot":"","sources":["../../src/scenes/signers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAInC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC,UAAU,GAAG,MAAM,CAM7D;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,iBAAiB,EACzB,gBAAgB,EAAE,CAChB,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,GAAG,CAAC,UAAU,KACnB,OAAO,gDAyBb"}
@@ -1,11 +1,12 @@
1
1
  import { ccc } from "@ckb-ccc/ccc";
2
2
  import { html } from "lit";
3
3
  import { repeat } from "lit/directives/repeat.js";
4
- import { BTC_SVG, ETH_SVG } from "../assets/chains";
4
+ import { BTC_SVG, CKB_SVG, ETH_SVG } from "../assets/chains";
5
5
  export function signerTypeToIcon(type) {
6
6
  return {
7
7
  [ccc.SignerType.BTC]: BTC_SVG,
8
8
  [ccc.SignerType.EVM]: ETH_SVG,
9
+ [ccc.SignerType.CKB]: CKB_SVG,
9
10
  }[type];
10
11
  }
11
12
  export function generateSignersScene(wallet, onSignerSelected) {
@@ -22,7 +23,7 @@ export function generateSignersScene(wallet, onSignerSelected) {
22
23
  }}
23
24
  >
24
25
  <img src=${signerTypeToIcon(signer.type)} alt=${signer.type} />
25
- ${signer.type}
26
+ ${signer.name}
26
27
  </button>
27
28
  `)}
28
29
  `,
@@ -1,4 +1,4 @@
1
1
  import { ccc } from "@ckb-ccc/ccc";
2
2
  import { WalletWithSigners } from "../types";
3
- export declare function generateWalletsScene(wallets: WalletWithSigners[], onWalletSelected: (wallet: ccc.Wallet) => unknown, onSignerSelected: (wallet: ccc.Wallet, signer: ccc.SignerInfo) => unknown): unknown[];
3
+ export declare function generateWalletsScene(wallets: WalletWithSigners[], onWalletSelected: (wallet: WalletWithSigners) => unknown, onSignerSelected: (wallet: WalletWithSigners, signer: ccc.SignerInfo) => unknown): (string | import("lit").TemplateResult<1>)[];
4
4
  //# sourceMappingURL=wallets.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wallets.d.ts","sourceRoot":"","sources":["../../src/scenes/wallets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,iBAAiB,EAAE,EAC5B,gBAAgB,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,KAAK,OAAO,EACjD,gBAAgB,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,UAAU,KAAK,OAAO,aAwB1E"}
1
+ {"version":3,"file":"wallets.d.ts","sourceRoot":"","sources":["../../src/scenes/wallets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAMnC,OAAO,EAAc,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAEzD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,iBAAiB,EAAE,EAC5B,gBAAgB,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,OAAO,EACxD,gBAAgB,EAAE,CAChB,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,GAAG,CAAC,UAAU,KACnB,OAAO,gDAgEb"}
@@ -1,12 +1,45 @@
1
1
  import { html } from "lit";
2
2
  import { repeat } from "lit/directives/repeat.js";
3
+ import { METAMASK_SVG } from "../assets/metamask.svg";
4
+ import { OKX_SVG } from "../assets/okx.svg";
5
+ import { UNI_SAT_SVG } from "../assets/uni-sat.svg";
3
6
  export function generateWalletsScene(wallets, onWalletSelected, onSignerSelected) {
7
+ const recommendedWallets = [
8
+ {
9
+ name: "MetaMask",
10
+ icon: METAMASK_SVG,
11
+ downloadLink: `https://metamask.app.link/dapp/${window.location.href}`,
12
+ },
13
+ {
14
+ name: "OKX Wallet",
15
+ icon: OKX_SVG,
16
+ downloadLink: "https://www.okx.com/zh-hans/download",
17
+ },
18
+ {
19
+ name: "UniSat",
20
+ icon: UNI_SAT_SVG,
21
+ downloadLink: "https://unisat.io/",
22
+ },
23
+ ];
24
+ const missingWallets = recommendedWallets.filter((recommendedWallet) => !wallets.some((wallet) => wallet.name === recommendedWallet.name));
25
+ const additionalButtons = missingWallets.map((wallet) => html `
26
+ <button
27
+ class="btn-primary mb-1"
28
+ @click=${() => {
29
+ window.open(wallet.downloadLink, "_blank");
30
+ }}
31
+ >
32
+ <img src=${wallet.icon} alt=${wallet.name} />
33
+ ${wallet.name}
34
+ </button>
35
+ `);
4
36
  return [
5
37
  "Connect Wallet",
6
- repeat(wallets, (wallet) => wallet.name, (wallet) => html `
7
- <button
8
- class="btn-primary mb-1"
9
- @click=${async () => {
38
+ html `
39
+ ${repeat(wallets, (wallet) => wallet.name, (wallet) => html `
40
+ <button
41
+ class="btn-primary mb-1"
42
+ @click=${async () => {
10
43
  if (wallet.signers.length === 1) {
11
44
  onSignerSelected(wallet, wallet.signers[0]);
12
45
  }
@@ -14,10 +47,12 @@ export function generateWalletsScene(wallets, onWalletSelected, onSignerSelected
14
47
  onWalletSelected(wallet);
15
48
  }
16
49
  }}
17
- >
18
- <img src=${wallet.icon} alt=${wallet.name} />
19
- ${wallet.name}
20
- </button>
21
- `),
50
+ >
51
+ <img src=${wallet.icon} alt=${wallet.name} />
52
+ ${wallet.name}
53
+ </button>
54
+ `)}
55
+ ${additionalButtons}
56
+ `,
22
57
  ];
23
58
  }
@@ -2,4 +2,9 @@ import { ccc } from "@ckb-ccc/ccc";
2
2
  export type WalletWithSigners = ccc.Wallet & {
3
3
  signers: ccc.SignerInfo[];
4
4
  };
5
+ export interface WalletInfo {
6
+ name: string;
7
+ icon: string;
8
+ downloadLink: string;
9
+ }
5
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEnC,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,GAAG;IAC3C,OAAO,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC;CAC3B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEnC,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,GAAG;IAC3C,OAAO,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckb-ccc/connector",
3
- "version": "0.0.4",
3
+ "version": "0.0.5-alpha.0",
4
4
  "description": "Common Chains Connector UI",
5
5
  "author": "Hanssen0 <hanssen0@hanssen0.com>",
6
6
  "license": "MIT",
@@ -37,8 +37,8 @@
37
37
  "access": "public"
38
38
  },
39
39
  "dependencies": {
40
- "@ckb-ccc/ccc": "0.0.4",
40
+ "@ckb-ccc/ccc": "0.0.5-alpha.0",
41
41
  "lit": "^3.1.3"
42
42
  },
43
- "gitHead": "76485b6b76ce3c97d5acebd42decbafd546aa433"
43
+ "gitHead": "8a927f901a8f2fe7dfe2f6bf78a44689d6503949"
44
44
  }
@@ -0,0 +1,5 @@
1
+ import { encodeSvgToImgSrc } from "../utils";
2
+
3
+ export const CKB_SVG = encodeSvgToImgSrc(
4
+ '<svg width="668" height="666.66669" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"><polygon points="170.265,206.318 223.416,206.318 223.416,93.897 264.161,93.897 170.265,0 " transform="matrix(1.8256046,0,0,1.8256046,-166.4037,144.47964)" /><polygon points="324.79,112.422 284.046,112.422 377.941,206.318 377.941,0 324.79,0 " transform="matrix(1.8256046,0,0,1.8256046,-166.4037,144.47964)" /></svg>',
5
+ );
@@ -1,2 +1,3 @@
1
1
  export * from "./btc.svg";
2
+ export * from "./ckb.svg";
2
3
  export * from "./eth.svg";
@@ -0,0 +1,5 @@
1
+ import { encodeSvgToImgSrc } from "./utils";
2
+
3
+ export const JOY_ID_SVG = encodeSvgToImgSrc(
4
+ '<svg xmlns="http://www.w3.org/2000/svg" width="420" height="420" viewBox="0 0 420 420" fill="none"><circle cx="210" cy="210" r="210" fill="#333333"/><path d="M271.127 204.419C279.096 204.419 285.555 197.959 285.555 189.991C285.555 182.022 279.096 175.562 271.127 175.562C263.159 175.562 256.699 182.022 256.699 189.991C256.699 197.959 263.159 204.419 271.127 204.419Z" fill="#8CDD00"/><path d="M173.995 175.562C166.773 175.562 160.91 181.425 160.91 188.648C160.91 195.87 166.773 201.733 173.995 201.733C181.218 201.733 187.081 195.87 187.081 188.648C187.064 181.425 181.218 175.562 173.995 175.562Z" fill="#8CDD00"/><path d="M213.43 164.836L198.969 233.586C197.626 240.006 191.878 244.657 185.327 244.657C181.086 244.657 177.139 242.757 174.47 239.465C172.39 236.894 171.342 233.734 171.391 230.491L145.27 237.238C146.383 244.084 149.2 250.618 153.687 256.203C161.434 265.816 172.963 271.335 185.311 271.335C204.407 271.335 221.111 257.775 225.041 239.089L240.665 164.852H213.43V164.836Z" fill="#C1C1C1"/><path d="M335.83 115.983C327.068 105.19 314.065 99 300.161 99H267.981L262.363 125.662H300.161C305.991 125.662 311.445 128.249 315.113 132.786C318.782 137.306 320.207 143.185 319.011 148.884L313.394 175.562H340.645L345.116 154.387C347.965 140.778 344.592 126.775 335.83 115.983Z" fill="#8CDD00"/><path d="M295.216 261.999C291.285 280.669 274.597 294.212 255.518 294.212H226.875L221.258 320.874H255.518C287.126 320.874 314.803 298.421 321.304 267.485L326.021 245.049H298.77L295.216 261.999Z" fill="#8CDD00"/><path d="M98.8061 152.39L93.9258 175.58H121.177L124.894 157.892C128.825 139.223 145.513 125.679 164.592 125.679H192.04L197.657 99.0176H164.592C132.985 99.0012 105.308 121.454 98.8061 152.39Z" fill="#8CDD00"/><path d="M104.998 287.072C101.33 282.552 99.9049 276.673 101.1 270.974L106.079 247.342L77.2555 254.777L74.9956 265.487C72.1296 279.097 75.5196 293.099 84.2813 303.891C93.0429 314.684 106.046 320.874 119.95 320.874H150.935L156.553 294.212H119.95C114.12 294.196 108.666 291.608 104.998 287.072Z" fill="#8CDD00"/></svg>',
5
+ );
@@ -0,0 +1,5 @@
1
+ import { encodeSvgToImgSrc } from "./utils";
2
+
3
+ export const METAMASK_SVG = encodeSvgToImgSrc(
4
+ `<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" id="Layer_1" x="0" y="0" version="1.1" viewBox="0 0 318.6 318.6"><style>.st1,.st6{fill:#e4761b;stroke:#e4761b;stroke-linecap:round;stroke-linejoin:round}.st6{fill:#f6851b;stroke:#f6851b}</style><path fill="#e2761b" stroke="#e2761b" stroke-linecap="round" stroke-linejoin="round" d="m274.1 35.5-99.5 73.9L193 65.8z"/><path d="m44.4 35.5 98.7 74.6-17.5-44.3zm193.9 171.3-26.5 40.6 56.7 15.6 16.3-55.3zm-204.4.9L50.1 263l56.7-15.6-26.5-40.6z" class="st1"/><path d="m103.6 138.2-15.8 23.9 56.3 2.5-2-60.5zm111.3 0-39-34.8-1.3 61.2 56.2-2.5zM106.8 247.4l33.8-16.5-29.2-22.8zm71.1-16.5 33.9 16.5-4.7-39.3z" class="st1"/><path fill="#d7c1b3" stroke="#d7c1b3" stroke-linecap="round" stroke-linejoin="round" d="m211.8 247.4-33.9-16.5 2.7 22.1-.3 9.3zm-105 0 31.5 14.9-.2-9.3 2.5-22.1z"/><path fill="#233447" stroke="#233447" stroke-linecap="round" stroke-linejoin="round" d="m138.8 193.5-28.2-8.3 19.9-9.1zm40.9 0 8.3-17.4 20 9.1z"/><path fill="#cd6116" stroke="#cd6116" stroke-linecap="round" stroke-linejoin="round" d="m106.8 247.4 4.8-40.6-31.3.9zM207 206.8l4.8 40.6 26.5-39.7zm23.8-44.7-56.2 2.5 5.2 28.9 8.3-17.4 20 9.1zm-120.2 23.1 20-9.1 8.2 17.4 5.3-28.9-56.3-2.5z"/><path fill="#e4751f" stroke="#e4751f" stroke-linecap="round" stroke-linejoin="round" d="m87.8 162.1 23.6 46-.8-22.9zm120.3 23.1-1 22.9 23.7-46zm-64-20.6-5.3 28.9 6.6 34.1 1.5-44.9zm30.5 0-2.7 18 1.2 45 6.7-34.1z"/><path d="m179.8 193.5-6.7 34.1 4.8 3.3 29.2-22.8 1-22.9zm-69.2-8.3.8 22.9 29.2 22.8 4.8-3.3-6.6-34.1z" class="st6"/><path fill="#c0ad9e" stroke="#c0ad9e" stroke-linecap="round" stroke-linejoin="round" d="m180.3 262.3.3-9.3-2.5-2.2h-37.7l-2.3 2.2.2 9.3-31.5-14.9 11 9 22.3 15.5h38.3l22.4-15.5 11-9z"/><path fill="#161616" stroke="#161616" stroke-linecap="round" stroke-linejoin="round" d="m177.9 230.9-4.8-3.3h-27.7l-4.8 3.3-2.5 22.1 2.3-2.2h37.7l2.5 2.2z"/><path fill="#763d16" stroke="#763d16" stroke-linecap="round" stroke-linejoin="round" d="m278.3 114.2 8.5-40.8-12.7-37.9-96.2 71.4 37 31.3 52.3 15.3 11.6-13.5-5-3.6 8-7.3-6.2-4.8 8-6.1zM31.8 73.4l8.5 40.8-5.4 4 8 6.1-6.1 4.8 8 7.3-5 3.6 11.5 13.5 52.3-15.3 37-31.3-96.2-71.4z"/><path d="m267.2 153.5-52.3-15.3 15.9 23.9-23.7 46 31.2-.4h46.5zm-163.6-15.3-52.3 15.3-17.4 54.2h46.4l31.1.4-23.6-46zm71 26.4 3.3-57.7 15.2-41.1h-67.5l15 41.1 3.5 57.7 1.2 18.2.1 44.8h27.7l.2-44.8z" class="st6"/><script xmlns=""/></svg>`,
5
+ );
@@ -2,6 +2,7 @@ import { ccc } from "@ckb-ccc/ccc";
2
2
  import { LitElement, PropertyValues, css, html } from "lit";
3
3
  import { customElement, property, state } from "lit/decorators.js";
4
4
  import { CLOSE_SVG } from "../assets/close.svg";
5
+ import { JOY_ID_SVG } from "../assets/joy-id.svg";
5
6
  import { OKX_SVG } from "../assets/okx.svg";
6
7
  import { UNI_SAT_SVG } from "../assets/uni-sat.svg";
7
8
  import { WillUpdateEvent } from "../events";
@@ -12,6 +13,13 @@ import {
12
13
  } from "../scenes";
13
14
  import { WalletWithSigners } from "../types";
14
15
 
16
+ enum Scene {
17
+ SelectingWallets = "SelectingWallets",
18
+ SelectingSigners = "SelectingSigners",
19
+ Connecting = "Connecting",
20
+ Connected = "Connected",
21
+ }
22
+
15
23
  @customElement("ccc-connector")
16
24
  export class WebComponentConnector extends LitElement {
17
25
  @state()
@@ -32,68 +40,49 @@ export class WebComponentConnector extends LitElement {
32
40
  }
33
41
 
34
42
  @state()
35
- private walletName?: string;
36
- @state()
37
- private signerType?: ccc.SignerType;
43
+ private scene: Scene = Scene.SelectingWallets;
38
44
  @state()
39
45
  private selectedWallet?: WalletWithSigners;
40
- private updateWallet() {
41
- this.selectedWallet = this.wallets.find(
42
- (wallet) => this.walletName === wallet.name,
43
- );
44
- }
45
46
  @state()
46
47
  private selectedSigner?: ccc.SignerInfo;
47
- private updateSigner() {
48
- this.selectedSigner = this.selectedWallet?.signers.find(
49
- ({ type }) => type === this.signerType,
50
- );
51
- }
48
+
52
49
  @state()
53
- public wallet?: WalletWithSigners;
50
+ private walletName?: string;
51
+ @state()
52
+ private signerName?: string;
53
+ @state()
54
+ public wallet?: ccc.Wallet;
54
55
  @state()
55
56
  public signer?: ccc.SignerInfo;
56
- private canConnect = false;
57
57
  private prepareSigner() {
58
58
  (async () => {
59
- if (!this.selectedSigner) {
60
- this.wallet = undefined;
61
- this.signer = undefined;
59
+ if (this.signer && (await this.signer.signer.isConnected())) {
60
+ this.scene = Scene.Connected;
62
61
  return;
63
62
  }
64
63
 
65
- if (!(await this.selectedSigner.signer.isConnected())) {
66
- if (!this.canConnect) {
67
- this.disconnect();
68
- return;
69
- }
70
- await this.selectedSigner.signer.connect();
71
- }
72
-
73
- this.saveConnection();
74
- this.wallet = this.selectedWallet;
75
- this.signer = this.selectedSigner;
76
- this.closedHandler();
64
+ this.wallet = undefined;
65
+ this.signer = undefined;
66
+ this.scene = Scene.SelectingWallets;
77
67
  })();
78
68
  }
79
69
 
80
70
  public disconnect() {
71
+ this.signer?.signer?.disconnect();
81
72
  this.walletName = undefined;
82
- this.wallet = undefined;
83
- this.signerType = undefined;
84
- this.signer = undefined;
73
+ this.signerName = undefined;
85
74
  this.saveConnection();
86
75
  }
87
76
 
88
77
  private loadConnection() {
89
78
  const {
90
- signerType,
79
+ signerName,
91
80
  walletName,
92
- }: { signerType?: ccc.SignerType; walletName?: string } = JSON.parse(
81
+ }: { signerName?: string; walletName?: string } = JSON.parse(
93
82
  window.localStorage.getItem("ccc-connection-info") ?? "{}",
94
83
  );
95
84
 
96
- this.signerType = signerType;
85
+ this.signerName = signerName;
97
86
  this.walletName = walletName;
98
87
  }
99
88
 
@@ -101,7 +90,7 @@ export class WebComponentConnector extends LitElement {
101
90
  window.localStorage.setItem(
102
91
  "ccc-connection-info",
103
92
  JSON.stringify({
104
- signerType: this.signerType,
93
+ signerName: this.signerName,
105
94
  walletName: this.walletName,
106
95
  }),
107
96
  );
@@ -121,15 +110,18 @@ export class WebComponentConnector extends LitElement {
121
110
  changedProperties.has("walletName") ||
122
111
  changedProperties.has("wallets")
123
112
  ) {
124
- this.updateWallet();
113
+ this.wallet = this.wallets.find(({ name }) => name === this.walletName);
125
114
  }
126
115
  if (
127
- changedProperties.has("signerType") ||
128
- changedProperties.has("selectedWallet")
116
+ changedProperties.has("signerName") ||
117
+ changedProperties.has("wallet")
129
118
  ) {
130
- this.updateSigner();
119
+ const wallet = this.wallets.find(({ name }) => name === this.walletName);
120
+ this.signer = wallet?.signers.find(
121
+ ({ name }) => name === this.signerName,
122
+ );
131
123
  }
132
- if (changedProperties.has("selectedSigner")) {
124
+ if (changedProperties.has("signer")) {
133
125
  this.prepareSigner();
134
126
  }
135
127
 
@@ -140,35 +132,39 @@ export class WebComponentConnector extends LitElement {
140
132
  this.wallets = [];
141
133
 
142
134
  (async () => {
143
- if (!this.selectedSigner) {
135
+ if (!this.signer) {
144
136
  return;
145
137
  }
146
138
 
147
- const newSigner = await this.selectedSigner.signer.replaceClient(
148
- this.client,
149
- );
150
- if (newSigner) {
151
- this.selectedSigner = {
152
- ...this.selectedSigner,
153
- signer: newSigner,
154
- };
155
- } else {
156
- this.disconnect();
157
- }
139
+ this.signer = {
140
+ ...this.signer,
141
+ signer: await this.signer.signer.replaceClient(this.client),
142
+ };
158
143
  })();
159
144
 
160
145
  this.resetListeners.forEach((listener) => listener());
161
146
  this.resetListeners = [];
162
147
 
148
+ ccc.JoyId.getJoyIdSigners(this.client).forEach(({ signer, type, name }) => {
149
+ this.addSigner("JoyID", name, JOY_ID_SVG, type, signer);
150
+ });
151
+
163
152
  const uniSatSigner = ccc.UniSat.getUniSatSigner(this.client);
164
153
  if (uniSatSigner) {
165
- this.addSigner("UniSat", UNI_SAT_SVG, ccc.SignerType.BTC, uniSatSigner);
154
+ this.addSigner(
155
+ "UniSat",
156
+ "BTC",
157
+ UNI_SAT_SVG,
158
+ ccc.SignerType.BTC,
159
+ uniSatSigner,
160
+ );
166
161
  }
167
162
 
168
163
  const okxBitcoinSigner = ccc.Okx.getOKXBitcoinSigner(this.client);
169
164
  if (okxBitcoinSigner) {
170
165
  this.addSigner(
171
166
  "OKX Wallet",
167
+ "BTC",
172
168
  OKX_SVG,
173
169
  ccc.SignerType.BTC,
174
170
  okxBitcoinSigner,
@@ -180,6 +176,7 @@ export class WebComponentConnector extends LitElement {
180
176
  eip6963Manager.subscribeSigners((signer) => {
181
177
  this.addSigner(
182
178
  `${signer.detail.info.name}`,
179
+ "EVM",
183
180
  signer.detail.info.icon,
184
181
  ccc.SignerType.EVM,
185
182
  signer,
@@ -189,29 +186,30 @@ export class WebComponentConnector extends LitElement {
189
186
  }
190
187
 
191
188
  private addSigner(
192
- name: string,
189
+ walletName: string,
190
+ signerName: string,
193
191
  icon: string,
194
192
  type: ccc.SignerType,
195
193
  signer: ccc.Signer,
196
194
  ) {
197
195
  let updated = false;
198
196
  const wallets = this.wallets.map((wallet) => {
199
- if (wallet.name !== name) {
197
+ if (wallet.name !== walletName) {
200
198
  return wallet;
201
199
  }
202
200
 
203
201
  updated = true;
204
202
  return {
205
203
  ...wallet,
206
- signers: [...wallet.signers, { type, signer }],
204
+ signers: [...wallet.signers, { type, name: signerName, signer }],
207
205
  };
208
206
  });
209
207
 
210
208
  if (!updated) {
211
209
  wallets.push({
212
- name,
210
+ name: walletName,
213
211
  icon,
214
- signers: [{ type, signer }],
212
+ signers: [{ type, name: signerName, signer }],
215
213
  });
216
214
  }
217
215
 
@@ -220,14 +218,17 @@ export class WebComponentConnector extends LitElement {
220
218
 
221
219
  render() {
222
220
  const [title, body] = (() => {
223
- if (!this.selectedWallet) {
221
+ if (this.scene === Scene.SelectingWallets || !this.selectedWallet) {
224
222
  return generateWalletsScene(
225
223
  this.wallets,
226
- this.signerSelectedHandler,
224
+ (wallet) => {
225
+ this.selectedWallet = wallet;
226
+ this.scene = Scene.SelectingSigners;
227
+ },
227
228
  this.signerSelectedHandler,
228
229
  );
229
230
  }
230
- if (!this.selectedSigner) {
231
+ if (this.scene === Scene.SelectingSigners || !this.selectedSigner) {
231
232
  return generateSignersScene(
232
233
  this.selectedWallet,
233
234
  this.signerSelectedHandler,
@@ -248,7 +249,6 @@ export class WebComponentConnector extends LitElement {
248
249
  --btn-primary: #f8f8f8;
249
250
  --btn-primary-hover: #efeeee;
250
251
  --btn-secondary: #ddd;
251
- --btn-icon: #e9e4de;
252
252
  color: #1e1e1e;
253
253
  --tip-color: #666;
254
254
  }
@@ -273,19 +273,38 @@ export class WebComponentConnector extends LitElement {
273
273
  }
274
274
 
275
275
  private closedHandler = () => {
276
- if (this.signer === undefined) {
277
- this.disconnect();
276
+ if (
277
+ [
278
+ Scene.SelectingSigners,
279
+ Scene.SelectingWallets,
280
+ Scene.Connecting,
281
+ ].includes(this.scene)
282
+ ) {
283
+ this.scene = Scene.SelectingWallets;
284
+ this.selectedSigner = undefined;
285
+ this.selectedWallet = undefined;
278
286
  }
279
287
  this.isOpen = false;
280
288
  };
281
289
 
282
290
  private signerSelectedHandler = (
283
- wallet?: ccc.Wallet,
284
- signer?: ccc.SignerInfo,
291
+ wallet: WalletWithSigners,
292
+ signer: ccc.SignerInfo,
285
293
  ) => {
286
- this.walletName = wallet?.name;
287
- this.signerType = signer?.type;
288
- this.canConnect = true;
294
+ this.scene = Scene.Connecting;
295
+ this.selectedWallet = wallet;
296
+ this.selectedSigner = signer;
297
+ (async () => {
298
+ await signer.signer.connect();
299
+ if (!(await signer.signer.isConnected())) {
300
+ return;
301
+ }
302
+ this.scene = Scene.Connected;
303
+ this.walletName = wallet.name;
304
+ this.signerName = signer.name;
305
+ this.saveConnection();
306
+ this.closedHandler();
307
+ })();
289
308
  };
290
309
 
291
310
  static styles = css`
@@ -385,8 +404,6 @@ export class WebComponentConnector extends LitElement {
385
404
  width: 2rem;
386
405
  height: 2rem;
387
406
  margin-right: 1rem;
388
- border-radius: 0.4rem;
389
- background: var(--btn-icon);
390
407
  }
391
408
 
392
409
  .btn-primary:hover {
@@ -412,8 +429,6 @@ export class WebComponentConnector extends LitElement {
412
429
  width: 4rem;
413
430
  height: 4rem;
414
431
  margin-bottom: 0.5rem;
415
- border-radius: 0.8rem;
416
- background: var(--btn-icon);
417
432
  }
418
433
 
419
434
  .connecting-wallet-icon {
@@ -1,12 +1,13 @@
1
1
  import { ccc } from "@ckb-ccc/ccc";
2
2
  import { html } from "lit";
3
3
  import { RETRY_SVG } from "../assets/retry.svg";
4
+ import { WalletWithSigners } from "../types";
4
5
 
5
6
  export function generateConnectingScene(
6
- wallet: ccc.Wallet,
7
+ wallet: WalletWithSigners,
7
8
  signer: ccc.SignerInfo,
8
9
  onSignerSelected: (
9
- wallet: ccc.Wallet | undefined,
10
+ wallet: WalletWithSigners,
10
11
  signer: ccc.SignerInfo,
11
12
  ) => unknown,
12
13
  ) {
@@ -1,20 +1,21 @@
1
1
  import { ccc } from "@ckb-ccc/ccc";
2
2
  import { html } from "lit";
3
3
  import { repeat } from "lit/directives/repeat.js";
4
- import { BTC_SVG, ETH_SVG } from "../assets/chains";
4
+ import { BTC_SVG, CKB_SVG, ETH_SVG } from "../assets/chains";
5
5
  import { WalletWithSigners } from "../types";
6
6
 
7
7
  export function signerTypeToIcon(type: ccc.SignerType): string {
8
8
  return {
9
9
  [ccc.SignerType.BTC]: BTC_SVG,
10
10
  [ccc.SignerType.EVM]: ETH_SVG,
11
+ [ccc.SignerType.CKB]: CKB_SVG,
11
12
  }[type];
12
13
  }
13
14
 
14
15
  export function generateSignersScene(
15
16
  wallet: WalletWithSigners,
16
17
  onSignerSelected: (
17
- wallet: ccc.Wallet | undefined,
18
+ wallet: WalletWithSigners,
18
19
  signer: ccc.SignerInfo,
19
20
  ) => unknown,
20
21
  ) {
@@ -35,7 +36,7 @@ export function generateSignersScene(
35
36
  }}
36
37
  >
37
38
  <img src=${signerTypeToIcon(signer.type)} alt=${signer.type} />
38
- ${signer.type}
39
+ ${signer.name}
39
40
  </button>
40
41
  `,
41
42
  )}
@@ -1,33 +1,79 @@
1
1
  import { ccc } from "@ckb-ccc/ccc";
2
2
  import { html } from "lit";
3
3
  import { repeat } from "lit/directives/repeat.js";
4
- import { WalletWithSigners } from "../types";
4
+ import { METAMASK_SVG } from "../assets/metamask.svg";
5
+ import { OKX_SVG } from "../assets/okx.svg";
6
+ import { UNI_SAT_SVG } from "../assets/uni-sat.svg";
7
+ import { WalletInfo, WalletWithSigners } from "../types";
5
8
 
6
9
  export function generateWalletsScene(
7
10
  wallets: WalletWithSigners[],
8
- onWalletSelected: (wallet: ccc.Wallet) => unknown,
9
- onSignerSelected: (wallet: ccc.Wallet, signer: ccc.SignerInfo) => unknown,
11
+ onWalletSelected: (wallet: WalletWithSigners) => unknown,
12
+ onSignerSelected: (
13
+ wallet: WalletWithSigners,
14
+ signer: ccc.SignerInfo,
15
+ ) => unknown,
10
16
  ) {
17
+ const recommendedWallets = [
18
+ {
19
+ name: "MetaMask",
20
+ icon: METAMASK_SVG,
21
+ downloadLink: `https://metamask.app.link/dapp/${window.location.href}`,
22
+ },
23
+ {
24
+ name: "OKX Wallet",
25
+ icon: OKX_SVG,
26
+ downloadLink: "https://www.okx.com/zh-hans/download",
27
+ },
28
+ {
29
+ name: "UniSat",
30
+ icon: UNI_SAT_SVG,
31
+ downloadLink: "https://unisat.io/",
32
+ },
33
+ ];
34
+
35
+ const missingWallets = recommendedWallets.filter(
36
+ (recommendedWallet) =>
37
+ !wallets.some((wallet) => wallet.name === recommendedWallet.name),
38
+ );
39
+
40
+ const additionalButtons = missingWallets.map(
41
+ (wallet: WalletInfo) => html`
42
+ <button
43
+ class="btn-primary mb-1"
44
+ @click=${() => {
45
+ window.open(wallet.downloadLink, "_blank");
46
+ }}
47
+ >
48
+ <img src=${wallet.icon} alt=${wallet.name} />
49
+ ${wallet.name}
50
+ </button>
51
+ `,
52
+ );
53
+
11
54
  return [
12
55
  "Connect Wallet",
13
- repeat(
14
- wallets,
15
- (wallet) => wallet.name,
16
- (wallet) => html`
17
- <button
18
- class="btn-primary mb-1"
19
- @click=${async () => {
20
- if (wallet.signers.length === 1) {
21
- onSignerSelected(wallet, wallet.signers[0]);
22
- } else {
23
- onWalletSelected(wallet);
24
- }
25
- }}
26
- >
27
- <img src=${wallet.icon} alt=${wallet.name} />
28
- ${wallet.name}
29
- </button>
30
- `,
31
- ),
56
+ html`
57
+ ${repeat(
58
+ wallets,
59
+ (wallet) => wallet.name,
60
+ (wallet) => html`
61
+ <button
62
+ class="btn-primary mb-1"
63
+ @click=${async () => {
64
+ if (wallet.signers.length === 1) {
65
+ onSignerSelected(wallet, wallet.signers[0]);
66
+ } else {
67
+ onWalletSelected(wallet);
68
+ }
69
+ }}
70
+ >
71
+ <img src=${wallet.icon} alt=${wallet.name} />
72
+ ${wallet.name}
73
+ </button>
74
+ `,
75
+ )}
76
+ ${additionalButtons}
77
+ `,
32
78
  ];
33
79
  }
@@ -3,3 +3,9 @@ import { ccc } from "@ckb-ccc/ccc";
3
3
  export type WalletWithSigners = ccc.Wallet & {
4
4
  signers: ccc.SignerInfo[];
5
5
  };
6
+
7
+ export interface WalletInfo {
8
+ name: string;
9
+ icon: string;
10
+ downloadLink: string;
11
+ }
@@ -1,21 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "es2020",
4
- "incremental": true,
5
- "allowJs": true,
6
- "importHelpers": false,
7
- "declaration": true,
8
- "declarationMap": true,
9
- "experimentalDecorators": true,
10
- "useDefineForClassFields": false,
11
- "esModuleInterop": true,
12
- "strict": true,
13
- "noImplicitAny": true,
14
- "strictBindCallApply": true,
15
- "strictNullChecks": true,
16
- "alwaysStrict": true,
17
- "noFallthroughCasesInSwitch": true,
18
- "forceConsistentCasingInFileNames": true
19
- },
20
- "include": ["src/**/*"]
21
- }
@@ -1,8 +0,0 @@
1
- {
2
- "extends": "./tsconfig.base.json",
3
- "compilerOptions": {
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "outDir": "./dist.commonjs"
7
- }
8
- }