@docknetwork/wallet-sdk-wasm 1.7.0 → 1.7.6
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/lib/index.js +1 -0
- package/lib/index.mjs +1 -0
- package/lib/modules/network-manager.js +15 -12
- package/lib/modules/network-manager.mjs +15 -12
- package/lib/rpc-server.js +1 -0
- package/lib/rpc-server.mjs +1 -0
- package/lib/services/blockchain/service.js +22 -9
- package/lib/services/blockchain/service.mjs +23 -10
- package/lib/services/credential/bound-check.js +1 -1
- package/lib/services/credential/bound-check.mjs +1 -1
- package/lib/services/credential/delegatable-credentials.js +300 -0
- package/lib/services/credential/delegatable-credentials.mjs +263 -0
- package/lib/services/credential/index.js +39 -0
- package/lib/services/credential/index.mjs +4 -0
- package/lib/services/credential/pex-helpers.js +4 -4
- package/lib/services/credential/pex-helpers.mjs +4 -4
- package/lib/services/edv/index.js +1 -0
- package/lib/services/edv/index.mjs +1 -0
- package/lib/services/edv/service-rpc.js +23 -0
- package/lib/services/edv/service-rpc.mjs +23 -0
- package/lib/services/edv/service.js +81 -1
- package/lib/services/edv/service.mjs +78 -2
- package/lib/services/index.js +1 -0
- package/lib/services/index.mjs +1 -0
- package/lib/services/pex/config.js +4 -0
- package/lib/services/pex/config.mjs +4 -0
- package/lib/services/pex/service-rpc.js +4 -0
- package/lib/services/pex/service-rpc.mjs +4 -0
- package/lib/services/pex/service.js +7 -0
- package/lib/services/pex/service.mjs +7 -0
- package/lib/setup-nodejs.js +1 -0
- package/lib/setup-nodejs.mjs +1 -0
- package/lib/setup-tests.js +1 -0
- package/lib/setup-tests.mjs +1 -0
- package/lib/src/modules/event-manager.d.ts +0 -1
- package/lib/src/modules/event-manager.d.ts.map +1 -1
- package/lib/src/modules/network-manager.d.ts +2 -4
- package/lib/src/modules/network-manager.d.ts.map +1 -1
- package/lib/src/services/blockchain/configs.d.ts +1 -2
- package/lib/src/services/blockchain/configs.d.ts.map +1 -1
- package/lib/src/services/blockchain/service.d.ts +4 -3
- package/lib/src/services/blockchain/service.d.ts.map +1 -1
- package/lib/src/services/credential/bbs-revocation.d.ts +1 -1
- package/lib/src/services/credential/bbs-revocation.d.ts.map +1 -1
- package/lib/src/services/credential/bound-check.d.ts.map +1 -1
- package/lib/src/services/credential/delegatable-credentials.d.ts +272 -0
- package/lib/src/services/credential/delegatable-credentials.d.ts.map +1 -0
- package/lib/src/services/credential/index.d.ts +1 -0
- package/lib/src/services/credential/index.d.ts.map +1 -1
- package/lib/src/services/credential/pex-helpers.d.ts +2 -2
- package/lib/src/services/credential/pex-helpers.d.ts.map +1 -1
- package/lib/src/services/dids/keypair-utils.d.ts +2 -2
- package/lib/src/services/dids/keypair-utils.d.ts.map +1 -1
- package/lib/src/services/dids/service.d.ts +35 -3
- package/lib/src/services/dids/service.d.ts.map +1 -1
- package/lib/src/services/edv/service.d.ts +50 -1
- package/lib/src/services/edv/service.d.ts.map +1 -1
- package/lib/src/services/pex/config.d.ts +1 -0
- package/lib/src/services/pex/config.d.ts.map +1 -1
- package/lib/src/services/pex/service.d.ts +1 -0
- package/lib/src/services/pex/service.d.ts.map +1 -1
- package/lib/src/services/relay-service/service.d.ts +19 -7
- package/lib/src/services/relay-service/service.d.ts.map +1 -1
- package/lib/src/services/storage/service.d.ts.map +1 -1
- package/lib/src/services/util-crypto/service.d.ts +2 -2
- package/lib/src/services/util-crypto/service.d.ts.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +24 -16
- package/rollup.config.mjs +5 -3
- package/src/globals.d.ts +3 -0
- package/src/modules/network-manager.ts +15 -14
- package/src/services/blockchain/configs.ts +1 -2
- package/src/services/blockchain/service.ts +26 -10
- package/src/services/credential/bound-check.ts +1 -1
- package/src/services/credential/delegatable-credentials.ts +409 -0
- package/src/services/credential/index.ts +16 -0
- package/src/services/credential/pex-helpers.js +4 -4
- package/src/services/credential/pex-helpers.test.js +2 -2
- package/src/services/edv/index.test.js +229 -0
- package/src/services/edv/service-rpc.js +23 -0
- package/src/services/edv/service.ts +119 -0
- package/src/services/pex/config.ts +4 -0
- package/src/services/pex/service-rpc.js +4 -0
- package/src/services/pex/service.ts +13 -0
- package/src/services/pex/tests/pex-service.test.js +210 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docknetwork/wallet-sdk-wasm",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.6",
|
|
4
4
|
"license": "https://github.com/docknetwork/wallet-sdk/LICENSE",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -18,34 +18,42 @@
|
|
|
18
18
|
"p-limit": "2.3.0"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"p-limit": "2.3.0",
|
|
22
21
|
"@astronautlabs/jsonpath": "^1.1.2",
|
|
23
|
-
"@
|
|
24
|
-
"@docknetwork/wallet-sdk-dids": "^1.7.0",
|
|
22
|
+
"@cedar-policy/cedar-wasm": "^4.5.0",
|
|
25
23
|
"@cosmjs/proto-signing": "^0.32.4",
|
|
26
|
-
"@docknetwork/cheqd-blockchain-api": "4.
|
|
27
|
-
"@docknetwork/cheqd-blockchain-modules": "4.0.
|
|
28
|
-
"@
|
|
24
|
+
"@docknetwork/cheqd-blockchain-api": "4.1.1",
|
|
25
|
+
"@docknetwork/cheqd-blockchain-modules": "4.0.8",
|
|
26
|
+
"@docknetwork/credential-sdk": "0.54.16",
|
|
27
|
+
"@docknetwork/universal-wallet": "^2.0.1",
|
|
28
|
+
"@docknetwork/vc-delegation-engine": "1.0.3",
|
|
29
|
+
"@docknetwork/wallet-sdk-dids": "^1.7.6",
|
|
29
30
|
"@noble/hashes": "1.8.0",
|
|
30
|
-
"@
|
|
31
|
-
"@sphereon/oid4vci-client": "^0.16.0",
|
|
32
|
-
"@sphereon/oid4vci-common": "^0.16.0",
|
|
31
|
+
"@scure/bip39": "^1.6.0",
|
|
33
32
|
"@sd-jwt/crypto-nodejs": "^0.15.0",
|
|
34
33
|
"@sd-jwt/sd-jwt-vc": "^0.15.1",
|
|
35
|
-
"
|
|
34
|
+
"@sphereon/oid4vci-client": "^0.16.0",
|
|
35
|
+
"@sphereon/oid4vci-common": "^0.16.0",
|
|
36
|
+
"@sphereon/pex": "^1.1.4",
|
|
36
37
|
"axios": "^0.25.0",
|
|
38
|
+
"axios-retry": "^3.2.5",
|
|
39
|
+
"base64url": "^3.0.1",
|
|
40
|
+
"cwait": "1.1.2",
|
|
41
|
+
"futoin-hkdf": "^1.5.3",
|
|
37
42
|
"json-rpc-2.0": "^0.2.16",
|
|
43
|
+
"jsonld": "^6.0.0",
|
|
44
|
+
"p-limit": "2.3.0",
|
|
38
45
|
"uuid": "^8.3.2",
|
|
39
|
-
"winston": "^3.3.3"
|
|
40
|
-
"cwait": "1.1.2",
|
|
41
|
-
"axios-retry": "^3.2.5",
|
|
42
|
-
"@sphereon/pex": "^1.1.4"
|
|
46
|
+
"winston": "^3.3.3"
|
|
43
47
|
},
|
|
44
48
|
"devDependencies": {
|
|
45
49
|
"@babel/node": "^7.16.0",
|
|
46
|
-
"sinon": "^12.0.1",
|
|
47
50
|
"jest": "29.6.1",
|
|
51
|
+
"sinon": "^12.0.1",
|
|
48
52
|
"ts-jest": "29.1.0",
|
|
49
53
|
"typescript": "^5.0.4"
|
|
54
|
+
},
|
|
55
|
+
"overrides": {
|
|
56
|
+
"@digitalbazaar/http-client": "^3.4.1",
|
|
57
|
+
"base58-universal": "2.0.0"
|
|
50
58
|
}
|
|
51
59
|
}
|
package/rollup.config.mjs
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import json from '@rollup/plugin-json';
|
|
2
|
-
import
|
|
2
|
+
import _multiInput from 'rollup-plugin-multi-input';
|
|
3
3
|
import commonjs from '@rollup/plugin-commonjs';
|
|
4
4
|
import flow from 'rollup-plugin-flow';
|
|
5
5
|
import typescript from '@rollup/plugin-typescript';
|
|
6
6
|
|
|
7
|
+
const multiInput = _multiInput.default || _multiInput;
|
|
8
|
+
|
|
7
9
|
export default async function () {
|
|
8
10
|
return [
|
|
9
11
|
{
|
|
10
12
|
plugins: [
|
|
11
|
-
multiInput
|
|
13
|
+
multiInput(),
|
|
12
14
|
json(),
|
|
13
15
|
flow({
|
|
14
16
|
all: true,
|
|
@@ -17,7 +19,7 @@ export default async function () {
|
|
|
17
19
|
commonjs(),
|
|
18
20
|
typescript(),
|
|
19
21
|
],
|
|
20
|
-
input: ['src/**/*.ts', 'src/**/*.js', '!src/**/*.test.ts', '!src/**/*.test.js'],
|
|
22
|
+
input: ['src/**/*.ts', 'src/**/*.js', '!src/**/*.test.ts', '!src/**/*.test.js', '!src/**/*.d.ts'],
|
|
21
23
|
output: [
|
|
22
24
|
{
|
|
23
25
|
dir: 'lib',
|
package/src/globals.d.ts
ADDED
|
@@ -3,35 +3,36 @@ import assert from 'assert';
|
|
|
3
3
|
|
|
4
4
|
export type NetworkInfo = {
|
|
5
5
|
name: string,
|
|
6
|
-
|
|
7
|
-
addressPrefix: number,
|
|
8
|
-
cheqdApiUrl: string,
|
|
6
|
+
cheqdApiUrl: string | string[],
|
|
9
7
|
};
|
|
10
8
|
|
|
11
9
|
export type NetworkId = 'mainnet' | 'testnet' | 'local' | 'custom';
|
|
12
10
|
|
|
13
|
-
export const
|
|
11
|
+
export const BLOCKCHAIN_NETWORKS : Record<NetworkId, NetworkInfo> = {
|
|
14
12
|
mainnet: {
|
|
15
13
|
name: 'Cheqd Mainnet',
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
cheqdApiUrl: [
|
|
15
|
+
'https://mainnet.cheqd.docknode.io',
|
|
16
|
+
'https://rpc.cheqd.net',
|
|
17
|
+
],
|
|
19
18
|
},
|
|
20
19
|
testnet: {
|
|
21
20
|
name: 'Cheqd Testnet',
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
cheqdApiUrl: [
|
|
22
|
+
'https://testnet.cheqd.docknode.io',
|
|
23
|
+
'https://api.cheqd.network',
|
|
24
|
+
],
|
|
25
25
|
},
|
|
26
26
|
local: {
|
|
27
27
|
name: 'Local Node',
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
cheqdApiUrl: [
|
|
29
|
+
'http://localhost:8080',
|
|
30
|
+
],
|
|
30
31
|
},
|
|
31
32
|
};
|
|
32
33
|
|
|
33
34
|
function getNetworkInfo(networkId): NetworkInfo {
|
|
34
|
-
const networkInfo =
|
|
35
|
+
const networkInfo = BLOCKCHAIN_NETWORKS[networkId];
|
|
35
36
|
|
|
36
37
|
assert(!!networkInfo, `Network ${networkId} not found`);
|
|
37
38
|
|
|
@@ -57,7 +58,7 @@ export class NetworkManager {
|
|
|
57
58
|
* @param {string} networkId
|
|
58
59
|
*/
|
|
59
60
|
setNetworkId(networkId: NetworkId) {
|
|
60
|
-
assert(!!
|
|
61
|
+
assert(!!BLOCKCHAIN_NETWORKS[networkId], `invalid networkId ${networkId}`);
|
|
61
62
|
|
|
62
63
|
this.networkId = networkId;
|
|
63
64
|
}
|
|
@@ -60,7 +60,11 @@ export class BlockchainService {
|
|
|
60
60
|
cheqdApi;
|
|
61
61
|
cheqdApiUrl;
|
|
62
62
|
isBlockchainReady = false;
|
|
63
|
-
|
|
63
|
+
private _resolver: any;
|
|
64
|
+
|
|
65
|
+
get resolver(): any {
|
|
66
|
+
return this._resolver;
|
|
67
|
+
}
|
|
64
68
|
/**
|
|
65
69
|
* Event names emitted by the blockchain service
|
|
66
70
|
* @static
|
|
@@ -93,7 +97,8 @@ export class BlockchainService {
|
|
|
93
97
|
this.cheqdModules = new CheqdCoreModules(this.cheqdApi);
|
|
94
98
|
this.modules = new MultiApiCoreModules([this.cheqdModules]);
|
|
95
99
|
this.emitter = new EventEmitter();
|
|
96
|
-
|
|
100
|
+
// Blockchain is not ready yet, but we can use fallback resolvers
|
|
101
|
+
this._resolver = this.createDIDResolver();
|
|
97
102
|
}
|
|
98
103
|
|
|
99
104
|
/**
|
|
@@ -161,12 +166,21 @@ export class BlockchainService {
|
|
|
161
166
|
* @private
|
|
162
167
|
* @returns {CachedDIDResolver} Cached DID resolver instance
|
|
163
168
|
*/
|
|
164
|
-
createDIDResolver() {
|
|
165
|
-
|
|
166
|
-
new DIDKeyResolver(),
|
|
167
|
-
new CoreResolver(this.modules),
|
|
169
|
+
createDIDResolver(isBlockchainReady: boolean) {
|
|
170
|
+
let resolvers = [
|
|
168
171
|
new UniversalResolver(universalResolverUrl),
|
|
169
|
-
|
|
172
|
+
new DIDKeyResolver(),
|
|
173
|
+
]
|
|
174
|
+
|
|
175
|
+
// Add blockchain resolvers if the blockchain is ready
|
|
176
|
+
if (isBlockchainReady) {
|
|
177
|
+
resolvers = [
|
|
178
|
+
new CoreResolver(this.modules),
|
|
179
|
+
...resolvers
|
|
180
|
+
]
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const router = new AnyDIDResolver(resolvers);
|
|
170
184
|
|
|
171
185
|
return new CachedDIDResolver(router);
|
|
172
186
|
}
|
|
@@ -217,16 +231,18 @@ export class BlockchainService {
|
|
|
217
231
|
try {
|
|
218
232
|
await this.cheqdApi.init({
|
|
219
233
|
wallet,
|
|
220
|
-
|
|
234
|
+
urls: Array.isArray(checkdApiUrl) ? checkdApiUrl : [checkdApiUrl],
|
|
221
235
|
network: cheqdNetworkId,
|
|
222
236
|
});
|
|
223
237
|
Logger.info(`Cheqd initialized at: ${checkdApiUrl}`);
|
|
224
238
|
} catch (err) {
|
|
239
|
+
debugger
|
|
225
240
|
Logger.error(`Failed to initialize cheqd at: ${checkdApiUrl}`, err);
|
|
226
241
|
}
|
|
227
242
|
|
|
228
243
|
|
|
229
|
-
|
|
244
|
+
// Re-create the resolver with the new blockchain connection
|
|
245
|
+
this._resolver = this.createDIDResolver(true);
|
|
230
246
|
|
|
231
247
|
if (
|
|
232
248
|
process.env.NODE_ENV !== 'test' ||
|
|
@@ -299,7 +315,7 @@ export class BlockchainService {
|
|
|
299
315
|
* @example
|
|
300
316
|
* const apiUrl = await blockchainService.getAddress();
|
|
301
317
|
*/
|
|
302
|
-
async getAddress() {
|
|
318
|
+
async getAddress(): Promise<string | string[]> {
|
|
303
319
|
return this.cheqdApiUrl;
|
|
304
320
|
}
|
|
305
321
|
|
|
@@ -107,7 +107,7 @@ export function blobFromBase64(base64String: string): Uint8Array {
|
|
|
107
107
|
/^data:application\/octet-stream;base64,/,
|
|
108
108
|
'',
|
|
109
109
|
);
|
|
110
|
-
return base64url.toBuffer(cleanedBase64);
|
|
110
|
+
return new Uint8Array(base64url.toBuffer(cleanedBase64));
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
export async function isBase64OrDataUrl(str: string): Promise<boolean> {
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import * as cedar from '@cedar-policy/cedar-wasm/nodejs';
|
|
3
|
+
import {
|
|
4
|
+
verifyPresentation,
|
|
5
|
+
issueCredential,
|
|
6
|
+
signPresentation,
|
|
7
|
+
documentLoader,
|
|
8
|
+
getSuiteFromKeyDoc,
|
|
9
|
+
} from '@docknetwork/credential-sdk/vc';
|
|
10
|
+
import { MAY_CLAIM_IRI } from '@docknetwork/vc-delegation-engine';
|
|
11
|
+
import { getKeypairFromDoc } from '@docknetwork/universal-wallet/methods/keypairs';
|
|
12
|
+
import { blockchainService } from '../blockchain/service';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Prepares a key document for signing by creating a proper keypair with signer capability
|
|
16
|
+
* @param keyDoc - The key document with id, controller, type, and key material
|
|
17
|
+
* @returns A key document with an active signer
|
|
18
|
+
*/
|
|
19
|
+
function prepareKeyForSigning(keyDoc: KeyPair): any {
|
|
20
|
+
const kp = getKeypairFromDoc(keyDoc);
|
|
21
|
+
// Get the signer from the keypair - this returns an object with id and sign method
|
|
22
|
+
const signer = kp.signer();
|
|
23
|
+
// Set the id on the signer to match the verification method
|
|
24
|
+
signer.id = keyDoc.id;
|
|
25
|
+
return {
|
|
26
|
+
...keyDoc,
|
|
27
|
+
keypair: kp,
|
|
28
|
+
signer,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface VerificationResult {
|
|
33
|
+
verified: boolean;
|
|
34
|
+
credentialResults?: any[];
|
|
35
|
+
delegationResult?: {
|
|
36
|
+
decision: string;
|
|
37
|
+
summaries?: any[];
|
|
38
|
+
authorizations?: any[];
|
|
39
|
+
failures?: any[];
|
|
40
|
+
};
|
|
41
|
+
error?: any;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface CedarPolicies {
|
|
45
|
+
staticPolicies: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface VerifiablePresentation {
|
|
49
|
+
'@context': any[];
|
|
50
|
+
type: string[];
|
|
51
|
+
proof?: any;
|
|
52
|
+
verifiableCredential?: any[];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface DelegationCredential {
|
|
56
|
+
'@context': any[];
|
|
57
|
+
id: string;
|
|
58
|
+
type: string[];
|
|
59
|
+
issuer: string;
|
|
60
|
+
issuanceDate: string;
|
|
61
|
+
previousCredentialId: string | null;
|
|
62
|
+
rootCredentialId: string;
|
|
63
|
+
credentialSubject: {
|
|
64
|
+
id: string;
|
|
65
|
+
[key: string]: any;
|
|
66
|
+
};
|
|
67
|
+
proof?: any;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface VerifyDelegationOptions {
|
|
71
|
+
challenge?: string;
|
|
72
|
+
domain?: string;
|
|
73
|
+
unsignedPresentation?: boolean;
|
|
74
|
+
failOnUnauthorizedClaims?: boolean;
|
|
75
|
+
policies?: CedarPolicies;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface KeyPair {
|
|
79
|
+
type: string;
|
|
80
|
+
id?: string;
|
|
81
|
+
controller?: string;
|
|
82
|
+
publicKeyJwk?: any;
|
|
83
|
+
privateKeyJwk?: any;
|
|
84
|
+
publicKeyBase58?: string;
|
|
85
|
+
privateKeyBase58?: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* W3C Credentials V1 context URL
|
|
90
|
+
*/
|
|
91
|
+
export const W3C_CREDENTIALS_V1 = 'https://www.w3.org/2018/credentials/v1';
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Re-export MAY_CLAIM_IRI for use in credentials
|
|
95
|
+
*/
|
|
96
|
+
export { MAY_CLAIM_IRI };
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Namespace used by the vc-delegation-engine for delegation properties
|
|
100
|
+
*/
|
|
101
|
+
export const DELEGATION_ENGINE_NS = 'https://ld.truvera.io/credentials/delegation#';
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Base delegation context terms required for delegation credentials.
|
|
105
|
+
* These terms define the JSON-LD mappings needed for the vc-delegation-engine
|
|
106
|
+
* to properly process delegation chains.
|
|
107
|
+
*
|
|
108
|
+
* Use this as a base and extend with your own application-specific terms:
|
|
109
|
+
* @example
|
|
110
|
+
* const myContext = [
|
|
111
|
+
* W3C_CREDENTIALS_V1,
|
|
112
|
+
* {
|
|
113
|
+
* ...DELEGATION_CONTEXT_TERMS,
|
|
114
|
+
* // Add your custom terms here
|
|
115
|
+
* MyCredentialType: 'https://example.org/MyCredentialType',
|
|
116
|
+
* myField: 'https://example.org/myField',
|
|
117
|
+
* },
|
|
118
|
+
* ];
|
|
119
|
+
*/
|
|
120
|
+
export const DELEGATION_CONTEXT_TERMS = {
|
|
121
|
+
'@version': 1.1,
|
|
122
|
+
'@protected': true,
|
|
123
|
+
DelegationCredential: `${DELEGATION_ENGINE_NS}DelegationCredential`,
|
|
124
|
+
mayClaim: { '@id': MAY_CLAIM_IRI, '@container': '@set' },
|
|
125
|
+
rootCredentialId: { '@id': `${DELEGATION_ENGINE_NS}rootCredentialId`, '@type': '@id' },
|
|
126
|
+
previousCredentialId: { '@id': `${DELEGATION_ENGINE_NS}previousCredentialId`, '@type': '@id' },
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Default context for verifiable presentations
|
|
131
|
+
*/
|
|
132
|
+
export const PRESENTATION_CONTEXT = [W3C_CREDENTIALS_V1];
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Issues a delegation credential that grants authority to a delegate
|
|
136
|
+
* @param keyPair - The key pair to sign the credential
|
|
137
|
+
* @param params - Delegation parameters
|
|
138
|
+
* @returns Signed delegation credential
|
|
139
|
+
*/
|
|
140
|
+
export async function issueDelegationCredential(
|
|
141
|
+
keyPair: KeyPair,
|
|
142
|
+
credential: any
|
|
143
|
+
): Promise<DelegationCredential> {
|
|
144
|
+
const preparedKey = prepareKeyForSigning(keyPair);
|
|
145
|
+
return issueCredential(preparedKey, credential);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Issues a credential as a delegate (with delegation chain reference)
|
|
150
|
+
* @param keyPair - The delegate's key pair to sign the credential
|
|
151
|
+
* @param params - Credential parameters
|
|
152
|
+
* @returns Signed credential
|
|
153
|
+
*/
|
|
154
|
+
export async function issueDelegatedCredential(
|
|
155
|
+
keyPair: KeyPair,
|
|
156
|
+
credential: any
|
|
157
|
+
): Promise<any> {
|
|
158
|
+
const preparedKey = prepareKeyForSigning(keyPair);
|
|
159
|
+
return issueCredential(preparedKey, credential);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Creates and signs a verifiable presentation with delegation credentials
|
|
164
|
+
* @param keyPair - The key pair to sign the presentation
|
|
165
|
+
* @param params - Presentation parameters
|
|
166
|
+
* @returns Signed verifiable presentation
|
|
167
|
+
*/
|
|
168
|
+
export async function createSignedPresentation(
|
|
169
|
+
keyPair: KeyPair,
|
|
170
|
+
params: {
|
|
171
|
+
credentials: any[];
|
|
172
|
+
holderDid: string;
|
|
173
|
+
challenge: string;
|
|
174
|
+
domain: string;
|
|
175
|
+
context?: any[];
|
|
176
|
+
}
|
|
177
|
+
): Promise<VerifiablePresentation> {
|
|
178
|
+
const {
|
|
179
|
+
credentials,
|
|
180
|
+
holderDid,
|
|
181
|
+
challenge,
|
|
182
|
+
domain,
|
|
183
|
+
context = PRESENTATION_CONTEXT,
|
|
184
|
+
} = params;
|
|
185
|
+
|
|
186
|
+
const presentation = {
|
|
187
|
+
'@context': context,
|
|
188
|
+
type: ['VerifiablePresentation'],
|
|
189
|
+
holder: holderDid,
|
|
190
|
+
verifiableCredential: credentials,
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// Create key document for signing with proper keypair
|
|
194
|
+
const keyDoc = {
|
|
195
|
+
...keyPair,
|
|
196
|
+
id: keyPair.id || `${holderDid}#keys-1`,
|
|
197
|
+
controller: keyPair.controller || holderDid,
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const preparedKey = prepareKeyForSigning(keyDoc);
|
|
201
|
+
return signPresentation(presentation, preparedKey, challenge, domain);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Verifies a verifiable presentation with optional delegation chain validation
|
|
206
|
+
* Uses the credential-sdk's verifyPresentation which automatically:
|
|
207
|
+
* 1. Verifies the presentation signature
|
|
208
|
+
* 2. Verifies all credentials
|
|
209
|
+
* 3. Detects delegation credentials
|
|
210
|
+
* 4. Validates the delegation chain
|
|
211
|
+
* 5. Applies Cedar policies if provided
|
|
212
|
+
*
|
|
213
|
+
* @param vp - The verifiable presentation to verify
|
|
214
|
+
* @param options - Verification options
|
|
215
|
+
* @returns Verification result with delegation info if applicable
|
|
216
|
+
*/
|
|
217
|
+
export async function verifyDelegatablePresentation(
|
|
218
|
+
vp: VerifiablePresentation,
|
|
219
|
+
options: VerifyDelegationOptions = {}
|
|
220
|
+
): Promise<VerificationResult> {
|
|
221
|
+
const {
|
|
222
|
+
challenge = vp.proof?.challenge || 'default-challenge',
|
|
223
|
+
domain = vp.proof?.domain || 'default-domain',
|
|
224
|
+
unsignedPresentation = false,
|
|
225
|
+
failOnUnauthorizedClaims = true,
|
|
226
|
+
policies,
|
|
227
|
+
} = options;
|
|
228
|
+
|
|
229
|
+
const verifyOptions: any = {
|
|
230
|
+
challenge,
|
|
231
|
+
domain,
|
|
232
|
+
documentLoader: documentLoader(blockchainService.resolver),
|
|
233
|
+
unsignedPresentation,
|
|
234
|
+
failOnUnauthorizedClaims,
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
// Add Cedar authorization if policies are provided
|
|
238
|
+
if (policies) {
|
|
239
|
+
verifyOptions.cedarAuth = {
|
|
240
|
+
policies,
|
|
241
|
+
cedar,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return verifyPresentation(vp, verifyOptions);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Creates a Cedar policy for delegation verification
|
|
250
|
+
* @param config - Policy configuration
|
|
251
|
+
* @returns Cedar policy object
|
|
252
|
+
*/
|
|
253
|
+
export function createCedarPolicy(config: {
|
|
254
|
+
maxDepth?: number;
|
|
255
|
+
rootIssuer: string;
|
|
256
|
+
requiredClaims?: Record<string, any>;
|
|
257
|
+
}): CedarPolicies {
|
|
258
|
+
const { maxDepth = 2, rootIssuer, requiredClaims = {} } = config;
|
|
259
|
+
|
|
260
|
+
let claimsConditions = '';
|
|
261
|
+
for (const [key, value] of Object.entries(requiredClaims)) {
|
|
262
|
+
if (typeof value === 'number') {
|
|
263
|
+
claimsConditions += ` &&\n context.authorizedClaims.${key} >= ${value}`;
|
|
264
|
+
} else if (typeof value === 'string') {
|
|
265
|
+
claimsConditions += ` &&\n context.authorizedClaims.${key} == "${value}"`;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const policyText = `
|
|
270
|
+
permit(
|
|
271
|
+
principal in Credential::Chain::"Action:Verify",
|
|
272
|
+
action == Credential::Action::"Verify",
|
|
273
|
+
resource
|
|
274
|
+
) when {
|
|
275
|
+
principal == context.vpSigner &&
|
|
276
|
+
context.tailDepth <= ${maxDepth} &&
|
|
277
|
+
context.rootIssuer == Credential::Actor::"${rootIssuer}"${claimsConditions}
|
|
278
|
+
};
|
|
279
|
+
`;
|
|
280
|
+
|
|
281
|
+
return { staticPolicies: policyText };
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Creates an unsigned verifiable presentation (for testing)
|
|
286
|
+
* @param credentials - Array of credentials to include
|
|
287
|
+
* @param proof - Optional proof object
|
|
288
|
+
* @param context - Optional context
|
|
289
|
+
* @returns Verifiable presentation object
|
|
290
|
+
*/
|
|
291
|
+
export function createUnsignedPresentation(
|
|
292
|
+
credentials: any[],
|
|
293
|
+
proof?: any,
|
|
294
|
+
context: any[] = PRESENTATION_CONTEXT
|
|
295
|
+
): VerifiablePresentation {
|
|
296
|
+
const vp: VerifiablePresentation = {
|
|
297
|
+
'@context': context,
|
|
298
|
+
type: ['VerifiablePresentation'],
|
|
299
|
+
verifiableCredential: credentials,
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
if (proof) {
|
|
303
|
+
vp.proof = proof;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return vp;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Re-export cedar for use in tests and external code
|
|
311
|
+
*/
|
|
312
|
+
export { cedar };
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Service class for delegatable credentials operations
|
|
316
|
+
*/
|
|
317
|
+
class DelegatableCredentialsService {
|
|
318
|
+
name = 'delegatable-credentials';
|
|
319
|
+
|
|
320
|
+
rpcMethods = [
|
|
321
|
+
DelegatableCredentialsService.prototype.issueDelegation,
|
|
322
|
+
DelegatableCredentialsService.prototype.issueDelegatedCredential,
|
|
323
|
+
DelegatableCredentialsService.prototype.createPresentation,
|
|
324
|
+
DelegatableCredentialsService.prototype.verifyPresentation,
|
|
325
|
+
DelegatableCredentialsService.prototype.createPolicy,
|
|
326
|
+
];
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Issues a delegation credential
|
|
330
|
+
*/
|
|
331
|
+
async issueDelegation(params: {
|
|
332
|
+
keyPair: KeyPair;
|
|
333
|
+
id: string;
|
|
334
|
+
issuerDid: string;
|
|
335
|
+
delegateDid: string;
|
|
336
|
+
mayClaim: string[];
|
|
337
|
+
context: any[];
|
|
338
|
+
types: string[];
|
|
339
|
+
additionalSubjectProperties?: Record<string, any>;
|
|
340
|
+
previousCredentialId?: string | null;
|
|
341
|
+
rootCredentialId?: string;
|
|
342
|
+
}): Promise<DelegationCredential> {
|
|
343
|
+
return issueDelegationCredential(params.keyPair, params);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Issues a credential as a delegate
|
|
348
|
+
*/
|
|
349
|
+
async issueDelegatedCredential(params: {
|
|
350
|
+
keyPair: KeyPair;
|
|
351
|
+
id: string;
|
|
352
|
+
issuerDid: string;
|
|
353
|
+
subjectDid: string;
|
|
354
|
+
claims: Record<string, any>;
|
|
355
|
+
rootCredentialId: string;
|
|
356
|
+
previousCredentialId: string;
|
|
357
|
+
context: any[];
|
|
358
|
+
types: string[];
|
|
359
|
+
}): Promise<any> {
|
|
360
|
+
return issueDelegatedCredential(params.keyPair, params);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Creates and signs a verifiable presentation
|
|
365
|
+
*/
|
|
366
|
+
async createPresentation(params: {
|
|
367
|
+
keyPair: KeyPair;
|
|
368
|
+
credentials: any[];
|
|
369
|
+
holderDid: string;
|
|
370
|
+
challenge: string;
|
|
371
|
+
domain: string;
|
|
372
|
+
context?: any[];
|
|
373
|
+
}): Promise<VerifiablePresentation> {
|
|
374
|
+
return createSignedPresentation(params.keyPair, params);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Verifies a verifiable presentation with delegation chain
|
|
379
|
+
*/
|
|
380
|
+
async verifyPresentation(params: {
|
|
381
|
+
presentation: VerifiablePresentation;
|
|
382
|
+
challenge?: string;
|
|
383
|
+
domain?: string;
|
|
384
|
+
unsignedPresentation?: boolean;
|
|
385
|
+
failOnUnauthorizedClaims?: boolean;
|
|
386
|
+
policies?: CedarPolicies;
|
|
387
|
+
}): Promise<VerificationResult> {
|
|
388
|
+
return verifyDelegatablePresentation(params.presentation, {
|
|
389
|
+
challenge: params.challenge,
|
|
390
|
+
domain: params.domain,
|
|
391
|
+
unsignedPresentation: params.unsignedPresentation,
|
|
392
|
+
failOnUnauthorizedClaims: params.failOnUnauthorizedClaims,
|
|
393
|
+
policies: params.policies,
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Creates a Cedar policy for delegation verification
|
|
399
|
+
*/
|
|
400
|
+
createPolicy(params: {
|
|
401
|
+
maxDepth?: number;
|
|
402
|
+
rootIssuer: string;
|
|
403
|
+
requiredClaims?: Record<string, any>;
|
|
404
|
+
}): CedarPolicies {
|
|
405
|
+
return createCedarPolicy(params);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export const delegatableCredentialsService = new DelegatableCredentialsService();
|
|
@@ -3,3 +3,19 @@ import {credentialService} from './service';
|
|
|
3
3
|
|
|
4
4
|
// TODO: rename it to credentialService, will need to update dock-app
|
|
5
5
|
export const credentialServiceRPC = credentialService;
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
delegatableCredentialsService,
|
|
9
|
+
verifyDelegatablePresentation,
|
|
10
|
+
issueDelegationCredential,
|
|
11
|
+
issueDelegatedCredential,
|
|
12
|
+
createSignedPresentation,
|
|
13
|
+
createUnsignedPresentation,
|
|
14
|
+
createCedarPolicy,
|
|
15
|
+
cedar,
|
|
16
|
+
MAY_CLAIM_IRI,
|
|
17
|
+
W3C_CREDENTIALS_V1,
|
|
18
|
+
DELEGATION_ENGINE_NS,
|
|
19
|
+
DELEGATION_CONTEXT_TERMS,
|
|
20
|
+
PRESENTATION_CONTEXT,
|
|
21
|
+
} from './delegatable-credentials';
|