@ckb-ccc/joy-id 0.0.8-alpha.4 → 0.0.9-alpha.1

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 (43) hide show
  1. package/dist/btc/index.d.ts +16 -12
  2. package/dist/btc/index.d.ts.map +1 -1
  3. package/dist/btc/index.js +38 -13
  4. package/dist/ckb/index.d.ts +3 -1
  5. package/dist/ckb/index.d.ts.map +1 -1
  6. package/dist/ckb/index.js +13 -1
  7. package/dist/connectionsStorage/index.d.ts +1 -1
  8. package/dist/connectionsStorage/index.d.ts.map +1 -1
  9. package/dist/connectionsStorage/index.js +5 -5
  10. package/dist/evm/index.d.ts +9 -7
  11. package/dist/evm/index.d.ts.map +1 -1
  12. package/dist/evm/index.js +22 -8
  13. package/dist/nostr/index.d.ts +20 -7
  14. package/dist/nostr/index.d.ts.map +1 -1
  15. package/dist/nostr/index.js +44 -14
  16. package/dist/signerFactory/index.d.ts +1 -1
  17. package/dist/signerFactory/index.d.ts.map +1 -1
  18. package/dist/signerFactory/index.js +4 -4
  19. package/dist.commonjs/btc/index.d.ts +16 -12
  20. package/dist.commonjs/btc/index.d.ts.map +1 -1
  21. package/dist.commonjs/btc/index.js +38 -13
  22. package/dist.commonjs/ckb/index.d.ts +3 -1
  23. package/dist.commonjs/ckb/index.d.ts.map +1 -1
  24. package/dist.commonjs/ckb/index.js +13 -1
  25. package/dist.commonjs/connectionsStorage/index.d.ts +1 -1
  26. package/dist.commonjs/connectionsStorage/index.d.ts.map +1 -1
  27. package/dist.commonjs/connectionsStorage/index.js +7 -7
  28. package/dist.commonjs/evm/index.d.ts +9 -7
  29. package/dist.commonjs/evm/index.d.ts.map +1 -1
  30. package/dist.commonjs/evm/index.js +22 -8
  31. package/dist.commonjs/nostr/index.d.ts +20 -7
  32. package/dist.commonjs/nostr/index.d.ts.map +1 -1
  33. package/dist.commonjs/nostr/index.js +44 -14
  34. package/dist.commonjs/signerFactory/index.d.ts +1 -1
  35. package/dist.commonjs/signerFactory/index.d.ts.map +1 -1
  36. package/dist.commonjs/signerFactory/index.js +4 -4
  37. package/package.json +3 -3
  38. package/src/btc/index.ts +53 -15
  39. package/src/ckb/index.ts +16 -1
  40. package/src/connectionsStorage/index.ts +10 -5
  41. package/src/evm/index.ts +25 -7
  42. package/src/nostr/index.ts +51 -16
  43. package/src/signerFactory/index.ts +10 -3
package/src/btc/index.ts CHANGED
@@ -14,6 +14,7 @@ import {
14
14
  */
15
15
  export class BitcoinSigner extends ccc.SignerBtc {
16
16
  private connection?: Connection;
17
+ private network = "btcTestnet";
17
18
 
18
19
  /**
19
20
  * Ensures that the signer is connected and returns the connection.
@@ -31,39 +32,76 @@ export class BitcoinSigner extends ccc.SignerBtc {
31
32
 
32
33
  /**
33
34
  * Creates an instance of BitcoinSigner.
34
- * @param {ccc.Client} client - The client instance.
35
- * @param {string} name - The name of the signer.
36
- * @param {string} icon - The icon URL of the signer.
37
- * @param {"auto" | "p2wpkh" | "p2tr"} [addressType="auto"] - The address type.
38
- * @param {string} [appUri="https://app.joy.id"] - The application URI.
39
- * @param {ConnectionsRepo} [connectionsRepo=new ConnectionsRepoLocalStorage()] - The connections repository.
35
+ * @param client - The client instance.
36
+ * @param name - The name of the signer.
37
+ * @param icon - The icon URL of the signer.
38
+ * @param addressType - The address type.
39
+ * @param _appUri - The application URI.
40
+ * @param connectionsRepo - The connections repository.
40
41
  */
41
42
  constructor(
42
43
  client: ccc.Client,
43
- private readonly name: string,
44
- private readonly icon: string,
45
- private readonly addressType: "auto" | "p2wpkh" | "p2tr" = "auto",
46
- private readonly appUri = "https://app.joy.id",
44
+ public readonly name: string,
45
+ public readonly icon: string,
46
+ private readonly preferredNetworks: ccc.NetworkPreference[],
47
+ public readonly addressType: "auto" | "p2wpkh" | "p2tr" = "auto",
48
+ private readonly _appUri?: string,
47
49
  private readonly connectionsRepo: ConnectionsRepo = new ConnectionsRepoLocalStorage(),
48
50
  ) {
49
51
  super(client);
50
52
  }
51
53
 
54
+ async replaceClient(client: ccc.Client): Promise<boolean> {
55
+ if (!(await super.replaceClient(client))) {
56
+ return false;
57
+ }
58
+ this.connection = undefined;
59
+ return true;
60
+ }
61
+
52
62
  /**
53
63
  * Gets the configuration for JoyID.
54
64
  * @private
55
- * @returns {object} The configuration object.
65
+ * @returns The configuration object.
56
66
  */
57
67
  private getConfig() {
68
+ const { network } = this.matchNetworkPreference(
69
+ this.preferredNetworks,
70
+ this.network,
71
+ ) ?? { network: this.network };
72
+ if (this.network !== network) {
73
+ this.connection = undefined;
74
+ }
75
+ this.network = network;
76
+
77
+ const url = {
78
+ btc: "https://app.joy.id",
79
+ btcTestnet: "https://testnet.joyid.dev",
80
+ }[network];
81
+ if (!url) {
82
+ throw new Error(
83
+ `JoyID wallet doesn't support the requested chain ${this.network}`,
84
+ );
85
+ }
86
+
58
87
  return {
59
88
  redirectURL: location.href,
60
- joyidAppURL: this.appUri,
89
+ joyidAppURL: this._appUri ?? url,
61
90
  requestNetwork: `btc-${this.addressType}`,
62
91
  name: this.name,
63
92
  logo: this.icon,
64
93
  };
65
94
  }
66
95
 
96
+ async disconnect(): Promise<void> {
97
+ await super.disconnect();
98
+
99
+ await this.connectionsRepo.set(
100
+ { uri: this.getConfig().joyidAppURL, addressType: "btc" },
101
+ undefined,
102
+ );
103
+ }
104
+
67
105
  /**
68
106
  * Gets the Bitcoin account address.
69
107
  * @returns {Promise<string>} A promise that resolves to the Bitcoin account address.
@@ -107,11 +145,11 @@ export class BitcoinSigner extends ccc.SignerBtc {
107
145
  };
108
146
  await Promise.all([
109
147
  this.connectionsRepo.set(
110
- { uri: this.appUri, addressType: `btc-${res.btcAddressType}` },
148
+ { uri: config.joyidAppURL, addressType: `btc-${res.btcAddressType}` },
111
149
  this.connection,
112
150
  ),
113
151
  this.connectionsRepo.set(
114
- { uri: this.appUri, addressType: "btc-auto" },
152
+ { uri: config.joyidAppURL, addressType: "btc-auto" },
115
153
  this.connection,
116
154
  ),
117
155
  ]);
@@ -127,7 +165,7 @@ export class BitcoinSigner extends ccc.SignerBtc {
127
165
  }
128
166
 
129
167
  this.connection = await this.connectionsRepo.get({
130
- uri: this.appUri,
168
+ uri: this.getConfig().joyidAppURL,
131
169
  addressType: `btc-${this.addressType}`,
132
170
  });
133
171
  return this.connection !== undefined;
package/src/ckb/index.ts CHANGED
@@ -66,10 +66,18 @@ export class CkbSigner extends ccc.Signer {
66
66
  super(client);
67
67
  }
68
68
 
69
+ async replaceClient(client: ccc.Client): Promise<boolean> {
70
+ if (!(await super.replaceClient(client))) {
71
+ return false;
72
+ }
73
+ this.connection = undefined;
74
+ return true;
75
+ }
76
+
69
77
  /**
70
78
  * Gets the configuration for JoyID.
71
79
  * @private
72
- * @returns {object} The configuration object.
80
+ * @returns The configuration object.
73
81
  */
74
82
  private getConfig() {
75
83
  return {
@@ -118,6 +126,13 @@ export class CkbSigner extends ccc.Signer {
118
126
  await this.saveConnection();
119
127
  }
120
128
 
129
+ async disconnect(): Promise<void> {
130
+ await super.disconnect();
131
+
132
+ this.connection = undefined;
133
+ await this.saveConnection();
134
+ }
135
+
121
136
  /**
122
137
  * Checks if the signer is connected.
123
138
  * @returns {Promise<boolean>} A promise that resolves to true if connected, false otherwise.
@@ -17,8 +17,11 @@ export type AccountSelector = {
17
17
  * @param {AccountSelector} b - The second account selector.
18
18
  * @returns {boolean} True if the selectors are equal, false otherwise.
19
19
  */
20
- export function isSelectorEq(a: AccountSelector, b: AccountSelector): boolean {
21
- return a.uri === b.uri && a.addressType === b.addressType;
20
+ export function isSelectorMatch(
21
+ a: AccountSelector,
22
+ filter: AccountSelector,
23
+ ): boolean {
24
+ return a.uri === filter.uri && a.addressType.startsWith(filter.addressType);
22
25
  }
23
26
 
24
27
  /**
@@ -85,7 +88,7 @@ export class ConnectionsRepoLocalStorage implements ConnectionsRepo {
85
88
  */
86
89
  async get(selector: AccountSelector): Promise<Connection | undefined> {
87
90
  return (await this.readConnections()).find(([s]) =>
88
- isSelectorEq(selector, s),
91
+ isSelectorMatch(selector, s),
89
92
  )?.[1];
90
93
  }
91
94
 
@@ -102,7 +105,7 @@ export class ConnectionsRepoLocalStorage implements ConnectionsRepo {
102
105
  const connections = await this.readConnections();
103
106
 
104
107
  if (connection) {
105
- const existed = connections.find(([s]) => isSelectorEq(s, selector));
108
+ const existed = connections.find(([s]) => isSelectorMatch(s, selector));
106
109
  if (existed) {
107
110
  existed[1] = connection;
108
111
  } else {
@@ -112,7 +115,9 @@ export class ConnectionsRepoLocalStorage implements ConnectionsRepo {
112
115
  } else {
113
116
  window.localStorage.setItem(
114
117
  this.storageKey,
115
- JSON.stringify(connections.filter(([s]) => !isSelectorEq(s, selector))),
118
+ JSON.stringify(
119
+ connections.filter(([s]) => !isSelectorMatch(s, selector)),
120
+ ),
116
121
  );
117
122
  }
118
123
  }
package/src/evm/index.ts CHANGED
@@ -31,22 +31,30 @@ export class EvmSigner extends ccc.SignerEvm {
31
31
 
32
32
  /**
33
33
  * Creates an instance of EvmSigner.
34
- * @param {ccc.Client} client - The client instance.
35
- * @param {string} name - The name of the signer.
36
- * @param {string} icon - The icon URL of the signer.
37
- * @param {string} [appUri="https://app.joy.id"] - The application URI.
38
- * @param {ConnectionsRepo} [connectionsRepo=new ConnectionsRepoLocalStorage()] - The connections repository.
34
+ * @param client - The client instance.
35
+ * @param name - The name of the signer.
36
+ * @param icon - The icon URL of the signer.
37
+ * @param appUri - The application URI.
38
+ * @param connectionsRepo - The connections repository.
39
39
  */
40
40
  constructor(
41
41
  client: ccc.Client,
42
42
  private readonly name: string,
43
43
  private readonly icon: string,
44
- private readonly appUri = "https://app.joy.id",
44
+ private readonly _appUri?: string,
45
45
  private readonly connectionsRepo: ConnectionsRepo = new ConnectionsRepoLocalStorage(),
46
46
  ) {
47
47
  super(client);
48
48
  }
49
49
 
50
+ async replaceClient(client: ccc.Client): Promise<boolean> {
51
+ if (!(await super.replaceClient(client))) {
52
+ return false;
53
+ }
54
+ this.connection = undefined;
55
+ return true;
56
+ }
57
+
50
58
  /**
51
59
  * Gets the configuration for JoyID.
52
60
  * @private
@@ -55,7 +63,10 @@ export class EvmSigner extends ccc.SignerEvm {
55
63
  private getConfig() {
56
64
  return {
57
65
  redirectURL: location.href,
58
- joyidAppURL: this.appUri,
66
+ joyidAppURL:
67
+ this._appUri ?? this.client.addressPrefix === "ckb"
68
+ ? "https://app.joy.id"
69
+ : "https://testnet.joyid.dev",
59
70
  requestNetwork: `ethereum`,
60
71
  name: this.name,
61
72
  logo: this.icon,
@@ -90,6 +101,13 @@ export class EvmSigner extends ccc.SignerEvm {
90
101
  await this.saveConnection();
91
102
  }
92
103
 
104
+ async disconnect(): Promise<void> {
105
+ await super.disconnect();
106
+
107
+ this.connection = undefined;
108
+ await this.saveConnection();
109
+ }
110
+
93
111
  /**
94
112
  * Checks if the signer is connected.
95
113
  * @returns {Promise<boolean>} A promise that resolves to true if connected, false otherwise.
@@ -31,24 +31,28 @@ export class NostrSigner extends ccc.SignerNostr {
31
31
 
32
32
  /**
33
33
  * Creates an instance of NostrSigner.
34
- * @param {ccc.Client} client - The client instance.
35
- * @param {string} name - The name of the signer.
36
- * @param {string} icon - The icon URL of the signer.
37
- * @param {string} [appUri="https://app.joy.id"] - The application URI.
38
- * @param {ConnectionsRepo} [connectionsRepo=new ConnectionsRepoLocalStorage()] - The connections repository.
34
+ * @param client - The client instance.
35
+ * @param name - The name of the signer.
36
+ * @param icon - The icon URL of the signer.
37
+ * @param appUri - The application URI.
38
+ * @param connectionsRepo - The connections repository.
39
39
  */
40
40
  constructor(
41
41
  client: ccc.Client,
42
42
  private readonly name: string,
43
43
  private readonly icon: string,
44
- private readonly appUri = "https://app.joy.id",
44
+ private readonly _appUri?: string,
45
45
  private readonly connectionsRepo: ConnectionsRepo = new ConnectionsRepoLocalStorage(),
46
46
  ) {
47
47
  super(client);
48
48
  }
49
49
 
50
50
  async replaceClient(client: ccc.Client): Promise<boolean> {
51
- return super.replaceClient(client);
51
+ if (!(await super.replaceClient(client))) {
52
+ return false;
53
+ }
54
+ this.connection = undefined;
55
+ return true;
52
56
  }
53
57
 
54
58
  /**
@@ -59,7 +63,10 @@ export class NostrSigner extends ccc.SignerNostr {
59
63
  private getConfig() {
60
64
  return {
61
65
  redirectURL: location.href,
62
- joyidAppURL: this.appUri,
66
+ joyidAppURL:
67
+ this._appUri ?? this.client.addressPrefix === "ckb"
68
+ ? "https://app.joy.id"
69
+ : "https://testnet.joyid.dev",
63
70
  requestNetwork: "nostr",
64
71
  name: this.name,
65
72
  logo: this.icon,
@@ -82,10 +89,14 @@ export class NostrSigner extends ccc.SignerNostr {
82
89
  publicKey: ccc.hexFrom(res.nostrPubkey),
83
90
  keyType: res.keyType,
84
91
  };
85
- await this.connectionsRepo.set(
86
- { uri: this.appUri, addressType: "nostr" },
87
- this.connection,
88
- );
92
+ await this.saveConnection();
93
+ }
94
+
95
+ async disconnect(): Promise<void> {
96
+ await super.disconnect();
97
+
98
+ this.connection = undefined;
99
+ await this.saveConnection();
89
100
  }
90
101
 
91
102
  /**
@@ -97,10 +108,7 @@ export class NostrSigner extends ccc.SignerNostr {
97
108
  return true;
98
109
  }
99
110
 
100
- this.connection = await this.connectionsRepo.get({
101
- uri: this.appUri,
102
- addressType: "nostr",
103
- });
111
+ await this.restoreConnection();
104
112
  return this.connection !== undefined;
105
113
  }
106
114
 
@@ -121,4 +129,31 @@ export class NostrSigner extends ccc.SignerNostr {
121
129
  );
122
130
  return res.event;
123
131
  }
132
+
133
+ /**
134
+ * Saves the current connection.
135
+ * @private
136
+ * @returns {Promise<void>}
137
+ */
138
+ private async saveConnection(): Promise<void> {
139
+ return this.connectionsRepo.set(
140
+ {
141
+ uri: this.getConfig().joyidAppURL,
142
+ addressType: "nostr",
143
+ },
144
+ this.connection,
145
+ );
146
+ }
147
+
148
+ /**
149
+ * Restores the previous connection.
150
+ * @private
151
+ * @returns {Promise<void>}
152
+ */
153
+ private async restoreConnection(): Promise<void> {
154
+ this.connection = await this.connectionsRepo.get({
155
+ uri: this.getConfig().joyidAppURL,
156
+ addressType: "nostr",
157
+ });
158
+ }
124
159
  }
@@ -18,6 +18,7 @@ export function getJoyIdSigners(
18
18
  client: ccc.Client,
19
19
  name: string,
20
20
  icon: string,
21
+ preferredNetworks: ccc.NetworkPreference[],
21
22
  ): ccc.SignerInfo[] {
22
23
  if (isStandaloneBrowser() || ccc.isWebview(window.navigator.userAgent)) {
23
24
  return [ccc.SignerType.CKB, ccc.SignerType.EVM, ccc.SignerType.BTC].map(
@@ -39,7 +40,7 @@ export function getJoyIdSigners(
39
40
  },
40
41
  {
41
42
  name: "BTC",
42
- signer: new BitcoinSigner(client, name, icon),
43
+ signer: new BitcoinSigner(client, name, icon, preferredNetworks),
43
44
  },
44
45
  {
45
46
  name: "Nostr",
@@ -51,11 +52,17 @@ export function getJoyIdSigners(
51
52
  },
52
53
  {
53
54
  name: "BTC (P2WPKH)",
54
- signer: new BitcoinSigner(client, name, icon, "p2wpkh"),
55
+ signer: new BitcoinSigner(
56
+ client,
57
+ name,
58
+ icon,
59
+ preferredNetworks,
60
+ "p2wpkh",
61
+ ),
55
62
  },
56
63
  {
57
64
  name: "BTC (P2TR)",
58
- signer: new BitcoinSigner(client, name, icon, "p2tr"),
65
+ signer: new BitcoinSigner(client, name, icon, preferredNetworks, "p2tr"),
59
66
  },
60
67
  ];
61
68
  }