@owlmeans/did 0.1.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.
- package/LICENSE +21 -0
- package/README.md +552 -0
- package/build/.gitkeep +0 -0
- package/build/consts.d.ts +9 -0
- package/build/consts.d.ts.map +1 -0
- package/build/consts.js +9 -0
- package/build/consts.js.map +1 -0
- package/build/errors.d.ts +22 -0
- package/build/errors.d.ts.map +1 -0
- package/build/errors.js +41 -0
- package/build/errors.js.map +1 -0
- package/build/i18n/en.json +8 -0
- package/build/i18n/wallet-en.json +99 -0
- package/build/i18n.d.ts +2 -0
- package/build/i18n.d.ts.map +1 -0
- package/build/i18n.js +6 -0
- package/build/i18n.js.map +1 -0
- package/build/index.d.ts +9 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +8 -0
- package/build/index.js.map +1 -0
- package/build/model.d.ts +4 -0
- package/build/model.d.ts.map +1 -0
- package/build/model.js +41 -0
- package/build/model.js.map +1 -0
- package/build/plugins/ed25519owl.d.ts +3 -0
- package/build/plugins/ed25519owl.d.ts.map +1 -0
- package/build/plugins/ed25519owl.js +23 -0
- package/build/plugins/ed25519owl.js.map +1 -0
- package/build/plugins/exports.d.ts +3 -0
- package/build/plugins/exports.d.ts.map +1 -0
- package/build/plugins/exports.js +3 -0
- package/build/plugins/exports.js.map +1 -0
- package/build/plugins/index.d.ts +2 -0
- package/build/plugins/index.d.ts.map +1 -0
- package/build/plugins/index.js +6 -0
- package/build/plugins/index.js.map +1 -0
- package/build/types.d.ts +64 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/build/utils/index.d.ts +4 -0
- package/build/utils/index.d.ts.map +1 -0
- package/build/utils/index.js +4 -0
- package/build/utils/index.js.map +1 -0
- package/build/utils/key.d.ts +3 -0
- package/build/utils/key.d.ts.map +1 -0
- package/build/utils/key.js +24 -0
- package/build/utils/key.js.map +1 -0
- package/build/utils/mnemonic.d.ts +6 -0
- package/build/utils/mnemonic.d.ts.map +1 -0
- package/build/utils/mnemonic.js +15 -0
- package/build/utils/mnemonic.js.map +1 -0
- package/build/utils.d.ts +5 -0
- package/build/utils.d.ts.map +1 -0
- package/build/utils.js +24 -0
- package/build/utils.js.map +1 -0
- package/build/wallet/index.d.ts +2 -0
- package/build/wallet/index.d.ts.map +1 -0
- package/build/wallet/index.js +2 -0
- package/build/wallet/index.js.map +1 -0
- package/build/wallet/types.d.ts +30 -0
- package/build/wallet/types.d.ts.map +1 -0
- package/build/wallet/types.js +2 -0
- package/build/wallet/types.js.map +1 -0
- package/build/wallet.d.ts +3 -0
- package/build/wallet.d.ts.map +1 -0
- package/build/wallet.js +151 -0
- package/build/wallet.js.map +1 -0
- package/package.json +42 -0
- package/src/consts.ts +16 -0
- package/src/errors.ts +51 -0
- package/src/i18n/en.json +8 -0
- package/src/i18n/wallet-en.json +99 -0
- package/src/i18n.ts +7 -0
- package/src/index.ts +9 -0
- package/src/model.ts +52 -0
- package/src/plugins/ed25519owl.ts +35 -0
- package/src/plugins/exports.ts +3 -0
- package/src/plugins/index.ts +9 -0
- package/src/types.ts +89 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/key.ts +29 -0
- package/src/utils/mnemonic.ts +24 -0
- package/src/utils.ts +34 -0
- package/src/wallet/index.ts +2 -0
- package/src/wallet/types.ts +43 -0
- package/src/wallet.ts +183 -0
- package/tsconfig.json +16 -0
- package/tsconfig.tsbuildinfo +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 OwlMeans Common — Fullstack typescript framework
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
# @owlmeans/did
|
|
2
|
+
|
|
3
|
+
A comprehensive Decentralized Identity (DID) and cryptographic wallet management library for OwlMeans Common applications. This package provides secure key generation, hierarchical deterministic wallets, and decentralized identity management with mnemonic seed support.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `@owlmeans/did` package is the core decentralized identity library in the OwlMeans Common ecosystem, providing:
|
|
8
|
+
|
|
9
|
+
- **DID Wallet Management**: Hierarchical deterministic wallet creation and management
|
|
10
|
+
- **Mnemonic Key Generation**: BIP39-compatible mnemonic phrase generation and recovery
|
|
11
|
+
- **Cryptographic Key Derivation**: Secure key derivation with configurable depth
|
|
12
|
+
- **Identity Management**: Profile and entity-based identity organization
|
|
13
|
+
- **Secure Storage**: Resource-based secure storage for keys and metadata
|
|
14
|
+
- **Plugin Architecture**: Extensible cryptographic algorithm support
|
|
15
|
+
- **Cross-Platform Support**: Works across server, web, and mobile environments
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @owlmeans/did
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Core Concepts
|
|
24
|
+
|
|
25
|
+
### DID Wallet
|
|
26
|
+
|
|
27
|
+
A `DIDWallet` is a hierarchical deterministic wallet that manages cryptographic keys and associated metadata. It supports key derivation, profile management, and secure storage.
|
|
28
|
+
|
|
29
|
+
### DID Key Model
|
|
30
|
+
|
|
31
|
+
A `DIDKeyModel` extends the basic key pair model with DID-specific functionality, including path-based key derivation and parent-child key relationships.
|
|
32
|
+
|
|
33
|
+
### Key Metadata
|
|
34
|
+
|
|
35
|
+
Key metadata associates human-readable information with cryptographic keys, including names, entity IDs, and profile information.
|
|
36
|
+
|
|
37
|
+
### Mnemonic Seeds
|
|
38
|
+
|
|
39
|
+
Mnemonic phrases provide a human-readable way to backup and restore wallets, following BIP39 standards.
|
|
40
|
+
|
|
41
|
+
## API Reference
|
|
42
|
+
|
|
43
|
+
### Types
|
|
44
|
+
|
|
45
|
+
#### `DIDWallet`
|
|
46
|
+
Core wallet interface for managing decentralized identities.
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
interface DIDWallet {
|
|
50
|
+
store: DIDStore // Storage backend
|
|
51
|
+
generate: (opts?: MnemonicOptions) => Promise<void> // Generate new wallet
|
|
52
|
+
mnemonic: (crash?: boolean) => Promise<string | false> // Get mnemonic phrase
|
|
53
|
+
master: () => Promise<DIDKeyModel> // Get master key
|
|
54
|
+
add: (key: DIDKeyModel, meta: KeyMeta) => Promise<void> // Add key with metadata
|
|
55
|
+
meta: (key: string | DIDKeyModel) => Promise<KeyMeta> // Get key metadata
|
|
56
|
+
update: (key: DIDKeyModel, meta: KeyMeta) => Promise<[DIDKeyModel, KeyMeta]> // Update key metadata
|
|
57
|
+
get: (did: string) => Promise<DIDKeyModel | null> // Get key by DID
|
|
58
|
+
find: (meta: Partial<KeyMeta>) => Promise<DIDKeyModel[]> // Find keys by metadata
|
|
59
|
+
provide: (meta: Partial<KeyMeta>) => Promise<DIDKeyModel[]> // Provide keys matching criteria
|
|
60
|
+
remove: (did: string | KeyMeta | DIDKeyModel) => Promise<DIDKeyModel> // Remove key
|
|
61
|
+
all: () => Promise<DIDKeyModel[]> // Get all keys
|
|
62
|
+
allMeta: () => Promise<KeyMeta[]> // Get all metadata
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### `DIDKeyModel`
|
|
67
|
+
Extended key model with DID capabilities.
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
interface DIDKeyModel extends KeyPairModel {
|
|
71
|
+
keyPair?: DIDKeyPair // Underlying key pair
|
|
72
|
+
derive: (path: string) => DIDKeyModel // Derive child keys
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### `KeyMeta`
|
|
77
|
+
Metadata associated with keys.
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
interface KeyMeta extends Partial<Profile> {
|
|
81
|
+
id: string // Unique identifier
|
|
82
|
+
name: string // Human-readable name
|
|
83
|
+
entityId?: string // Associated entity ID
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
#### `DIDStore`
|
|
88
|
+
Storage interface for wallet data.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
interface DIDStore {
|
|
92
|
+
master: MasterResource // Master key storage
|
|
93
|
+
keys: KeyPairResource // Key pair storage
|
|
94
|
+
meta: KeyMetaResource // Metadata storage
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Factory Functions
|
|
99
|
+
|
|
100
|
+
#### `makeWallet(store: DIDStore, opts?: MakeDIDWalletOptions): Promise<DIDWallet>`
|
|
101
|
+
Creates a new DID wallet instance.
|
|
102
|
+
|
|
103
|
+
**Parameters:**
|
|
104
|
+
- `store`: Storage backend for wallet data
|
|
105
|
+
- `opts`: Optional wallet creation options
|
|
106
|
+
|
|
107
|
+
**Options:**
|
|
108
|
+
```typescript
|
|
109
|
+
interface MakeDIDWalletOptions {
|
|
110
|
+
force?: boolean // Force creation even if master exists
|
|
111
|
+
allowEmpty?: boolean // Allow empty wallet creation
|
|
112
|
+
mnemonic?: MnemonicOptions // Mnemonic generation options
|
|
113
|
+
type?: string // Key type (default: 'owlmk')
|
|
114
|
+
allowCustomType?: boolean // Allow custom key types
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### `makeDidKeyModel(input?: KeyPair | string): DIDKeyModel`
|
|
119
|
+
Creates a DID key model from key pair or type string.
|
|
120
|
+
|
|
121
|
+
### Wallet Operations
|
|
122
|
+
|
|
123
|
+
#### `generate(opts?: MnemonicOptions): Promise<void>`
|
|
124
|
+
Generates a new wallet with mnemonic seed.
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
// Generate with default options
|
|
128
|
+
await wallet.generate()
|
|
129
|
+
|
|
130
|
+
// Generate with custom entropy
|
|
131
|
+
await wallet.generate({ size: 256 })
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
#### `mnemonic(crash?: boolean): Promise<string | false>`
|
|
135
|
+
Retrieves the wallet's mnemonic phrase.
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
// Get mnemonic (safe, returns false if not available)
|
|
139
|
+
const mnemonic = await wallet.mnemonic()
|
|
140
|
+
|
|
141
|
+
// Get mnemonic (throws error if not available)
|
|
142
|
+
const mnemonic = await wallet.mnemonic(true)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### `master(): Promise<DIDKeyModel>`
|
|
146
|
+
Gets the master key for the wallet.
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
const masterKey = await wallet.master()
|
|
150
|
+
console.log('Master DID:', masterKey.did)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Key Management
|
|
154
|
+
|
|
155
|
+
#### `add(key: DIDKeyModel, meta: KeyMeta): Promise<void>`
|
|
156
|
+
Adds a key with metadata to the wallet.
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
const childKey = masterKey.derive('profile/user')
|
|
160
|
+
await wallet.add(childKey, {
|
|
161
|
+
id: 'user-profile',
|
|
162
|
+
name: 'User Profile Key',
|
|
163
|
+
entityId: 'user-123'
|
|
164
|
+
})
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### `get(did: string): Promise<DIDKeyModel | null>`
|
|
168
|
+
Retrieves a key by its DID.
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
const key = await wallet.get('did:owlmeans:key:...')
|
|
172
|
+
if (key) {
|
|
173
|
+
console.log('Found key:', key.did)
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### `find(meta: Partial<KeyMeta>): Promise<DIDKeyModel[]>`
|
|
178
|
+
Finds keys matching metadata criteria.
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// Find all profile keys
|
|
182
|
+
const profileKeys = await wallet.find({ entityId: 'user-123' })
|
|
183
|
+
|
|
184
|
+
// Find keys by name pattern
|
|
185
|
+
const namedKeys = await wallet.find({ name: 'Service Key' })
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Key Derivation
|
|
189
|
+
|
|
190
|
+
#### `derive(path: string): DIDKeyModel`
|
|
191
|
+
Derives child keys from parent keys using hierarchical paths.
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
const masterKey = await wallet.master()
|
|
195
|
+
|
|
196
|
+
// Derive profile key
|
|
197
|
+
const profileKey = masterKey.derive('profile/user')
|
|
198
|
+
|
|
199
|
+
// Derive service key
|
|
200
|
+
const serviceKey = masterKey.derive('service/api')
|
|
201
|
+
|
|
202
|
+
// Derive entity-specific key
|
|
203
|
+
const entityKey = masterKey.derive('entity/org/dept')
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Constants
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
const KEY_OWL = 'owlmk' // Default key type
|
|
210
|
+
const MAX_DEPTH = 6 // Maximum derivation depth
|
|
211
|
+
const PROFILE_PREFIX = 'profile' // Profile key prefix
|
|
212
|
+
const ENTITY_PREFIX = 'entity' // Entity key prefix
|
|
213
|
+
const SERVICE_PREFIX = 'service' // Service key prefix
|
|
214
|
+
const MASTER = '_master_key' // Master key identifier
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Usage Examples
|
|
218
|
+
|
|
219
|
+
### Basic Wallet Creation
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import { makeWallet } from '@owlmeans/did'
|
|
223
|
+
import { createDIDStore } from './storage'
|
|
224
|
+
|
|
225
|
+
// Create storage backend
|
|
226
|
+
const store = createDIDStore()
|
|
227
|
+
|
|
228
|
+
// Create new wallet
|
|
229
|
+
const wallet = await makeWallet(store, {
|
|
230
|
+
allowEmpty: true
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
// Generate master key
|
|
234
|
+
await wallet.generate()
|
|
235
|
+
|
|
236
|
+
// Get mnemonic for backup
|
|
237
|
+
const mnemonic = await wallet.mnemonic()
|
|
238
|
+
console.log('Backup phrase:', mnemonic)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Key Derivation and Management
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
// Get master key
|
|
245
|
+
const master = await wallet.master()
|
|
246
|
+
|
|
247
|
+
// Derive keys for different purposes
|
|
248
|
+
const profileKey = master.derive('profile/personal')
|
|
249
|
+
const workKey = master.derive('profile/work')
|
|
250
|
+
const apiKey = master.derive('service/api/v1')
|
|
251
|
+
|
|
252
|
+
// Add keys with metadata
|
|
253
|
+
await wallet.add(profileKey, {
|
|
254
|
+
id: 'personal-profile',
|
|
255
|
+
name: 'Personal Profile',
|
|
256
|
+
entityId: 'user-123'
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
await wallet.add(workKey, {
|
|
260
|
+
id: 'work-profile',
|
|
261
|
+
name: 'Work Profile',
|
|
262
|
+
entityId: 'org-456'
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
await wallet.add(apiKey, {
|
|
266
|
+
id: 'api-service',
|
|
267
|
+
name: 'API Service Key',
|
|
268
|
+
entityId: 'service-789'
|
|
269
|
+
})
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Identity Management
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
// Create identity for a user
|
|
276
|
+
const createUserIdentity = async (userId: string, name: string) => {
|
|
277
|
+
const master = await wallet.master()
|
|
278
|
+
const userKey = master.derive(`profile/${userId}`)
|
|
279
|
+
|
|
280
|
+
await wallet.add(userKey, {
|
|
281
|
+
id: `user-${userId}`,
|
|
282
|
+
name: `${name}'s Identity`,
|
|
283
|
+
entityId: userId,
|
|
284
|
+
scopes: ['user:profile', 'user:data']
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
return userKey
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Create identity for a service
|
|
291
|
+
const createServiceIdentity = async (serviceName: string) => {
|
|
292
|
+
const master = await wallet.master()
|
|
293
|
+
const serviceKey = master.derive(`service/${serviceName}`)
|
|
294
|
+
|
|
295
|
+
await wallet.add(serviceKey, {
|
|
296
|
+
id: `service-${serviceName}`,
|
|
297
|
+
name: `${serviceName} Service`,
|
|
298
|
+
entityId: serviceName,
|
|
299
|
+
scopes: ['service:*']
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
return serviceKey
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Signature and Verification
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
// Sign data with a specific key
|
|
310
|
+
const signWithProfile = async (data: string, profileId: string) => {
|
|
311
|
+
const keys = await wallet.find({ id: profileId })
|
|
312
|
+
if (keys.length === 0) {
|
|
313
|
+
throw new Error('Profile key not found')
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const key = keys[0]
|
|
317
|
+
const signature = await key.sign(Buffer.from(data, 'utf8'))
|
|
318
|
+
|
|
319
|
+
return {
|
|
320
|
+
data,
|
|
321
|
+
signature: signature.toString('base64'),
|
|
322
|
+
did: key.did,
|
|
323
|
+
publicKey: key.publicKey?.toString('base64')
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Verify signature
|
|
328
|
+
const verifySignature = async (signedData: any) => {
|
|
329
|
+
const key = await wallet.get(signedData.did)
|
|
330
|
+
if (!key) {
|
|
331
|
+
throw new Error('Key not found')
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const signature = Buffer.from(signedData.signature, 'base64')
|
|
335
|
+
const data = Buffer.from(signedData.data, 'utf8')
|
|
336
|
+
|
|
337
|
+
return await key.verify(data, signature)
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Multi-Entity Wallet
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
// Organization with multiple departments
|
|
345
|
+
const setupOrganizationWallet = async () => {
|
|
346
|
+
const master = await wallet.master()
|
|
347
|
+
|
|
348
|
+
// Organization master key
|
|
349
|
+
const orgKey = master.derive('entity/acme-corp')
|
|
350
|
+
await wallet.add(orgKey, {
|
|
351
|
+
id: 'acme-corp',
|
|
352
|
+
name: 'ACME Corporation',
|
|
353
|
+
entityId: 'org-acme'
|
|
354
|
+
})
|
|
355
|
+
|
|
356
|
+
// Department keys
|
|
357
|
+
const departments = ['hr', 'engineering', 'sales']
|
|
358
|
+
|
|
359
|
+
for (const dept of departments) {
|
|
360
|
+
const deptKey = orgKey.derive(`dept/${dept}`)
|
|
361
|
+
await wallet.add(deptKey, {
|
|
362
|
+
id: `acme-${dept}`,
|
|
363
|
+
name: `ACME ${dept.toUpperCase()} Department`,
|
|
364
|
+
entityId: `org-acme-${dept}`
|
|
365
|
+
})
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Employee keys within departments
|
|
369
|
+
const engineeringKey = await wallet.get('acme-engineering')
|
|
370
|
+
const employeeKey = engineeringKey!.derive('employee/john-doe')
|
|
371
|
+
|
|
372
|
+
await wallet.add(employeeKey, {
|
|
373
|
+
id: 'john-doe-work',
|
|
374
|
+
name: 'John Doe Work Identity',
|
|
375
|
+
entityId: 'user-john-doe',
|
|
376
|
+
groups: ['engineering', 'senior-dev']
|
|
377
|
+
})
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Wallet Recovery
|
|
382
|
+
|
|
383
|
+
```typescript
|
|
384
|
+
// Recover wallet from mnemonic
|
|
385
|
+
const recoverWallet = async (mnemonic: string, store: DIDStore) => {
|
|
386
|
+
// Create wallet allowing empty state
|
|
387
|
+
const wallet = await makeWallet(store, { allowEmpty: true })
|
|
388
|
+
|
|
389
|
+
// Import from mnemonic
|
|
390
|
+
await wallet.generate({ mnemonic })
|
|
391
|
+
|
|
392
|
+
// Verify master key was restored
|
|
393
|
+
const master = await wallet.master()
|
|
394
|
+
console.log('Recovered master DID:', master.did)
|
|
395
|
+
|
|
396
|
+
// List all recovered keys
|
|
397
|
+
const allKeys = await wallet.all()
|
|
398
|
+
console.log(`Recovered ${allKeys.length} keys`)
|
|
399
|
+
|
|
400
|
+
return wallet
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Key Export and Import
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
// Export key for external use
|
|
408
|
+
const exportKey = async (keyId: string) => {
|
|
409
|
+
const keys = await wallet.find({ id: keyId })
|
|
410
|
+
if (keys.length === 0) {
|
|
411
|
+
throw new Error('Key not found')
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const key = keys[0]
|
|
415
|
+
const meta = await wallet.meta(key)
|
|
416
|
+
|
|
417
|
+
return {
|
|
418
|
+
did: key.did,
|
|
419
|
+
publicKey: key.publicKey?.toString('base64'),
|
|
420
|
+
privateKey: key.privateKey?.toString('base64'), // Only if needed
|
|
421
|
+
meta: {
|
|
422
|
+
id: meta.id,
|
|
423
|
+
name: meta.name,
|
|
424
|
+
entityId: meta.entityId
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// Import external key
|
|
430
|
+
const importKey = async (keyData: any) => {
|
|
431
|
+
const keyModel = makeDidKeyModel({
|
|
432
|
+
type: 'ed25519',
|
|
433
|
+
publicKey: Buffer.from(keyData.publicKey, 'base64'),
|
|
434
|
+
privateKey: keyData.privateKey ? Buffer.from(keyData.privateKey, 'base64') : undefined
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
await wallet.add(keyModel, keyData.meta)
|
|
438
|
+
}
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
## Advanced Features
|
|
442
|
+
|
|
443
|
+
### Custom Key Types
|
|
444
|
+
|
|
445
|
+
```typescript
|
|
446
|
+
// Register custom key type
|
|
447
|
+
const customKeyType = 'custom-ed25519'
|
|
448
|
+
|
|
449
|
+
const wallet = await makeWallet(store, {
|
|
450
|
+
type: customKeyType,
|
|
451
|
+
allowCustomType: true
|
|
452
|
+
})
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### Hierarchical Path Management
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
// Standardized path structure
|
|
459
|
+
const createStandardPath = (type: 'profile' | 'entity' | 'service', identifier: string, subpath?: string) => {
|
|
460
|
+
const basePath = `${type}/${identifier}`
|
|
461
|
+
return subpath ? `${basePath}/${subpath}` : basePath
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// Usage
|
|
465
|
+
const userProfilePath = createStandardPath('profile', 'user123')
|
|
466
|
+
const serviceApiPath = createStandardPath('service', 'api', 'v1')
|
|
467
|
+
const entityDeptPath = createStandardPath('entity', 'corp', 'dept/engineering')
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
### Batch Operations
|
|
471
|
+
|
|
472
|
+
```typescript
|
|
473
|
+
// Batch key creation
|
|
474
|
+
const createBatchKeys = async (specifications: Array<{path: string, meta: Omit<KeyMeta, 'id'>}>) => {
|
|
475
|
+
const master = await wallet.master()
|
|
476
|
+
const keys: DIDKeyModel[] = []
|
|
477
|
+
|
|
478
|
+
for (const spec of specifications) {
|
|
479
|
+
const key = master.derive(spec.path)
|
|
480
|
+
await wallet.add(key, {
|
|
481
|
+
...spec.meta,
|
|
482
|
+
id: `${spec.meta.name.toLowerCase().replace(/\s+/g, '-')}`
|
|
483
|
+
})
|
|
484
|
+
keys.push(key)
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
return keys
|
|
488
|
+
}
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
## Error Handling
|
|
492
|
+
|
|
493
|
+
The package provides specialized error types:
|
|
494
|
+
|
|
495
|
+
```typescript
|
|
496
|
+
import { DIDWalletError, DIDKeyError, DIDInitializationError } from '@owlmeans/did'
|
|
497
|
+
|
|
498
|
+
try {
|
|
499
|
+
const wallet = await makeWallet(store)
|
|
500
|
+
await wallet.generate()
|
|
501
|
+
} catch (error) {
|
|
502
|
+
if (error instanceof DIDInitializationError) {
|
|
503
|
+
console.error('Wallet initialization failed:', error.message)
|
|
504
|
+
} else if (error instanceof DIDKeyError) {
|
|
505
|
+
console.error('Key operation failed:', error.message)
|
|
506
|
+
} else if (error instanceof DIDWalletError) {
|
|
507
|
+
console.error('Wallet operation failed:', error.message)
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
## Integration with OwlMeans Ecosystem
|
|
513
|
+
|
|
514
|
+
The `@owlmeans/did` package integrates with:
|
|
515
|
+
|
|
516
|
+
- **@owlmeans/basic-keys**: Core cryptographic operations and key management
|
|
517
|
+
- **@owlmeans/auth**: Authentication and authorization with DID-based identities
|
|
518
|
+
- **@owlmeans/resource**: Storage backend for wallet data persistence
|
|
519
|
+
- **@owlmeans/client-did**: Client-side DID wallet implementations
|
|
520
|
+
- **@owlmeans/server-auth**: Server-side DID authentication
|
|
521
|
+
- **@owlmeans/context**: Service registration and dependency injection
|
|
522
|
+
|
|
523
|
+
## Security Considerations
|
|
524
|
+
|
|
525
|
+
- Store mnemonic phrases securely and never expose them in logs
|
|
526
|
+
- Use appropriate key derivation paths to prevent key correlation
|
|
527
|
+
- Implement proper access controls for wallet operations
|
|
528
|
+
- Regular backup of wallet data and mnemonic phrases
|
|
529
|
+
- Use secure random number generation for key creation
|
|
530
|
+
- Validate all imported keys and metadata
|
|
531
|
+
|
|
532
|
+
## Best Practices
|
|
533
|
+
|
|
534
|
+
### Key Management
|
|
535
|
+
- Use descriptive names and metadata for all keys
|
|
536
|
+
- Implement consistent path naming conventions
|
|
537
|
+
- Regular audit of stored keys and remove unused ones
|
|
538
|
+
- Use different keys for different purposes (signing, encryption, etc.)
|
|
539
|
+
|
|
540
|
+
### Security
|
|
541
|
+
- Never store private keys in plain text
|
|
542
|
+
- Use hardware security modules where possible
|
|
543
|
+
- Implement proper key rotation policies
|
|
544
|
+
- Monitor for unauthorized key access
|
|
545
|
+
|
|
546
|
+
### Performance
|
|
547
|
+
- Cache frequently used keys in memory
|
|
548
|
+
- Use batch operations for multiple key operations
|
|
549
|
+
- Implement proper indexing for key searches
|
|
550
|
+
- Consider key compression for storage efficiency
|
|
551
|
+
|
|
552
|
+
Fixes #32.
|
package/build/.gitkeep
ADDED
|
File without changes
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const KEY_OWL = "owlmk";
|
|
2
|
+
export declare const KP_SEP = "/";
|
|
3
|
+
export declare const MAX_DEPTH = 6;
|
|
4
|
+
export declare const PROFILE_PREFIX = "profile";
|
|
5
|
+
export declare const ENTITY_PREFIX = "entity";
|
|
6
|
+
export declare const SERVICE_PREFIX = "service";
|
|
7
|
+
export declare const PREFIX_SEP = ".";
|
|
8
|
+
export declare const MASTER = "_master_key";
|
|
9
|
+
//# sourceMappingURL=consts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,OAAO,UAAU,CAAA;AAE9B,eAAO,MAAM,MAAM,MAAM,CAAA;AAEzB,eAAO,MAAM,SAAS,IAAI,CAAA;AAE1B,eAAO,MAAM,cAAc,YAAY,CAAA;AAEvC,eAAO,MAAM,aAAa,WAAW,CAAA;AAErC,eAAO,MAAM,cAAc,YAAY,CAAA;AAEvC,eAAO,MAAM,UAAU,MAAM,CAAA;AAE7B,eAAO,MAAM,MAAM,gBAAgB,CAAA"}
|
package/build/consts.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const KEY_OWL = 'owlmk';
|
|
2
|
+
export const KP_SEP = '/';
|
|
3
|
+
export const MAX_DEPTH = 6;
|
|
4
|
+
export const PROFILE_PREFIX = 'profile';
|
|
5
|
+
export const ENTITY_PREFIX = 'entity';
|
|
6
|
+
export const SERVICE_PREFIX = 'service';
|
|
7
|
+
export const PREFIX_SEP = '.';
|
|
8
|
+
export const MASTER = '_master_key';
|
|
9
|
+
//# sourceMappingURL=consts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAA;AAE9B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;AAEzB,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAA;AAE1B,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAA;AAEvC,MAAM,CAAC,MAAM,aAAa,GAAG,QAAQ,CAAA;AAErC,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAA;AAEvC,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAA;AAE7B,MAAM,CAAC,MAAM,MAAM,GAAG,aAAa,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ResilientError } from '@owlmeans/error';
|
|
2
|
+
export declare class DIDError extends ResilientError {
|
|
3
|
+
static typeName: string;
|
|
4
|
+
constructor(message?: string);
|
|
5
|
+
}
|
|
6
|
+
export declare class DIDKeyError extends DIDError {
|
|
7
|
+
static typeName: string;
|
|
8
|
+
constructor(message?: string);
|
|
9
|
+
}
|
|
10
|
+
export declare class DIDWalletError extends DIDError {
|
|
11
|
+
static typeName: string;
|
|
12
|
+
constructor(message?: string);
|
|
13
|
+
}
|
|
14
|
+
export declare class DIDWalletPermissionError extends DIDWalletError {
|
|
15
|
+
static typeName: string;
|
|
16
|
+
constructor(message?: string);
|
|
17
|
+
}
|
|
18
|
+
export declare class DIDInitializationError extends DIDWalletError {
|
|
19
|
+
static typeName: string;
|
|
20
|
+
constructor(message?: string);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,qBAAa,QAAS,SAAQ,cAAc;IAC1C,OAAuB,QAAQ,SAAa;gBAEhC,OAAO,GAAE,MAAgB;CAGtC;AAED,qBAAa,WAAY,SAAQ,QAAQ;IACvC,OAAuB,QAAQ,SAA6B;gBAEhD,OAAO,GAAE,MAAgB;CAItC;AAED,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,OAAuB,QAAQ,SAAgC;gBAEnD,OAAO,GAAE,MAAgB;CAItC;AAED,qBAAa,wBAAyB,SAAQ,cAAc;IAC1D,OAAuB,QAAQ,SAA0C;gBAE7D,OAAO,GAAE,MAAgB;CAItC;AAED,qBAAa,sBAAuB,SAAQ,cAAc;IACxD,OAAuB,QAAQ,SAA8C;gBAEjE,OAAO,GAAE,MAAgB;CAItC"}
|
package/build/errors.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ResilientError } from '@owlmeans/error';
|
|
2
|
+
export class DIDError extends ResilientError {
|
|
3
|
+
static typeName = 'DIDError';
|
|
4
|
+
constructor(message = 'error') {
|
|
5
|
+
super(DIDError.typeName, `did:${message}`);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export class DIDKeyError extends DIDError {
|
|
9
|
+
static typeName = `${DIDError.typeName}:Key`;
|
|
10
|
+
constructor(message = 'error') {
|
|
11
|
+
super(`wallet:${message}`);
|
|
12
|
+
this.type = DIDKeyError.typeName;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export class DIDWalletError extends DIDError {
|
|
16
|
+
static typeName = `${DIDError.typeName}:Wallet`;
|
|
17
|
+
constructor(message = 'error') {
|
|
18
|
+
super(`wallet:${message}`);
|
|
19
|
+
this.type = DIDWalletError.typeName;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export class DIDWalletPermissionError extends DIDWalletError {
|
|
23
|
+
static typeName = `${DIDWalletError.typeName}:Permission`;
|
|
24
|
+
constructor(message = 'error') {
|
|
25
|
+
super(`permission:${message}`);
|
|
26
|
+
this.type = DIDWalletPermissionError.typeName;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export class DIDInitializationError extends DIDWalletError {
|
|
30
|
+
static typeName = `${DIDWalletError.typeName}:Initialization`;
|
|
31
|
+
constructor(message = 'error') {
|
|
32
|
+
super(`init:${message}`);
|
|
33
|
+
this.type = DIDInitializationError.typeName;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
ResilientError.registerErrorClass(DIDError);
|
|
37
|
+
ResilientError.registerErrorClass(DIDKeyError);
|
|
38
|
+
ResilientError.registerErrorClass(DIDWalletError);
|
|
39
|
+
ResilientError.registerErrorClass(DIDWalletPermissionError);
|
|
40
|
+
ResilientError.registerErrorClass(DIDInitializationError);
|
|
41
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,MAAM,OAAO,QAAS,SAAQ,cAAc;IACnC,MAAM,CAAU,QAAQ,GAAG,UAAU,CAAA;IAE5C,YAAY,UAAkB,OAAO;QACnC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,OAAO,EAAE,CAAC,CAAA;IAC5C,CAAC;;AAGH,MAAM,OAAO,WAAY,SAAQ,QAAQ;IAChC,MAAM,CAAU,QAAQ,GAAG,GAAG,QAAQ,CAAC,QAAQ,MAAM,CAAA;IAE5D,YAAY,UAAkB,OAAO;QACnC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAA;QAC1B,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAA;IAClC,CAAC;;AAGH,MAAM,OAAO,cAAe,SAAQ,QAAQ;IACnC,MAAM,CAAU,QAAQ,GAAG,GAAG,QAAQ,CAAC,QAAQ,SAAS,CAAA;IAE/D,YAAY,UAAkB,OAAO;QACnC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAA;QAC1B,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC,QAAQ,CAAA;IACrC,CAAC;;AAGH,MAAM,OAAO,wBAAyB,SAAQ,cAAc;IACnD,MAAM,CAAU,QAAQ,GAAG,GAAG,cAAc,CAAC,QAAQ,aAAa,CAAA;IAEzE,YAAY,UAAkB,OAAO;QACnC,KAAK,CAAC,cAAc,OAAO,EAAE,CAAC,CAAA;QAC9B,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC,QAAQ,CAAA;IAC/C,CAAC;;AAGH,MAAM,OAAO,sBAAuB,SAAQ,cAAc;IACjD,MAAM,CAAU,QAAQ,GAAG,GAAG,cAAc,CAAC,QAAQ,iBAAiB,CAAA;IAE7E,YAAY,UAAkB,OAAO;QACnC,KAAK,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAA;QACxB,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC,QAAQ,CAAA;IAC7C,CAAC;;AAGH,cAAc,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAA;AAC3C,cAAc,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAA;AAC9C,cAAc,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAA;AACjD,cAAc,CAAC,kBAAkB,CAAC,wBAAwB,CAAC,CAAA;AAC3D,cAAc,CAAC,kBAAkB,CAAC,sBAAsB,CAAC,CAAA"}
|