@phantom/indexed-db-stamper 0.1.1 → 0.1.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/README.md +39 -25
- package/dist/index.d.ts +8 -2
- package/dist/index.js +14 -5
- package/dist/index.mjs +14 -5
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -22,24 +22,27 @@ npm install @phantom/indexed-db-stamper
|
|
|
22
22
|
### Basic Usage
|
|
23
23
|
|
|
24
24
|
```typescript
|
|
25
|
-
import { IndexedDbStamper } from
|
|
25
|
+
import { IndexedDbStamper } from "@phantom/indexed-db-stamper";
|
|
26
26
|
|
|
27
27
|
// Create stamper instance
|
|
28
28
|
const stamper = new IndexedDbStamper({
|
|
29
|
-
dbName:
|
|
30
|
-
storeName:
|
|
31
|
-
keyName:
|
|
29
|
+
dbName: "my-app-keys", // optional, defaults to 'phantom-indexed-db-stamper'
|
|
30
|
+
storeName: "crypto-keys", // optional, defaults to 'crypto-keys'
|
|
31
|
+
keyName: "signing-key", // optional, defaults to 'signing-key',
|
|
32
|
+
type: "PKI", // optional, defaults to 'PKI', accepts 'PKI' or 'OIDC'
|
|
33
|
+
idToken?: undefined, // required for OIDC type, optional for PKI
|
|
34
|
+
salt?: undefined, // required for OIDC type, optional for PKI
|
|
32
35
|
});
|
|
33
36
|
|
|
34
37
|
// Initialize and generate/load keys
|
|
35
38
|
const keyInfo = await stamper.init();
|
|
36
|
-
console.log(
|
|
37
|
-
console.log(
|
|
39
|
+
console.log("Key ID:", keyInfo.keyId);
|
|
40
|
+
console.log("Public Key:", keyInfo.publicKey);
|
|
38
41
|
|
|
39
42
|
// Create X-Phantom-Stamp header value for API requests
|
|
40
|
-
const requestData = Buffer.from(JSON.stringify({ action:
|
|
43
|
+
const requestData = Buffer.from(JSON.stringify({ action: "transfer", amount: 100 }), "utf8");
|
|
41
44
|
const stamp = await stamper.stamp({ data: requestData });
|
|
42
|
-
console.log(
|
|
45
|
+
console.log("X-Phantom-Stamp:", stamp);
|
|
43
46
|
```
|
|
44
47
|
|
|
45
48
|
### Advanced Usage
|
|
@@ -47,7 +50,7 @@ console.log('X-Phantom-Stamp:', stamp);
|
|
|
47
50
|
```typescript
|
|
48
51
|
// Check if already initialized
|
|
49
52
|
if (stamper.getKeyInfo()) {
|
|
50
|
-
console.log(
|
|
53
|
+
console.log("Stamper already has keys");
|
|
51
54
|
} else {
|
|
52
55
|
await stamper.init();
|
|
53
56
|
}
|
|
@@ -56,20 +59,20 @@ if (stamper.getKeyInfo()) {
|
|
|
56
59
|
const newKeyInfo = await stamper.resetKeyPair();
|
|
57
60
|
|
|
58
61
|
// Stamp different data types with PKI (default)
|
|
59
|
-
const stringData = Buffer.from(
|
|
62
|
+
const stringData = Buffer.from("string data", "utf8");
|
|
60
63
|
const binaryData = Buffer.from([1, 2, 3]);
|
|
61
|
-
const jsonData = Buffer.from(JSON.stringify({ key:
|
|
64
|
+
const jsonData = Buffer.from(JSON.stringify({ key: "value" }), "utf8");
|
|
62
65
|
|
|
63
66
|
await stamper.stamp({ data: stringData });
|
|
64
|
-
await stamper.stamp({ data: binaryData
|
|
67
|
+
await stamper.stamp({ data: binaryData }); // explicit PKI type
|
|
65
68
|
await stamper.stamp({ data: jsonData });
|
|
66
69
|
|
|
67
70
|
// OIDC type stamping (requires idToken and salt)
|
|
68
|
-
const oidcStamp = await stamper.stamp({
|
|
69
|
-
data: requestData,
|
|
70
|
-
type:
|
|
71
|
-
idToken:
|
|
72
|
-
salt:
|
|
71
|
+
const oidcStamp = await stamper.stamp({
|
|
72
|
+
data: requestData,
|
|
73
|
+
type: "OIDC",
|
|
74
|
+
idToken: "your-id-token",
|
|
75
|
+
salt: "your-salt-value",
|
|
73
76
|
});
|
|
74
77
|
|
|
75
78
|
// Clear all stored keys
|
|
@@ -85,27 +88,33 @@ new IndexedDbStamper(config?: IndexedDbStamperConfig)
|
|
|
85
88
|
```
|
|
86
89
|
|
|
87
90
|
**Config Options:**
|
|
91
|
+
|
|
88
92
|
- `dbName?: string` - IndexedDB database name (default: 'phantom-indexed-db-stamper')
|
|
89
|
-
- `storeName?: string` - Object store name (default: 'crypto-keys')
|
|
93
|
+
- `storeName?: string` - Object store name (default: 'crypto-keys')
|
|
90
94
|
- `keyName?: string` - Key identifier prefix (default: 'signing-key')
|
|
91
95
|
|
|
92
96
|
### Methods
|
|
93
97
|
|
|
94
98
|
#### `init(): Promise<StamperKeyInfo>`
|
|
99
|
+
|
|
95
100
|
Initialize the stamper and generate/load cryptographic keys.
|
|
96
101
|
|
|
97
102
|
**Returns:** `StamperKeyInfo` with `keyId` and `publicKey`
|
|
98
103
|
|
|
99
104
|
#### `getKeyInfo(): StamperKeyInfo | null`
|
|
105
|
+
|
|
100
106
|
Get current key information without async operation.
|
|
101
107
|
|
|
102
|
-
#### `resetKeyPair(): Promise<StamperKeyInfo>`
|
|
108
|
+
#### `resetKeyPair(): Promise<StamperKeyInfo>`
|
|
109
|
+
|
|
103
110
|
Generate and store a new key pair, replacing any existing keys.
|
|
104
111
|
|
|
105
112
|
#### `stamp(params: { data: Buffer; type?: 'PKI'; idToken?: never; salt?: never; } | { data: Buffer; type: 'OIDC'; idToken: string; salt: string; }): Promise<string>`
|
|
113
|
+
|
|
106
114
|
Create X-Phantom-Stamp header value using the stored private key.
|
|
107
115
|
|
|
108
116
|
**Parameters:**
|
|
117
|
+
|
|
109
118
|
- `params.data: Buffer` - Data to sign (typically JSON stringified request body)
|
|
110
119
|
- `params.type?: 'PKI' | 'OIDC'` - Stamp type (defaults to 'PKI')
|
|
111
120
|
- `params.idToken?: string` - Required for OIDC type
|
|
@@ -116,21 +125,26 @@ Create X-Phantom-Stamp header value using the stored private key.
|
|
|
116
125
|
**Note:** The public key is stored internally in base58 format but converted to base64url when creating stamps for API compatibility.
|
|
117
126
|
|
|
118
127
|
#### `clear(): Promise<void>`
|
|
128
|
+
|
|
119
129
|
Remove all stored keys from IndexedDB.
|
|
120
130
|
|
|
121
131
|
## Security Features
|
|
122
132
|
|
|
123
133
|
### Non-Extractable Keys
|
|
134
|
+
|
|
124
135
|
The stamper generates Ed25519 CryptoKey objects with `extractable: false`, meaning private keys cannot be exported, extracted, or accessed outside of Web Crypto API signing operations. This provides the strongest possible security in browser environments.
|
|
125
136
|
|
|
126
|
-
### Cryptographic Isolation
|
|
137
|
+
### Cryptographic Isolation
|
|
138
|
+
|
|
127
139
|
Keys are generated and stored entirely within the browser's secure cryptographic context:
|
|
140
|
+
|
|
128
141
|
- Private keys never exist in JavaScript memory at any point
|
|
129
142
|
- Signing operations happen within Web Crypto API secure boundaries
|
|
130
143
|
- Secure elements used when available by the browser
|
|
131
144
|
- Origin-based security isolation through IndexedDB
|
|
132
145
|
|
|
133
146
|
### Signature Format
|
|
147
|
+
|
|
134
148
|
The stamper uses Ed25519 signatures in their native 64-byte format, providing efficient and secure signing operations.
|
|
135
149
|
|
|
136
150
|
## Error Handling
|
|
@@ -139,20 +153,20 @@ The stamper includes comprehensive error handling for:
|
|
|
139
153
|
|
|
140
154
|
```typescript
|
|
141
155
|
// Environment validation
|
|
142
|
-
if (typeof window ===
|
|
143
|
-
throw new Error(
|
|
156
|
+
if (typeof window === "undefined") {
|
|
157
|
+
throw new Error("IndexedDbStamper requires a browser environment");
|
|
144
158
|
}
|
|
145
159
|
|
|
146
160
|
// Initialization checks
|
|
147
161
|
if (!stamper.getKeyInfo()) {
|
|
148
|
-
throw new Error(
|
|
162
|
+
throw new Error("Stamper not initialized. Call init() first.");
|
|
149
163
|
}
|
|
150
164
|
|
|
151
165
|
// Storage errors
|
|
152
166
|
try {
|
|
153
167
|
await stamper.init();
|
|
154
168
|
} catch (error) {
|
|
155
|
-
console.error(
|
|
169
|
+
console.error("Failed to initialize stamper:", error);
|
|
156
170
|
}
|
|
157
171
|
```
|
|
158
172
|
|
|
@@ -162,4 +176,4 @@ Requires IndexedDB and Web Crypto API support.
|
|
|
162
176
|
|
|
163
177
|
## License
|
|
164
178
|
|
|
165
|
-
MIT
|
|
179
|
+
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,9 @@ type IndexedDbStamperConfig = {
|
|
|
5
5
|
dbName?: string;
|
|
6
6
|
storeName?: string;
|
|
7
7
|
keyName?: string;
|
|
8
|
+
type?: "PKI" | "OIDC";
|
|
9
|
+
idToken?: string;
|
|
10
|
+
salt?: string;
|
|
8
11
|
};
|
|
9
12
|
/**
|
|
10
13
|
* IndexedDB-based key manager that stores cryptographic keys securely in IndexedDB
|
|
@@ -25,6 +28,9 @@ declare class IndexedDbStamper implements StamperWithKeyManagement {
|
|
|
25
28
|
private keyInfo;
|
|
26
29
|
private cryptoKeyPair;
|
|
27
30
|
algorithm: Algorithm;
|
|
31
|
+
type: "PKI" | "OIDC";
|
|
32
|
+
idToken?: string;
|
|
33
|
+
salt?: string;
|
|
28
34
|
constructor(config?: IndexedDbStamperConfig);
|
|
29
35
|
/**
|
|
30
36
|
* Initialize the stamper by opening IndexedDB and retrieving or generating keys
|
|
@@ -45,12 +51,12 @@ declare class IndexedDbStamper implements StamperWithKeyManagement {
|
|
|
45
51
|
*/
|
|
46
52
|
stamp(params: {
|
|
47
53
|
data: Buffer;
|
|
48
|
-
type?:
|
|
54
|
+
type?: "PKI";
|
|
49
55
|
idToken?: never;
|
|
50
56
|
salt?: never;
|
|
51
57
|
} | {
|
|
52
58
|
data: Buffer;
|
|
53
|
-
type:
|
|
59
|
+
type: "OIDC";
|
|
54
60
|
idToken: string;
|
|
55
61
|
salt: string;
|
|
56
62
|
}): Promise<string>;
|
package/dist/index.js
CHANGED
|
@@ -37,18 +37,24 @@ var import_base64url = require("@phantom/base64url");
|
|
|
37
37
|
var import_bs58 = __toESM(require("bs58"));
|
|
38
38
|
var import_sdk_types = require("@phantom/sdk-types");
|
|
39
39
|
var IndexedDbStamper = class {
|
|
40
|
-
//
|
|
40
|
+
// Optional for PKI, required for OIDC
|
|
41
41
|
constructor(config = {}) {
|
|
42
42
|
this.db = null;
|
|
43
43
|
this.keyInfo = null;
|
|
44
44
|
this.cryptoKeyPair = null;
|
|
45
45
|
this.algorithm = import_sdk_types.Algorithm.ed25519;
|
|
46
|
+
// Use Ed25519 for maximum security and performance
|
|
47
|
+
// The type of stamper, can be changed at any time
|
|
48
|
+
this.type = "PKI";
|
|
46
49
|
if (typeof window === "undefined" || !window.indexedDB) {
|
|
47
50
|
throw new Error("IndexedDbStamper requires a browser environment with IndexedDB support");
|
|
48
51
|
}
|
|
49
52
|
this.dbName = config.dbName || "phantom-indexed-db-stamper";
|
|
50
53
|
this.storeName = config.storeName || "crypto-keys";
|
|
51
54
|
this.keyName = config.keyName || "signing-key";
|
|
55
|
+
this.type = config.type || "PKI";
|
|
56
|
+
this.idToken = config.idToken;
|
|
57
|
+
this.salt = config.salt;
|
|
52
58
|
}
|
|
53
59
|
/**
|
|
54
60
|
* Initialize the stamper by opening IndexedDB and retrieving or generating keys
|
|
@@ -85,7 +91,7 @@ var IndexedDbStamper = class {
|
|
|
85
91
|
* @returns Complete X-Phantom-Stamp header value
|
|
86
92
|
*/
|
|
87
93
|
async stamp(params) {
|
|
88
|
-
const { data
|
|
94
|
+
const { data } = params;
|
|
89
95
|
if (!this.keyInfo || !this.cryptoKeyPair) {
|
|
90
96
|
throw new Error("Stamper not initialized. Call init() first.");
|
|
91
97
|
}
|
|
@@ -99,7 +105,10 @@ var IndexedDbStamper = class {
|
|
|
99
105
|
dataBytes
|
|
100
106
|
);
|
|
101
107
|
const signatureBase64url = (0, import_base64url.base64urlEncode)(new Uint8Array(signature));
|
|
102
|
-
const
|
|
108
|
+
const stampType = params.type || this.type;
|
|
109
|
+
const idToken = params.type === "OIDC" ? params.idToken : this.idToken;
|
|
110
|
+
const salt = params.type === "OIDC" ? params.salt : this.salt;
|
|
111
|
+
const stampData = stampType === "PKI" ? {
|
|
103
112
|
// Decode base58 public key to bytes, then encode as base64url (consistent with ApiKeyStamper)
|
|
104
113
|
publicKey: (0, import_base64url.base64urlEncode)(import_bs58.default.decode(this.keyInfo.publicKey)),
|
|
105
114
|
signature: signatureBase64url,
|
|
@@ -107,9 +116,9 @@ var IndexedDbStamper = class {
|
|
|
107
116
|
algorithm: this.algorithm
|
|
108
117
|
} : {
|
|
109
118
|
kind: "OIDC",
|
|
110
|
-
idToken
|
|
119
|
+
idToken,
|
|
111
120
|
publicKey: (0, import_base64url.base64urlEncode)(import_bs58.default.decode(this.keyInfo.publicKey)),
|
|
112
|
-
salt
|
|
121
|
+
salt,
|
|
113
122
|
algorithm: this.algorithm,
|
|
114
123
|
signature: signatureBase64url
|
|
115
124
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -3,18 +3,24 @@ import { base64urlEncode } from "@phantom/base64url";
|
|
|
3
3
|
import bs58 from "bs58";
|
|
4
4
|
import { Algorithm } from "@phantom/sdk-types";
|
|
5
5
|
var IndexedDbStamper = class {
|
|
6
|
-
//
|
|
6
|
+
// Optional for PKI, required for OIDC
|
|
7
7
|
constructor(config = {}) {
|
|
8
8
|
this.db = null;
|
|
9
9
|
this.keyInfo = null;
|
|
10
10
|
this.cryptoKeyPair = null;
|
|
11
11
|
this.algorithm = Algorithm.ed25519;
|
|
12
|
+
// Use Ed25519 for maximum security and performance
|
|
13
|
+
// The type of stamper, can be changed at any time
|
|
14
|
+
this.type = "PKI";
|
|
12
15
|
if (typeof window === "undefined" || !window.indexedDB) {
|
|
13
16
|
throw new Error("IndexedDbStamper requires a browser environment with IndexedDB support");
|
|
14
17
|
}
|
|
15
18
|
this.dbName = config.dbName || "phantom-indexed-db-stamper";
|
|
16
19
|
this.storeName = config.storeName || "crypto-keys";
|
|
17
20
|
this.keyName = config.keyName || "signing-key";
|
|
21
|
+
this.type = config.type || "PKI";
|
|
22
|
+
this.idToken = config.idToken;
|
|
23
|
+
this.salt = config.salt;
|
|
18
24
|
}
|
|
19
25
|
/**
|
|
20
26
|
* Initialize the stamper by opening IndexedDB and retrieving or generating keys
|
|
@@ -51,7 +57,7 @@ var IndexedDbStamper = class {
|
|
|
51
57
|
* @returns Complete X-Phantom-Stamp header value
|
|
52
58
|
*/
|
|
53
59
|
async stamp(params) {
|
|
54
|
-
const { data
|
|
60
|
+
const { data } = params;
|
|
55
61
|
if (!this.keyInfo || !this.cryptoKeyPair) {
|
|
56
62
|
throw new Error("Stamper not initialized. Call init() first.");
|
|
57
63
|
}
|
|
@@ -65,7 +71,10 @@ var IndexedDbStamper = class {
|
|
|
65
71
|
dataBytes
|
|
66
72
|
);
|
|
67
73
|
const signatureBase64url = base64urlEncode(new Uint8Array(signature));
|
|
68
|
-
const
|
|
74
|
+
const stampType = params.type || this.type;
|
|
75
|
+
const idToken = params.type === "OIDC" ? params.idToken : this.idToken;
|
|
76
|
+
const salt = params.type === "OIDC" ? params.salt : this.salt;
|
|
77
|
+
const stampData = stampType === "PKI" ? {
|
|
69
78
|
// Decode base58 public key to bytes, then encode as base64url (consistent with ApiKeyStamper)
|
|
70
79
|
publicKey: base64urlEncode(bs58.decode(this.keyInfo.publicKey)),
|
|
71
80
|
signature: signatureBase64url,
|
|
@@ -73,9 +82,9 @@ var IndexedDbStamper = class {
|
|
|
73
82
|
algorithm: this.algorithm
|
|
74
83
|
} : {
|
|
75
84
|
kind: "OIDC",
|
|
76
|
-
idToken
|
|
85
|
+
idToken,
|
|
77
86
|
publicKey: base64urlEncode(bs58.decode(this.keyInfo.publicKey)),
|
|
78
|
-
salt
|
|
87
|
+
salt,
|
|
79
88
|
algorithm: this.algorithm,
|
|
80
89
|
signature: signatureBase64url
|
|
81
90
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phantom/indexed-db-stamper",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "IndexedDB stamper for Phantom Wallet SDK with non-extractable key storage",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@phantom/base64url": "^0.1.0",
|
|
43
|
-
"@phantom/crypto": "^0.1.
|
|
44
|
-
"@phantom/embedded-provider-core": "^0.1.
|
|
45
|
-
"@phantom/sdk-types": "^0.1.
|
|
43
|
+
"@phantom/crypto": "^0.1.2",
|
|
44
|
+
"@phantom/embedded-provider-core": "^0.1.4",
|
|
45
|
+
"@phantom/sdk-types": "^0.1.3",
|
|
46
46
|
"bs58": "^6.0.0",
|
|
47
47
|
"buffer": "^6.0.3"
|
|
48
48
|
},
|