@phantom/indexed-db-stamper 1.0.2 → 1.0.3

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/dist/index.d.ts CHANGED
@@ -13,8 +13,13 @@ type IndexedDbStamperConfig = {
13
13
  * IndexedDB-based key manager that stores cryptographic keys securely in IndexedDB
14
14
  * and performs signing operations without ever exposing private key material.
15
15
  *
16
+ * Algorithm selection:
17
+ * - Prefers Ed25519 for maximum security and performance
18
+ * - Automatically falls back to ECDSA P-256 (secp256r1) on browsers that don't support Ed25519
19
+ * (e.g., older Android WebViews before Chrome 113)
20
+ *
16
21
  * Security model:
17
- * - Generates non-extractable Ed25519 keypairs using Web Crypto API
22
+ * - Generates non-extractable keypairs using Web Crypto API
18
23
  * - Stores keys entirely within Web Crypto API secure context
19
24
  * - Private keys NEVER exist in JavaScript memory
20
25
  * - Provides signing methods without exposing private keys
@@ -33,9 +38,11 @@ declare class IndexedDbStamper implements StamperWithKeyManagement {
33
38
  salt?: string;
34
39
  constructor(config?: IndexedDbStamperConfig);
35
40
  /**
36
- * Initialize the stamper by opening IndexedDB and retrieving or generating keys
41
+ * Initialize the stamper by opening IndexedDB and retrieving or generating keys.
42
+ * Automatically selects the best supported algorithm.
37
43
  */
38
44
  init(): Promise<StamperKeyInfo>;
45
+ private getSupportedAlgorithm;
39
46
  /**
40
47
  * Get the public key information
41
48
  */
package/dist/index.js CHANGED
@@ -34,16 +34,26 @@ __export(src_exports, {
34
34
  });
35
35
  module.exports = __toCommonJS(src_exports);
36
36
  var import_base64url = require("@phantom/base64url");
37
+ var import_constants = require("@phantom/constants");
37
38
  var import_bs58 = __toESM(require("bs58"));
38
39
  var import_sdk_types = require("@phantom/sdk-types");
40
+ var WEB_CRYPTO_ALGORITHM_CONFIGS = {
41
+ [import_constants.DEFAULT_AUTHENTICATOR_ALGORITHM]: {
42
+ generateParams: { name: "Ed25519" },
43
+ signParams: { name: "Ed25519" }
44
+ },
45
+ [import_sdk_types.Algorithm.secp256r1]: {
46
+ generateParams: { name: "ECDSA", namedCurve: "P-256" },
47
+ signParams: { name: "ECDSA", hash: "SHA-256" }
48
+ }
49
+ };
39
50
  var IndexedDbStamper = class {
40
51
  // Optional for PKI, required for OIDC
41
52
  constructor(config = {}) {
42
53
  this.db = null;
43
54
  this.activeKeyPairRecord = null;
44
55
  this.pendingKeyPairRecord = null;
45
- this.algorithm = import_sdk_types.Algorithm.ed25519;
46
- // Use Ed25519 for maximum security and performance
56
+ this.algorithm = import_constants.DEFAULT_AUTHENTICATOR_ALGORITHM;
47
57
  // The type of stamper, can be changed at any time
48
58
  this.type = "PKI";
49
59
  if (typeof window === "undefined" || !window.indexedDB) {
@@ -57,17 +67,34 @@ var IndexedDbStamper = class {
57
67
  this.salt = config.salt;
58
68
  }
59
69
  /**
60
- * Initialize the stamper by opening IndexedDB and retrieving or generating keys
70
+ * Initialize the stamper by opening IndexedDB and retrieving or generating keys.
71
+ * Automatically selects the best supported algorithm.
61
72
  */
62
73
  async init() {
63
74
  await this.openDB();
64
75
  this.activeKeyPairRecord = await this.loadActiveKeyPairRecord();
65
- if (!this.activeKeyPairRecord) {
76
+ if (this.activeKeyPairRecord) {
77
+ this.algorithm = this.activeKeyPairRecord.keyPair.privateKey.algorithm.name === "Ed25519" ? import_sdk_types.Algorithm.ed25519 : import_sdk_types.Algorithm.secp256r1;
78
+ } else {
79
+ this.algorithm = await this.getSupportedAlgorithm();
66
80
  this.activeKeyPairRecord = await this.generateAndStoreNewKeyPair("active");
67
81
  }
68
82
  this.pendingKeyPairRecord = await this.loadPendingKeyPairRecord();
69
83
  return this.activeKeyPairRecord.keyInfo;
70
84
  }
85
+ async getSupportedAlgorithm() {
86
+ for (const [algorithm, params] of Object.entries(WEB_CRYPTO_ALGORITHM_CONFIGS)) {
87
+ try {
88
+ await crypto.subtle.generateKey(params.generateParams, false, ["sign", "verify"]);
89
+ return algorithm;
90
+ } catch {
91
+ continue;
92
+ }
93
+ }
94
+ throw new Error(
95
+ "Your browser does not support the encryption needed for secure authentication. Please use a different browser or upgrade to a supported browser."
96
+ );
97
+ }
71
98
  /**
72
99
  * Get the public key information
73
100
  */
@@ -95,10 +122,7 @@ var IndexedDbStamper = class {
95
122
  }
96
123
  const dataBytes = new Uint8Array(data);
97
124
  const signature = await crypto.subtle.sign(
98
- {
99
- name: this.algorithm,
100
- hash: "SHA-256"
101
- },
125
+ WEB_CRYPTO_ALGORITHM_CONFIGS[this.algorithm].signParams,
102
126
  this.activeKeyPairRecord.keyPair.privateKey,
103
127
  dataBytes
104
128
  );
@@ -210,9 +234,7 @@ var IndexedDbStamper = class {
210
234
  }
211
235
  async generateAndStoreNewKeyPair(type) {
212
236
  const keyPair = await crypto.subtle.generateKey(
213
- {
214
- name: "Ed25519"
215
- },
237
+ WEB_CRYPTO_ALGORITHM_CONFIGS[this.algorithm].generateParams,
216
238
  false,
217
239
  // non-extractable - private key can never be exported
218
240
  ["sign", "verify"]
package/dist/index.mjs CHANGED
@@ -1,15 +1,25 @@
1
1
  // src/index.ts
2
2
  import { base64urlEncode } from "@phantom/base64url";
3
+ import { DEFAULT_AUTHENTICATOR_ALGORITHM } from "@phantom/constants";
3
4
  import bs58 from "bs58";
4
5
  import { Algorithm } from "@phantom/sdk-types";
6
+ var WEB_CRYPTO_ALGORITHM_CONFIGS = {
7
+ [DEFAULT_AUTHENTICATOR_ALGORITHM]: {
8
+ generateParams: { name: "Ed25519" },
9
+ signParams: { name: "Ed25519" }
10
+ },
11
+ [Algorithm.secp256r1]: {
12
+ generateParams: { name: "ECDSA", namedCurve: "P-256" },
13
+ signParams: { name: "ECDSA", hash: "SHA-256" }
14
+ }
15
+ };
5
16
  var IndexedDbStamper = class {
6
17
  // Optional for PKI, required for OIDC
7
18
  constructor(config = {}) {
8
19
  this.db = null;
9
20
  this.activeKeyPairRecord = null;
10
21
  this.pendingKeyPairRecord = null;
11
- this.algorithm = Algorithm.ed25519;
12
- // Use Ed25519 for maximum security and performance
22
+ this.algorithm = DEFAULT_AUTHENTICATOR_ALGORITHM;
13
23
  // The type of stamper, can be changed at any time
14
24
  this.type = "PKI";
15
25
  if (typeof window === "undefined" || !window.indexedDB) {
@@ -23,17 +33,34 @@ var IndexedDbStamper = class {
23
33
  this.salt = config.salt;
24
34
  }
25
35
  /**
26
- * Initialize the stamper by opening IndexedDB and retrieving or generating keys
36
+ * Initialize the stamper by opening IndexedDB and retrieving or generating keys.
37
+ * Automatically selects the best supported algorithm.
27
38
  */
28
39
  async init() {
29
40
  await this.openDB();
30
41
  this.activeKeyPairRecord = await this.loadActiveKeyPairRecord();
31
- if (!this.activeKeyPairRecord) {
42
+ if (this.activeKeyPairRecord) {
43
+ this.algorithm = this.activeKeyPairRecord.keyPair.privateKey.algorithm.name === "Ed25519" ? Algorithm.ed25519 : Algorithm.secp256r1;
44
+ } else {
45
+ this.algorithm = await this.getSupportedAlgorithm();
32
46
  this.activeKeyPairRecord = await this.generateAndStoreNewKeyPair("active");
33
47
  }
34
48
  this.pendingKeyPairRecord = await this.loadPendingKeyPairRecord();
35
49
  return this.activeKeyPairRecord.keyInfo;
36
50
  }
51
+ async getSupportedAlgorithm() {
52
+ for (const [algorithm, params] of Object.entries(WEB_CRYPTO_ALGORITHM_CONFIGS)) {
53
+ try {
54
+ await crypto.subtle.generateKey(params.generateParams, false, ["sign", "verify"]);
55
+ return algorithm;
56
+ } catch {
57
+ continue;
58
+ }
59
+ }
60
+ throw new Error(
61
+ "Your browser does not support the encryption needed for secure authentication. Please use a different browser or upgrade to a supported browser."
62
+ );
63
+ }
37
64
  /**
38
65
  * Get the public key information
39
66
  */
@@ -61,10 +88,7 @@ var IndexedDbStamper = class {
61
88
  }
62
89
  const dataBytes = new Uint8Array(data);
63
90
  const signature = await crypto.subtle.sign(
64
- {
65
- name: this.algorithm,
66
- hash: "SHA-256"
67
- },
91
+ WEB_CRYPTO_ALGORITHM_CONFIGS[this.algorithm].signParams,
68
92
  this.activeKeyPairRecord.keyPair.privateKey,
69
93
  dataBytes
70
94
  );
@@ -176,9 +200,7 @@ var IndexedDbStamper = class {
176
200
  }
177
201
  async generateAndStoreNewKeyPair(type) {
178
202
  const keyPair = await crypto.subtle.generateKey(
179
- {
180
- name: "Ed25519"
181
- },
203
+ WEB_CRYPTO_ALGORITHM_CONFIGS[this.algorithm].generateParams,
182
204
  false,
183
205
  // non-extractable - private key can never be exported
184
206
  ["sign", "verify"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phantom/indexed-db-stamper",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "IndexedDB stamper for Phantom Wallet SDK with non-extractable key storage",
5
5
  "repository": {
6
6
  "type": "git",
@@ -44,10 +44,11 @@
44
44
  "typescript": "^5.0.4"
45
45
  },
46
46
  "dependencies": {
47
- "@phantom/base64url": "^1.0.2",
48
- "@phantom/crypto": "^1.0.2",
49
- "@phantom/embedded-provider-core": "^1.0.2",
50
- "@phantom/sdk-types": "^1.0.2",
47
+ "@phantom/base64url": "^1.0.3",
48
+ "@phantom/constants": "^1.0.3",
49
+ "@phantom/crypto": "^1.0.3",
50
+ "@phantom/embedded-provider-core": "^1.0.3",
51
+ "@phantom/sdk-types": "^1.0.3",
51
52
  "bs58": "^6.0.0",
52
53
  "buffer": "^6.0.3"
53
54
  },