@owlmeans/did 0.1.18-rc.9 → 0.1.18
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 +2 -2
- package/agent-meta/manifest.json +3 -3
- package/agent-meta/skills/did/SKILL.md +113 -16
- package/build/consts.local.d.ts +2 -0
- package/build/consts.local.d.ts.map +1 -0
- package/build/consts.local.js +2 -0
- package/build/consts.local.js.map +1 -0
- package/build/i18n/fr.json +8 -0
- package/build/i18n/wallet-fr.json +99 -0
- package/build/i18n.js +19 -15
- package/build/i18n.js.map +1 -1
- package/build/model.d.ts.map +1 -1
- package/build/model.js +4 -4
- package/build/model.js.map +1 -1
- package/build/plugins/ed25519owl.js +5 -5
- package/build/plugins/ed25519owl.js.map +1 -1
- package/build/utils/index.d.ts +2 -0
- package/build/utils/index.d.ts.map +1 -1
- package/build/utils/index.js.map +1 -1
- package/build/utils/key.d.ts.map +1 -1
- package/build/utils/key.js +2 -2
- package/build/utils/key.js.map +1 -1
- package/build/utils/mnemonic/types.d.ts +13 -0
- package/build/utils/mnemonic/types.d.ts.map +1 -0
- package/build/utils/mnemonic/types.js +2 -0
- package/build/utils/mnemonic/types.js.map +1 -0
- package/build/utils/mnemonic.d.ts +3 -5
- package/build/utils/mnemonic.d.ts.map +1 -1
- package/build/utils/mnemonic.js +15 -11
- package/build/utils/mnemonic.js.map +1 -1
- package/build/utils/types.d.ts +11 -0
- package/build/utils/types.d.ts.map +1 -0
- package/build/utils/types.js +2 -0
- package/build/utils/types.js.map +1 -0
- package/build/utils.d.ts +3 -4
- package/build/utils.d.ts.map +1 -1
- package/build/utils.js +25 -21
- package/build/utils.js.map +1 -1
- package/build/wallet.d.ts.map +1 -1
- package/build/wallet.js +15 -15
- package/build/wallet.js.map +1 -1
- package/package.json +12 -11
- package/src/consts.local.ts +1 -0
- package/src/i18n/fr.json +8 -0
- package/src/i18n/wallet-fr.json +99 -0
- package/src/i18n.ts +20 -15
- package/src/model.ts +4 -4
- package/src/plugins/ed25519owl.ts +5 -5
- package/src/utils/index.ts +2 -0
- package/src/utils/key.ts +3 -3
- package/src/utils/mnemonic/types.ts +13 -0
- package/src/utils/mnemonic.ts +21 -14
- package/src/utils/types.ts +11 -0
- package/src/utils.ts +32 -26
- package/src/wallet.ts +19 -18
- package/tests/mnemonic.spec.ts +31 -0
- package/tsconfig.json +1 -1
- package/build/.gitkeep +0 -0
package/src/utils.ts
CHANGED
|
@@ -1,34 +1,40 @@
|
|
|
1
1
|
import { ENTITY_PREFIX, KP_SEP, PREFIX_SEP, PROFILE_PREFIX, SERVICE_PREFIX } from './consts.js'
|
|
2
2
|
import type { KeyMeta } from './types.js'
|
|
3
|
+
import { skipFields } from './consts.local.js'
|
|
4
|
+
import type { KeyPathUtils } from './utils/types.js'
|
|
3
5
|
|
|
4
|
-
export const
|
|
5
|
-
|
|
6
|
-
).join(
|
|
6
|
+
export const createKeyPathUtils = (): KeyPathUtils => {
|
|
7
|
+
const toPath = (...args: (string | string[])[]): string => args.map(
|
|
8
|
+
arg => Array.isArray(arg) ? arg.join(PREFIX_SEP) : arg
|
|
9
|
+
).join(KP_SEP)
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
const mataToPath = (meta: Partial<KeyMeta>): string => {
|
|
12
|
+
const { scopes, id, entityId } = meta
|
|
13
|
+
const items: (string | string[])[] = []
|
|
14
|
+
if (scopes != null && scopes.length === 1) {
|
|
15
|
+
items.push([SERVICE_PREFIX, scopes[0]])
|
|
16
|
+
}
|
|
17
|
+
if (entityId != null) {
|
|
18
|
+
items.push([ENTITY_PREFIX, entityId])
|
|
19
|
+
}
|
|
20
|
+
if (id != null) {
|
|
21
|
+
items.push([PROFILE_PREFIX, id])
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return toPath(...items)
|
|
19
25
|
}
|
|
20
26
|
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
const matchMeta = (haystack: KeyMeta, needle: Partial<KeyMeta>): boolean =>
|
|
28
|
+
Object.entries(needle).every(([key, value]) =>
|
|
29
|
+
skipFields.includes(key)
|
|
30
|
+
|| (haystack[key as keyof typeof haystack] != null
|
|
31
|
+
&& (Array.isArray(value)
|
|
32
|
+
? Array.isArray(haystack[key as keyof typeof haystack])
|
|
33
|
+
&& value.every(value => (haystack[key as keyof typeof haystack] as unknown[]).includes(value))
|
|
34
|
+
: haystack[key as keyof typeof haystack] === value)
|
|
35
|
+
))
|
|
23
36
|
|
|
24
|
-
|
|
37
|
+
return { toPath, mataToPath, matchMeta }
|
|
38
|
+
}
|
|
25
39
|
|
|
26
|
-
export const
|
|
27
|
-
Object.entries(needle).every(([key, value]) =>
|
|
28
|
-
skipFields.includes(key)
|
|
29
|
-
|| (haystack[key as keyof typeof haystack] != null
|
|
30
|
-
&& (Array.isArray(value)
|
|
31
|
-
? Array.isArray(haystack[key as keyof typeof haystack])
|
|
32
|
-
&& value.every(value => (haystack[key as keyof typeof haystack] as unknown[]).includes(value))
|
|
33
|
-
: haystack[key as keyof typeof haystack] === value)
|
|
34
|
-
))
|
|
40
|
+
export const keyPathUtils = createKeyPathUtils()
|
package/src/wallet.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { DIDInitializationError, DIDKeyError, DIDWalletError } from './errors.js'
|
|
2
|
-
import type {
|
|
3
|
-
import {
|
|
2
|
+
import type { Criteria } from '@owlmeans/resource'
|
|
3
|
+
import type { DIDKeyModel, DIDStore, DIDWallet, KeyMeta, KeyMetaRecord, KeyPairRecord, MakeDIDWalletOptions } from './types.js'
|
|
4
4
|
import { KEY_OWL, MASTER } from './consts.js'
|
|
5
5
|
import { plugins } from './plugins/index.js'
|
|
6
6
|
import { ed25519owlPluginBuilder } from './plugins/ed25519owl.js'
|
|
7
7
|
import { produceKey } from './utils/key.js'
|
|
8
8
|
import { makeDidKeyModel } from './model.js'
|
|
9
|
-
import {
|
|
9
|
+
import { keyPathUtils } from './utils.js'
|
|
10
|
+
import { mnemonicHelper } from './utils/mnemonic.js'
|
|
10
11
|
|
|
11
|
-
export const makeWallet = async (store: DIDStore, opts?: MakeDIDWalletOptions) => {
|
|
12
|
+
export const makeWallet = async (store: DIDStore, opts?: MakeDIDWalletOptions): Promise<DIDWallet> => {
|
|
12
13
|
if (await store.master.load(MASTER) == null) {
|
|
13
14
|
if (!opts?.force && !opts?.allowEmpty) {
|
|
14
15
|
throw new DIDInitializationError('master')
|
|
@@ -26,11 +27,11 @@ export const makeWallet = async (store: DIDStore, opts?: MakeDIDWalletOptions) =
|
|
|
26
27
|
store,
|
|
27
28
|
|
|
28
29
|
generate: async opts => {
|
|
29
|
-
const mnemonic = generateMnemonic(opts)
|
|
30
|
+
const mnemonic = mnemonicHelper.generateMnemonic(opts)
|
|
30
31
|
|
|
31
32
|
const seed = {
|
|
32
|
-
entropy: toEntropy(mnemonic),
|
|
33
|
-
seed: toSeed(mnemonic)
|
|
33
|
+
entropy: mnemonicHelper.toEntropy(mnemonic),
|
|
34
|
+
seed: mnemonicHelper.toSeed(mnemonic)
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
const master = produceKey(seed.seed, type)
|
|
@@ -46,7 +47,7 @@ export const makeWallet = async (store: DIDStore, opts?: MakeDIDWalletOptions) =
|
|
|
46
47
|
return false
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
return toMnemonic(master.seed)
|
|
50
|
+
return mnemonicHelper.toMnemonic(master.seed)
|
|
50
51
|
},
|
|
51
52
|
|
|
52
53
|
master: async () => makeDidKeyModel(await store.master.get(MASTER)),
|
|
@@ -94,11 +95,12 @@ export const makeWallet = async (store: DIDStore, opts?: MakeDIDWalletOptions) =
|
|
|
94
95
|
},
|
|
95
96
|
|
|
96
97
|
find: async meta => {
|
|
97
|
-
const
|
|
98
|
-
Object.
|
|
98
|
+
const where: Criteria<KeyMetaRecord> = Object.fromEntries(
|
|
99
|
+
Object.entries(meta).filter(([_, v]) => typeof v !== 'boolean')
|
|
99
100
|
)
|
|
101
|
+
const result = await store.meta.list(where)
|
|
100
102
|
|
|
101
|
-
const keys = await Promise.all(result.items.filter(item => matchMeta(item, meta))
|
|
103
|
+
const keys = await Promise.all(result.items.filter(item => keyPathUtils.matchMeta(item, meta))
|
|
102
104
|
.map(async meta => store.keys.get(meta.id)))
|
|
103
105
|
|
|
104
106
|
return keys.map(key => makeDidKeyModel(key))
|
|
@@ -107,7 +109,7 @@ export const makeWallet = async (store: DIDStore, opts?: MakeDIDWalletOptions) =
|
|
|
107
109
|
provide: async meta => {
|
|
108
110
|
const found = await wallet.find(meta)
|
|
109
111
|
if (found.length === 0) {
|
|
110
|
-
const path = mataToPath(meta)
|
|
112
|
+
const path = keyPathUtils.mataToPath(meta)
|
|
111
113
|
const master = await wallet.master()
|
|
112
114
|
const key = master.derive(path)
|
|
113
115
|
if (meta.name == null) {
|
|
@@ -142,7 +144,7 @@ export const makeWallet = async (store: DIDStore, opts?: MakeDIDWalletOptions) =
|
|
|
142
144
|
if (key == null) {
|
|
143
145
|
throw new DIDWalletError('no:key')
|
|
144
146
|
}
|
|
145
|
-
await store.keys.delete(
|
|
147
|
+
await store.keys.delete(did)
|
|
146
148
|
const model = makeDidKeyModel(key)
|
|
147
149
|
await store.meta.delete(model.exportAddress())
|
|
148
150
|
|
|
@@ -153,9 +155,9 @@ export const makeWallet = async (store: DIDStore, opts?: MakeDIDWalletOptions) =
|
|
|
153
155
|
const result: KeyPairRecord[] = []
|
|
154
156
|
let more = false
|
|
155
157
|
do {
|
|
156
|
-
const found = await store.keys.list(
|
|
158
|
+
const found = await store.keys.list(undefined, { page: Math.floor(result.length / 100), size: 100 })
|
|
157
159
|
result.push(...found.items)
|
|
158
|
-
more = found.
|
|
160
|
+
more = found.items.length > 0 && found.total > result.length
|
|
159
161
|
} while (more)
|
|
160
162
|
|
|
161
163
|
return result.map(key => makeDidKeyModel(key))
|
|
@@ -165,10 +167,9 @@ export const makeWallet = async (store: DIDStore, opts?: MakeDIDWalletOptions) =
|
|
|
165
167
|
const result: KeyMeta[] = []
|
|
166
168
|
let more = false
|
|
167
169
|
do {
|
|
168
|
-
|
|
169
|
-
const found = await store.meta.list({ pager: { page: Math.floor(result.length / 100), size: 100 } })
|
|
170
|
+
const found = await store.meta.list(undefined, { page: Math.floor(result.length / 100), size: 100 })
|
|
170
171
|
result.push(...found.items)
|
|
171
|
-
more = found.
|
|
172
|
+
more = found.items.length > 0 && found.total > result.length
|
|
172
173
|
} while (more)
|
|
173
174
|
|
|
174
175
|
return result
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test'
|
|
2
|
+
import { wordlist } from '@scure/bip39/wordlists/english.js'
|
|
3
|
+
import { mnemonicHelper } from '../src/utils/mnemonic.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Answers computed with @scure/bip39 1.6 before the v2 line: the seed of the all-`abandon` test mnemonic is
|
|
7
|
+
* the published BIP-39 vector, so a changed derivation fails here rather than as a different DID.
|
|
8
|
+
*/
|
|
9
|
+
const MNEMONIC = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
|
|
10
|
+
const SEED_HEX = '5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4'
|
|
11
|
+
|
|
12
|
+
describe('@owlmeans/did — mnemonic derivation', () => {
|
|
13
|
+
test('the seed of the BIP-39 test mnemonic is the published vector', () => {
|
|
14
|
+
expect(mnemonicHelper.toEntropy(MNEMONIC)).toBe(SEED_HEX)
|
|
15
|
+
expect(Buffer.from(mnemonicHelper.toSeed(MNEMONIC), 'base64').toString('hex')).toBe(SEED_HEX)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
test('entropy turns back into the mnemonic it came from', () => {
|
|
19
|
+
expect(mnemonicHelper.toMnemonic('00000000000000000000000000000000')).toBe(MNEMONIC)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('a generated mnemonic is a valid BIP-39 length and made of words of the list', () => {
|
|
23
|
+
const words = mnemonicHelper.generateMnemonic({ size: 12 }).split(' ')
|
|
24
|
+
expect([12, 15, 18, 21, 24]).toContain(words.length)
|
|
25
|
+
expect(words.every(word => wordlist.includes(word))).toBe(true)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('sizes outside 12–24 are refused', () => {
|
|
29
|
+
expect(() => mnemonicHelper.generateMnemonic({ size: 8 })).toThrow()
|
|
30
|
+
})
|
|
31
|
+
})
|
package/tsconfig.json
CHANGED
package/build/.gitkeep
DELETED
|
File without changes
|