@idos-network/issuer 1.5.0 → 2.2.2
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 +7 -4
- package/dist/index.d.mts +15 -38
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -235
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -8
- package/src/index.test.ts +226 -0
- package/src/index.ts +27 -65
- package/src/services/credential.service.ts +77 -121
- package/src/services/user.service.ts +7 -0
- package/src/services/grant.service.ts +0 -56
package/README.md
CHANGED
|
@@ -22,11 +22,10 @@ pnpm add @idos-network/issuer
|
|
|
22
22
|
```typescript
|
|
23
23
|
import { idOSIssuer as idOSIssuerClass } from "@idos-network/issuer";
|
|
24
24
|
|
|
25
|
-
// Initialize with your signing
|
|
25
|
+
// Initialize with your signing keypair
|
|
26
26
|
const idOSIssuer = await idOSIssuerClass.init({
|
|
27
27
|
nodeUrl: "https://nodes.idos.network",
|
|
28
28
|
signingKeyPair, // Your signing keypair
|
|
29
|
-
encryptionSecretKey, // Your encryption secret key
|
|
30
29
|
});
|
|
31
30
|
|
|
32
31
|
// Create a user profile
|
|
@@ -35,8 +34,12 @@ await idOSIssuer.createUser(user, wallet);
|
|
|
35
34
|
// Build and issue a W3C Verifiable Credential
|
|
36
35
|
const credential = await idOSIssuer.buildCredential(credentialFields, credentialSubject, issuer);
|
|
37
36
|
|
|
38
|
-
// Write credential using delegated write grant
|
|
39
|
-
await idOSIssuer.createCredentialByDelegatedWriteGrant(
|
|
37
|
+
// Write blob-backed credential using delegated write grant
|
|
38
|
+
await idOSIssuer.createCredentialByDelegatedWriteGrant(
|
|
39
|
+
credentialPayload,
|
|
40
|
+
delegatedWriteGrant,
|
|
41
|
+
consumerEncryptionPublicKey,
|
|
42
|
+
);
|
|
40
43
|
```
|
|
41
44
|
|
|
42
45
|
## Documentation
|
package/dist/index.d.mts
CHANGED
|
@@ -1,36 +1,16 @@
|
|
|
1
|
-
import { Credential, FaceIdCredential } from "@idos-network/credentials/builder";
|
|
2
1
|
import "@idos-network/kwil-infra";
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import { AvailableIssuerType,
|
|
2
|
+
import { BuildPreliminaryIDOSCredentialArgs } from "@idos-network/credentials/utils";
|
|
3
|
+
import { AddWalletMessageInput, DelegatedWriteGrantBaseParams, EditPublicNotesAsIssuerInput, idOSDelegatedWriteGrant, idOSGrant, idOSUser, idOSUser as idOSUser$1, idOSUserAttribute, idOSWallet, idOSWallet as idOSWallet$1, toDelegatedWriteGrantBaseParams } from "@idos-network/kwil-infra/actions";
|
|
4
|
+
import { AvailableIssuerType, idOSCredential, idOSCredentialRecord } from "@idos-network/credentials/types";
|
|
5
|
+
import { SignKeyPair } from "tweetnacl";
|
|
6
|
+
import "@idos-network/utils/blob-gateway";
|
|
6
7
|
//#region src/services/credential.service.d.ts
|
|
7
|
-
type
|
|
8
|
-
id?: string;
|
|
9
|
-
userId: string;
|
|
10
|
-
publicNotes: string;
|
|
11
|
-
plaintextContent: Uint8Array;
|
|
12
|
-
recipientEncryptionPublicKey: Uint8Array;
|
|
13
|
-
};
|
|
14
|
-
type DelegatedWriteGrantBaseParams = Omit<BaseCredentialParams, "userId">;
|
|
15
|
-
type DelegatedWriteGrantParams = {
|
|
16
|
-
id: string;
|
|
17
|
-
ownerWalletIdentifier: string;
|
|
18
|
-
consumerWalletIdentifier: string;
|
|
19
|
-
issuerPublicKey: string;
|
|
20
|
-
accessGrantTimelock: string;
|
|
21
|
-
notUsableBefore: string;
|
|
22
|
-
notUsableAfter: string;
|
|
8
|
+
type DelegatedWriteGrantParams = DelegatedWriteGrantBaseParams & {
|
|
23
9
|
signature: string;
|
|
24
10
|
};
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
dag_data_id: string;
|
|
29
|
-
dag_owner_wallet_identifier: string;
|
|
30
|
-
dag_grantee_wallet_identifier: string;
|
|
31
|
-
dag_signature: string;
|
|
32
|
-
dag_locked_until: number;
|
|
33
|
-
dag_content_hash: string;
|
|
11
|
+
type CredentialByDelegatedWriteGrantBaseParams = Omit<BuildPreliminaryIDOSCredentialArgs, "issuerSigningSecretKey" | "contentUri"> & {
|
|
12
|
+
originalContentUri?: string;
|
|
13
|
+
copyContentUri?: string;
|
|
34
14
|
};
|
|
35
15
|
//#endregion
|
|
36
16
|
//#region src/services/user.service.d.ts
|
|
@@ -48,31 +28,28 @@ type CreateWalletReqParams = Omit<UpsertWalletReqParams, "user_id"> & {
|
|
|
48
28
|
type CreateIssuerParams = {
|
|
49
29
|
chainId?: string;
|
|
50
30
|
nodeUrl: string;
|
|
31
|
+
blobGatewayUrl?: string;
|
|
51
32
|
signingKeyPair: SignKeyPair;
|
|
52
|
-
encryptionSecretKey: Uint8Array;
|
|
53
33
|
};
|
|
54
|
-
declare class idOSIssuer {
|
|
34
|
+
export declare class idOSIssuer {
|
|
55
35
|
#private;
|
|
56
36
|
static init(params: CreateIssuerParams): Promise<idOSIssuer>;
|
|
57
37
|
private constructor();
|
|
58
38
|
hasProfile(userAddress: string): Promise<boolean>;
|
|
59
39
|
createUserProfile(params: CreateProfileReqParams): Promise<idOSUser>;
|
|
60
40
|
upsertWalletAsInserter(params: UpsertWalletReqParams): Promise<idOSWallet>;
|
|
41
|
+
addWalletMessage(params: AddWalletMessageInput): Promise<string>;
|
|
61
42
|
createUser(user: CreateProfileReqParams, wallet: CreateWalletReqParams): Promise<[idOSUser, idOSWallet]>;
|
|
62
43
|
getUser(id: string): Promise<idOSUser>;
|
|
63
44
|
requestDelegatedWriteGrantMessage(params: idOSDelegatedWriteGrant): Promise<string>;
|
|
64
|
-
createCredentialByDelegatedWriteGrant(credentialParams:
|
|
45
|
+
createCredentialByDelegatedWriteGrant(credentialParams: CredentialByDelegatedWriteGrantBaseParams, delegatedWriteGrant: DelegatedWriteGrantParams, consumerEncryptionPublicKey: Uint8Array): Promise<{
|
|
65
46
|
originalCredential: Omit<idOSCredential, "user_id">;
|
|
66
47
|
copyCredential: Omit<idOSCredential, "user_id">;
|
|
67
48
|
}>;
|
|
68
49
|
editCredentialAsIssuer(publicNotesId: string, publicNotes: string): Promise<EditPublicNotesAsIssuerInput | null>;
|
|
69
50
|
getCredentialIdByContentHash(contentHash: string): Promise<string | null>;
|
|
70
|
-
getCredentialShared(id: string): Promise<
|
|
71
|
-
createAccessGrantFromDAG(params: CreateAccessGrantFromDAGParams): Promise<CreateAccessGrantFromDAGParams | null>;
|
|
72
|
-
buildCredential(fields: CredentialFields, subject: CredentialSubject, issuer: AvailableIssuerType, validate?: boolean): Promise<Credential>;
|
|
73
|
-
deriveCredentialLevel(subject: CredentialSubject): string;
|
|
74
|
-
buildFaceIdCredential(fields: CredentialFields, subject: CredentialSubjectFaceId, issuer: AvailableIssuerType, validate?: boolean): Promise<FaceIdCredential>;
|
|
51
|
+
getCredentialShared(id: string): Promise<idOSCredentialRecord | null>;
|
|
75
52
|
}
|
|
76
53
|
//#endregion
|
|
77
|
-
export { type AvailableIssuerType, type
|
|
54
|
+
export { type AvailableIssuerType, type CredentialByDelegatedWriteGrantBaseParams, type DelegatedWriteGrantBaseParams, type DelegatedWriteGrantParams, type idOSCredential, type idOSDelegatedWriteGrant, type idOSGrant, type idOSUser, type idOSUserAttribute, type idOSWallet, toDelegatedWriteGrantBaseParams };
|
|
78
55
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/services/credential.service.ts","../src/services/
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/services/credential.service.ts","../src/services/user.service.ts","../src/index.ts"],"mappings":";;;;;;;KA2BY,4BAA4B;EACtC;;KAGU,4CAA4C,KACtD;EAGA;EACA;;;;KCtBU,yBAAyB,KAAK;EACxC;;KAGU,wBAAwB,KAAK;EACvC;;KAGU,wBAAwB,KAAK;EACvC;;;;KCYG;EACH;EACA;EACA;EACA,gBAAgB;;qBAGL;;SAIE,KAAK,QAAQ,qBAAqB,QAAQ;UAqB/C;EAMR,WAAiB,sBAAsB;EAIvC,kBAAwB,QAAQ,yBAAyB,QAAQ;EAIjE,uBAA6B,QAAQ,wBAAwB,QAAQ;EAIrE,iBAAuB,QAAQ,wBAAwB;EAIvD,WACE,MAAM,wBACN,QAAQ,wBACP,SAAS,UAAU;EAItB,QAAc,aAAa,QAAQ;EAInC,kCAAwC,QAAQ,0BAA0B;EAI1E,sCACE,kBAAkB,2CAClB,qBAAqB,2BACrB,6BAA6B,aAC5B;IACD,oBAAoB,KAAK;IACzB,gBAAgB,KAAK;;EASvB,uBACE,uBACA,sBACC,QAAQ;EAIX,6BAAmC,sBAAsB;EAIzD,oBAA0B,aAAa,QAAQ"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,236 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { deriveLevel } from "@idos-network/credentials/utils";
|
|
3
|
-
import { createNodeKwilClient, createServerKwilSigner } from "@idos-network/kwil-infra";
|
|
4
|
-
import { addUserAsInserter, createAgByDagForCopy, createCredentialsByDwg, dwgMessage, editPublicNotesAsIssuer, getCredentialShared, getSiblingCredentialId, getUserAsInserter, hasProfile, upsertWalletAsInserter } from "@idos-network/kwil-infra/actions";
|
|
5
|
-
import { base64Decode, base64Encode, hexEncode, hexEncodeSha256Hash, utf8Encode } from "@idos-network/utils/codecs";
|
|
6
|
-
import { NoncedBox, encryptContent } from "@idos-network/utils/cryptography";
|
|
7
|
-
import nacl from "tweetnacl";
|
|
8
|
-
//#region ../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js
|
|
9
|
-
var isProduction = process.env.NODE_ENV === "production";
|
|
10
|
-
var prefix = "Invariant failed";
|
|
11
|
-
function invariant(condition, message) {
|
|
12
|
-
if (condition) return;
|
|
13
|
-
if (isProduction) throw new Error(prefix);
|
|
14
|
-
var provided = typeof message === "function" ? message() : message;
|
|
15
|
-
var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
|
|
16
|
-
throw new Error(value);
|
|
17
|
-
}
|
|
18
|
-
//#endregion
|
|
19
|
-
//#region src/services/credential.service.ts
|
|
20
|
-
var CredentialService = class {
|
|
21
|
-
#kwilClient;
|
|
22
|
-
#signingKeyPair;
|
|
23
|
-
#encryptionSecretKey;
|
|
24
|
-
constructor(kwilClient, signingKeyPair, encryptionSecretKey) {
|
|
25
|
-
this.#kwilClient = kwilClient;
|
|
26
|
-
this.#signingKeyPair = signingKeyPair;
|
|
27
|
-
this.#encryptionSecretKey = encryptionSecretKey;
|
|
28
|
-
}
|
|
29
|
-
#buildInsertableIDOSCredential({ userId, publicNotes, plaintextContent, recipientEncryptionPublicKey }) {
|
|
30
|
-
const ephemeralKeyPair = nacl.box.keyPair();
|
|
31
|
-
const content = encryptContent(plaintextContent, recipientEncryptionPublicKey, ephemeralKeyPair.secretKey);
|
|
32
|
-
const public_notes_signature = base64Encode(nacl.sign.detached(utf8Encode(publicNotes), this.#signingKeyPair.secretKey));
|
|
33
|
-
return {
|
|
34
|
-
user_id: userId,
|
|
35
|
-
content: base64Encode(content),
|
|
36
|
-
public_notes: publicNotes,
|
|
37
|
-
public_notes_signature,
|
|
38
|
-
broader_signature: base64Encode(nacl.sign.detached(Uint8Array.from([...base64Decode(public_notes_signature), ...content]), this.#signingKeyPair.secretKey)),
|
|
39
|
-
issuer_auth_public_key: hexEncode(this.#signingKeyPair.publicKey, true),
|
|
40
|
-
encryptor_public_key: base64Encode(ephemeralKeyPair.publicKey)
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
#ensureEntityId(entity) {
|
|
44
|
-
if (!entity.id) entity.id = crypto.randomUUID();
|
|
45
|
-
return entity;
|
|
46
|
-
}
|
|
47
|
-
async requestDelegatedWriteGrantMessage(params) {
|
|
48
|
-
return dwgMessage(this.#kwilClient, params).then((res) => res.message);
|
|
49
|
-
}
|
|
50
|
-
async createCredentialByDelegatedWriteGrant(credentialParams, delegatedWriteGrant, consumerEncryptionPublicKey) {
|
|
51
|
-
let recipientPublicKey = consumerEncryptionPublicKey;
|
|
52
|
-
if (!recipientPublicKey) recipientPublicKey = nacl.box.keyPair.fromSecretKey(this.#encryptionSecretKey).publicKey;
|
|
53
|
-
const originalCredential = this.#ensureEntityId(this.#buildInsertableIDOSCredential(credentialParams));
|
|
54
|
-
const contentHash = hexEncodeSha256Hash(credentialParams.plaintextContent);
|
|
55
|
-
const copyCredential = this.#ensureEntityId(this.#buildInsertableIDOSCredential({
|
|
56
|
-
publicNotes: "",
|
|
57
|
-
plaintextContent: credentialParams.plaintextContent,
|
|
58
|
-
recipientEncryptionPublicKey: recipientPublicKey
|
|
59
|
-
}));
|
|
60
|
-
const payload = {
|
|
61
|
-
issuer_auth_public_key: originalCredential.issuer_auth_public_key,
|
|
62
|
-
original_encryptor_public_key: originalCredential.encryptor_public_key,
|
|
63
|
-
original_credential_id: originalCredential.id,
|
|
64
|
-
original_content: originalCredential.content,
|
|
65
|
-
original_public_notes: originalCredential.public_notes,
|
|
66
|
-
original_public_notes_signature: originalCredential.public_notes_signature,
|
|
67
|
-
original_broader_signature: originalCredential.broader_signature,
|
|
68
|
-
copy_encryptor_public_key: copyCredential.encryptor_public_key,
|
|
69
|
-
copy_credential_id: copyCredential.id,
|
|
70
|
-
copy_content: copyCredential.content,
|
|
71
|
-
copy_public_notes_signature: copyCredential.public_notes_signature,
|
|
72
|
-
copy_broader_signature: copyCredential.broader_signature,
|
|
73
|
-
content_hash: contentHash,
|
|
74
|
-
dwg_owner: delegatedWriteGrant.ownerWalletIdentifier,
|
|
75
|
-
dwg_grantee: delegatedWriteGrant.consumerWalletIdentifier,
|
|
76
|
-
dwg_issuer_public_key: delegatedWriteGrant.issuerPublicKey,
|
|
77
|
-
dwg_id: delegatedWriteGrant.id,
|
|
78
|
-
dwg_access_grant_timelock: delegatedWriteGrant.accessGrantTimelock,
|
|
79
|
-
dwg_not_before: delegatedWriteGrant.notUsableBefore,
|
|
80
|
-
dwg_not_after: delegatedWriteGrant.notUsableAfter,
|
|
81
|
-
dwg_signature: delegatedWriteGrant.signature
|
|
82
|
-
};
|
|
83
|
-
await createCredentialsByDwg(this.#kwilClient, payload);
|
|
84
|
-
return {
|
|
85
|
-
originalCredential,
|
|
86
|
-
copyCredential
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
async editCredentialAsIssuer(publicNotesId, publicNotes) {
|
|
90
|
-
const payload = {
|
|
91
|
-
public_notes_id: publicNotesId,
|
|
92
|
-
public_notes: publicNotes
|
|
93
|
-
};
|
|
94
|
-
await editPublicNotesAsIssuer(this.#kwilClient, payload);
|
|
95
|
-
return payload;
|
|
96
|
-
}
|
|
97
|
-
async getCredentialIdByContentHash(contentHash) {
|
|
98
|
-
const id = await getSiblingCredentialId(this.#kwilClient, { content_hash: contentHash }).then((res) => res.id);
|
|
99
|
-
invariant(id, "Required `idOSCredential` id not found");
|
|
100
|
-
return id;
|
|
101
|
-
}
|
|
102
|
-
async getCredentialShared(id) {
|
|
103
|
-
return await getCredentialShared(this.#kwilClient, { id }).then((res) => res[0]) ?? null;
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
//#endregion
|
|
107
|
-
//#region src/services/grant.service.ts
|
|
108
|
-
var GrantService = class {
|
|
109
|
-
#kwilClient;
|
|
110
|
-
#encryptionSecretKey;
|
|
111
|
-
constructor(kwilClient, encryptionSecretKey) {
|
|
112
|
-
this.#kwilClient = kwilClient;
|
|
113
|
-
this.#encryptionSecretKey = encryptionSecretKey;
|
|
114
|
-
}
|
|
115
|
-
async createAccessGrantFromDAG(params, getCredentialIdByContentHash, getCredentialShared) {
|
|
116
|
-
const credentialId = await getCredentialIdByContentHash(params.dag_content_hash);
|
|
117
|
-
invariant(credentialId, "Missing `idOSCredential` id");
|
|
118
|
-
const credential = await getCredentialShared(credentialId);
|
|
119
|
-
invariant(credential, "`idOSCredential` with id `{credentialId}` not found");
|
|
120
|
-
if (hexEncodeSha256Hash(utf8Encode(await NoncedBox.nonceFromBase64SecretKey(base64Encode(this.#encryptionSecretKey)).decrypt(credential.content, credential.encryptor_public_key))) !== params.dag_content_hash) throw new Error("Hash mismatch between `DAG` and `idOSCredential` content");
|
|
121
|
-
return await createAgByDagForCopy(this.#kwilClient, params) ?? null;
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
//#endregion
|
|
125
|
-
//#region src/services/user.service.ts
|
|
126
|
-
var UserService = class {
|
|
127
|
-
#kwilClient;
|
|
128
|
-
constructor(kwilClient) {
|
|
129
|
-
this.#kwilClient = kwilClient;
|
|
130
|
-
}
|
|
131
|
-
#ensureEntityId(entity) {
|
|
132
|
-
if (!entity.id) entity.id = crypto.randomUUID();
|
|
133
|
-
return entity;
|
|
134
|
-
}
|
|
135
|
-
async hasProfile(address) {
|
|
136
|
-
return hasProfile(this.#kwilClient, { address }).then((res) => res.has_profile);
|
|
137
|
-
}
|
|
138
|
-
async createUserProfile(params) {
|
|
139
|
-
const payload = this.#ensureEntityId(params);
|
|
140
|
-
await addUserAsInserter(this.#kwilClient, payload);
|
|
141
|
-
return payload;
|
|
142
|
-
}
|
|
143
|
-
async upsertWalletAsInserter(params) {
|
|
144
|
-
const payload = this.#ensureEntityId(params);
|
|
145
|
-
await upsertWalletAsInserter(this.#kwilClient, payload);
|
|
146
|
-
return payload;
|
|
147
|
-
}
|
|
148
|
-
async getUser(params) {
|
|
149
|
-
return getUserAsInserter(this.#kwilClient, this.#ensureEntityId(params));
|
|
150
|
-
}
|
|
151
|
-
async createUser(user, wallet) {
|
|
152
|
-
const user_id = user.id ?? crypto.randomUUID();
|
|
153
|
-
const wallet_id = wallet.id ?? crypto.randomUUID();
|
|
154
|
-
const userReqParams = {
|
|
155
|
-
...user,
|
|
156
|
-
id: user_id
|
|
157
|
-
};
|
|
158
|
-
const userResponse = await this.createUserProfile(userReqParams);
|
|
159
|
-
const walletReqParams = {
|
|
160
|
-
...wallet,
|
|
161
|
-
user_id,
|
|
162
|
-
id: wallet_id
|
|
163
|
-
};
|
|
164
|
-
return [userResponse, await this.upsertWalletAsInserter(walletReqParams)];
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
//#endregion
|
|
168
|
-
//#region src/index.ts
|
|
169
|
-
var idOSIssuer = class idOSIssuer {
|
|
170
|
-
#credentialService;
|
|
171
|
-
#grantService;
|
|
172
|
-
#userService;
|
|
173
|
-
static async init(params) {
|
|
174
|
-
const kwilClient = await createNodeKwilClient({
|
|
175
|
-
nodeUrl: params.nodeUrl,
|
|
176
|
-
chainId: params.chainId
|
|
177
|
-
});
|
|
178
|
-
const [signer] = await createServerKwilSigner(params.signingKeyPair);
|
|
179
|
-
kwilClient.setSigner(signer);
|
|
180
|
-
const credentialService = new CredentialService(kwilClient, params.signingKeyPair, params.encryptionSecretKey);
|
|
181
|
-
const grantService = new GrantService(kwilClient, params.encryptionSecretKey);
|
|
182
|
-
const userService = new UserService(kwilClient);
|
|
183
|
-
return new idOSIssuer(credentialService, grantService, userService);
|
|
184
|
-
}
|
|
185
|
-
constructor(credentialService, grantService, userService) {
|
|
186
|
-
this.#credentialService = credentialService;
|
|
187
|
-
this.#grantService = grantService;
|
|
188
|
-
this.#userService = userService;
|
|
189
|
-
}
|
|
190
|
-
async hasProfile(userAddress) {
|
|
191
|
-
return this.#userService.hasProfile(userAddress);
|
|
192
|
-
}
|
|
193
|
-
async createUserProfile(params) {
|
|
194
|
-
return this.#userService.createUserProfile(params);
|
|
195
|
-
}
|
|
196
|
-
async upsertWalletAsInserter(params) {
|
|
197
|
-
return this.#userService.upsertWalletAsInserter(params);
|
|
198
|
-
}
|
|
199
|
-
async createUser(user, wallet) {
|
|
200
|
-
return this.#userService.createUser(user, wallet);
|
|
201
|
-
}
|
|
202
|
-
async getUser(id) {
|
|
203
|
-
return this.#userService.getUser({ id });
|
|
204
|
-
}
|
|
205
|
-
async requestDelegatedWriteGrantMessage(params) {
|
|
206
|
-
return this.#credentialService.requestDelegatedWriteGrantMessage(params);
|
|
207
|
-
}
|
|
208
|
-
async createCredentialByDelegatedWriteGrant(credentialParams, delegatedWriteGrant, consumerEncryptionPublicKey) {
|
|
209
|
-
return this.#credentialService.createCredentialByDelegatedWriteGrant(credentialParams, delegatedWriteGrant, consumerEncryptionPublicKey);
|
|
210
|
-
}
|
|
211
|
-
async editCredentialAsIssuer(publicNotesId, publicNotes) {
|
|
212
|
-
return this.#credentialService.editCredentialAsIssuer(publicNotesId, publicNotes);
|
|
213
|
-
}
|
|
214
|
-
async getCredentialIdByContentHash(contentHash) {
|
|
215
|
-
return this.#credentialService.getCredentialIdByContentHash(contentHash);
|
|
216
|
-
}
|
|
217
|
-
async getCredentialShared(id) {
|
|
218
|
-
return this.#credentialService.getCredentialShared(id);
|
|
219
|
-
}
|
|
220
|
-
async createAccessGrantFromDAG(params) {
|
|
221
|
-
return this.#grantService.createAccessGrantFromDAG(params, (contentHash) => this.getCredentialIdByContentHash(contentHash), (id) => this.getCredentialShared(id));
|
|
222
|
-
}
|
|
223
|
-
async buildCredential(fields, subject, issuer, validate = true) {
|
|
224
|
-
return buildCredential(fields, subject, issuer, validate);
|
|
225
|
-
}
|
|
226
|
-
deriveCredentialLevel(subject) {
|
|
227
|
-
return deriveLevel(subject);
|
|
228
|
-
}
|
|
229
|
-
async buildFaceIdCredential(fields, subject, issuer, validate = true) {
|
|
230
|
-
return buildFaceIdCredential(fields, subject, issuer, validate);
|
|
231
|
-
}
|
|
232
|
-
};
|
|
233
|
-
//#endregion
|
|
234
|
-
export { idOSIssuer };
|
|
235
|
-
|
|
1
|
+
import{createKgwAuthenticatedBlobGateway as e,createNodeKwilClient as t,createServerKwilSigner as n}from"@idos-network/kwil-infra";import{buildPreliminaryIDOSCredential as r,mapPreliminaryToIDOSCredential as i}from"@idos-network/credentials/utils";import{addUserAsInserter as a,addWalletMessage as o,createPreliminaryCredentialsByDwg as s,dwgMessage as c,editPublicNotesAsIssuer as l,getCredentialShared as u,getSiblingCredentialId as d,getUserAsInserter as f,hasProfile as p,toDelegatedWriteGrantBaseParams as m,upsertWalletAsInserter as h}from"@idos-network/kwil-infra/actions";import{hexEncodeSha256Hash as g}from"@idos-network/utils/codecs";var _=process.env.NODE_ENV===`production`,v=`Invariant failed`;function y(e,t){if(!e){if(_)throw Error(v);var n=typeof t==`function`?t():t,r=n?`${v}: ${n}`:v;throw Error(r)}}var b=class{#e;#t;#n;constructor(e,t,n){this.#e=e,this.#t=t,this.#n=n}async requestDelegatedWriteGrantMessage(e){return c(this.#e,e).then(e=>e.message)}async createCredentialByDelegatedWriteGrant(e,t,n){let{originalContentUri:a,copyContentUri:o,...c}=e,l={...await r({...c,contentUri:a,issuerSigningSecretKey:this.#t.secretKey}),id:crypto.randomUUID()},u=g(e.plaintextContent),d={...await r({...c,contentUri:o,publicNotes:``,recipientEncryptionPublicKey:n,issuerSigningSecretKey:this.#t.secretKey}),id:crypto.randomUUID()};y(l.contentUri!==d.contentUri,`Original and copy credentials must use distinct content URIs`);let f=crypto.randomUUID(),p={request_id:f,issuer_auth_public_key:l.issuerAuthPublicKey,original_encryptor_public_key:l.encryptorPublicKey,original_id:l.id,original_content_uri:l.contentUri,original_content_size:l.contentSize,original_public_notes:l.publicNotes,original_public_notes_signature:l.publicNotesSignature,original_broader_signature:l.broaderSignature,copy_encryptor_public_key:d.encryptorPublicKey,copy_id:d.id,copy_content_uri:d.contentUri,copy_content_size:d.contentSize,copy_public_notes_signature:d.publicNotesSignature,copy_broader_signature:d.broaderSignature,content_hash:u,dwg_owner:t.ownerWalletIdentifier,dwg_grantee:t.consumerWalletIdentifier,dwg_issuer_public_key:t.issuerPublicKey,dwg_id:t.id,dwg_access_grant_timelock:t.accessGrantTimelock,dwg_not_before:t.notUsableBefore,dwg_not_after:t.notUsableAfter,dwg_signature:t.signature};return await s(this.#e,p),await this.#n.uploadCredentialBlobs({requestId:f,original:l.encryptedContent,copy:d.encryptedContent}),{originalCredential:i(l),copyCredential:i(d)}}async editCredentialAsIssuer(e,t){let n={public_notes_id:e,public_notes:t};return await l(this.#e,n),n}async getCredentialIdByContentHash(e){let t=await d(this.#e,{content_hash:e}).then(e=>e.id);return y(t,"Required `idOSCredential` id not found"),t}async getCredentialShared(e){return await u(this.#e,{id:e}).then(e=>e[0])??null}},x=class{#e;constructor(e){this.#e=e}#t(e){return e.id||=crypto.randomUUID(),e}async hasProfile(e){return p(this.#e,{address:e}).then(e=>e.has_profile)}async createUserProfile(e){let t=this.#t(e);return await a(this.#e,t),t}async upsertWalletAsInserter(e){let t=this.#t(e);return await h(this.#e,t),t}async addWalletMessage(e){return(await o(this.#e,e)).message}async getUser(e){return f(this.#e,this.#t(e))}async createUser(e,t){let n=e.id??crypto.randomUUID(),r=t.id??crypto.randomUUID(),i={...e,id:n},a=await this.createUserProfile(i),o={...t,user_id:n,id:r};return[a,await this.upsertWalletAsInserter(o)]}},S=class r{#e;#t;static async init(i){let a=await t({nodeUrl:i.nodeUrl,chainId:i.chainId}),[o]=await n(i.signingKeyPair);a.setSigner(o);let s=e({url:i.blobGatewayUrl??i.nodeUrl,kwilClient:a,signer:o}),c=new b(a,i.signingKeyPair,s),l=new x(a);return new r(c,l)}constructor(e,t){this.#e=e,this.#t=t}async hasProfile(e){return this.#t.hasProfile(e)}async createUserProfile(e){return this.#t.createUserProfile(e)}async upsertWalletAsInserter(e){return this.#t.upsertWalletAsInserter(e)}async addWalletMessage(e){return this.#t.addWalletMessage(e)}async createUser(e,t){return this.#t.createUser(e,t)}async getUser(e){return this.#t.getUser({id:e})}async requestDelegatedWriteGrantMessage(e){return this.#e.requestDelegatedWriteGrantMessage(e)}async createCredentialByDelegatedWriteGrant(e,t,n){return this.#e.createCredentialByDelegatedWriteGrant(e,t,n)}async editCredentialAsIssuer(e,t){return this.#e.editCredentialAsIssuer(e,t)}async getCredentialIdByContentHash(e){return this.#e.getCredentialIdByContentHash(e)}async getCredentialShared(e){return this.#e.getCredentialShared(e)}};export{S as idOSIssuer,m as toDelegatedWriteGrantBaseParams};
|
|
236
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["#kwilClient","#signingKeyPair","#encryptionSecretKey","#ensureEntityId","#buildInsertableIDOSCredential","#kwilClient","#encryptionSecretKey","_createAgByDagForCopy","#kwilClient","_hasProfile","#ensureEntityId","_upsertWalletAsInserter","#credentialService","#grantService","#userService"],"sources":["../../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js","../src/services/credential.service.ts","../src/services/grant.service.ts","../src/services/user.service.ts","../src/index.ts"],"sourcesContent":["var isProduction = process.env.NODE_ENV === 'production';\nvar prefix = 'Invariant failed';\nfunction invariant(condition, message) {\n if (condition) {\n return;\n }\n if (isProduction) {\n throw new Error(prefix);\n }\n var provided = typeof message === 'function' ? message() : message;\n var value = provided ? \"\".concat(prefix, \": \").concat(provided) : prefix;\n throw new Error(value);\n}\n\nexport { invariant as default };\n","import type { idOSCredential } from \"@idos-network/credentials/types\";\nimport type { KwilActionClient } from \"@idos-network/kwil-infra\";\n\nimport {\n type CreateCredentialsByDwgInput,\n createCredentialsByDwg,\n dwgMessage,\n type EditPublicNotesAsIssuerInput,\n editPublicNotesAsIssuer,\n getCredentialShared,\n getSiblingCredentialId,\n type idOSDelegatedWriteGrant,\n} from \"@idos-network/kwil-infra/actions\";\nimport {\n base64Decode,\n base64Encode,\n hexEncode,\n hexEncodeSha256Hash,\n utf8Encode,\n} from \"@idos-network/utils/codecs\";\nimport { encryptContent } from \"@idos-network/utils/cryptography\";\nimport invariant from \"tiny-invariant\";\nimport nacl from \"tweetnacl\";\n\ntype InsertableIDOSCredential = Omit<idOSCredential, \"id\" | \"original_id\"> & {\n id?: idOSCredential[\"id\"];\n content_hash?: string;\n public_notes_signature: string;\n broader_signature: string;\n};\n\ntype BuildInsertableIDOSCredentialArgs = {\n userId: string;\n publicNotes: string;\n plaintextContent: Uint8Array;\n recipientEncryptionPublicKey: Uint8Array;\n};\n\nexport type BaseCredentialParams = {\n id?: string;\n userId: string;\n publicNotes: string;\n plaintextContent: Uint8Array;\n recipientEncryptionPublicKey: Uint8Array;\n};\n\nexport type DelegatedWriteGrantBaseParams = Omit<BaseCredentialParams, \"userId\">;\n\nexport type DelegatedWriteGrantParams = {\n id: string;\n ownerWalletIdentifier: string;\n consumerWalletIdentifier: string;\n issuerPublicKey: string;\n accessGrantTimelock: string;\n notUsableBefore: string;\n notUsableAfter: string;\n signature: string;\n};\n\nexport class CredentialService {\n readonly #kwilClient: KwilActionClient;\n readonly #signingKeyPair: nacl.SignKeyPair;\n readonly #encryptionSecretKey: Uint8Array;\n\n constructor(\n kwilClient: KwilActionClient,\n signingKeyPair: nacl.SignKeyPair,\n encryptionSecretKey: Uint8Array,\n ) {\n this.#kwilClient = kwilClient;\n this.#signingKeyPair = signingKeyPair;\n this.#encryptionSecretKey = encryptionSecretKey;\n }\n\n #buildInsertableIDOSCredential({\n userId,\n publicNotes,\n plaintextContent,\n recipientEncryptionPublicKey,\n }: Omit<BuildInsertableIDOSCredentialArgs, \"userId\"> & { userId?: string }):\n | InsertableIDOSCredential\n | Omit<InsertableIDOSCredential, \"user_id\"> {\n const ephemeralKeyPair = nacl.box.keyPair();\n const content = encryptContent(\n plaintextContent,\n recipientEncryptionPublicKey,\n ephemeralKeyPair.secretKey,\n );\n\n const public_notes_signature = base64Encode(\n nacl.sign.detached(utf8Encode(publicNotes), this.#signingKeyPair.secretKey),\n );\n\n return {\n user_id: userId,\n content: base64Encode(content),\n public_notes: publicNotes,\n public_notes_signature,\n\n broader_signature: base64Encode(\n nacl.sign.detached(\n Uint8Array.from([...base64Decode(public_notes_signature), ...content]),\n this.#signingKeyPair.secretKey,\n ),\n ),\n\n issuer_auth_public_key: hexEncode(this.#signingKeyPair.publicKey, true),\n encryptor_public_key: base64Encode(ephemeralKeyPair.publicKey),\n };\n }\n\n #ensureEntityId<T extends { id?: string }>(entity: T): T & { id: string } {\n if (!entity.id) {\n (entity as T & { id: string }).id = crypto.randomUUID();\n }\n return entity as T & { id: string };\n }\n\n async requestDelegatedWriteGrantMessage(params: idOSDelegatedWriteGrant): Promise<string> {\n return dwgMessage(this.#kwilClient, params).then((res) => res.message);\n }\n\n async createCredentialByDelegatedWriteGrant(\n credentialParams: DelegatedWriteGrantBaseParams,\n delegatedWriteGrant: DelegatedWriteGrantParams,\n consumerEncryptionPublicKey?: Uint8Array,\n ): Promise<{\n originalCredential: Omit<idOSCredential, \"user_id\">;\n copyCredential: Omit<idOSCredential, \"user_id\">;\n }> {\n let recipientPublicKey = consumerEncryptionPublicKey;\n if (!recipientPublicKey) {\n // If we're not explicitly given a consumer enc pub key, we're assuming that the issuer is creating a copy\n // for themselves. So, we derive the recipient encryption public key from the issuer's encryption secret key.\n recipientPublicKey = nacl.box.keyPair.fromSecretKey(this.#encryptionSecretKey).publicKey;\n }\n\n const originalCredential = this.#ensureEntityId(\n this.#buildInsertableIDOSCredential(credentialParams),\n );\n\n const contentHash = hexEncodeSha256Hash(credentialParams.plaintextContent);\n\n const copyCredential = this.#ensureEntityId(\n this.#buildInsertableIDOSCredential({\n publicNotes: \"\",\n plaintextContent: credentialParams.plaintextContent,\n recipientEncryptionPublicKey: recipientPublicKey,\n }),\n );\n\n const payload: CreateCredentialsByDwgInput = {\n issuer_auth_public_key: originalCredential.issuer_auth_public_key,\n original_encryptor_public_key: originalCredential.encryptor_public_key,\n original_credential_id: originalCredential.id,\n original_content: originalCredential.content,\n original_public_notes: originalCredential.public_notes,\n original_public_notes_signature: originalCredential.public_notes_signature,\n original_broader_signature: originalCredential.broader_signature,\n copy_encryptor_public_key: copyCredential.encryptor_public_key,\n copy_credential_id: copyCredential.id,\n copy_content: copyCredential.content,\n copy_public_notes_signature: copyCredential.public_notes_signature,\n copy_broader_signature: copyCredential.broader_signature,\n content_hash: contentHash,\n dwg_owner: delegatedWriteGrant.ownerWalletIdentifier,\n dwg_grantee: delegatedWriteGrant.consumerWalletIdentifier,\n dwg_issuer_public_key: delegatedWriteGrant.issuerPublicKey,\n dwg_id: delegatedWriteGrant.id,\n dwg_access_grant_timelock: delegatedWriteGrant.accessGrantTimelock,\n dwg_not_before: delegatedWriteGrant.notUsableBefore,\n dwg_not_after: delegatedWriteGrant.notUsableAfter,\n dwg_signature: delegatedWriteGrant.signature,\n };\n\n await createCredentialsByDwg(this.#kwilClient, payload);\n\n return { originalCredential, copyCredential };\n }\n\n async editCredentialAsIssuer(\n publicNotesId: string,\n publicNotes: string,\n ): Promise<EditPublicNotesAsIssuerInput | null> {\n const payload = {\n public_notes_id: publicNotesId,\n public_notes: publicNotes,\n };\n\n await editPublicNotesAsIssuer(this.#kwilClient, payload);\n\n return payload;\n }\n\n async getCredentialIdByContentHash(contentHash: string): Promise<string | null> {\n const id = await getSiblingCredentialId(this.#kwilClient, { content_hash: contentHash }).then(\n (res) => res.id,\n );\n\n invariant(id, \"Required `idOSCredential` id not found\");\n\n return id;\n }\n\n async getCredentialShared(id: string): Promise<idOSCredential | null> {\n const result = await getCredentialShared(this.#kwilClient, { id }).then((res) => res[0]);\n\n return result ?? null;\n }\n}\n","import type { idOSCredential } from \"@idos-network/credentials/types\";\nimport type { KwilActionClient } from \"@idos-network/kwil-infra\";\n\nimport { createAgByDagForCopy as _createAgByDagForCopy } from \"@idos-network/kwil-infra/actions\";\nimport { base64Encode, hexEncodeSha256Hash, utf8Encode } from \"@idos-network/utils/codecs\";\nimport { NoncedBox } from \"@idos-network/utils/cryptography\";\nimport invariant from \"tiny-invariant\";\n\nexport type CreateAccessGrantFromDAGParams = {\n dag_data_id: string;\n dag_owner_wallet_identifier: string;\n dag_grantee_wallet_identifier: string;\n dag_signature: string;\n dag_locked_until: number;\n dag_content_hash: string;\n};\n\nexport class GrantService {\n readonly #kwilClient: KwilActionClient;\n readonly #encryptionSecretKey: Uint8Array;\n\n constructor(kwilClient: KwilActionClient, encryptionSecretKey: Uint8Array) {\n this.#kwilClient = kwilClient;\n this.#encryptionSecretKey = encryptionSecretKey;\n }\n\n async createAccessGrantFromDAG(\n params: CreateAccessGrantFromDAGParams,\n getCredentialIdByContentHash: (contentHash: string) => Promise<string | null>,\n getCredentialShared: (id: string) => Promise<idOSCredential | null>,\n ): Promise<CreateAccessGrantFromDAGParams | null> {\n const credentialId = await getCredentialIdByContentHash(params.dag_content_hash);\n\n invariant(credentialId, \"Missing `idOSCredential` id\");\n\n const credential = await getCredentialShared(credentialId);\n\n invariant(credential, \"`idOSCredential` with id `{credentialId}` not found\");\n\n const plaintextContent = await NoncedBox.nonceFromBase64SecretKey(\n base64Encode(this.#encryptionSecretKey),\n ).decrypt(credential.content, credential.encryptor_public_key);\n\n // Get the content hash from the plaintext content\n const contentHash = hexEncodeSha256Hash(utf8Encode(plaintextContent));\n\n // Check if the content hash matches the content hash in the credential\n if (contentHash !== params.dag_content_hash) {\n throw new Error(\"Hash mismatch between `DAG` and `idOSCredential` content\");\n }\n\n const result = await _createAgByDagForCopy(this.#kwilClient, params);\n\n return result ?? null;\n }\n}\n","import type { KwilActionClient } from \"@idos-network/kwil-infra\";\n\nimport {\n hasProfile as _hasProfile,\n upsertWalletAsInserter as _upsertWalletAsInserter,\n addUserAsInserter,\n type GetUserAsInserterInput,\n getUserAsInserter,\n type idOSUser,\n type idOSWallet,\n} from \"@idos-network/kwil-infra/actions\";\n\nexport type CreateProfileReqParams = Omit<idOSUser, \"id\"> & {\n id?: string;\n};\n\nexport type UpsertWalletReqParams = Omit<idOSWallet, \"id\"> & {\n id?: string;\n};\n\nexport type CreateWalletReqParams = Omit<UpsertWalletReqParams, \"user_id\"> & {\n id?: string;\n};\n\nexport class UserService {\n readonly #kwilClient: KwilActionClient;\n\n constructor(kwilClient: KwilActionClient) {\n this.#kwilClient = kwilClient;\n }\n\n #ensureEntityId<T extends { id?: string }>(entity: T): T & { id: string } {\n if (!entity.id) {\n (entity as T & { id: string }).id = crypto.randomUUID();\n }\n return entity as T & { id: string };\n }\n\n async hasProfile(address: string): Promise<boolean> {\n return _hasProfile(this.#kwilClient, { address }).then((res) => res.has_profile);\n }\n\n async createUserProfile(params: CreateProfileReqParams): Promise<idOSUser> {\n const payload = this.#ensureEntityId(params);\n await addUserAsInserter(this.#kwilClient, payload);\n return payload;\n }\n\n async upsertWalletAsInserter(params: UpsertWalletReqParams): Promise<idOSWallet> {\n const payload = this.#ensureEntityId(params);\n await _upsertWalletAsInserter(this.#kwilClient, payload);\n return payload;\n }\n\n /// Useful to understand if a user id already exists.\n async getUser(params: GetUserAsInserterInput): Promise<idOSUser> {\n return getUserAsInserter(this.#kwilClient, this.#ensureEntityId(params));\n }\n\n async createUser(\n user: CreateProfileReqParams,\n wallet: CreateWalletReqParams,\n ): Promise<[idOSUser, idOSWallet]> {\n const user_id = user.id ?? crypto.randomUUID();\n const wallet_id = wallet.id ?? crypto.randomUUID();\n\n const userReqParams = {\n ...user,\n id: user_id,\n };\n\n const userResponse = await this.createUserProfile(userReqParams);\n\n const walletReqParams = {\n ...wallet,\n user_id,\n id: wallet_id,\n };\n\n const walletResponse = await this.upsertWalletAsInserter(walletReqParams);\n\n return [userResponse, walletResponse];\n }\n}\n","import type {\n AvailableIssuerType,\n CredentialFields,\n CredentialSubject,\n CredentialSubjectFaceId,\n idOSCredential,\n} from \"@idos-network/credentials/types\";\nimport type {\n EditPublicNotesAsIssuerInput,\n idOSDelegatedWriteGrant,\n idOSGrant,\n idOSUser,\n idOSUserAttribute,\n idOSWallet,\n} from \"@idos-network/kwil-infra/actions\";\nimport type { SignKeyPair } from \"tweetnacl\";\n\nimport {\n buildCredential,\n buildFaceIdCredential,\n type Credential,\n type FaceIdCredential,\n} from \"@idos-network/credentials/builder\";\nimport { deriveLevel } from \"@idos-network/credentials/utils\";\nimport { createNodeKwilClient, createServerKwilSigner } from \"@idos-network/kwil-infra\";\n\nimport {\n CredentialService,\n type DelegatedWriteGrantBaseParams,\n type DelegatedWriteGrantParams,\n} from \"./services/credential.service\";\nimport { type CreateAccessGrantFromDAGParams, GrantService } from \"./services/grant.service\";\nimport {\n type CreateProfileReqParams,\n type CreateWalletReqParams,\n type UpsertWalletReqParams,\n UserService,\n} from \"./services/user.service\";\n\ntype CreateIssuerParams = {\n chainId?: string;\n nodeUrl: string;\n signingKeyPair: SignKeyPair;\n encryptionSecretKey: Uint8Array;\n};\n\nexport class idOSIssuer {\n readonly #credentialService: CredentialService;\n readonly #grantService: GrantService;\n readonly #userService: UserService;\n\n static async init(params: CreateIssuerParams): Promise<idOSIssuer> {\n const kwilClient = await createNodeKwilClient({\n nodeUrl: params.nodeUrl,\n chainId: params.chainId,\n });\n\n const [signer] = await createServerKwilSigner(params.signingKeyPair);\n kwilClient.setSigner(signer);\n\n const credentialService = new CredentialService(\n kwilClient,\n params.signingKeyPair,\n params.encryptionSecretKey,\n );\n\n const grantService = new GrantService(kwilClient, params.encryptionSecretKey);\n const userService = new UserService(kwilClient);\n\n return new idOSIssuer(credentialService, grantService, userService);\n }\n\n private constructor(\n credentialService: CredentialService,\n grantService: GrantService,\n userService: UserService,\n ) {\n this.#credentialService = credentialService;\n this.#grantService = grantService;\n this.#userService = userService;\n }\n\n // User Service facade methods\n async hasProfile(userAddress: string): Promise<boolean> {\n return this.#userService.hasProfile(userAddress);\n }\n\n async createUserProfile(params: CreateProfileReqParams): Promise<idOSUser> {\n return this.#userService.createUserProfile(params);\n }\n\n async upsertWalletAsInserter(params: UpsertWalletReqParams): Promise<idOSWallet> {\n return this.#userService.upsertWalletAsInserter(params);\n }\n\n async createUser(\n user: CreateProfileReqParams,\n wallet: CreateWalletReqParams,\n ): Promise<[idOSUser, idOSWallet]> {\n return this.#userService.createUser(user, wallet);\n }\n\n async getUser(id: string): Promise<idOSUser> {\n return this.#userService.getUser({ id });\n }\n\n async requestDelegatedWriteGrantMessage(params: idOSDelegatedWriteGrant): Promise<string> {\n return this.#credentialService.requestDelegatedWriteGrantMessage(params);\n }\n\n async createCredentialByDelegatedWriteGrant(\n credentialParams: DelegatedWriteGrantBaseParams,\n delegatedWriteGrant: DelegatedWriteGrantParams,\n consumerEncryptionPublicKey?: Uint8Array,\n ): Promise<{\n originalCredential: Omit<idOSCredential, \"user_id\">;\n copyCredential: Omit<idOSCredential, \"user_id\">;\n }> {\n return this.#credentialService.createCredentialByDelegatedWriteGrant(\n credentialParams,\n delegatedWriteGrant,\n consumerEncryptionPublicKey,\n );\n }\n\n async editCredentialAsIssuer(\n publicNotesId: string,\n publicNotes: string,\n ): Promise<EditPublicNotesAsIssuerInput | null> {\n return this.#credentialService.editCredentialAsIssuer(publicNotesId, publicNotes);\n }\n\n async getCredentialIdByContentHash(contentHash: string): Promise<string | null> {\n return this.#credentialService.getCredentialIdByContentHash(contentHash);\n }\n\n async getCredentialShared(id: string): Promise<idOSCredential | null> {\n return this.#credentialService.getCredentialShared(id);\n }\n\n async createAccessGrantFromDAG(\n params: CreateAccessGrantFromDAGParams,\n ): Promise<CreateAccessGrantFromDAGParams | null> {\n return this.#grantService.createAccessGrantFromDAG(\n params,\n (contentHash: string) => this.getCredentialIdByContentHash(contentHash),\n (id: string) => this.getCredentialShared(id),\n );\n }\n\n async buildCredential(\n fields: CredentialFields,\n subject: CredentialSubject,\n issuer: AvailableIssuerType,\n validate = true,\n ): Promise<Credential> {\n return buildCredential(fields, subject, issuer, validate);\n }\n\n deriveCredentialLevel(subject: CredentialSubject): string {\n return deriveLevel(subject);\n }\n\n async buildFaceIdCredential(\n fields: CredentialFields,\n subject: CredentialSubjectFaceId,\n issuer: AvailableIssuerType,\n validate = true,\n ): Promise<FaceIdCredential> {\n return buildFaceIdCredential(fields, subject, issuer, validate);\n }\n}\n\nexport type {\n idOSCredential,\n idOSGrant,\n idOSUser,\n idOSUserAttribute,\n idOSDelegatedWriteGrant,\n idOSWallet,\n CredentialFields,\n CredentialSubject,\n AvailableIssuerType,\n Credential,\n CredentialSubjectFaceId,\n FaceIdCredential,\n};\n"],"x_google_ignoreList":[0],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["_hasProfile","_upsertWalletAsInserter","_addWalletMessage"],"sources":["../../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js","../src/services/credential.service.ts","../src/services/user.service.ts","../src/index.ts"],"sourcesContent":["var isProduction = process.env.NODE_ENV === 'production';\nvar prefix = 'Invariant failed';\nfunction invariant(condition, message) {\n if (condition) {\n return;\n }\n if (isProduction) {\n throw new Error(prefix);\n }\n var provided = typeof message === 'function' ? message() : message;\n var value = provided ? \"\".concat(prefix, \": \").concat(provided) : prefix;\n throw new Error(value);\n}\n\nexport { invariant as default };\n","import type { idOSCredential, idOSCredentialRecord } from \"@idos-network/credentials/types\";\nimport type { KwilActionClient } from \"@idos-network/kwil-infra\";\n\nimport {\n buildPreliminaryIDOSCredential,\n BuildPreliminaryIDOSCredentialArgs,\n mapPreliminaryToIDOSCredential,\n PreliminaryIDOSCredential,\n} from \"@idos-network/credentials/utils\";\nimport {\n type CreatePreliminaryCredentialsByDwgInput,\n createPreliminaryCredentialsByDwg,\n dwgMessage,\n type EditPublicNotesAsIssuerInput,\n editPublicNotesAsIssuer,\n getCredentialShared,\n getSiblingCredentialId,\n type idOSDelegatedWriteGrant,\n type DelegatedWriteGrantBaseParams,\n} from \"@idos-network/kwil-infra/actions\";\nimport { BlobGateway } from \"@idos-network/utils/blob-gateway\";\nimport { hexEncodeSha256Hash } from \"@idos-network/utils/codecs\";\nimport invariant from \"tiny-invariant\";\nimport nacl from \"tweetnacl\";\n\nexport type { DelegatedWriteGrantBaseParams };\n\nexport type DelegatedWriteGrantParams = DelegatedWriteGrantBaseParams & {\n signature: string;\n};\n\nexport type CredentialByDelegatedWriteGrantBaseParams = Omit<\n BuildPreliminaryIDOSCredentialArgs,\n \"issuerSigningSecretKey\" | \"contentUri\"\n> & {\n originalContentUri?: string;\n copyContentUri?: string;\n};\n\nexport class CredentialService {\n readonly #kwilClient: KwilActionClient;\n readonly #signingKeyPair: nacl.SignKeyPair;\n readonly #blobGateway: BlobGateway;\n\n constructor(\n kwilClient: KwilActionClient,\n signingKeyPair: nacl.SignKeyPair,\n blobGateway: BlobGateway,\n ) {\n this.#kwilClient = kwilClient;\n this.#signingKeyPair = signingKeyPair;\n this.#blobGateway = blobGateway;\n }\n\n async requestDelegatedWriteGrantMessage(params: idOSDelegatedWriteGrant): Promise<string> {\n return dwgMessage(this.#kwilClient, params).then((res) => res.message);\n }\n\n async createCredentialByDelegatedWriteGrant(\n credentialParams: CredentialByDelegatedWriteGrantBaseParams,\n delegatedWriteGrant: DelegatedWriteGrantParams,\n consumerEncryptionPublicKey: Uint8Array,\n ): Promise<{\n originalCredential: Omit<idOSCredential, \"user_id\">;\n copyCredential: Omit<idOSCredential, \"user_id\">;\n }> {\n const { originalContentUri, copyContentUri, ...sharedCredentialParams } = credentialParams;\n const originalCredential: PreliminaryIDOSCredential = {\n ...(await buildPreliminaryIDOSCredential({\n ...sharedCredentialParams,\n contentUri: originalContentUri,\n issuerSigningSecretKey: this.#signingKeyPair.secretKey,\n })),\n id: crypto.randomUUID(),\n };\n\n const contentHash = hexEncodeSha256Hash(credentialParams.plaintextContent);\n\n const copyCredential: PreliminaryIDOSCredential = {\n ...(await buildPreliminaryIDOSCredential({\n ...sharedCredentialParams,\n contentUri: copyContentUri,\n publicNotes: \"\",\n recipientEncryptionPublicKey: consumerEncryptionPublicKey,\n issuerSigningSecretKey: this.#signingKeyPair.secretKey,\n })),\n id: crypto.randomUUID(),\n };\n\n invariant(\n originalCredential.contentUri !== copyCredential.contentUri,\n \"Original and copy credentials must use distinct content URIs\",\n );\n\n const requestId = crypto.randomUUID();\n const payload: CreatePreliminaryCredentialsByDwgInput = {\n request_id: requestId,\n issuer_auth_public_key: originalCredential.issuerAuthPublicKey,\n original_encryptor_public_key: originalCredential.encryptorPublicKey,\n original_id: originalCredential.id,\n original_content_uri: originalCredential.contentUri,\n original_content_size: originalCredential.contentSize,\n original_public_notes: originalCredential.publicNotes,\n original_public_notes_signature: originalCredential.publicNotesSignature,\n original_broader_signature: originalCredential.broaderSignature,\n copy_encryptor_public_key: copyCredential.encryptorPublicKey,\n copy_id: copyCredential.id,\n copy_content_uri: copyCredential.contentUri,\n copy_content_size: copyCredential.contentSize,\n copy_public_notes_signature: copyCredential.publicNotesSignature,\n copy_broader_signature: copyCredential.broaderSignature,\n content_hash: contentHash,\n dwg_owner: delegatedWriteGrant.ownerWalletIdentifier,\n dwg_grantee: delegatedWriteGrant.consumerWalletIdentifier,\n dwg_issuer_public_key: delegatedWriteGrant.issuerPublicKey,\n dwg_id: delegatedWriteGrant.id,\n dwg_access_grant_timelock: delegatedWriteGrant.accessGrantTimelock,\n dwg_not_before: delegatedWriteGrant.notUsableBefore,\n dwg_not_after: delegatedWriteGrant.notUsableAfter,\n dwg_signature: delegatedWriteGrant.signature,\n };\n\n await createPreliminaryCredentialsByDwg(this.#kwilClient, payload);\n\n await this.#blobGateway.uploadCredentialBlobs({\n requestId,\n original: originalCredential.encryptedContent,\n copy: copyCredential.encryptedContent,\n });\n\n return {\n originalCredential: mapPreliminaryToIDOSCredential(originalCredential),\n copyCredential: mapPreliminaryToIDOSCredential(copyCredential),\n };\n }\n\n async editCredentialAsIssuer(\n publicNotesId: string,\n publicNotes: string,\n ): Promise<EditPublicNotesAsIssuerInput | null> {\n const payload = {\n public_notes_id: publicNotesId,\n public_notes: publicNotes,\n };\n\n await editPublicNotesAsIssuer(this.#kwilClient, payload);\n\n return payload;\n }\n\n async getCredentialIdByContentHash(contentHash: string): Promise<string | null> {\n const id = await getSiblingCredentialId(this.#kwilClient, { content_hash: contentHash }).then(\n (res) => res.id,\n );\n\n invariant(id, \"Required `idOSCredential` id not found\");\n\n return id;\n }\n\n async getCredentialShared(id: string): Promise<idOSCredentialRecord | null> {\n const result = await getCredentialShared(this.#kwilClient, { id }).then((res) => res[0]);\n\n return result ?? null;\n }\n}\n","import type { KwilActionClient } from \"@idos-network/kwil-infra\";\n\nimport {\n hasProfile as _hasProfile,\n upsertWalletAsInserter as _upsertWalletAsInserter,\n addUserAsInserter,\n addWalletMessage as _addWalletMessage,\n type AddWalletMessageInput,\n type GetUserAsInserterInput,\n getUserAsInserter,\n type idOSUser,\n type idOSWallet,\n} from \"@idos-network/kwil-infra/actions\";\n\nexport type CreateProfileReqParams = Omit<idOSUser, \"id\"> & {\n id?: string;\n};\n\nexport type UpsertWalletReqParams = Omit<idOSWallet, \"id\"> & {\n id?: string;\n};\n\nexport type CreateWalletReqParams = Omit<UpsertWalletReqParams, \"user_id\"> & {\n id?: string;\n};\n\nexport class UserService {\n readonly #kwilClient: KwilActionClient;\n\n constructor(kwilClient: KwilActionClient) {\n this.#kwilClient = kwilClient;\n }\n\n #ensureEntityId<T extends { id?: string }>(entity: T): T & { id: string } {\n if (!entity.id) {\n (entity as T & { id: string }).id = crypto.randomUUID();\n }\n return entity as T & { id: string };\n }\n\n async hasProfile(address: string): Promise<boolean> {\n return _hasProfile(this.#kwilClient, { address }).then((res) => res.has_profile);\n }\n\n async createUserProfile(params: CreateProfileReqParams): Promise<idOSUser> {\n const payload = this.#ensureEntityId(params);\n await addUserAsInserter(this.#kwilClient, payload);\n return payload;\n }\n\n async upsertWalletAsInserter(params: UpsertWalletReqParams): Promise<idOSWallet> {\n const payload = this.#ensureEntityId(params);\n await _upsertWalletAsInserter(this.#kwilClient, payload);\n return payload;\n }\n\n async addWalletMessage(params: AddWalletMessageInput): Promise<string> {\n const result = await _addWalletMessage(this.#kwilClient, params);\n return result.message;\n }\n\n /// Useful to understand if a user id already exists.\n async getUser(params: GetUserAsInserterInput): Promise<idOSUser> {\n return getUserAsInserter(this.#kwilClient, this.#ensureEntityId(params));\n }\n\n async createUser(\n user: CreateProfileReqParams,\n wallet: CreateWalletReqParams,\n ): Promise<[idOSUser, idOSWallet]> {\n const user_id = user.id ?? crypto.randomUUID();\n const wallet_id = wallet.id ?? crypto.randomUUID();\n\n const userReqParams = {\n ...user,\n id: user_id,\n };\n\n const userResponse = await this.createUserProfile(userReqParams);\n\n const walletReqParams = {\n ...wallet,\n user_id,\n id: wallet_id,\n };\n\n const walletResponse = await this.upsertWalletAsInserter(walletReqParams);\n\n return [userResponse, walletResponse];\n }\n}\n","import type {\n AvailableIssuerType,\n idOSCredential,\n idOSCredentialRecord,\n} from \"@idos-network/credentials/types\";\nimport type {\n AddWalletMessageInput,\n EditPublicNotesAsIssuerInput,\n idOSDelegatedWriteGrant,\n idOSGrant,\n idOSUser,\n idOSUserAttribute,\n idOSWallet,\n} from \"@idos-network/kwil-infra/actions\";\nimport type { SignKeyPair } from \"tweetnacl\";\n\nimport {\n createKgwAuthenticatedBlobGateway,\n createNodeKwilClient,\n createServerKwilSigner,\n} from \"@idos-network/kwil-infra\";\n\nimport {\n CredentialService,\n type CredentialByDelegatedWriteGrantBaseParams,\n type DelegatedWriteGrantBaseParams,\n type DelegatedWriteGrantParams,\n} from \"./services/credential.service\";\nimport {\n type CreateProfileReqParams,\n type CreateWalletReqParams,\n type UpsertWalletReqParams,\n UserService,\n} from \"./services/user.service\";\n\ntype CreateIssuerParams = {\n chainId?: string;\n nodeUrl: string;\n blobGatewayUrl?: string;\n signingKeyPair: SignKeyPair;\n};\n\nexport class idOSIssuer {\n readonly #credentialService: CredentialService;\n readonly #userService: UserService;\n\n static async init(params: CreateIssuerParams): Promise<idOSIssuer> {\n const kwilClient = await createNodeKwilClient({\n nodeUrl: params.nodeUrl,\n chainId: params.chainId,\n });\n\n const [signer] = await createServerKwilSigner(params.signingKeyPair);\n kwilClient.setSigner(signer);\n\n const blobGateway = createKgwAuthenticatedBlobGateway({\n url: params.blobGatewayUrl ?? params.nodeUrl,\n kwilClient,\n signer,\n });\n\n const credentialService = new CredentialService(kwilClient, params.signingKeyPair, blobGateway);\n const userService = new UserService(kwilClient);\n\n return new idOSIssuer(credentialService, userService);\n }\n\n private constructor(credentialService: CredentialService, userService: UserService) {\n this.#credentialService = credentialService;\n this.#userService = userService;\n }\n\n // User Service facade methods\n async hasProfile(userAddress: string): Promise<boolean> {\n return this.#userService.hasProfile(userAddress);\n }\n\n async createUserProfile(params: CreateProfileReqParams): Promise<idOSUser> {\n return this.#userService.createUserProfile(params);\n }\n\n async upsertWalletAsInserter(params: UpsertWalletReqParams): Promise<idOSWallet> {\n return this.#userService.upsertWalletAsInserter(params);\n }\n\n async addWalletMessage(params: AddWalletMessageInput): Promise<string> {\n return this.#userService.addWalletMessage(params);\n }\n\n async createUser(\n user: CreateProfileReqParams,\n wallet: CreateWalletReqParams,\n ): Promise<[idOSUser, idOSWallet]> {\n return this.#userService.createUser(user, wallet);\n }\n\n async getUser(id: string): Promise<idOSUser> {\n return this.#userService.getUser({ id });\n }\n\n async requestDelegatedWriteGrantMessage(params: idOSDelegatedWriteGrant): Promise<string> {\n return this.#credentialService.requestDelegatedWriteGrantMessage(params);\n }\n\n async createCredentialByDelegatedWriteGrant(\n credentialParams: CredentialByDelegatedWriteGrantBaseParams,\n delegatedWriteGrant: DelegatedWriteGrantParams,\n consumerEncryptionPublicKey: Uint8Array,\n ): Promise<{\n originalCredential: Omit<idOSCredential, \"user_id\">;\n copyCredential: Omit<idOSCredential, \"user_id\">;\n }> {\n return this.#credentialService.createCredentialByDelegatedWriteGrant(\n credentialParams,\n delegatedWriteGrant,\n consumerEncryptionPublicKey,\n );\n }\n\n async editCredentialAsIssuer(\n publicNotesId: string,\n publicNotes: string,\n ): Promise<EditPublicNotesAsIssuerInput | null> {\n return this.#credentialService.editCredentialAsIssuer(publicNotesId, publicNotes);\n }\n\n async getCredentialIdByContentHash(contentHash: string): Promise<string | null> {\n return this.#credentialService.getCredentialIdByContentHash(contentHash);\n }\n\n async getCredentialShared(id: string): Promise<idOSCredentialRecord | null> {\n return this.#credentialService.getCredentialShared(id);\n }\n}\n\nexport type {\n idOSCredential,\n idOSGrant,\n idOSUser,\n idOSUserAttribute,\n idOSDelegatedWriteGrant,\n idOSWallet,\n AvailableIssuerType,\n CredentialByDelegatedWriteGrantBaseParams,\n DelegatedWriteGrantBaseParams,\n DelegatedWriteGrantParams,\n};\n\nexport { toDelegatedWriteGrantBaseParams } from \"@idos-network/kwil-infra/actions\";\n"],"x_google_ignoreList":[0],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idos-network/issuer",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "idOS Issuer JavaScript SDK for server environments",
|
|
5
5
|
"homepage": "https://idos.network",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "github
|
|
9
|
+
"url": "git+https://github.com/idos-network/idos-sdk-js.git",
|
|
10
|
+
"directory": "packages/issuer"
|
|
10
11
|
},
|
|
11
12
|
"files": [
|
|
12
13
|
"dist/**/*",
|
|
@@ -27,15 +28,16 @@
|
|
|
27
28
|
"access": "public"
|
|
28
29
|
},
|
|
29
30
|
"dependencies": {
|
|
30
|
-
"@idos-network/
|
|
31
|
-
"
|
|
32
|
-
"@idos-network/
|
|
33
|
-
"@idos-network/
|
|
34
|
-
"
|
|
31
|
+
"@idos-network/credentials": "2.2.2",
|
|
32
|
+
"@idos-network/kwil-infra": "2.2.2",
|
|
33
|
+
"@idos-network/kwil-js": "0.2.1",
|
|
34
|
+
"@idos-network/utils": "2.2.2",
|
|
35
|
+
"tweetnacl": "^1.0.3"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"tiny-invariant": "^1.3.3",
|
|
38
|
-
"tsdown": "^0.
|
|
39
|
+
"tsdown": "^0.23.0",
|
|
40
|
+
"vitest": "4.1.11"
|
|
39
41
|
},
|
|
40
42
|
"peerDependencies": {
|
|
41
43
|
"typescript": "^5.9.3"
|
|
@@ -47,6 +49,7 @@
|
|
|
47
49
|
"build": "tsdown",
|
|
48
50
|
"dev": "tsdown --watch",
|
|
49
51
|
"publint": "pnpx publint --strict",
|
|
52
|
+
"test": "vitest",
|
|
50
53
|
"typecheck": "tsc --noEmit"
|
|
51
54
|
}
|
|
52
55
|
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import nacl from "tweetnacl";
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
|
+
|
|
4
|
+
import { idOSIssuer, toDelegatedWriteGrantBaseParams } from "./index.js";
|
|
5
|
+
|
|
6
|
+
const mocks = vi.hoisted(() => ({
|
|
7
|
+
blobGateway: { fetchBlob: vi.fn(), uploadCredentialBlobs: vi.fn() },
|
|
8
|
+
createPreliminaryCredentialsByDwg: vi.fn(),
|
|
9
|
+
addWalletMessage: vi.fn(async () => ({ message: "add-wallet-message" })),
|
|
10
|
+
dwgMessage: vi.fn(async () => ({ message: "dwg-message-string" })),
|
|
11
|
+
kwilClient: {
|
|
12
|
+
setSigner: vi.fn(),
|
|
13
|
+
},
|
|
14
|
+
signer: { publicKey: "signer" },
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
vi.mock("@idos-network/kwil-infra", () => ({
|
|
18
|
+
createKgwAuthenticatedBlobGateway: vi.fn(() => mocks.blobGateway),
|
|
19
|
+
createNodeKwilClient: vi.fn(async () => mocks.kwilClient),
|
|
20
|
+
createServerKwilSigner: vi.fn(async () => [mocks.signer]),
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
vi.mock("@idos-network/kwil-infra/actions", async (importOriginal) => ({
|
|
24
|
+
...((await importOriginal()) as object),
|
|
25
|
+
addWalletMessage: mocks.addWalletMessage,
|
|
26
|
+
createPreliminaryCredentialsByDwg: mocks.createPreliminaryCredentialsByDwg,
|
|
27
|
+
dwgMessage: mocks.dwgMessage,
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
describe("idOSIssuer", () => {
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
vi.clearAllMocks();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("creates one KGW authenticated blob gateway for issuer services", async () => {
|
|
36
|
+
const { createKgwAuthenticatedBlobGateway } = await import("@idos-network/kwil-infra");
|
|
37
|
+
const signingKeyPair = nacl.sign.keyPair();
|
|
38
|
+
|
|
39
|
+
await idOSIssuer.init({
|
|
40
|
+
nodeUrl: "https://nodes.example",
|
|
41
|
+
blobGatewayUrl: "https://blob.example",
|
|
42
|
+
signingKeyPair,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
expect(createKgwAuthenticatedBlobGateway).toHaveBeenCalledWith({
|
|
46
|
+
url: "https://blob.example",
|
|
47
|
+
kwilClient: mocks.kwilClient,
|
|
48
|
+
signer: mocks.signer,
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("creates delegated write grant credentials through the blob-backed flow", async () => {
|
|
53
|
+
const { createPreliminaryCredentialsByDwg } = await import("@idos-network/kwil-infra/actions");
|
|
54
|
+
const issuer = await idOSIssuer.init({
|
|
55
|
+
nodeUrl: "https://nodes.example",
|
|
56
|
+
blobGatewayUrl: "https://blob.example",
|
|
57
|
+
signingKeyPair: nacl.sign.keyPair(),
|
|
58
|
+
});
|
|
59
|
+
const userEncryptionKeyPair = nacl.box.keyPair();
|
|
60
|
+
const copyEncryptionKeyPair = nacl.box.keyPair();
|
|
61
|
+
|
|
62
|
+
const result = await issuer.createCredentialByDelegatedWriteGrant(
|
|
63
|
+
{
|
|
64
|
+
publicNotes: "{}",
|
|
65
|
+
plaintextContent: new Uint8Array([1, 2, 3]),
|
|
66
|
+
recipientEncryptionPublicKey: userEncryptionKeyPair.publicKey,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: crypto.randomUUID(),
|
|
70
|
+
ownerWalletIdentifier: "owner",
|
|
71
|
+
consumerWalletIdentifier: "consumer",
|
|
72
|
+
issuerPublicKey: "issuer",
|
|
73
|
+
accessGrantTimelock: "2026-01-01T00:00:00Z",
|
|
74
|
+
notUsableBefore: "2026-01-01T00:00:00Z",
|
|
75
|
+
notUsableAfter: "2026-01-02T00:00:00Z",
|
|
76
|
+
signature: "signature",
|
|
77
|
+
},
|
|
78
|
+
copyEncryptionKeyPair.publicKey,
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
expect(createPreliminaryCredentialsByDwg).toHaveBeenCalledOnce();
|
|
82
|
+
expect(mocks.blobGateway.uploadCredentialBlobs).toHaveBeenCalledOnce();
|
|
83
|
+
|
|
84
|
+
const payload = mocks.createPreliminaryCredentialsByDwg.mock.calls[0]?.[1];
|
|
85
|
+
expect(payload.original_content_uri).toMatch(/^ipfs:\/\//);
|
|
86
|
+
expect(payload.copy_content_uri).toMatch(/^ipfs:\/\//);
|
|
87
|
+
expect(payload.original_content_size).toBeGreaterThan(0);
|
|
88
|
+
expect(payload.copy_content_size).toBeGreaterThan(0);
|
|
89
|
+
expect(mocks.blobGateway.uploadCredentialBlobs).toHaveBeenCalledWith({
|
|
90
|
+
requestId: payload.request_id,
|
|
91
|
+
original: expect.any(Uint8Array),
|
|
92
|
+
copy: expect.any(Uint8Array),
|
|
93
|
+
});
|
|
94
|
+
expect(result.originalCredential).toMatchObject({
|
|
95
|
+
id: payload.original_id,
|
|
96
|
+
content_uri: payload.original_content_uri,
|
|
97
|
+
content_size: payload.original_content_size,
|
|
98
|
+
});
|
|
99
|
+
expect(result.copyCredential).toMatchObject({
|
|
100
|
+
id: payload.copy_id,
|
|
101
|
+
content_uri: payload.copy_content_uri,
|
|
102
|
+
content_size: payload.copy_content_size,
|
|
103
|
+
});
|
|
104
|
+
expect(mocks.createPreliminaryCredentialsByDwg.mock.invocationCallOrder[0]).toBeLessThan(
|
|
105
|
+
mocks.blobGateway.uploadCredentialBlobs.mock.invocationCallOrder[0],
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("uses and enforces distinct custom content URIs for delegated write grants", async () => {
|
|
110
|
+
const issuer = await idOSIssuer.init({
|
|
111
|
+
nodeUrl: "https://nodes.example",
|
|
112
|
+
blobGatewayUrl: "https://blob.example",
|
|
113
|
+
signingKeyPair: nacl.sign.keyPair(),
|
|
114
|
+
});
|
|
115
|
+
const originalContentUri = "ukyc://storage-abc/blobs/original";
|
|
116
|
+
const copyContentUri = "ukyc://storage-abc/blobs/copy";
|
|
117
|
+
const credentialParams = {
|
|
118
|
+
publicNotes: "{}",
|
|
119
|
+
plaintextContent: new Uint8Array([1, 2, 3]),
|
|
120
|
+
recipientEncryptionPublicKey: nacl.box.keyPair().publicKey,
|
|
121
|
+
originalContentUri,
|
|
122
|
+
copyContentUri,
|
|
123
|
+
};
|
|
124
|
+
const delegatedWriteGrant = {
|
|
125
|
+
id: crypto.randomUUID(),
|
|
126
|
+
ownerWalletIdentifier: "owner",
|
|
127
|
+
consumerWalletIdentifier: "consumer",
|
|
128
|
+
issuerPublicKey: "issuer",
|
|
129
|
+
accessGrantTimelock: "2026-01-01T00:00:00Z",
|
|
130
|
+
notUsableBefore: "2026-01-01T00:00:00Z",
|
|
131
|
+
notUsableAfter: "2026-01-02T00:00:00Z",
|
|
132
|
+
signature: "signature",
|
|
133
|
+
};
|
|
134
|
+
const consumerEncryptionPublicKey = nacl.box.keyPair().publicKey;
|
|
135
|
+
|
|
136
|
+
const result = await issuer.createCredentialByDelegatedWriteGrant(
|
|
137
|
+
credentialParams,
|
|
138
|
+
delegatedWriteGrant,
|
|
139
|
+
consumerEncryptionPublicKey,
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
const payload = mocks.createPreliminaryCredentialsByDwg.mock.calls[0]?.[1];
|
|
143
|
+
expect(payload.original_content_uri).toBe(originalContentUri);
|
|
144
|
+
expect(payload.copy_content_uri).toBe(copyContentUri);
|
|
145
|
+
expect(result.originalCredential.content_uri).toBe(originalContentUri);
|
|
146
|
+
expect(result.copyCredential.content_uri).toBe(copyContentUri);
|
|
147
|
+
|
|
148
|
+
await expect(
|
|
149
|
+
issuer.createCredentialByDelegatedWriteGrant(
|
|
150
|
+
{ ...credentialParams, copyContentUri: originalContentUri },
|
|
151
|
+
delegatedWriteGrant,
|
|
152
|
+
consumerEncryptionPublicKey,
|
|
153
|
+
),
|
|
154
|
+
).rejects.toThrow("Original and copy credentials must use distinct content URIs");
|
|
155
|
+
expect(mocks.createPreliminaryCredentialsByDwg).toHaveBeenCalledOnce();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("maps request params for createCredentialByDelegatedWriteGrant via toDelegatedWriteGrantBaseParams", async () => {
|
|
159
|
+
const issuer = await idOSIssuer.init({
|
|
160
|
+
nodeUrl: "https://nodes.example",
|
|
161
|
+
blobGatewayUrl: "https://blob.example",
|
|
162
|
+
signingKeyPair: nacl.sign.keyPair(),
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const dwgInput = {
|
|
166
|
+
id: crypto.randomUUID(),
|
|
167
|
+
owner_wallet_identifier: "0x311CEe6648df431EbbeA38dfB680C28661c893Ea",
|
|
168
|
+
grantee_wallet_identifier: "0x1111111111111111111111111111111111111111",
|
|
169
|
+
issuer_public_key: "issuer-key",
|
|
170
|
+
access_grant_timelock: "2026-01-01T00:00:00Z",
|
|
171
|
+
not_usable_before: "2026-01-01T00:00:00Z",
|
|
172
|
+
not_usable_after: "2026-01-02T00:00:00Z",
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const walletMessage = await issuer.addWalletMessage({
|
|
176
|
+
address: "0x311CEe6648df431EbbeA38dfB680C28661c893Ea",
|
|
177
|
+
wallet_type: "EVM",
|
|
178
|
+
user_id: crypto.randomUUID(),
|
|
179
|
+
not_before: "2026-01-01T00:00:00Z",
|
|
180
|
+
not_after: "2026-01-01T00:15:00Z",
|
|
181
|
+
});
|
|
182
|
+
expect(walletMessage).toBe("add-wallet-message");
|
|
183
|
+
expect(mocks.addWalletMessage).toHaveBeenCalledOnce();
|
|
184
|
+
|
|
185
|
+
const message = await issuer.requestDelegatedWriteGrantMessage(dwgInput);
|
|
186
|
+
const params = toDelegatedWriteGrantBaseParams(dwgInput);
|
|
187
|
+
|
|
188
|
+
expect(message).toBe("dwg-message-string");
|
|
189
|
+
expect(params).toEqual({
|
|
190
|
+
id: dwgInput.id,
|
|
191
|
+
ownerWalletIdentifier: dwgInput.owner_wallet_identifier,
|
|
192
|
+
consumerWalletIdentifier: dwgInput.grantee_wallet_identifier,
|
|
193
|
+
issuerPublicKey: dwgInput.issuer_public_key,
|
|
194
|
+
accessGrantTimelock: dwgInput.access_grant_timelock,
|
|
195
|
+
notUsableBefore: dwgInput.not_usable_before,
|
|
196
|
+
notUsableAfter: dwgInput.not_usable_after,
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const userEncryptionKeyPair = nacl.box.keyPair();
|
|
200
|
+
const copyEncryptionKeyPair = nacl.box.keyPair();
|
|
201
|
+
|
|
202
|
+
await issuer.createCredentialByDelegatedWriteGrant(
|
|
203
|
+
{
|
|
204
|
+
publicNotes: "{}",
|
|
205
|
+
plaintextContent: new Uint8Array([1, 2, 3]),
|
|
206
|
+
recipientEncryptionPublicKey: userEncryptionKeyPair.publicKey,
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
...params,
|
|
210
|
+
signature: "0xsignature",
|
|
211
|
+
},
|
|
212
|
+
copyEncryptionKeyPair.publicKey,
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
expect(mocks.createPreliminaryCredentialsByDwg).toHaveBeenCalled();
|
|
216
|
+
const payload = mocks.createPreliminaryCredentialsByDwg.mock.calls.at(-1)?.[1];
|
|
217
|
+
expect(payload.dwg_id).toBe(params.id);
|
|
218
|
+
expect(payload.dwg_owner).toBe(params.ownerWalletIdentifier);
|
|
219
|
+
expect(payload.dwg_grantee).toBe(params.consumerWalletIdentifier);
|
|
220
|
+
expect(payload.dwg_issuer_public_key).toBe(params.issuerPublicKey);
|
|
221
|
+
expect(payload.dwg_access_grant_timelock).toBe(params.accessGrantTimelock);
|
|
222
|
+
expect(payload.dwg_not_before).toBe(params.notUsableBefore);
|
|
223
|
+
expect(payload.dwg_not_after).toBe(params.notUsableAfter);
|
|
224
|
+
expect(payload.dwg_signature).toBe("0xsignature");
|
|
225
|
+
});
|
|
226
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AvailableIssuerType,
|
|
3
|
-
CredentialFields,
|
|
4
|
-
CredentialSubject,
|
|
5
|
-
CredentialSubjectFaceId,
|
|
6
3
|
idOSCredential,
|
|
4
|
+
idOSCredentialRecord,
|
|
7
5
|
} from "@idos-network/credentials/types";
|
|
8
6
|
import type {
|
|
7
|
+
AddWalletMessageInput,
|
|
9
8
|
EditPublicNotesAsIssuerInput,
|
|
10
9
|
idOSDelegatedWriteGrant,
|
|
11
10
|
idOSGrant,
|
|
@@ -16,20 +15,17 @@ import type {
|
|
|
16
15
|
import type { SignKeyPair } from "tweetnacl";
|
|
17
16
|
|
|
18
17
|
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
} from "@idos-network/credentials/builder";
|
|
24
|
-
import { deriveLevel } from "@idos-network/credentials/utils";
|
|
25
|
-
import { createNodeKwilClient, createServerKwilSigner } from "@idos-network/kwil-infra";
|
|
18
|
+
createKgwAuthenticatedBlobGateway,
|
|
19
|
+
createNodeKwilClient,
|
|
20
|
+
createServerKwilSigner,
|
|
21
|
+
} from "@idos-network/kwil-infra";
|
|
26
22
|
|
|
27
23
|
import {
|
|
28
24
|
CredentialService,
|
|
25
|
+
type CredentialByDelegatedWriteGrantBaseParams,
|
|
29
26
|
type DelegatedWriteGrantBaseParams,
|
|
30
27
|
type DelegatedWriteGrantParams,
|
|
31
28
|
} from "./services/credential.service";
|
|
32
|
-
import { type CreateAccessGrantFromDAGParams, GrantService } from "./services/grant.service";
|
|
33
29
|
import {
|
|
34
30
|
type CreateProfileReqParams,
|
|
35
31
|
type CreateWalletReqParams,
|
|
@@ -40,13 +36,12 @@ import {
|
|
|
40
36
|
type CreateIssuerParams = {
|
|
41
37
|
chainId?: string;
|
|
42
38
|
nodeUrl: string;
|
|
39
|
+
blobGatewayUrl?: string;
|
|
43
40
|
signingKeyPair: SignKeyPair;
|
|
44
|
-
encryptionSecretKey: Uint8Array;
|
|
45
41
|
};
|
|
46
42
|
|
|
47
43
|
export class idOSIssuer {
|
|
48
44
|
readonly #credentialService: CredentialService;
|
|
49
|
-
readonly #grantService: GrantService;
|
|
50
45
|
readonly #userService: UserService;
|
|
51
46
|
|
|
52
47
|
static async init(params: CreateIssuerParams): Promise<idOSIssuer> {
|
|
@@ -58,25 +53,20 @@ export class idOSIssuer {
|
|
|
58
53
|
const [signer] = await createServerKwilSigner(params.signingKeyPair);
|
|
59
54
|
kwilClient.setSigner(signer);
|
|
60
55
|
|
|
61
|
-
const
|
|
56
|
+
const blobGateway = createKgwAuthenticatedBlobGateway({
|
|
57
|
+
url: params.blobGatewayUrl ?? params.nodeUrl,
|
|
62
58
|
kwilClient,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
);
|
|
59
|
+
signer,
|
|
60
|
+
});
|
|
66
61
|
|
|
67
|
-
const
|
|
62
|
+
const credentialService = new CredentialService(kwilClient, params.signingKeyPair, blobGateway);
|
|
68
63
|
const userService = new UserService(kwilClient);
|
|
69
64
|
|
|
70
|
-
return new idOSIssuer(credentialService,
|
|
65
|
+
return new idOSIssuer(credentialService, userService);
|
|
71
66
|
}
|
|
72
67
|
|
|
73
|
-
private constructor(
|
|
74
|
-
credentialService: CredentialService,
|
|
75
|
-
grantService: GrantService,
|
|
76
|
-
userService: UserService,
|
|
77
|
-
) {
|
|
68
|
+
private constructor(credentialService: CredentialService, userService: UserService) {
|
|
78
69
|
this.#credentialService = credentialService;
|
|
79
|
-
this.#grantService = grantService;
|
|
80
70
|
this.#userService = userService;
|
|
81
71
|
}
|
|
82
72
|
|
|
@@ -93,6 +83,10 @@ export class idOSIssuer {
|
|
|
93
83
|
return this.#userService.upsertWalletAsInserter(params);
|
|
94
84
|
}
|
|
95
85
|
|
|
86
|
+
async addWalletMessage(params: AddWalletMessageInput): Promise<string> {
|
|
87
|
+
return this.#userService.addWalletMessage(params);
|
|
88
|
+
}
|
|
89
|
+
|
|
96
90
|
async createUser(
|
|
97
91
|
user: CreateProfileReqParams,
|
|
98
92
|
wallet: CreateWalletReqParams,
|
|
@@ -109,9 +103,9 @@ export class idOSIssuer {
|
|
|
109
103
|
}
|
|
110
104
|
|
|
111
105
|
async createCredentialByDelegatedWriteGrant(
|
|
112
|
-
credentialParams:
|
|
106
|
+
credentialParams: CredentialByDelegatedWriteGrantBaseParams,
|
|
113
107
|
delegatedWriteGrant: DelegatedWriteGrantParams,
|
|
114
|
-
consumerEncryptionPublicKey
|
|
108
|
+
consumerEncryptionPublicKey: Uint8Array,
|
|
115
109
|
): Promise<{
|
|
116
110
|
originalCredential: Omit<idOSCredential, "user_id">;
|
|
117
111
|
copyCredential: Omit<idOSCredential, "user_id">;
|
|
@@ -134,41 +128,9 @@ export class idOSIssuer {
|
|
|
134
128
|
return this.#credentialService.getCredentialIdByContentHash(contentHash);
|
|
135
129
|
}
|
|
136
130
|
|
|
137
|
-
async getCredentialShared(id: string): Promise<
|
|
131
|
+
async getCredentialShared(id: string): Promise<idOSCredentialRecord | null> {
|
|
138
132
|
return this.#credentialService.getCredentialShared(id);
|
|
139
133
|
}
|
|
140
|
-
|
|
141
|
-
async createAccessGrantFromDAG(
|
|
142
|
-
params: CreateAccessGrantFromDAGParams,
|
|
143
|
-
): Promise<CreateAccessGrantFromDAGParams | null> {
|
|
144
|
-
return this.#grantService.createAccessGrantFromDAG(
|
|
145
|
-
params,
|
|
146
|
-
(contentHash: string) => this.getCredentialIdByContentHash(contentHash),
|
|
147
|
-
(id: string) => this.getCredentialShared(id),
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
async buildCredential(
|
|
152
|
-
fields: CredentialFields,
|
|
153
|
-
subject: CredentialSubject,
|
|
154
|
-
issuer: AvailableIssuerType,
|
|
155
|
-
validate = true,
|
|
156
|
-
): Promise<Credential> {
|
|
157
|
-
return buildCredential(fields, subject, issuer, validate);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
deriveCredentialLevel(subject: CredentialSubject): string {
|
|
161
|
-
return deriveLevel(subject);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
async buildFaceIdCredential(
|
|
165
|
-
fields: CredentialFields,
|
|
166
|
-
subject: CredentialSubjectFaceId,
|
|
167
|
-
issuer: AvailableIssuerType,
|
|
168
|
-
validate = true,
|
|
169
|
-
): Promise<FaceIdCredential> {
|
|
170
|
-
return buildFaceIdCredential(fields, subject, issuer, validate);
|
|
171
|
-
}
|
|
172
134
|
}
|
|
173
135
|
|
|
174
136
|
export type {
|
|
@@ -178,10 +140,10 @@ export type {
|
|
|
178
140
|
idOSUserAttribute,
|
|
179
141
|
idOSDelegatedWriteGrant,
|
|
180
142
|
idOSWallet,
|
|
181
|
-
CredentialFields,
|
|
182
|
-
CredentialSubject,
|
|
183
143
|
AvailableIssuerType,
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
144
|
+
CredentialByDelegatedWriteGrantBaseParams,
|
|
145
|
+
DelegatedWriteGrantBaseParams,
|
|
146
|
+
DelegatedWriteGrantParams,
|
|
187
147
|
};
|
|
148
|
+
|
|
149
|
+
export { toDelegatedWriteGrantBaseParams } from "@idos-network/kwil-infra/actions";
|
|
@@ -1,119 +1,55 @@
|
|
|
1
|
-
import type { idOSCredential } from "@idos-network/credentials/types";
|
|
1
|
+
import type { idOSCredential, idOSCredentialRecord } from "@idos-network/credentials/types";
|
|
2
2
|
import type { KwilActionClient } from "@idos-network/kwil-infra";
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
buildPreliminaryIDOSCredential,
|
|
6
|
+
BuildPreliminaryIDOSCredentialArgs,
|
|
7
|
+
mapPreliminaryToIDOSCredential,
|
|
8
|
+
PreliminaryIDOSCredential,
|
|
9
|
+
} from "@idos-network/credentials/utils";
|
|
10
|
+
import {
|
|
11
|
+
type CreatePreliminaryCredentialsByDwgInput,
|
|
12
|
+
createPreliminaryCredentialsByDwg,
|
|
7
13
|
dwgMessage,
|
|
8
14
|
type EditPublicNotesAsIssuerInput,
|
|
9
15
|
editPublicNotesAsIssuer,
|
|
10
16
|
getCredentialShared,
|
|
11
17
|
getSiblingCredentialId,
|
|
12
18
|
type idOSDelegatedWriteGrant,
|
|
19
|
+
type DelegatedWriteGrantBaseParams,
|
|
13
20
|
} from "@idos-network/kwil-infra/actions";
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
base64Encode,
|
|
17
|
-
hexEncode,
|
|
18
|
-
hexEncodeSha256Hash,
|
|
19
|
-
utf8Encode,
|
|
20
|
-
} from "@idos-network/utils/codecs";
|
|
21
|
-
import { encryptContent } from "@idos-network/utils/cryptography";
|
|
21
|
+
import { BlobGateway } from "@idos-network/utils/blob-gateway";
|
|
22
|
+
import { hexEncodeSha256Hash } from "@idos-network/utils/codecs";
|
|
22
23
|
import invariant from "tiny-invariant";
|
|
23
24
|
import nacl from "tweetnacl";
|
|
24
25
|
|
|
25
|
-
type
|
|
26
|
-
id?: idOSCredential["id"];
|
|
27
|
-
content_hash?: string;
|
|
28
|
-
public_notes_signature: string;
|
|
29
|
-
broader_signature: string;
|
|
30
|
-
};
|
|
26
|
+
export type { DelegatedWriteGrantBaseParams };
|
|
31
27
|
|
|
32
|
-
type
|
|
33
|
-
|
|
34
|
-
publicNotes: string;
|
|
35
|
-
plaintextContent: Uint8Array;
|
|
36
|
-
recipientEncryptionPublicKey: Uint8Array;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export type BaseCredentialParams = {
|
|
40
|
-
id?: string;
|
|
41
|
-
userId: string;
|
|
42
|
-
publicNotes: string;
|
|
43
|
-
plaintextContent: Uint8Array;
|
|
44
|
-
recipientEncryptionPublicKey: Uint8Array;
|
|
28
|
+
export type DelegatedWriteGrantParams = DelegatedWriteGrantBaseParams & {
|
|
29
|
+
signature: string;
|
|
45
30
|
};
|
|
46
31
|
|
|
47
|
-
export type
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
issuerPublicKey: string;
|
|
54
|
-
accessGrantTimelock: string;
|
|
55
|
-
notUsableBefore: string;
|
|
56
|
-
notUsableAfter: string;
|
|
57
|
-
signature: string;
|
|
32
|
+
export type CredentialByDelegatedWriteGrantBaseParams = Omit<
|
|
33
|
+
BuildPreliminaryIDOSCredentialArgs,
|
|
34
|
+
"issuerSigningSecretKey" | "contentUri"
|
|
35
|
+
> & {
|
|
36
|
+
originalContentUri?: string;
|
|
37
|
+
copyContentUri?: string;
|
|
58
38
|
};
|
|
59
39
|
|
|
60
40
|
export class CredentialService {
|
|
61
41
|
readonly #kwilClient: KwilActionClient;
|
|
62
42
|
readonly #signingKeyPair: nacl.SignKeyPair;
|
|
63
|
-
readonly #
|
|
43
|
+
readonly #blobGateway: BlobGateway;
|
|
64
44
|
|
|
65
45
|
constructor(
|
|
66
46
|
kwilClient: KwilActionClient,
|
|
67
47
|
signingKeyPair: nacl.SignKeyPair,
|
|
68
|
-
|
|
48
|
+
blobGateway: BlobGateway,
|
|
69
49
|
) {
|
|
70
50
|
this.#kwilClient = kwilClient;
|
|
71
51
|
this.#signingKeyPair = signingKeyPair;
|
|
72
|
-
this.#
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
#buildInsertableIDOSCredential({
|
|
76
|
-
userId,
|
|
77
|
-
publicNotes,
|
|
78
|
-
plaintextContent,
|
|
79
|
-
recipientEncryptionPublicKey,
|
|
80
|
-
}: Omit<BuildInsertableIDOSCredentialArgs, "userId"> & { userId?: string }):
|
|
81
|
-
| InsertableIDOSCredential
|
|
82
|
-
| Omit<InsertableIDOSCredential, "user_id"> {
|
|
83
|
-
const ephemeralKeyPair = nacl.box.keyPair();
|
|
84
|
-
const content = encryptContent(
|
|
85
|
-
plaintextContent,
|
|
86
|
-
recipientEncryptionPublicKey,
|
|
87
|
-
ephemeralKeyPair.secretKey,
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
const public_notes_signature = base64Encode(
|
|
91
|
-
nacl.sign.detached(utf8Encode(publicNotes), this.#signingKeyPair.secretKey),
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
return {
|
|
95
|
-
user_id: userId,
|
|
96
|
-
content: base64Encode(content),
|
|
97
|
-
public_notes: publicNotes,
|
|
98
|
-
public_notes_signature,
|
|
99
|
-
|
|
100
|
-
broader_signature: base64Encode(
|
|
101
|
-
nacl.sign.detached(
|
|
102
|
-
Uint8Array.from([...base64Decode(public_notes_signature), ...content]),
|
|
103
|
-
this.#signingKeyPair.secretKey,
|
|
104
|
-
),
|
|
105
|
-
),
|
|
106
|
-
|
|
107
|
-
issuer_auth_public_key: hexEncode(this.#signingKeyPair.publicKey, true),
|
|
108
|
-
encryptor_public_key: base64Encode(ephemeralKeyPair.publicKey),
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
#ensureEntityId<T extends { id?: string }>(entity: T): T & { id: string } {
|
|
113
|
-
if (!entity.id) {
|
|
114
|
-
(entity as T & { id: string }).id = crypto.randomUUID();
|
|
115
|
-
}
|
|
116
|
-
return entity as T & { id: string };
|
|
52
|
+
this.#blobGateway = blobGateway;
|
|
117
53
|
}
|
|
118
54
|
|
|
119
55
|
async requestDelegatedWriteGrantMessage(params: idOSDelegatedWriteGrant): Promise<string> {
|
|
@@ -121,47 +57,58 @@ export class CredentialService {
|
|
|
121
57
|
}
|
|
122
58
|
|
|
123
59
|
async createCredentialByDelegatedWriteGrant(
|
|
124
|
-
credentialParams:
|
|
60
|
+
credentialParams: CredentialByDelegatedWriteGrantBaseParams,
|
|
125
61
|
delegatedWriteGrant: DelegatedWriteGrantParams,
|
|
126
|
-
consumerEncryptionPublicKey
|
|
62
|
+
consumerEncryptionPublicKey: Uint8Array,
|
|
127
63
|
): Promise<{
|
|
128
64
|
originalCredential: Omit<idOSCredential, "user_id">;
|
|
129
65
|
copyCredential: Omit<idOSCredential, "user_id">;
|
|
130
66
|
}> {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
);
|
|
67
|
+
const { originalContentUri, copyContentUri, ...sharedCredentialParams } = credentialParams;
|
|
68
|
+
const originalCredential: PreliminaryIDOSCredential = {
|
|
69
|
+
...(await buildPreliminaryIDOSCredential({
|
|
70
|
+
...sharedCredentialParams,
|
|
71
|
+
contentUri: originalContentUri,
|
|
72
|
+
issuerSigningSecretKey: this.#signingKeyPair.secretKey,
|
|
73
|
+
})),
|
|
74
|
+
id: crypto.randomUUID(),
|
|
75
|
+
};
|
|
141
76
|
|
|
142
77
|
const contentHash = hexEncodeSha256Hash(credentialParams.plaintextContent);
|
|
143
78
|
|
|
144
|
-
const copyCredential =
|
|
145
|
-
|
|
79
|
+
const copyCredential: PreliminaryIDOSCredential = {
|
|
80
|
+
...(await buildPreliminaryIDOSCredential({
|
|
81
|
+
...sharedCredentialParams,
|
|
82
|
+
contentUri: copyContentUri,
|
|
146
83
|
publicNotes: "",
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}),
|
|
84
|
+
recipientEncryptionPublicKey: consumerEncryptionPublicKey,
|
|
85
|
+
issuerSigningSecretKey: this.#signingKeyPair.secretKey,
|
|
86
|
+
})),
|
|
87
|
+
id: crypto.randomUUID(),
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
invariant(
|
|
91
|
+
originalCredential.contentUri !== copyCredential.contentUri,
|
|
92
|
+
"Original and copy credentials must use distinct content URIs",
|
|
150
93
|
);
|
|
151
94
|
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
95
|
+
const requestId = crypto.randomUUID();
|
|
96
|
+
const payload: CreatePreliminaryCredentialsByDwgInput = {
|
|
97
|
+
request_id: requestId,
|
|
98
|
+
issuer_auth_public_key: originalCredential.issuerAuthPublicKey,
|
|
99
|
+
original_encryptor_public_key: originalCredential.encryptorPublicKey,
|
|
100
|
+
original_id: originalCredential.id,
|
|
101
|
+
original_content_uri: originalCredential.contentUri,
|
|
102
|
+
original_content_size: originalCredential.contentSize,
|
|
103
|
+
original_public_notes: originalCredential.publicNotes,
|
|
104
|
+
original_public_notes_signature: originalCredential.publicNotesSignature,
|
|
105
|
+
original_broader_signature: originalCredential.broaderSignature,
|
|
106
|
+
copy_encryptor_public_key: copyCredential.encryptorPublicKey,
|
|
107
|
+
copy_id: copyCredential.id,
|
|
108
|
+
copy_content_uri: copyCredential.contentUri,
|
|
109
|
+
copy_content_size: copyCredential.contentSize,
|
|
110
|
+
copy_public_notes_signature: copyCredential.publicNotesSignature,
|
|
111
|
+
copy_broader_signature: copyCredential.broaderSignature,
|
|
165
112
|
content_hash: contentHash,
|
|
166
113
|
dwg_owner: delegatedWriteGrant.ownerWalletIdentifier,
|
|
167
114
|
dwg_grantee: delegatedWriteGrant.consumerWalletIdentifier,
|
|
@@ -173,9 +120,18 @@ export class CredentialService {
|
|
|
173
120
|
dwg_signature: delegatedWriteGrant.signature,
|
|
174
121
|
};
|
|
175
122
|
|
|
176
|
-
await
|
|
123
|
+
await createPreliminaryCredentialsByDwg(this.#kwilClient, payload);
|
|
177
124
|
|
|
178
|
-
|
|
125
|
+
await this.#blobGateway.uploadCredentialBlobs({
|
|
126
|
+
requestId,
|
|
127
|
+
original: originalCredential.encryptedContent,
|
|
128
|
+
copy: copyCredential.encryptedContent,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
originalCredential: mapPreliminaryToIDOSCredential(originalCredential),
|
|
133
|
+
copyCredential: mapPreliminaryToIDOSCredential(copyCredential),
|
|
134
|
+
};
|
|
179
135
|
}
|
|
180
136
|
|
|
181
137
|
async editCredentialAsIssuer(
|
|
@@ -202,7 +158,7 @@ export class CredentialService {
|
|
|
202
158
|
return id;
|
|
203
159
|
}
|
|
204
160
|
|
|
205
|
-
async getCredentialShared(id: string): Promise<
|
|
161
|
+
async getCredentialShared(id: string): Promise<idOSCredentialRecord | null> {
|
|
206
162
|
const result = await getCredentialShared(this.#kwilClient, { id }).then((res) => res[0]);
|
|
207
163
|
|
|
208
164
|
return result ?? null;
|
|
@@ -4,6 +4,8 @@ import {
|
|
|
4
4
|
hasProfile as _hasProfile,
|
|
5
5
|
upsertWalletAsInserter as _upsertWalletAsInserter,
|
|
6
6
|
addUserAsInserter,
|
|
7
|
+
addWalletMessage as _addWalletMessage,
|
|
8
|
+
type AddWalletMessageInput,
|
|
7
9
|
type GetUserAsInserterInput,
|
|
8
10
|
getUserAsInserter,
|
|
9
11
|
type idOSUser,
|
|
@@ -52,6 +54,11 @@ export class UserService {
|
|
|
52
54
|
return payload;
|
|
53
55
|
}
|
|
54
56
|
|
|
57
|
+
async addWalletMessage(params: AddWalletMessageInput): Promise<string> {
|
|
58
|
+
const result = await _addWalletMessage(this.#kwilClient, params);
|
|
59
|
+
return result.message;
|
|
60
|
+
}
|
|
61
|
+
|
|
55
62
|
/// Useful to understand if a user id already exists.
|
|
56
63
|
async getUser(params: GetUserAsInserterInput): Promise<idOSUser> {
|
|
57
64
|
return getUserAsInserter(this.#kwilClient, this.#ensureEntityId(params));
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import type { idOSCredential } from "@idos-network/credentials/types";
|
|
2
|
-
import type { KwilActionClient } from "@idos-network/kwil-infra";
|
|
3
|
-
|
|
4
|
-
import { createAgByDagForCopy as _createAgByDagForCopy } from "@idos-network/kwil-infra/actions";
|
|
5
|
-
import { base64Encode, hexEncodeSha256Hash, utf8Encode } from "@idos-network/utils/codecs";
|
|
6
|
-
import { NoncedBox } from "@idos-network/utils/cryptography";
|
|
7
|
-
import invariant from "tiny-invariant";
|
|
8
|
-
|
|
9
|
-
export type CreateAccessGrantFromDAGParams = {
|
|
10
|
-
dag_data_id: string;
|
|
11
|
-
dag_owner_wallet_identifier: string;
|
|
12
|
-
dag_grantee_wallet_identifier: string;
|
|
13
|
-
dag_signature: string;
|
|
14
|
-
dag_locked_until: number;
|
|
15
|
-
dag_content_hash: string;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export class GrantService {
|
|
19
|
-
readonly #kwilClient: KwilActionClient;
|
|
20
|
-
readonly #encryptionSecretKey: Uint8Array;
|
|
21
|
-
|
|
22
|
-
constructor(kwilClient: KwilActionClient, encryptionSecretKey: Uint8Array) {
|
|
23
|
-
this.#kwilClient = kwilClient;
|
|
24
|
-
this.#encryptionSecretKey = encryptionSecretKey;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async createAccessGrantFromDAG(
|
|
28
|
-
params: CreateAccessGrantFromDAGParams,
|
|
29
|
-
getCredentialIdByContentHash: (contentHash: string) => Promise<string | null>,
|
|
30
|
-
getCredentialShared: (id: string) => Promise<idOSCredential | null>,
|
|
31
|
-
): Promise<CreateAccessGrantFromDAGParams | null> {
|
|
32
|
-
const credentialId = await getCredentialIdByContentHash(params.dag_content_hash);
|
|
33
|
-
|
|
34
|
-
invariant(credentialId, "Missing `idOSCredential` id");
|
|
35
|
-
|
|
36
|
-
const credential = await getCredentialShared(credentialId);
|
|
37
|
-
|
|
38
|
-
invariant(credential, "`idOSCredential` with id `{credentialId}` not found");
|
|
39
|
-
|
|
40
|
-
const plaintextContent = await NoncedBox.nonceFromBase64SecretKey(
|
|
41
|
-
base64Encode(this.#encryptionSecretKey),
|
|
42
|
-
).decrypt(credential.content, credential.encryptor_public_key);
|
|
43
|
-
|
|
44
|
-
// Get the content hash from the plaintext content
|
|
45
|
-
const contentHash = hexEncodeSha256Hash(utf8Encode(plaintextContent));
|
|
46
|
-
|
|
47
|
-
// Check if the content hash matches the content hash in the credential
|
|
48
|
-
if (contentHash !== params.dag_content_hash) {
|
|
49
|
-
throw new Error("Hash mismatch between `DAG` and `idOSCredential` content");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const result = await _createAgByDagForCopy(this.#kwilClient, params);
|
|
53
|
-
|
|
54
|
-
return result ?? null;
|
|
55
|
-
}
|
|
56
|
-
}
|