@docknetwork/wallet-sdk-wasm 1.7.7-alpha.0 → 1.9.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 (327) hide show
  1. package/package.json +7 -20
  2. package/rollup.config.mjs +1 -0
  3. package/src/globals.d.ts +4 -1
  4. package/src/services/blockchain/cached-did-resolver.ts +4 -3
  5. package/src/services/blockchain/normalize-did-document.ts +73 -0
  6. package/src/services/blockchain/service.ts +0 -2
  7. package/src/services/credential/bbs-revocation.test.js +147 -0
  8. package/src/services/credential/bbs-revocation.ts +65 -18
  9. package/src/services/credential/config.ts +7 -0
  10. package/src/services/credential/index.test.js +261 -17
  11. package/src/services/credential/oid4vci.js +44 -0
  12. package/src/services/credential/oid4vci.test.js +162 -0
  13. package/src/services/credential/pex-helpers.js +77 -31
  14. package/src/services/credential/pex-helpers.test.js +4 -4
  15. package/src/services/credential/sd-jwt.ts +41 -5
  16. package/src/services/credential/service-rpc.js +6 -0
  17. package/src/services/credential/service.ts +171 -16
  18. package/src/services/credential/utils.js +3 -5
  19. package/src/services/delegation/index.android.js +3 -0
  20. package/src/services/delegation/index.ios.js +3 -0
  21. package/src/services/delegation/index.ts +1 -0
  22. package/src/services/delegation/service-rpc.ts +21 -0
  23. package/src/services/delegation/service.ts +59 -0
  24. package/src/services/edv/service-rpc.js +18 -2
  25. package/src/services/edv/service.test.js +327 -0
  26. package/src/services/edv/service.ts +103 -13
  27. package/src/services/index.js +2 -0
  28. package/src/wallet/rpc-storage-interface.js +9 -4
  29. package/lib/core/crypto.js +0 -45
  30. package/lib/core/crypto.mjs +0 -33
  31. package/lib/core/format-utils.js +0 -51
  32. package/lib/core/format-utils.mjs +0 -42
  33. package/lib/core/keychain.js +0 -61
  34. package/lib/core/keychain.mjs +0 -37
  35. package/lib/core/logger.js +0 -13
  36. package/lib/core/logger.mjs +0 -9
  37. package/lib/core/storage.js +0 -14
  38. package/lib/core/storage.mjs +0 -9
  39. package/lib/core/validation.js +0 -29
  40. package/lib/core/validation.mjs +0 -16
  41. package/lib/core/webview-logger.js +0 -49
  42. package/lib/core/webview-logger.mjs +0 -41
  43. package/lib/errors.js +0 -17
  44. package/lib/errors.mjs +0 -12
  45. package/lib/events.js +0 -18
  46. package/lib/events.mjs +0 -13
  47. package/lib/index.js +0 -146
  48. package/lib/index.mjs +0 -144
  49. package/lib/logger.js +0 -22
  50. package/lib/logger.mjs +0 -17
  51. package/lib/modules/event-manager.js +0 -46
  52. package/lib/modules/event-manager.mjs +0 -37
  53. package/lib/modules/network-manager.js +0 -80
  54. package/lib/modules/network-manager.mjs +0 -71
  55. package/lib/mrklt.js +0 -2
  56. package/lib/mrklt.mjs +0 -1
  57. package/lib/rpc-client.js +0 -83
  58. package/lib/rpc-client.mjs +0 -73
  59. package/lib/rpc-server.js +0 -97
  60. package/lib/rpc-server.mjs +0 -95
  61. package/lib/rpc-util.js +0 -113
  62. package/lib/rpc-util.mjs +0 -103
  63. package/lib/sandbox-rpc-server.js +0 -28
  64. package/lib/sandbox-rpc-server.mjs +0 -26
  65. package/lib/sandbox.js +0 -102
  66. package/lib/sandbox.mjs +0 -100
  67. package/lib/services/blockchain/cached-did-resolver.js +0 -113
  68. package/lib/services/blockchain/cached-did-resolver.mjs +0 -109
  69. package/lib/services/blockchain/configs.js +0 -7
  70. package/lib/services/blockchain/configs.mjs +0 -3
  71. package/lib/services/blockchain/index.android.js +0 -18
  72. package/lib/services/blockchain/index.android.mjs +0 -14
  73. package/lib/services/blockchain/index.ios.js +0 -18
  74. package/lib/services/blockchain/index.ios.mjs +0 -14
  75. package/lib/services/blockchain/index.js +0 -36
  76. package/lib/services/blockchain/index.mjs +0 -28
  77. package/lib/services/blockchain/service-rpc.js +0 -72
  78. package/lib/services/blockchain/service-rpc.mjs +0 -68
  79. package/lib/services/blockchain/service.js +0 -312
  80. package/lib/services/blockchain/service.mjs +0 -306
  81. package/lib/services/credential/bbs-revocation.js +0 -92
  82. package/lib/services/credential/bbs-revocation.mjs +0 -87
  83. package/lib/services/credential/bound-check.js +0 -77
  84. package/lib/services/credential/bound-check.mjs +0 -64
  85. package/lib/services/credential/config.js +0 -56
  86. package/lib/services/credential/config.mjs +0 -47
  87. package/lib/services/credential/delegatable-credentials.js +0 -300
  88. package/lib/services/credential/delegatable-credentials.mjs +0 -263
  89. package/lib/services/credential/index.android.js +0 -19
  90. package/lib/services/credential/index.android.mjs +0 -15
  91. package/lib/services/credential/index.ios.js +0 -19
  92. package/lib/services/credential/index.ios.mjs +0 -15
  93. package/lib/services/credential/index.js +0 -106
  94. package/lib/services/credential/index.mjs +0 -67
  95. package/lib/services/credential/pex-helpers.js +0 -333
  96. package/lib/services/credential/pex-helpers.mjs +0 -319
  97. package/lib/services/credential/range-proofs-example.js +0 -107
  98. package/lib/services/credential/range-proofs-example.mjs +0 -103
  99. package/lib/services/credential/sd-jwt.js +0 -214
  100. package/lib/services/credential/sd-jwt.mjs +0 -200
  101. package/lib/services/credential/service-rpc.js +0 -61
  102. package/lib/services/credential/service-rpc.mjs +0 -57
  103. package/lib/services/credential/service.js +0 -683
  104. package/lib/services/credential/service.mjs +0 -672
  105. package/lib/services/credential/utils.js +0 -103
  106. package/lib/services/credential/utils.mjs +0 -78
  107. package/lib/services/dids/config.js +0 -40
  108. package/lib/services/dids/config.mjs +0 -31
  109. package/lib/services/dids/index.android.js +0 -19
  110. package/lib/services/dids/index.android.mjs +0 -15
  111. package/lib/services/dids/index.ios.js +0 -19
  112. package/lib/services/dids/index.ios.mjs +0 -15
  113. package/lib/services/dids/index.js +0 -23
  114. package/lib/services/dids/index.mjs +0 -19
  115. package/lib/services/dids/keypair-utils.js +0 -142
  116. package/lib/services/dids/keypair-utils.mjs +0 -113
  117. package/lib/services/dids/service-rpc.js +0 -37
  118. package/lib/services/dids/service-rpc.mjs +0 -33
  119. package/lib/services/dids/service.js +0 -100
  120. package/lib/services/dids/service.mjs +0 -92
  121. package/lib/services/edv/configs.js +0 -25
  122. package/lib/services/edv/configs.mjs +0 -16
  123. package/lib/services/edv/hmac.js +0 -88
  124. package/lib/services/edv/hmac.mjs +0 -63
  125. package/lib/services/edv/index.android.js +0 -19
  126. package/lib/services/edv/index.android.mjs +0 -15
  127. package/lib/services/edv/index.ios.js +0 -19
  128. package/lib/services/edv/index.ios.mjs +0 -15
  129. package/lib/services/edv/index.js +0 -32
  130. package/lib/services/edv/index.mjs +0 -24
  131. package/lib/services/edv/service-rpc.js +0 -78
  132. package/lib/services/edv/service-rpc.mjs +0 -74
  133. package/lib/services/edv/service.js +0 -370
  134. package/lib/services/edv/service.mjs +0 -357
  135. package/lib/services/index.js +0 -94
  136. package/lib/services/index.mjs +0 -92
  137. package/lib/services/pex/config.js +0 -29
  138. package/lib/services/pex/config.mjs +0 -20
  139. package/lib/services/pex/index.android.js +0 -19
  140. package/lib/services/pex/index.android.mjs +0 -15
  141. package/lib/services/pex/index.ios.js +0 -19
  142. package/lib/services/pex/index.ios.mjs +0 -15
  143. package/lib/services/pex/index.js +0 -12
  144. package/lib/services/pex/index.mjs +0 -4
  145. package/lib/services/pex/service-rpc.js +0 -39
  146. package/lib/services/pex/service-rpc.mjs +0 -35
  147. package/lib/services/pex/service.js +0 -91
  148. package/lib/services/pex/service.mjs +0 -86
  149. package/lib/services/pex/tests/jest.config.js +0 -25
  150. package/lib/services/pex/tests/jest.config.mjs +0 -23
  151. package/lib/services/relay-service/configs.js +0 -45
  152. package/lib/services/relay-service/configs.mjs +0 -36
  153. package/lib/services/relay-service/index.android.js +0 -21
  154. package/lib/services/relay-service/index.android.mjs +0 -17
  155. package/lib/services/relay-service/index.ios.js +0 -21
  156. package/lib/services/relay-service/index.ios.mjs +0 -17
  157. package/lib/services/relay-service/index.js +0 -14
  158. package/lib/services/relay-service/index.mjs +0 -6
  159. package/lib/services/relay-service/service-rpc.js +0 -47
  160. package/lib/services/relay-service/service-rpc.mjs +0 -43
  161. package/lib/services/relay-service/service.js +0 -181
  162. package/lib/services/relay-service/service.mjs +0 -173
  163. package/lib/services/rpc-service-client.js +0 -36
  164. package/lib/services/rpc-service-client.mjs +0 -28
  165. package/lib/services/sandbox.js +0 -10
  166. package/lib/services/sandbox.mjs +0 -8
  167. package/lib/services/storage/configs.js +0 -7
  168. package/lib/services/storage/configs.mjs +0 -3
  169. package/lib/services/storage/index.android.js +0 -18
  170. package/lib/services/storage/index.android.mjs +0 -14
  171. package/lib/services/storage/index.ios.js +0 -18
  172. package/lib/services/storage/index.ios.mjs +0 -14
  173. package/lib/services/storage/index.js +0 -26
  174. package/lib/services/storage/index.mjs +0 -24
  175. package/lib/services/storage/service-rpc.js +0 -37
  176. package/lib/services/storage/service-rpc.mjs +0 -33
  177. package/lib/services/storage/service.js +0 -32
  178. package/lib/services/storage/service.mjs +0 -27
  179. package/lib/services/test-utils.js +0 -98
  180. package/lib/services/test-utils.mjs +0 -84
  181. package/lib/services/util-crypto/configs.js +0 -23
  182. package/lib/services/util-crypto/configs.mjs +0 -15
  183. package/lib/services/util-crypto/index.android.js +0 -19
  184. package/lib/services/util-crypto/index.android.mjs +0 -15
  185. package/lib/services/util-crypto/index.ios.js +0 -19
  186. package/lib/services/util-crypto/index.ios.mjs +0 -15
  187. package/lib/services/util-crypto/index.js +0 -14
  188. package/lib/services/util-crypto/index.mjs +0 -6
  189. package/lib/services/util-crypto/service-rpc.js +0 -42
  190. package/lib/services/util-crypto/service-rpc.mjs +0 -38
  191. package/lib/services/util-crypto/service.js +0 -108
  192. package/lib/services/util-crypto/service.mjs +0 -83
  193. package/lib/services/wallet/configs.js +0 -32
  194. package/lib/services/wallet/configs.mjs +0 -23
  195. package/lib/services/wallet/index.android.js +0 -21
  196. package/lib/services/wallet/index.android.mjs +0 -17
  197. package/lib/services/wallet/index.ios.js +0 -21
  198. package/lib/services/wallet/index.ios.mjs +0 -17
  199. package/lib/services/wallet/index.js +0 -17
  200. package/lib/services/wallet/index.mjs +0 -9
  201. package/lib/services/wallet/service-rpc.js +0 -33
  202. package/lib/services/wallet/service-rpc.mjs +0 -29
  203. package/lib/services/wallet/service.js +0 -62
  204. package/lib/services/wallet/service.mjs +0 -57
  205. package/lib/setup-nodejs.js +0 -93
  206. package/lib/setup-nodejs.mjs +0 -91
  207. package/lib/setup-tests.js +0 -92
  208. package/lib/setup-tests.mjs +0 -90
  209. package/lib/src/core/crypto.d.ts +0 -8
  210. package/lib/src/core/crypto.d.ts.map +0 -1
  211. package/lib/src/core/format-utils.d.ts +0 -26
  212. package/lib/src/core/format-utils.d.ts.map +0 -1
  213. package/lib/src/core/logger.d.ts +0 -3
  214. package/lib/src/core/logger.d.ts.map +0 -1
  215. package/lib/src/core/storage.d.ts +0 -8
  216. package/lib/src/core/storage.d.ts.map +0 -1
  217. package/lib/src/core/validation.d.ts +0 -6
  218. package/lib/src/core/validation.d.ts.map +0 -1
  219. package/lib/src/errors.d.ts +0 -7
  220. package/lib/src/errors.d.ts.map +0 -1
  221. package/lib/src/logger.d.ts +0 -5
  222. package/lib/src/logger.d.ts.map +0 -1
  223. package/lib/src/modules/event-manager.d.ts +0 -12
  224. package/lib/src/modules/event-manager.d.ts.map +0 -1
  225. package/lib/src/modules/network-manager.d.ts +0 -32
  226. package/lib/src/modules/network-manager.d.ts.map +0 -1
  227. package/lib/src/rpc-client.d.ts +0 -4
  228. package/lib/src/rpc-client.d.ts.map +0 -1
  229. package/lib/src/rpc-util.d.ts +0 -11
  230. package/lib/src/rpc-util.d.ts.map +0 -1
  231. package/lib/src/services/blockchain/cached-did-resolver.d.ts +0 -28
  232. package/lib/src/services/blockchain/cached-did-resolver.d.ts.map +0 -1
  233. package/lib/src/services/blockchain/cached-did-resolver.test.d.ts +0 -2
  234. package/lib/src/services/blockchain/cached-did-resolver.test.d.ts.map +0 -1
  235. package/lib/src/services/blockchain/configs.d.ts +0 -7
  236. package/lib/src/services/blockchain/configs.d.ts.map +0 -1
  237. package/lib/src/services/blockchain/service.d.ts +0 -155
  238. package/lib/src/services/blockchain/service.d.ts.map +0 -1
  239. package/lib/src/services/credential/bbs-revocation.d.ts +0 -10
  240. package/lib/src/services/credential/bbs-revocation.d.ts.map +0 -1
  241. package/lib/src/services/credential/bound-check.d.ts +0 -61
  242. package/lib/src/services/credential/bound-check.d.ts.map +0 -1
  243. package/lib/src/services/credential/bound-check.test.d.ts +0 -2
  244. package/lib/src/services/credential/bound-check.test.d.ts.map +0 -1
  245. package/lib/src/services/credential/config.d.ts +0 -10
  246. package/lib/src/services/credential/config.d.ts.map +0 -1
  247. package/lib/src/services/credential/delegatable-credentials.d.ts +0 -272
  248. package/lib/src/services/credential/delegatable-credentials.d.ts.map +0 -1
  249. package/lib/src/services/credential/index.d.ts +0 -35
  250. package/lib/src/services/credential/index.d.ts.map +0 -1
  251. package/lib/src/services/credential/pex-helpers.d.ts +0 -23
  252. package/lib/src/services/credential/pex-helpers.d.ts.map +0 -1
  253. package/lib/src/services/credential/range-proofs-example.d.ts +0 -2
  254. package/lib/src/services/credential/range-proofs-example.d.ts.map +0 -1
  255. package/lib/src/services/credential/sd-jwt.test.d.ts +0 -2
  256. package/lib/src/services/credential/sd-jwt.test.d.ts.map +0 -1
  257. package/lib/src/services/credential/service.d.ts +0 -313
  258. package/lib/src/services/credential/service.d.ts.map +0 -1
  259. package/lib/src/services/credential/utils.d.ts +0 -3
  260. package/lib/src/services/credential/utils.d.ts.map +0 -1
  261. package/lib/src/services/dids/config.d.ts +0 -24
  262. package/lib/src/services/dids/config.d.ts.map +0 -1
  263. package/lib/src/services/dids/keypair-utils.d.ts +0 -15
  264. package/lib/src/services/dids/keypair-utils.d.ts.map +0 -1
  265. package/lib/src/services/dids/service-rpc.d.ts +0 -11
  266. package/lib/src/services/dids/service-rpc.d.ts.map +0 -1
  267. package/lib/src/services/dids/service.d.ts +0 -70
  268. package/lib/src/services/dids/service.d.ts.map +0 -1
  269. package/lib/src/services/edv/configs.d.ts +0 -12
  270. package/lib/src/services/edv/configs.d.ts.map +0 -1
  271. package/lib/src/services/edv/hmac.d.ts +0 -29
  272. package/lib/src/services/edv/hmac.d.ts.map +0 -1
  273. package/lib/src/services/edv/service.d.ts +0 -229
  274. package/lib/src/services/edv/service.d.ts.map +0 -1
  275. package/lib/src/services/pex/config.d.ts +0 -21
  276. package/lib/src/services/pex/config.d.ts.map +0 -1
  277. package/lib/src/services/pex/service.d.ts +0 -21
  278. package/lib/src/services/pex/service.d.ts.map +0 -1
  279. package/lib/src/services/relay-service/configs.d.ts +0 -35
  280. package/lib/src/services/relay-service/configs.d.ts.map +0 -1
  281. package/lib/src/services/relay-service/service-rpc.d.ts +0 -12
  282. package/lib/src/services/relay-service/service-rpc.d.ts.map +0 -1
  283. package/lib/src/services/relay-service/service.d.ts +0 -159
  284. package/lib/src/services/relay-service/service.d.ts.map +0 -1
  285. package/lib/src/services/rpc-service-client.d.ts +0 -7
  286. package/lib/src/services/rpc-service-client.d.ts.map +0 -1
  287. package/lib/src/services/storage/configs.d.ts +0 -2
  288. package/lib/src/services/storage/configs.d.ts.map +0 -1
  289. package/lib/src/services/storage/index.d.ts +0 -2
  290. package/lib/src/services/storage/index.d.ts.map +0 -1
  291. package/lib/src/services/storage/service-rpc.d.ts +0 -9
  292. package/lib/src/services/storage/service-rpc.d.ts.map +0 -1
  293. package/lib/src/services/storage/service.d.ts +0 -10
  294. package/lib/src/services/storage/service.d.ts.map +0 -1
  295. package/lib/src/services/util-crypto/configs.d.ts +0 -5
  296. package/lib/src/services/util-crypto/configs.d.ts.map +0 -1
  297. package/lib/src/services/util-crypto/index.d.ts +0 -2
  298. package/lib/src/services/util-crypto/index.d.ts.map +0 -1
  299. package/lib/src/services/util-crypto/service.d.ts +0 -10
  300. package/lib/src/services/util-crypto/service.d.ts.map +0 -1
  301. package/lib/src/services/wallet/configs.d.ts +0 -13
  302. package/lib/src/services/wallet/configs.d.ts.map +0 -1
  303. package/lib/src/services/wallet/service.d.ts +0 -13
  304. package/lib/src/services/wallet/service.d.ts.map +0 -1
  305. package/lib/src/types.d.ts +0 -12
  306. package/lib/src/types.d.ts.map +0 -1
  307. package/lib/src/wallet/memory-storage-interface.d.ts +0 -31
  308. package/lib/src/wallet/memory-storage-interface.d.ts.map +0 -1
  309. package/lib/src/wallet/memory-storage-wallet.d.ts +0 -6
  310. package/lib/src/wallet/memory-storage-wallet.d.ts.map +0 -1
  311. package/lib/src/wallet/rpc-storage-interface.d.ts +0 -32
  312. package/lib/src/wallet/rpc-storage-interface.d.ts.map +0 -1
  313. package/lib/src/wallet/rpc-storage-wallet.d.ts +0 -6
  314. package/lib/src/wallet/rpc-storage-wallet.d.ts.map +0 -1
  315. package/lib/test-utils.js +0 -46
  316. package/lib/test-utils.mjs +0 -38
  317. package/lib/tsconfig.tsbuildinfo +0 -1
  318. package/lib/types.js +0 -7
  319. package/lib/types.mjs +0 -3
  320. package/lib/wallet/memory-storage-interface.js +0 -101
  321. package/lib/wallet/memory-storage-interface.mjs +0 -95
  322. package/lib/wallet/memory-storage-wallet.js +0 -30
  323. package/lib/wallet/memory-storage-wallet.mjs +0 -24
  324. package/lib/wallet/rpc-storage-interface.js +0 -134
  325. package/lib/wallet/rpc-storage-interface.mjs +0 -128
  326. package/lib/wallet/rpc-storage-wallet.js +0 -46
  327. package/lib/wallet/rpc-storage-wallet.mjs +0 -40
@@ -1,7 +1,10 @@
1
1
  import {assertRpcService, getPromiseError} from '../test-utils';
2
- import {credentialService as service} from './service';
2
+ import {
3
+ credentialService as service,
4
+ credentialUtils as serviceCredentialUtils,
5
+ pexUtils,
6
+ } from './service';
3
7
  import {validation} from './config';
4
- import * as credentialUtils from '@docknetwork/credential-sdk/vc';
5
8
  import {CredentialServiceRPC} from './service-rpc';
6
9
  import {OpenID4VCIClientV1_0_13} from '@sphereon/oid4vci-client';
7
10
  import {didService} from '../dids/service';
@@ -13,17 +16,19 @@ describe('Credential Service', () => {
13
16
  const mockCreatePresentation = jest.fn();
14
17
  const mockDeriveCredentials = jest.fn(() => []);
15
18
 
16
- jest.spyOn(credentialUtils, 'Presentation').mockImplementation(() => {
17
- return {
18
- addCredentialToPresent: mockAddCredentialToPresent,
19
- addAttributeToReveal: mockAddAttributeToReveal,
20
- createPresentation: mockCreatePresentation,
21
- deriveCredentials: mockDeriveCredentials,
22
- presBuilder: {
23
- enforceBounds: jest.fn(),
24
- },
25
- };
26
- });
19
+ jest
20
+ .spyOn(serviceCredentialUtils, 'Presentation')
21
+ .mockImplementation(() => {
22
+ return {
23
+ addCredentialToPresent: mockAddCredentialToPresent,
24
+ addAttributeToReveal: mockAddAttributeToReveal,
25
+ createPresentation: mockCreatePresentation,
26
+ deriveCredentials: mockDeriveCredentials,
27
+ presBuilder: {
28
+ enforceBounds: jest.fn(),
29
+ },
30
+ };
31
+ });
27
32
  });
28
33
  it('ServiceRpc', () => {
29
34
  assertRpcService(CredentialServiceRPC, service, validation);
@@ -34,7 +39,7 @@ describe('Credential Service', () => {
34
39
  });
35
40
  it('expect to verify credential', async () => {
36
41
  jest
37
- .spyOn(credentialUtils, 'verifyCredential')
42
+ .spyOn(serviceCredentialUtils, 'verifyCredential')
38
43
  .mockImplementationOnce(async () => ({verified: true}));
39
44
  const credential = {
40
45
  '@context': [
@@ -86,7 +91,7 @@ describe('Credential Service', () => {
86
91
  },
87
92
  };
88
93
  await service.verifyCredential({credential});
89
- expect(credentialUtils.verifyCredential).toBeCalled();
94
+ expect(serviceCredentialUtils.verifyCredential).toBeCalled();
90
95
  });
91
96
  it('should create a vc', async () => {
92
97
  const subject = {
@@ -311,7 +316,7 @@ describe('Credential Service', () => {
311
316
  credentials,
312
317
  });
313
318
 
314
- const bbsPresentation = new credentialUtils.Presentation();
319
+ const bbsPresentation = new serviceCredentialUtils.Presentation();
315
320
  expect(bbsPresentation.addCredentialToPresent).toBeCalledWith(
316
321
  credential,
317
322
  expect.any(Object),
@@ -381,7 +386,7 @@ describe('Credential Service', () => {
381
386
  credentials,
382
387
  });
383
388
 
384
- const bbsPresentation = new credentialUtils.Presentation();
389
+ const bbsPresentation = new serviceCredentialUtils.Presentation();
385
390
  expect(bbsPresentation.addCredentialToPresent).toBeCalledWith(
386
391
  credential,
387
392
  expect.any(Object),
@@ -566,4 +571,243 @@ describe('Credential Service', () => {
566
571
  });
567
572
  });
568
573
  });
574
+
575
+ describe('generatePresentationFromPex', () => {
576
+ let generateSpy;
577
+
578
+ const basePexRequest = {
579
+ id: 'test-request',
580
+ input_descriptors: [
581
+ {
582
+ id: 'Credential 1',
583
+ constraints: {fields: [{path: ['$.type[*]']}]},
584
+ },
585
+ ],
586
+ };
587
+
588
+ const baseCredential = {
589
+ id: 'https://example.com/credential/1',
590
+ type: ['VerifiableCredential'],
591
+ credentialSubject: {id: 'did:example:123', name: 'Test'},
592
+ proof: {type: 'Bls12381BBS+SignatureDock2022'},
593
+ };
594
+
595
+ beforeEach(() => {
596
+ generateSpy = jest.spyOn(pexUtils, 'generatePresentationFromPexRequest');
597
+ });
598
+
599
+ afterEach(() => {
600
+ generateSpy.mockRestore();
601
+ });
602
+
603
+ it('should reject empty credentials array', async () => {
604
+ const error = await getPromiseError(() =>
605
+ service.generatePresentationFromPex({
606
+ credentials: [],
607
+ pexRequest: basePexRequest,
608
+ challenge: 'test-challenge',
609
+ }),
610
+ );
611
+ expect(error.message).toBe('no credential found');
612
+ });
613
+
614
+ it('should reject non-array credentials', async () => {
615
+ const error = await getPromiseError(() =>
616
+ service.generatePresentationFromPex({
617
+ credentials: 'invalid',
618
+ pexRequest: basePexRequest,
619
+ challenge: 'test-challenge',
620
+ }),
621
+ );
622
+ expect(error.message).toBe('invalid credentials');
623
+ });
624
+
625
+ it('should reject missing pexRequest', async () => {
626
+ const error = await getPromiseError(() =>
627
+ service.generatePresentationFromPex({
628
+ credentials: [{credential: baseCredential}],
629
+ challenge: 'test-challenge',
630
+ }),
631
+ );
632
+ expect(error.message).toBe('pexRequest is required');
633
+ });
634
+
635
+ it('should reject missing challenge', async () => {
636
+ const error = await getPromiseError(() =>
637
+ service.generatePresentationFromPex({
638
+ credentials: [{credential: baseCredential}],
639
+ pexRequest: basePexRequest,
640
+ }),
641
+ );
642
+ expect(error.message).toBe('challenge is required');
643
+ });
644
+
645
+ it('should call generatePresentationFromPexRequest and return presentation', async () => {
646
+ const mockPresentation = {
647
+ type: ['VerifiablePresentation'],
648
+ verifiableCredential: [baseCredential],
649
+ };
650
+
651
+ generateSpy.mockResolvedValueOnce({
652
+ status: pexUtils.GeneratePresentationStatus.SUCCESS,
653
+ presentation: mockPresentation,
654
+ });
655
+
656
+ const result = await service.generatePresentationFromPex({
657
+ credentials: [
658
+ {
659
+ credential: baseCredential,
660
+ attributesToReveal: ['credentialSubject.name'],
661
+ },
662
+ ],
663
+ pexRequest: basePexRequest,
664
+ challenge: 'test-challenge',
665
+ domain: 'dock.io',
666
+ skipSigning: true,
667
+ });
668
+
669
+ expect(result).toEqual(mockPresentation);
670
+ expect(pexUtils.generatePresentationFromPexRequest).toHaveBeenCalledWith(
671
+ expect.objectContaining({
672
+ credentials: [baseCredential],
673
+ pexRequest: basePexRequest,
674
+ challenge: 'test-challenge',
675
+ domain: 'dock.io',
676
+ skipSigning: true,
677
+ selectiveDisclosure: {
678
+ credentials: [
679
+ {
680
+ attributes: ['credentialSubject.name', 'id'],
681
+ witness: undefined,
682
+ },
683
+ ],
684
+ },
685
+ }),
686
+ );
687
+ });
688
+
689
+ it('should throw when generation status is not SUCCESS', async () => {
690
+ generateSpy.mockResolvedValueOnce({
691
+ status: pexUtils.GeneratePresentationStatus.REQUIREMENTS_NOT_MET,
692
+ error: new Error(
693
+ 'Credentials do not satisfy the presentation definition',
694
+ ),
695
+ });
696
+
697
+ const error = await getPromiseError(() =>
698
+ service.generatePresentationFromPex({
699
+ credentials: [{credential: baseCredential}],
700
+ pexRequest: basePexRequest,
701
+ challenge: 'test-challenge',
702
+ skipSigning: true,
703
+ }),
704
+ );
705
+
706
+ expect(error.message).toBe(
707
+ 'Credentials do not satisfy the presentation definition',
708
+ );
709
+ });
710
+
711
+ it('should throw generic error when generation fails without error object', async () => {
712
+ generateSpy.mockResolvedValueOnce({
713
+ status: pexUtils.GeneratePresentationStatus.REQUIREMENTS_NOT_MET,
714
+ });
715
+
716
+ const error = await getPromiseError(() =>
717
+ service.generatePresentationFromPex({
718
+ credentials: [{credential: baseCredential}],
719
+ pexRequest: basePexRequest,
720
+ challenge: 'test-challenge',
721
+ skipSigning: true,
722
+ }),
723
+ );
724
+
725
+ expect(error.message).toBe(
726
+ 'Presentation generation failed: requirements_not_met',
727
+ );
728
+ });
729
+
730
+ it('should pass credentials without witness as undefined', async () => {
731
+ generateSpy.mockResolvedValueOnce({
732
+ status: pexUtils.GeneratePresentationStatus.SUCCESS,
733
+ presentation: {type: ['VerifiablePresentation']},
734
+ });
735
+
736
+ await service.generatePresentationFromPex({
737
+ credentials: [{credential: baseCredential, attributesToReveal: []}],
738
+ pexRequest: basePexRequest,
739
+ challenge: 'test-challenge',
740
+ skipSigning: true,
741
+ });
742
+
743
+ const callArgs = generateSpy.mock.calls[0][0];
744
+ expect(
745
+ callArgs.selectiveDisclosure.credentials[0].witness,
746
+ ).toBeUndefined();
747
+ });
748
+
749
+ it('should not include loadProvingKey when no boundCheckSnarkKey', async () => {
750
+ generateSpy.mockResolvedValueOnce({
751
+ status: pexUtils.GeneratePresentationStatus.SUCCESS,
752
+ presentation: {type: ['VerifiablePresentation']},
753
+ });
754
+
755
+ await service.generatePresentationFromPex({
756
+ credentials: [{credential: baseCredential}],
757
+ pexRequest: basePexRequest,
758
+ challenge: 'test-challenge',
759
+ skipSigning: true,
760
+ });
761
+
762
+ const callArgs = generateSpy.mock.calls[0][0];
763
+ expect(callArgs.loadProvingKey).toBeUndefined();
764
+ });
765
+
766
+ it('should include loadProvingKey when boundCheckSnarkKey is provided', async () => {
767
+ generateSpy.mockResolvedValueOnce({
768
+ status: pexUtils.GeneratePresentationStatus.SUCCESS,
769
+ presentation: {type: ['VerifiablePresentation']},
770
+ });
771
+
772
+ await service.generatePresentationFromPex({
773
+ credentials: [{credential: baseCredential}],
774
+ pexRequest: basePexRequest,
775
+ challenge: 'test-challenge',
776
+ boundCheckSnarkKey: 'SGVsbG8gV29ybGQ=',
777
+ skipSigning: true,
778
+ });
779
+
780
+ const callArgs = generateSpy.mock.calls[0][0];
781
+ expect(typeof callArgs.loadProvingKey).toBe('function');
782
+ });
783
+
784
+ it('should always append id to attributesToReveal', async () => {
785
+ generateSpy.mockResolvedValueOnce({
786
+ status: pexUtils.GeneratePresentationStatus.SUCCESS,
787
+ presentation: {type: ['VerifiablePresentation']},
788
+ });
789
+
790
+ await service.generatePresentationFromPex({
791
+ credentials: [
792
+ {
793
+ credential: baseCredential,
794
+ attributesToReveal: ['credentialSubject.name'],
795
+ },
796
+ {credential: baseCredential},
797
+ ],
798
+ pexRequest: basePexRequest,
799
+ challenge: 'test-challenge',
800
+ skipSigning: true,
801
+ });
802
+
803
+ const callArgs = generateSpy.mock.calls[0][0];
804
+ expect(callArgs.selectiveDisclosure.credentials[0].attributes).toEqual([
805
+ 'credentialSubject.name',
806
+ 'id',
807
+ ]);
808
+ expect(callArgs.selectiveDisclosure.credentials[1].attributes).toEqual([
809
+ 'id',
810
+ ]);
811
+ });
812
+ });
569
813
  });
@@ -0,0 +1,44 @@
1
+ export function resolveOfferedCredentialConfig(client) {
2
+ const supported = client.getCredentialsSupported();
3
+ const offerIds =
4
+ client.credentialOffer?.credential_offer?.credential_configuration_ids ??
5
+ client.credentialOffer?.credential_configuration_ids ??
6
+ [];
7
+
8
+ if (Array.isArray(supported)) {
9
+ const matchedLegacy = supported.find(
10
+ entry => entry?.id && offerIds.includes(entry.id),
11
+ );
12
+ return matchedLegacy ?? supported[0];
13
+ }
14
+
15
+ const matched = offerIds.map(id => supported[id]).find(Boolean);
16
+ return matched ?? Object.values(supported)[0];
17
+ }
18
+
19
+ const KNOWN_FORMATS = new Set([
20
+ 'vc+sd-jwt',
21
+ 'dc+sd-jwt',
22
+ 'ldp_vc',
23
+ 'jwt_vc_json',
24
+ 'jwt_vc_json-ld',
25
+ 'jwt_vc',
26
+ ]);
27
+
28
+ export function resolveFormatAndType(config) {
29
+ const scopeSegments = config.scope?.split(':') ?? [];
30
+ const scopeTail = scopeSegments.slice(-1)[0];
31
+ const scopePrefix = scopeSegments.length > 1 ? scopeSegments[0] : undefined;
32
+ const definitionType = config.credential_definition?.type?.slice(-1)[0];
33
+
34
+ const format =
35
+ config.format ??
36
+ (scopePrefix && KNOWN_FORMATS.has(scopePrefix) ? scopePrefix : 'ldp_vc');
37
+
38
+ const credentialTypes =
39
+ format === 'vc+sd-jwt' || format === 'dc+sd-jwt'
40
+ ? config.vct
41
+ : definitionType ?? scopeTail;
42
+
43
+ return {format, credentialTypes};
44
+ }
@@ -0,0 +1,162 @@
1
+ import {resolveOfferedCredentialConfig, resolveFormatAndType} from './oid4vci';
2
+
3
+ function makeClient({supported, offerIds}) {
4
+ return {
5
+ getCredentialsSupported: () => supported,
6
+ credentialOffer: offerIds
7
+ ? {credential_offer: {credential_configuration_ids: offerIds}}
8
+ : undefined,
9
+ };
10
+ }
11
+
12
+ describe('OID4VCI offer resolution', () => {
13
+ describe('resolveOfferedCredentialConfig', () => {
14
+ it('returns the entry matching the offered configuration id', () => {
15
+ const supported = {
16
+ 'ldp_vc:MyCredential': {format: 'vc+sd-jwt', vct: 'MyCredential'},
17
+ 'ldp_vc:OtherCredential': {format: 'ldp_vc'},
18
+ };
19
+ const client = makeClient({
20
+ supported,
21
+ offerIds: ['ldp_vc:MyCredential'],
22
+ });
23
+
24
+ expect(resolveOfferedCredentialConfig(client)).toBe(
25
+ supported['ldp_vc:MyCredential'],
26
+ );
27
+ });
28
+
29
+ it('falls back to the first record entry when the offer id does not match', () => {
30
+ const supported = {
31
+ 'ldp_vc:A': {format: 'ldp_vc'},
32
+ 'ldp_vc:B': {format: 'vc+sd-jwt'},
33
+ };
34
+ const client = makeClient({supported, offerIds: ['nonexistent']});
35
+
36
+ expect(resolveOfferedCredentialConfig(client)).toBe(
37
+ supported['ldp_vc:A'],
38
+ );
39
+ });
40
+
41
+ it('handles array-shaped credentialsSupported by returning the first entry', () => {
42
+ const supported = [
43
+ {format: 'vc+sd-jwt', vct: 'MyCredential'},
44
+ {format: 'ldp_vc'},
45
+ ];
46
+ const client = makeClient({supported, offerIds: []});
47
+
48
+ expect(resolveOfferedCredentialConfig(client)).toBe(supported[0]);
49
+ });
50
+
51
+ it('matches an array-shaped entry by id when the offer provides one', () => {
52
+ const supported = [
53
+ {id: 'ldp_vc:A', format: 'ldp_vc'},
54
+ {id: 'sdjwt:B', format: 'vc+sd-jwt', vct: 'B'},
55
+ ];
56
+ const client = makeClient({supported, offerIds: ['sdjwt:B']});
57
+
58
+ expect(resolveOfferedCredentialConfig(client)).toBe(supported[1]);
59
+ });
60
+
61
+ it('falls back to the first array entry when no offered id matches', () => {
62
+ const supported = [
63
+ {id: 'ldp_vc:A', format: 'ldp_vc'},
64
+ {id: 'sdjwt:B', format: 'vc+sd-jwt'},
65
+ ];
66
+ const client = makeClient({supported, offerIds: ['nonexistent']});
67
+
68
+ expect(resolveOfferedCredentialConfig(client)).toBe(supported[0]);
69
+ });
70
+
71
+ it('reads offer ids from credentialOffer.credential_configuration_ids when not nested', () => {
72
+ const supported = {
73
+ 'ldp_vc:Wanted': {format: 'vc+sd-jwt', vct: 'Wanted'},
74
+ 'ldp_vc:Other': {format: 'ldp_vc'},
75
+ };
76
+ const client = {
77
+ getCredentialsSupported: () => supported,
78
+ credentialOffer: {credential_configuration_ids: ['ldp_vc:Wanted']},
79
+ };
80
+
81
+ expect(resolveOfferedCredentialConfig(client)).toBe(
82
+ supported['ldp_vc:Wanted'],
83
+ );
84
+ });
85
+ });
86
+
87
+ describe('resolveFormatAndType', () => {
88
+ it('returns vct as credentialTypes for vc+sd-jwt', () => {
89
+ const result = resolveFormatAndType({
90
+ format: 'vc+sd-jwt',
91
+ vct: 'MyCredential',
92
+ scope: 'ldp_vc:MyCredential',
93
+ });
94
+
95
+ expect(result).toEqual({
96
+ format: 'vc+sd-jwt',
97
+ credentialTypes: 'MyCredential',
98
+ });
99
+ });
100
+
101
+ it('returns the last credential_definition.type entry for ldp_vc', () => {
102
+ const result = resolveFormatAndType({
103
+ format: 'ldp_vc',
104
+ credential_definition: {
105
+ type: ['VerifiableCredential', 'UniversityDegreeCredential'],
106
+ },
107
+ });
108
+
109
+ expect(result).toEqual({
110
+ format: 'ldp_vc',
111
+ credentialTypes: 'UniversityDegreeCredential',
112
+ });
113
+ });
114
+
115
+ it('falls back to the scope suffix when credential_definition is missing', () => {
116
+ const result = resolveFormatAndType({
117
+ format: 'ldp_vc',
118
+ scope: 'ldp_vc:LegacyCredential',
119
+ });
120
+
121
+ expect(result).toEqual({
122
+ format: 'ldp_vc',
123
+ credentialTypes: 'LegacyCredential',
124
+ });
125
+ });
126
+
127
+ it('returns undefined credentialTypes when nothing identifies the type', () => {
128
+ const result = resolveFormatAndType({format: 'jwt_vc_json'});
129
+
130
+ expect(result).toEqual({
131
+ format: 'jwt_vc_json',
132
+ credentialTypes: undefined,
133
+ });
134
+ });
135
+
136
+ it('derives format from a known scope prefix when format is missing', () => {
137
+ const result = resolveFormatAndType({
138
+ scope: 'vc+sd-jwt:MyCredential',
139
+ vct: 'MyCredential',
140
+ });
141
+
142
+ expect(result).toEqual({
143
+ format: 'vc+sd-jwt',
144
+ credentialTypes: 'MyCredential',
145
+ });
146
+ });
147
+
148
+ it('defaults to ldp_vc when format and a recognizable scope prefix are missing', () => {
149
+ const result = resolveFormatAndType({
150
+ scope: 'MyCredential',
151
+ credential_definition: {
152
+ type: ['VerifiableCredential', 'MyCredential'],
153
+ },
154
+ });
155
+
156
+ expect(result).toEqual({
157
+ format: 'ldp_vc',
158
+ credentialTypes: 'MyCredential',
159
+ });
160
+ });
161
+ });
162
+ });
@@ -7,8 +7,8 @@ export const MAX_DATE_PLACEHOLDER = 884541351600000;
7
7
  export const MIN_DATE_PLACEHOLDER = -17592186044415;
8
8
  export const MAX_INTEGER = Number.MAX_SAFE_INTEGER;
9
9
  export const MIN_INTEGER = Number.MIN_SAFE_INTEGER;
10
- export const MAX_NUMBER = Number.MAX_SAFE_INTEGER;
11
- export const MIN_NUMBER = Number.MIN_SAFE_INTEGER;
10
+ export const MAX_NUMBER = 100 ** 5;
11
+ export const MIN_NUMBER = -(100 ** 5);
12
12
 
13
13
  /*
14
14
  PEX Filter rules:
@@ -283,35 +283,81 @@ export const shouldSkipAttribute = attributeName =>
283
283
  attributesToSkip.some(regex => regex.test(attributeName));
284
284
 
285
285
  export function getPexRequiredAttributes(pexRequest, selectedCredentials = []) {
286
- return pexRequest.input_descriptors
287
- .map((inputDescriptor, index) => {
288
- return inputDescriptor.constraints.fields
289
- .filter(field => {
290
- if (field.filter || field.optional) {
291
- return false;
292
- }
286
+ // Match each credential to its best-fitting descriptor by checking which
287
+ // descriptor's fields exist in the credential, rather than relying on
288
+ // positional index. This allows credentials to be provided in any order.
289
+ return selectedCredentials.map((credential, credIdx) => {
290
+ const matchedDescriptor = findMatchingDescriptor(
291
+ pexRequest.input_descriptors,
292
+ credential,
293
+ );
294
+ if (!matchedDescriptor) {
295
+ return [];
296
+ }
297
+ return matchedDescriptor.constraints.fields
298
+ .filter(field => {
299
+ if (field.filter || field.optional) {
300
+ return false;
301
+ }
293
302
 
294
- try {
295
- if (!selectedCredentials[index]) {
296
- return false;
297
- }
298
-
299
- const paths = Array.isArray(field.path)
300
- ? field.path.flatMap(singlePath =>
301
- JSONPath.paths(selectedCredentials[index], singlePath),
302
- )
303
- : JSONPath.paths(selectedCredentials[index], field.path);
304
-
305
- return paths.length !== 0;
306
- } catch (error) {
307
- console.error(`Error in field ${field.path}: ${error.message}`);
308
- return false;
303
+ try {
304
+ const paths = Array.isArray(field.path)
305
+ ? field.path.flatMap(singlePath =>
306
+ JSONPath.paths(credential, singlePath),
307
+ )
308
+ : JSONPath.paths(credential, field.path);
309
+
310
+ return paths.length !== 0;
311
+ } catch (error) {
312
+ console.error(`Error in field ${field.path}: ${error.message}`);
313
+ return false;
314
+ }
315
+ })
316
+ .map(field =>
317
+ getAttributeName({field, selectedCredentials, index: credIdx}),
318
+ )
319
+ .filter(attributeName => {
320
+ return !shouldSkipAttribute(attributeName);
321
+ });
322
+ });
323
+ }
324
+
325
+ export function findMatchingDescriptor(inputDescriptors, credential) {
326
+ let bestMatch = null;
327
+ let bestScore = -1;
328
+
329
+ for (const descriptor of inputDescriptors) {
330
+ const fields = descriptor.constraints?.fields || [];
331
+ if (fields.length === 0) {
332
+ continue;
333
+ }
334
+
335
+ let matched = 0;
336
+ for (const field of fields) {
337
+ try {
338
+ const fieldPaths = Array.isArray(field.path)
339
+ ? field.path
340
+ : [field.path];
341
+ for (const p of fieldPaths) {
342
+ const paths = JSONPath.paths(credential, p);
343
+ if (paths.length > 0) {
344
+ matched++;
345
+ break;
309
346
  }
310
- })
311
- .map(field => getAttributeName({field, selectedCredentials, index}))
312
- .filter(attributeName => {
313
- return !shouldSkipAttribute(attributeName);
314
- });
315
- })
316
- .filter(requiredAttributes => requiredAttributes.length > 0);
347
+ }
348
+ } catch {
349
+ // ignore
350
+ }
351
+ }
352
+
353
+ // Use match ratio so descriptors where all fields match score higher
354
+ // than descriptors where only generic fields (e.g. issuer) match
355
+ const score = matched / fields.length;
356
+ if (score > bestScore) {
357
+ bestScore = score;
358
+ bestMatch = descriptor;
359
+ }
360
+ }
361
+
362
+ return bestMatch;
317
363
  }
@@ -1,4 +1,4 @@
1
- import {getPexRequiredAttributes, pexToBounds} from './pex-helpers';
1
+ import {getPexRequiredAttributes, pexToBounds, MAX_NUMBER} from './pex-helpers';
2
2
 
3
3
  describe('pex helpers', () => {
4
4
  describe('getPexRequiredAttributes', () => {
@@ -253,7 +253,7 @@ describe('pex helpers', () => {
253
253
  },
254
254
  ],
255
255
  );
256
- expect(result).toEqual([]);
256
+ expect(result).toEqual([[]]);
257
257
  });
258
258
  });
259
259
 
@@ -302,7 +302,7 @@ describe('pex helpers', () => {
302
302
  {
303
303
  attributeName: 'credentialSubject.age',
304
304
  min: 0,
305
- max: Number.MAX_SAFE_INTEGER,
305
+ max: MAX_NUMBER,
306
306
  proofRequestMax: undefined,
307
307
  proofRequestMin: 0,
308
308
  format: undefined,
@@ -357,7 +357,7 @@ describe('pex helpers', () => {
357
357
  {
358
358
  attributeName: 'credentialSubject.age',
359
359
  min: 0,
360
- max: Number.MAX_SAFE_INTEGER,
360
+ max: MAX_NUMBER,
361
361
  proofRequestMax: undefined,
362
362
  proofRequestMin: 0,
363
363
  format: undefined,