@enbox/agent 0.6.0 → 0.6.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.
@@ -1 +1 @@
1
- {"version":3,"file":"identity-vault.d.ts","sourceRoot":"","sources":["../../../src/types/identity-vault.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IAEpB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IAEb,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,yEAAyE;IACzE,GAAG,EAAE,MAAM,CAAC;IAEZ,mFAAmF;IACnF,oBAAoB,EAAE,MAAM,CAAC;IAE7B,qFAAqF;IACrF,MAAM,EAAE,mBAAmB,CAAC;CAC7B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAEjC,+FAA+F;IAC/F,KAAK,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACpC,CAAC;AAEF,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;IAAE,gBAAgB,EAAE,GAAG,CAAA;CAAE;IACtF;;;;;OAKG;IACH,MAAM,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAEvC;;;;;;;OAOG;IACH,cAAc,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpF;;OAEG;IACH,MAAM,IAAI,OAAO,CAAC,SAAS,CAAC,CAAA;IAE5B;;;OAGG;IACH,SAAS,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAA;IAEzC;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAEzE;;OAEG;IACH,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAElC;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC;IAEpB;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;;;OAKG;IACH,OAAO,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,mBAAmB,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElF;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1B;;OAEG;IACH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC"}
1
+ {"version":3,"file":"identity-vault.d.ts","sourceRoot":"","sources":["../../../src/types/identity-vault.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IAEpB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IAEb,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,yEAAyE;IACzE,GAAG,EAAE,MAAM,CAAC;IAEZ,mFAAmF;IACnF,oBAAoB,EAAE,MAAM,CAAC;IAE7B,qFAAqF;IACrF,MAAM,EAAE,mBAAmB,CAAC;CAC7B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAEjC,+FAA+F;IAC/F,KAAK,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACpC,CAAC;AAEF,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;IAAE,gBAAgB,EAAE,GAAG,CAAA;CAAE;IACtF;;;;;OAKG;IACH,MAAM,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAEvC;;;;;;;OAOG;IACH,cAAc,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpF;;OAEG;IACH,MAAM,IAAI,OAAO,CAAC,SAAS,CAAC,CAAA;IAE5B;;;OAGG;IACH,SAAS,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAA;IAEzC;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAEzE;;OAEG;IACH,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAElC;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC;IAEpB;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;;;OAKG;IACH,OAAO,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,mBAAmB,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElF;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpD;;;;;;OAMG;IACH,WAAW,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEhE;;;;;;OAMG;IACH,WAAW,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC3D;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1B;;OAEG;IACH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enbox/agent",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "type": "module",
5
5
  "main": "./dist/esm/index.js",
6
6
  "module": "./dist/esm/index.js",
package/src/dwn-api.ts CHANGED
@@ -984,6 +984,20 @@ export class AgentDwnApi {
984
984
  );
985
985
  }
986
986
 
987
+ // When a ProtocolsConfigure is processed WITHOUT the encryption flag
988
+ // (e.g. a delegate installing the owner's protocol definition that
989
+ // already contains `$encryption` keys from the remote DWN), cache the
990
+ // definition so that subsequent RecordsWrite encryption can find it
991
+ // without re-querying the local DWN (which would fail for delegates
992
+ // because the query author doesn't match the unpublished protocol's
993
+ // tenant).
994
+ if (isDwnRequest(request, DwnInterface.ProtocolsConfigure) && !request.encryption && !rawMessage) {
995
+ const def = request.messageParams?.definition;
996
+ if (def?.protocol) {
997
+ this._protocolDefinitionCache.set(`${request.target}~${def.protocol}`, def);
998
+ }
999
+ }
1000
+
987
1001
  // Auto-encrypt data on RecordsWrite.
988
1002
  //
989
1003
  // Encryption scheme decision (unified key delivery):
@@ -1032,7 +1046,7 @@ export class AgentDwnApi {
1032
1046
  );
1033
1047
  } else {
1034
1048
  protocolDefinition = await this.getProtocolDefinition(
1035
- request.target, messageParams.protocol,
1049
+ request.target, messageParams.protocol, request.granteeDid,
1036
1050
  );
1037
1051
  }
1038
1052
 
@@ -1428,6 +1442,7 @@ export class AgentDwnApi {
1428
1442
  private async getProtocolDefinition(
1429
1443
  tenantDid: string,
1430
1444
  protocolUri: string,
1445
+ granteeDid?: string,
1431
1446
  ): Promise<ProtocolDefinition | undefined> {
1432
1447
  if (!this._dwn) {
1433
1448
  // Remote mode: query via RPC (same as fetchRemoteProtocolDefinition,
@@ -1447,9 +1462,29 @@ export class AgentDwnApi {
1447
1462
  throw error;
1448
1463
  }
1449
1464
  }
1465
+ // When operating as a delegate, resolve the ProtocolsQuery grant so
1466
+ // the local DWN authorises the query for unpublished protocols.
1467
+ let permissionGrantId: string | undefined;
1468
+ if (granteeDid) {
1469
+ try {
1470
+ const permissionsApi = new AgentPermissionsApi({ agent: this.agent });
1471
+ const { grant } = await permissionsApi.getPermissionForRequest({
1472
+ connectedDid : tenantDid,
1473
+ delegateDid : granteeDid,
1474
+ protocol : protocolUri,
1475
+ cached : true,
1476
+ messageType : DwnInterface.ProtocolsQuery,
1477
+ });
1478
+ permissionGrantId = grant.id;
1479
+ } catch {
1480
+ // No grant found — try without (works for published protocols).
1481
+ }
1482
+ }
1483
+
1450
1484
  return getProtocolDefinitionFn(
1451
1485
  tenantDid, protocolUri, this._dwn,
1452
1486
  this.getSigner.bind(this), this._protocolDefinitionCache,
1487
+ granteeDid, permissionGrantId,
1453
1488
  );
1454
1489
  }
1455
1490
 
@@ -71,6 +71,8 @@ export async function getProtocolDefinition(
71
71
  dwn: DwnNode,
72
72
  getSigner: GetSignerFn,
73
73
  cache: TtlCache<string, ProtocolDefinition>,
74
+ granteeDid?: string,
75
+ permissionGrantId?: string,
74
76
  ): Promise<ProtocolDefinition | undefined> {
75
77
  const cacheKey = `${tenantDid}~${protocolUri}`;
76
78
 
@@ -79,12 +81,18 @@ export async function getProtocolDefinition(
79
81
  return cached;
80
82
  }
81
83
 
82
- const signer = await getSigner(tenantDid);
84
+ // When operating as a delegate, the tenant's private signing key is not
85
+ // available locally. Sign the ProtocolsQuery with the delegate's key
86
+ // and include the permissionGrantId so the local DWN authorises the
87
+ // query against the unpublished protocol.
88
+ const signerDid = granteeDid ?? tenantDid;
89
+ const signer = await getSigner(signerDid);
83
90
  const protocolsQuery = await dwnMessageConstructors[
84
91
  DwnInterfaceEnum.ProtocolsQuery
85
92
  ].create({
86
93
  filter: { protocol: protocolUri },
87
94
  signer,
95
+ ...(permissionGrantId ? { permissionGrantId } : {}),
88
96
  });
89
97
 
90
98
  const reply = await dwn.processMessage(
@@ -792,6 +792,56 @@ export class HdIdentityVault implements IdentityVault<{ InitializeResult: string
792
792
  }
793
793
  }
794
794
 
795
+ /**
796
+ * Encrypts arbitrary data using the vault's content encryption key (CEK).
797
+ *
798
+ * The vault must be unlocked. The returned compact JWE string can be safely
799
+ * stored in untrusted storage (e.g. `localStorage`). Only the vault password
800
+ * can decrypt the data.
801
+ *
802
+ * @param params.plaintext - The data to encrypt.
803
+ * @returns A compact JWE string.
804
+ * @throws If the vault is locked.
805
+ */
806
+ public async encryptData({ plaintext }: { plaintext: Uint8Array }): Promise<string> {
807
+ if (this.isLocked() || !this._contentEncryptionKey) {
808
+ throw new Error('HdIdentityVault: Cannot encrypt data — vault is locked.');
809
+ }
810
+
811
+ return CompactJwe.encrypt({
812
+ key : this._contentEncryptionKey,
813
+ plaintext,
814
+ protectedHeader : { alg: 'dir', enc: 'A256GCM' },
815
+ crypto : this.crypto,
816
+ keyManager : new LocalKeyManager(),
817
+ });
818
+ }
819
+
820
+ /**
821
+ * Decrypts data that was previously encrypted with {@link encryptData}.
822
+ *
823
+ * The vault must be unlocked.
824
+ *
825
+ * @param params.jwe - The compact JWE string to decrypt.
826
+ * @returns The original plaintext bytes.
827
+ * @throws If the vault is locked or the JWE is invalid.
828
+ */
829
+ public async decryptData({ jwe }: { jwe: string }): Promise<Uint8Array> {
830
+ if (this.isLocked() || !this._contentEncryptionKey) {
831
+ throw new Error('HdIdentityVault: Cannot decrypt data — vault is locked.');
832
+ }
833
+
834
+ const { plaintext } = await CompactJwe.decrypt({
835
+ jwe,
836
+ key : this._contentEncryptionKey,
837
+ crypto : this.crypto,
838
+ keyManager : new LocalKeyManager(),
839
+ options : { minP2cCount: 1 },
840
+ });
841
+
842
+ return plaintext;
843
+ }
844
+
795
845
  /**
796
846
  * Retrieves the Decentralized Identifier (DID) associated with the identity vault from the vault
797
847
  * store.
package/src/index.ts CHANGED
@@ -41,3 +41,4 @@ export * from './test-harness.js';
41
41
  export * from './utils.js';
42
42
  export * from './enbox-connect-protocol.js';
43
43
  export * from './enbox-user-agent.js';
44
+ export { KeyDeliveryProtocolDefinition } from './store-data-protocols.js';
@@ -117,6 +117,24 @@ export interface IdentityVault<T extends Record<string, any> = { InitializeResul
117
117
  * @throws An error if the password is incorrect.
118
118
  */
119
119
  unlock(params: { password: string }): Promise<void>;
120
+
121
+ /**
122
+ * Encrypts arbitrary data using the vault's content encryption key.
123
+ * The vault must be unlocked.
124
+ *
125
+ * @returns A compact JWE string that can be safely stored in untrusted storage.
126
+ * @throws An error if the vault is locked.
127
+ */
128
+ encryptData(params: { plaintext: Uint8Array }): Promise<string>;
129
+
130
+ /**
131
+ * Decrypts data that was previously encrypted with {@link encryptData}.
132
+ * The vault must be unlocked.
133
+ *
134
+ * @returns The original plaintext bytes.
135
+ * @throws An error if the vault is locked or the JWE is invalid.
136
+ */
137
+ decryptData(params: { jwe: string }): Promise<Uint8Array>;
120
138
  }
121
139
 
122
140
  export type IdentityVaultStatus = {