@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.
Files changed (90) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +552 -0
  3. package/build/.gitkeep +0 -0
  4. package/build/consts.d.ts +9 -0
  5. package/build/consts.d.ts.map +1 -0
  6. package/build/consts.js +9 -0
  7. package/build/consts.js.map +1 -0
  8. package/build/errors.d.ts +22 -0
  9. package/build/errors.d.ts.map +1 -0
  10. package/build/errors.js +41 -0
  11. package/build/errors.js.map +1 -0
  12. package/build/i18n/en.json +8 -0
  13. package/build/i18n/wallet-en.json +99 -0
  14. package/build/i18n.d.ts +2 -0
  15. package/build/i18n.d.ts.map +1 -0
  16. package/build/i18n.js +6 -0
  17. package/build/i18n.js.map +1 -0
  18. package/build/index.d.ts +9 -0
  19. package/build/index.d.ts.map +1 -0
  20. package/build/index.js +8 -0
  21. package/build/index.js.map +1 -0
  22. package/build/model.d.ts +4 -0
  23. package/build/model.d.ts.map +1 -0
  24. package/build/model.js +41 -0
  25. package/build/model.js.map +1 -0
  26. package/build/plugins/ed25519owl.d.ts +3 -0
  27. package/build/plugins/ed25519owl.d.ts.map +1 -0
  28. package/build/plugins/ed25519owl.js +23 -0
  29. package/build/plugins/ed25519owl.js.map +1 -0
  30. package/build/plugins/exports.d.ts +3 -0
  31. package/build/plugins/exports.d.ts.map +1 -0
  32. package/build/plugins/exports.js +3 -0
  33. package/build/plugins/exports.js.map +1 -0
  34. package/build/plugins/index.d.ts +2 -0
  35. package/build/plugins/index.d.ts.map +1 -0
  36. package/build/plugins/index.js +6 -0
  37. package/build/plugins/index.js.map +1 -0
  38. package/build/types.d.ts +64 -0
  39. package/build/types.d.ts.map +1 -0
  40. package/build/types.js +2 -0
  41. package/build/types.js.map +1 -0
  42. package/build/utils/index.d.ts +4 -0
  43. package/build/utils/index.d.ts.map +1 -0
  44. package/build/utils/index.js +4 -0
  45. package/build/utils/index.js.map +1 -0
  46. package/build/utils/key.d.ts +3 -0
  47. package/build/utils/key.d.ts.map +1 -0
  48. package/build/utils/key.js +24 -0
  49. package/build/utils/key.js.map +1 -0
  50. package/build/utils/mnemonic.d.ts +6 -0
  51. package/build/utils/mnemonic.d.ts.map +1 -0
  52. package/build/utils/mnemonic.js +15 -0
  53. package/build/utils/mnemonic.js.map +1 -0
  54. package/build/utils.d.ts +5 -0
  55. package/build/utils.d.ts.map +1 -0
  56. package/build/utils.js +24 -0
  57. package/build/utils.js.map +1 -0
  58. package/build/wallet/index.d.ts +2 -0
  59. package/build/wallet/index.d.ts.map +1 -0
  60. package/build/wallet/index.js +2 -0
  61. package/build/wallet/index.js.map +1 -0
  62. package/build/wallet/types.d.ts +30 -0
  63. package/build/wallet/types.d.ts.map +1 -0
  64. package/build/wallet/types.js +2 -0
  65. package/build/wallet/types.js.map +1 -0
  66. package/build/wallet.d.ts +3 -0
  67. package/build/wallet.d.ts.map +1 -0
  68. package/build/wallet.js +151 -0
  69. package/build/wallet.js.map +1 -0
  70. package/package.json +42 -0
  71. package/src/consts.ts +16 -0
  72. package/src/errors.ts +51 -0
  73. package/src/i18n/en.json +8 -0
  74. package/src/i18n/wallet-en.json +99 -0
  75. package/src/i18n.ts +7 -0
  76. package/src/index.ts +9 -0
  77. package/src/model.ts +52 -0
  78. package/src/plugins/ed25519owl.ts +35 -0
  79. package/src/plugins/exports.ts +3 -0
  80. package/src/plugins/index.ts +9 -0
  81. package/src/types.ts +89 -0
  82. package/src/utils/index.ts +4 -0
  83. package/src/utils/key.ts +29 -0
  84. package/src/utils/mnemonic.ts +24 -0
  85. package/src/utils.ts +34 -0
  86. package/src/wallet/index.ts +2 -0
  87. package/src/wallet/types.ts +43 -0
  88. package/src/wallet.ts +183 -0
  89. package/tsconfig.json +16 -0
  90. package/tsconfig.tsbuildinfo +1 -0
package/src/utils.ts ADDED
@@ -0,0 +1,34 @@
1
+ import { ENTITY_PREFIX, KP_SEP, PREFIX_SEP, PROFILE_PREFIX, SERVICE_PREFIX } from './consts.js'
2
+ import type { KeyMeta } from './types.js'
3
+
4
+ export const toPath = (...args: (string | string[])[]) => args.map(
5
+ arg => Array.isArray(arg) ? arg.join(PREFIX_SEP) : arg
6
+ ).join(KP_SEP)
7
+
8
+ export const mataToPath = (meta: Partial<KeyMeta>): string => {
9
+ const { scopes, id, entityId } = meta
10
+ const items: (string | string[])[] = []
11
+ if (scopes != null && scopes.length === 1) {
12
+ items.push([SERVICE_PREFIX, scopes[0]])
13
+ }
14
+ if (entityId != null) {
15
+ items.push([ENTITY_PREFIX, entityId])
16
+ }
17
+ if (id != null) {
18
+ items.push([PROFILE_PREFIX, id])
19
+ }
20
+
21
+ return toPath(...items)
22
+ }
23
+
24
+ const skipFields = ['name']
25
+
26
+ export const matchMeta = (haystack: KeyMeta, needle: Partial<KeyMeta>): boolean =>
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
+ ))
@@ -0,0 +1,2 @@
1
+
2
+ export type * from './types.js'
@@ -0,0 +1,43 @@
1
+ import { DIDKeyPair, KeyMeta } from '../types.js'
2
+
3
+ export interface WalletFacade {
4
+ sign: (entityId: string | null, payload: Uint8Array, opts?: WalletOptions) => Promise<Uint8Array>
5
+
6
+ createKey: (entityId: string, opts?: NewKeyOptions) => Promise<string>
7
+
8
+ getEntityKey: (entityId: string, opts?: WalletOptions) => Promise<WalletKey>
9
+
10
+ // TODO: This operation is maximum unsecure. It needs to be double checked by user
11
+ // and probably limited by the client to only OwlMeans services
12
+ getMasterDid: (opts?: RequestReason) => Promise<string>
13
+
14
+ selectKey: (opts?: WalletOptions) => Promise<WalletKey>
15
+
16
+ getPublicDetails: (did: string, opts?: RequestReason) => Promise<WalletKey>
17
+
18
+ requestPermissions: (methods: string[], opts?: WalletOptions) => Promise<boolean>
19
+
20
+ close: () => Promise<void>
21
+ }
22
+
23
+ export interface WalletKey {
24
+ key: Partial<DIDKeyPair>
25
+ meta: KeyMeta
26
+ }
27
+
28
+ export interface RequestReason {
29
+ intro?: string
30
+ reason?: string
31
+ timestamp?: number
32
+ }
33
+
34
+ export interface WalletOptions extends RequestReason {
35
+ purpose?: string
36
+ type?: string
37
+ profileId?: string
38
+ service?: string
39
+ }
40
+
41
+ export interface NewKeyOptions extends WalletOptions {
42
+ name: string
43
+ }
package/src/wallet.ts ADDED
@@ -0,0 +1,183 @@
1
+ import { DIDInitializationError, DIDKeyError, DIDWalletError } from './errors.js'
2
+ import type { DIDKeyModel, DIDStore, DIDWallet, KeyMeta, KeyPairRecord, MakeDIDWalletOptions } from './types.js'
3
+ import { generateMnemonic, toEntropy, toMnemonic, toSeed } from './utils/mnemonic.js'
4
+ import { KEY_OWL, MASTER } from './consts.js'
5
+ import { plugins } from './plugins/index.js'
6
+ import { ed25519owlPluginBuilder } from './plugins/ed25519owl.js'
7
+ import { produceKey } from './utils/key.js'
8
+ import { makeDidKeyModel } from './model.js'
9
+ import { mataToPath, matchMeta } from './utils.js'
10
+
11
+ export const makeWallet = async (store: DIDStore, opts?: MakeDIDWalletOptions) => {
12
+ if (await store.master.load(MASTER) == null) {
13
+ if (!opts?.force && !opts?.allowEmpty) {
14
+ throw new DIDInitializationError('master')
15
+ }
16
+ }
17
+
18
+ const type = opts?.type ?? KEY_OWL
19
+ if (plugins[type] == null) {
20
+ if (opts?.allowCustomType) {
21
+ plugins[type] = ed25519owlPluginBuilder(type)
22
+ }
23
+ }
24
+
25
+ const wallet: DIDWallet = {
26
+ store,
27
+
28
+ generate: async opts => {
29
+ const mnemonic = generateMnemonic(opts)
30
+
31
+ const seed = {
32
+ entropy: toEntropy(mnemonic),
33
+ seed: toSeed(mnemonic)
34
+ }
35
+
36
+ const master = produceKey(seed.seed, type)
37
+ await store.master.save({ id: MASTER, ...master, ...seed })
38
+ },
39
+
40
+ mnemonic: async crash => {
41
+ const master = await store.master.get(MASTER)
42
+ if (master.seed == null) {
43
+ if (crash) {
44
+ throw new DIDWalletError('mnemonic')
45
+ }
46
+ return false
47
+ }
48
+
49
+ return toMnemonic(master.seed)
50
+ },
51
+
52
+ master: async () => makeDidKeyModel(await store.master.get(MASTER)),
53
+
54
+ add: async (key, meta) => {
55
+ if (key.keyPair == null || key.keyPair.privateKey == null) {
56
+ throw new DIDWalletError('key:non-managable')
57
+ }
58
+ const stored = await store.keys.load(key.exportAddress())
59
+ if (stored != null) {
60
+ throw new DIDWalletError('key:exists')
61
+ }
62
+ await store.keys.create({ id: key.exportAddress(), ...key.keyPair })
63
+ await store.meta.create({ ...meta, id: key.exportAddress() })
64
+ },
65
+
66
+ meta: async key => {
67
+ if (typeof key === 'string') {
68
+ if (null == await store.keys.load(key)) {
69
+ throw new DIDWalletError('no:key')
70
+ }
71
+
72
+ return store.meta.get(key)
73
+ }
74
+
75
+ return wallet.meta(key.exportAddress())
76
+ },
77
+
78
+ update: async (key, meta) => {
79
+ if (key.keyPair == null) {
80
+ throw new DIDWalletError('key:non-managable')
81
+ }
82
+ const did = key.exportAddress()
83
+ const returnKey = await store.keys.save({ id: did, ...key.keyPair })
84
+ const returnMeta = await store.meta.save({ ...meta, id: did })
85
+
86
+ return [makeDidKeyModel(returnKey), returnMeta]
87
+ },
88
+
89
+ get: async did => {
90
+ if (await store.keys.load(did) == null) {
91
+ throw new DIDWalletError('no:key')
92
+ }
93
+ return makeDidKeyModel(await store.keys.get(did))
94
+ },
95
+
96
+ find: async meta => {
97
+ const result = await store.meta.list(
98
+ Object.fromEntries(Object.entries(meta).filter(([_, v]) => typeof v !== 'boolean'))
99
+ )
100
+
101
+ const keys = await Promise.all(result.items.filter(item => matchMeta(item, meta))
102
+ .map(async meta => store.keys.get(meta.id)))
103
+
104
+ return keys.map(key => makeDidKeyModel(key))
105
+ },
106
+
107
+ provide: async meta => {
108
+ const found = await wallet.find(meta)
109
+ if (found.length === 0) {
110
+ const path = mataToPath(meta)
111
+ const master = await wallet.master()
112
+ const key = master.derive(path)
113
+ if (meta.name == null) {
114
+ throw new DIDKeyError('no:name')
115
+ }
116
+ const metaToSave: KeyMeta = {
117
+ ...meta, id: meta.id ?? key.exportAddress(), name: meta.name
118
+ }
119
+ await wallet.add(key, metaToSave)
120
+
121
+ return [key]
122
+ }
123
+
124
+ return found
125
+ },
126
+
127
+ remove: async did => {
128
+ if (typeof did === 'object') {
129
+ if ("keyPair" in did) {
130
+ return wallet.remove(did.exportAddress())
131
+ }
132
+ const keys = await wallet.find(did as KeyMeta)
133
+ const key = await keys.reduce<Promise<DIDKeyModel | null>>(async (_, key) => {
134
+ return wallet.remove(key)
135
+ }, Promise.resolve(null))
136
+ if (key == null) {
137
+ throw new DIDWalletError('no:key')
138
+ }
139
+ return key
140
+ }
141
+ const key = await store.keys.load(did)
142
+ if (key == null) {
143
+ throw new DIDWalletError('no:key')
144
+ }
145
+ await store.keys.delete(key)
146
+ const model = makeDidKeyModel(key)
147
+ await store.meta.delete(model.exportAddress())
148
+
149
+ return model
150
+ },
151
+
152
+ all: async () => {
153
+ const result: KeyPairRecord[] = []
154
+ let more = false
155
+ do {
156
+ const found = await store.keys.list({ pager: { page: Math.floor(result.length / 100), size: 100 } })
157
+ result.push(...found.items)
158
+ more = found.pager?.total != null && found.pager.total > result.length
159
+ } while (more)
160
+
161
+ return result.map(key => makeDidKeyModel(key))
162
+ },
163
+
164
+ allMeta: async () => {
165
+ const result: KeyMeta[] = []
166
+ let more = false
167
+ do {
168
+ // const found = await store.keys.list({ pager: { page: Math.floor(result.length / 100), size: 100 } })
169
+ const found = await store.meta.list({ pager: { page: Math.floor(result.length / 100), size: 100 } })
170
+ result.push(...found.items)
171
+ more = found.pager?.total != null && found.pager.total > result.length
172
+ } while (more)
173
+
174
+ return result
175
+ }
176
+ }
177
+
178
+ if (opts?.force) {
179
+ await wallet.generate(opts.mnemonic)
180
+ }
181
+
182
+ return wallet
183
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "extends": [
3
+ "../tsconfig.default.json",
4
+ "../tsconfig.react.json",
5
+ ],
6
+ "compilerOptions": {
7
+ "rootDir": "./src/", /* Specify the root folder within your source files. */
8
+ "outDir": "./build/", /* Specify an output folder for all emitted files. */
9
+ "moduleResolution": "Bundler"
10
+ },
11
+ "exclude": [
12
+ "./dist/**/*",
13
+ "./build/**/*",
14
+ "./*.ts"
15
+ ]
16
+ }
@@ -0,0 +1 @@
1
+ {"root":["./src/consts.ts","./src/errors.ts","./src/i18n.ts","./src/index.ts","./src/model.ts","./src/types.ts","./src/utils.ts","./src/wallet.ts","./src/plugins/ed25519owl.ts","./src/plugins/exports.ts","./src/plugins/index.ts","./src/utils/index.ts","./src/utils/key.ts","./src/utils/mnemonic.ts","./src/wallet/index.ts","./src/wallet/types.ts"],"version":"5.6.3"}