@haneullabs/seal 1.0.1 → 1.1.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @mysten/seal
2
2
 
3
+ ## 1.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 43e69f8: Add embedded LLM-friendly docs to published packages
8
+ - Updated dependencies [43e69f8]
9
+ - Updated dependencies [e51dc5d]
10
+ - @mysten/bcs@2.0.3
11
+ - @mysten/sui@2.8.0
12
+
13
+ ## 1.1.0
14
+
15
+ ### Minor Changes
16
+
17
+ - 8957bc4: [seal] use vector instead of vecmap for partial key servers
18
+
3
19
  ## 1.0.1
4
20
 
5
21
  ### Patch Changes
package/dist/bcs.d.mts CHANGED
@@ -1,7 +1,6 @@
1
1
  import * as _haneullabs_bcs0 from "@haneullabs/bcs";
2
2
 
3
3
  //#region src/bcs.d.ts
4
-
5
4
  /**
6
5
  * The encrypted object format. Should be aligned with the Rust implementation.
7
6
  */
@@ -1 +1 @@
1
- {"version":3,"file":"bcs.d.mts","names":[],"sources":["../src/bcs.ts"],"sourcesContent":[],"mappings":";;;;;;;cA8Ba,kCAAe;WAW1B,gBAAA,CAAA"}
1
+ {"version":3,"file":"bcs.d.mts","names":[],"sources":["../src/bcs.ts"],"mappings":";;;;;;cA8Ba,eAAA,mBAAe,SAAA;WAW1B,gBAAA,CAAA,OAAA"}
package/dist/bcs.mjs CHANGED
@@ -60,10 +60,7 @@ const ServerType = bcs$1.enum("ServerType", {
60
60
  Committee: bcs$1.struct("Committee", {
61
61
  version: bcs$1.u32(),
62
62
  threshold: bcs$1.u16(),
63
- partialKeyServers: bcs$1.vector(bcs$1.struct("VecMapEntry", {
64
- key: bcs$1.Address,
65
- value: PartialKeyServer
66
- }))
63
+ partialKeyServers: bcs$1.vector(PartialKeyServer)
67
64
  })
68
65
  });
69
66
  /**
package/dist/bcs.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bcs.mjs","names":["bcs"],"sources":["../src/bcs.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromHex, toHex } from '@haneullabs/bcs';\nimport { bcs } from '@haneullabs/haneul/bcs';\n\nexport const IBEEncryptions = bcs.enum('IBEEncryptions', {\n\tBonehFranklinBLS12381: bcs.struct('BonehFranklinBLS12381', {\n\t\tnonce: bcs.bytes(96),\n\t\tencryptedShares: bcs.vector(bcs.bytes(32)),\n\t\tencryptedRandomness: bcs.bytes(32),\n\t}),\n});\n\nexport const Ciphertext = bcs.enum('Ciphertext', {\n\tAes256Gcm: bcs.struct('Aes256Gcm', {\n\t\tblob: bcs.byteVector(),\n\t\taad: bcs.option(bcs.byteVector()),\n\t}),\n\tHmac256Ctr: bcs.struct('Hmac256Ctr', {\n\t\tblob: bcs.byteVector(),\n\t\taad: bcs.option(bcs.byteVector()),\n\t\tmac: bcs.bytes(32),\n\t}),\n\tPlain: bcs.struct('Plain', {}),\n});\n\n/**\n * The encrypted object format. Should be aligned with the Rust implementation.\n */\nexport const EncryptedObject = bcs.struct('EncryptedObject', {\n\tversion: bcs.u8(),\n\tpackageId: bcs.Address,\n\tid: bcs.byteVector().transform({\n\t\toutput: (val) => toHex(val),\n\t\tinput: (val: string) => fromHex(val),\n\t}),\n\tservices: bcs.vector(bcs.tuple([bcs.Address, bcs.u8()])),\n\tthreshold: bcs.u8(),\n\tencryptedShares: IBEEncryptions,\n\tciphertext: Ciphertext,\n});\n\n/**\n * The Move struct for the KeyServerV1 object.\n */\nexport const KeyServerMoveV1 = bcs.struct('KeyServerV1', {\n\tname: bcs.string(),\n\turl: bcs.string(),\n\tkeyType: bcs.u8(),\n\tpk: bcs.byteVector(),\n});\n\n/**\n * The Move struct for PartialKeyServer.\n */\nexport const PartialKeyServer = bcs.struct('PartialKeyServer', {\n\tname: bcs.string(),\n\turl: bcs.string(),\n\tpartialPk: bcs.byteVector(),\n\tpartyId: bcs.u16(),\n});\n\n/**\n * The Move enum for ServerType (V2).\n */\nexport const ServerType = bcs.enum('ServerType', {\n\tIndependent: bcs.struct('Independent', {\n\t\turl: bcs.string(),\n\t}),\n\tCommittee: bcs.struct('Committee', {\n\t\tversion: bcs.u32(),\n\t\tthreshold: bcs.u16(),\n\t\tpartialKeyServers: bcs.vector(\n\t\t\tbcs.struct('VecMapEntry', {\n\t\t\t\tkey: bcs.Address,\n\t\t\t\tvalue: PartialKeyServer,\n\t\t\t}),\n\t\t),\n\t}),\n});\n\n/**\n * The Move struct for the KeyServerV2 object.\n */\nexport const KeyServerMoveV2 = bcs.struct('KeyServerV2', {\n\tname: bcs.string(),\n\tkeyType: bcs.u8(),\n\tpk: bcs.byteVector(),\n\tserverType: ServerType,\n});\n\n/**\n * The Move struct for the parent object.\n */\nexport const KeyServerMove = bcs.struct('KeyServer', {\n\tid: bcs.Address,\n\tfirstVersion: bcs.u64(), // latest version\n\tlastVersion: bcs.u64(), // oldest version\n});\n"],"mappings":";;;;AAMA,MAAa,iBAAiBA,MAAI,KAAK,kBAAkB,EACxD,uBAAuBA,MAAI,OAAO,yBAAyB;CAC1D,OAAOA,MAAI,MAAM,GAAG;CACpB,iBAAiBA,MAAI,OAAOA,MAAI,MAAM,GAAG,CAAC;CAC1C,qBAAqBA,MAAI,MAAM,GAAG;CAClC,CAAC,EACF,CAAC;AAEF,MAAa,aAAaA,MAAI,KAAK,cAAc;CAChD,WAAWA,MAAI,OAAO,aAAa;EAClC,MAAMA,MAAI,YAAY;EACtB,KAAKA,MAAI,OAAOA,MAAI,YAAY,CAAC;EACjC,CAAC;CACF,YAAYA,MAAI,OAAO,cAAc;EACpC,MAAMA,MAAI,YAAY;EACtB,KAAKA,MAAI,OAAOA,MAAI,YAAY,CAAC;EACjC,KAAKA,MAAI,MAAM,GAAG;EAClB,CAAC;CACF,OAAOA,MAAI,OAAO,SAAS,EAAE,CAAC;CAC9B,CAAC;;;;AAKF,MAAa,kBAAkBA,MAAI,OAAO,mBAAmB;CAC5D,SAASA,MAAI,IAAI;CACjB,WAAWA,MAAI;CACf,IAAIA,MAAI,YAAY,CAAC,UAAU;EAC9B,SAAS,QAAQ,MAAM,IAAI;EAC3B,QAAQ,QAAgB,QAAQ,IAAI;EACpC,CAAC;CACF,UAAUA,MAAI,OAAOA,MAAI,MAAM,CAACA,MAAI,SAASA,MAAI,IAAI,CAAC,CAAC,CAAC;CACxD,WAAWA,MAAI,IAAI;CACnB,iBAAiB;CACjB,YAAY;CACZ,CAAC;;;;AAKF,MAAa,kBAAkBA,MAAI,OAAO,eAAe;CACxD,MAAMA,MAAI,QAAQ;CAClB,KAAKA,MAAI,QAAQ;CACjB,SAASA,MAAI,IAAI;CACjB,IAAIA,MAAI,YAAY;CACpB,CAAC;;;;AAKF,MAAa,mBAAmBA,MAAI,OAAO,oBAAoB;CAC9D,MAAMA,MAAI,QAAQ;CAClB,KAAKA,MAAI,QAAQ;CACjB,WAAWA,MAAI,YAAY;CAC3B,SAASA,MAAI,KAAK;CAClB,CAAC;;;;AAKF,MAAa,aAAaA,MAAI,KAAK,cAAc;CAChD,aAAaA,MAAI,OAAO,eAAe,EACtC,KAAKA,MAAI,QAAQ,EACjB,CAAC;CACF,WAAWA,MAAI,OAAO,aAAa;EAClC,SAASA,MAAI,KAAK;EAClB,WAAWA,MAAI,KAAK;EACpB,mBAAmBA,MAAI,OACtBA,MAAI,OAAO,eAAe;GACzB,KAAKA,MAAI;GACT,OAAO;GACP,CAAC,CACF;EACD,CAAC;CACF,CAAC;;;;AAKF,MAAa,kBAAkBA,MAAI,OAAO,eAAe;CACxD,MAAMA,MAAI,QAAQ;CAClB,SAASA,MAAI,IAAI;CACjB,IAAIA,MAAI,YAAY;CACpB,YAAY;CACZ,CAAC;;;;AAKF,MAAa,gBAAgBA,MAAI,OAAO,aAAa;CACpD,IAAIA,MAAI;CACR,cAAcA,MAAI,KAAK;CACvB,aAAaA,MAAI,KAAK;CACtB,CAAC"}
1
+ {"version":3,"file":"bcs.mjs","names":["bcs"],"sources":["../src/bcs.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromHex, toHex } from '@haneullabs/bcs';\nimport { bcs } from '@haneullabs/haneul/bcs';\n\nexport const IBEEncryptions = bcs.enum('IBEEncryptions', {\n\tBonehFranklinBLS12381: bcs.struct('BonehFranklinBLS12381', {\n\t\tnonce: bcs.bytes(96),\n\t\tencryptedShares: bcs.vector(bcs.bytes(32)),\n\t\tencryptedRandomness: bcs.bytes(32),\n\t}),\n});\n\nexport const Ciphertext = bcs.enum('Ciphertext', {\n\tAes256Gcm: bcs.struct('Aes256Gcm', {\n\t\tblob: bcs.byteVector(),\n\t\taad: bcs.option(bcs.byteVector()),\n\t}),\n\tHmac256Ctr: bcs.struct('Hmac256Ctr', {\n\t\tblob: bcs.byteVector(),\n\t\taad: bcs.option(bcs.byteVector()),\n\t\tmac: bcs.bytes(32),\n\t}),\n\tPlain: bcs.struct('Plain', {}),\n});\n\n/**\n * The encrypted object format. Should be aligned with the Rust implementation.\n */\nexport const EncryptedObject = bcs.struct('EncryptedObject', {\n\tversion: bcs.u8(),\n\tpackageId: bcs.Address,\n\tid: bcs.byteVector().transform({\n\t\toutput: (val) => toHex(val),\n\t\tinput: (val: string) => fromHex(val),\n\t}),\n\tservices: bcs.vector(bcs.tuple([bcs.Address, bcs.u8()])),\n\tthreshold: bcs.u8(),\n\tencryptedShares: IBEEncryptions,\n\tciphertext: Ciphertext,\n});\n\n/**\n * The Move struct for the KeyServerV1 object.\n */\nexport const KeyServerMoveV1 = bcs.struct('KeyServerV1', {\n\tname: bcs.string(),\n\turl: bcs.string(),\n\tkeyType: bcs.u8(),\n\tpk: bcs.byteVector(),\n});\n\n/**\n * The Move struct for PartialKeyServer.\n */\nexport const PartialKeyServer = bcs.struct('PartialKeyServer', {\n\tname: bcs.string(),\n\turl: bcs.string(),\n\tpartialPk: bcs.byteVector(),\n\tpartyId: bcs.u16(),\n});\n\n/**\n * The Move enum for ServerType (V2).\n */\nexport const ServerType = bcs.enum('ServerType', {\n\tIndependent: bcs.struct('Independent', {\n\t\turl: bcs.string(),\n\t}),\n\tCommittee: bcs.struct('Committee', {\n\t\tversion: bcs.u32(),\n\t\tthreshold: bcs.u16(),\n\t\tpartialKeyServers: bcs.vector(PartialKeyServer),\n\t}),\n});\n\n/**\n * The Move struct for the KeyServerV2 object.\n */\nexport const KeyServerMoveV2 = bcs.struct('KeyServerV2', {\n\tname: bcs.string(),\n\tkeyType: bcs.u8(),\n\tpk: bcs.byteVector(),\n\tserverType: ServerType,\n});\n\n/**\n * The Move struct for the parent object.\n */\nexport const KeyServerMove = bcs.struct('KeyServer', {\n\tid: bcs.Address,\n\tfirstVersion: bcs.u64(), // latest version\n\tlastVersion: bcs.u64(), // oldest version\n});\n"],"mappings":";;;;AAMA,MAAa,iBAAiBA,MAAI,KAAK,kBAAkB,EACxD,uBAAuBA,MAAI,OAAO,yBAAyB;CAC1D,OAAOA,MAAI,MAAM,GAAG;CACpB,iBAAiBA,MAAI,OAAOA,MAAI,MAAM,GAAG,CAAC;CAC1C,qBAAqBA,MAAI,MAAM,GAAG;CAClC,CAAC,EACF,CAAC;AAEF,MAAa,aAAaA,MAAI,KAAK,cAAc;CAChD,WAAWA,MAAI,OAAO,aAAa;EAClC,MAAMA,MAAI,YAAY;EACtB,KAAKA,MAAI,OAAOA,MAAI,YAAY,CAAC;EACjC,CAAC;CACF,YAAYA,MAAI,OAAO,cAAc;EACpC,MAAMA,MAAI,YAAY;EACtB,KAAKA,MAAI,OAAOA,MAAI,YAAY,CAAC;EACjC,KAAKA,MAAI,MAAM,GAAG;EAClB,CAAC;CACF,OAAOA,MAAI,OAAO,SAAS,EAAE,CAAC;CAC9B,CAAC;;;;AAKF,MAAa,kBAAkBA,MAAI,OAAO,mBAAmB;CAC5D,SAASA,MAAI,IAAI;CACjB,WAAWA,MAAI;CACf,IAAIA,MAAI,YAAY,CAAC,UAAU;EAC9B,SAAS,QAAQ,MAAM,IAAI;EAC3B,QAAQ,QAAgB,QAAQ,IAAI;EACpC,CAAC;CACF,UAAUA,MAAI,OAAOA,MAAI,MAAM,CAACA,MAAI,SAASA,MAAI,IAAI,CAAC,CAAC,CAAC;CACxD,WAAWA,MAAI,IAAI;CACnB,iBAAiB;CACjB,YAAY;CACZ,CAAC;;;;AAKF,MAAa,kBAAkBA,MAAI,OAAO,eAAe;CACxD,MAAMA,MAAI,QAAQ;CAClB,KAAKA,MAAI,QAAQ;CACjB,SAASA,MAAI,IAAI;CACjB,IAAIA,MAAI,YAAY;CACpB,CAAC;;;;AAKF,MAAa,mBAAmBA,MAAI,OAAO,oBAAoB;CAC9D,MAAMA,MAAI,QAAQ;CAClB,KAAKA,MAAI,QAAQ;CACjB,WAAWA,MAAI,YAAY;CAC3B,SAASA,MAAI,KAAK;CAClB,CAAC;;;;AAKF,MAAa,aAAaA,MAAI,KAAK,cAAc;CAChD,aAAaA,MAAI,OAAO,eAAe,EACtC,KAAKA,MAAI,QAAQ,EACjB,CAAC;CACF,WAAWA,MAAI,OAAO,aAAa;EAClC,SAASA,MAAI,KAAK;EAClB,WAAWA,MAAI,KAAK;EACpB,mBAAmBA,MAAI,OAAO,iBAAiB;EAC/C,CAAC;CACF,CAAC;;;;AAKF,MAAa,kBAAkBA,MAAI,OAAO,eAAe;CACxD,MAAMA,MAAI,QAAQ;CAClB,SAASA,MAAI,IAAI;CACjB,IAAIA,MAAI,YAAY;CACpB,YAAY;CACZ,CAAC;;;;AAKF,MAAa,gBAAgBA,MAAI,OAAO,aAAa;CACpD,IAAIA,MAAI;CACR,cAAcA,MAAI,KAAK;CACvB,aAAaA,MAAI,KAAK;CACtB,CAAC"}
@@ -2,7 +2,6 @@ import { Fp2 } from "@noble/curves/abstract/tower.js";
2
2
  import { WeierstrassPoint } from "@noble/curves/abstract/weierstrass.js";
3
3
 
4
4
  //#region src/bls12381.d.ts
5
-
6
5
  declare class G2Element {
7
6
  point: WeierstrassPoint<Fp2>;
8
7
  static readonly SIZE = 96;
@@ -1 +1 @@
1
- {"version":3,"file":"bls12381.d.mts","names":[],"sources":["../src/bls12381.ts"],"sourcesContent":[],"mappings":";;;;;AA+E2B,cAzBd,SAAA,CAyBc;EAIf,KAAA,EA5BJ,gBA4BI,CA5Ba,GA4Bb,CAAA;EAAY,gBAAA,IAAA,GAAA,EAAA;EAIE,WAAA,CAAA,KAAA,EA5BN,gBA4BM,CA5BW,GA4BX,CAAA;EAAa,OAAA,SAAA,CAAA,CAAA,EAxBlB,SAwBkB;EAIxB,OAAA,SAAA,CAAA,KAAA,EAxBU,UAwBV,CAAA,EAxBuB,SAwBvB;EAAS,OAAA,CAAA,CAAA,EAhBZ,UAgBY,CAhBD,WAgBC,CAAA;EA4CX,QAAA,CAAM,MAAA,EAxDD,MAwDC,CAAA,EAxDQ,SAwDR;EASiB,GAAA,CAAA,KAAA,EA7DxB,SA6DwB,CAAA,EA7DZ,SA6DY;EAOlB,OAAA,WAAA,CAAA,IAAA,EAhEQ,UAgER,CAAA,EAhEqB,SAgErB;EAKN,MAAA,CAAA,KAAA,EAjEG,SAiEH,CAAA,EAAA,OAAA;;cArBC,MAAA;;;;qCASuB;mBAOlB;aAKN;0BAIa,aAAa;4BAOX,aAAa"}
1
+ {"version":3,"file":"bls12381.d.mts","names":[],"sources":["../src/bls12381.ts"],"mappings":";;;;cAsDa,SAAA;EACZ,KAAA,EAAO,gBAAA,CAAiB,GAAA;EAAA,gBAED,IAAA;cAEX,KAAA,EAAO,gBAAA,CAAiB,GAAA;EAAA,OAI7B,SAAA,CAAA,GAAa,SAAA;EAAA,OAIb,SAAA,CAAU,KAAA,EAAO,UAAA,GAAa,SAAA;EAQrC,OAAA,CAAA,GAAW,UAAA,CAAW,WAAA;EAItB,QAAA,CAAS,MAAA,EAAQ,MAAA,GAAS,SAAA;EAI1B,GAAA,CAAI,KAAA,EAAO,SAAA,GAAY,SAAA;EAAA,OAIhB,WAAA,CAAY,IAAA,EAAM,UAAA,GAAa,SAAA;EAItC,MAAA,CAAO,KAAA,EAAO,SAAA;AAAA;AAAA,cA4CF,MAAA;EACZ,MAAA;EAAA,gBAEuB,IAAA;cAEX,MAAA;EAAA,OAIL,UAAA,CAAW,MAAA,WAAiB,MAAA;EAAA,OAO5B,MAAA,CAAA,GAAU,MAAA;EAKjB,OAAA,CAAA,GAAW,UAAA;EAAA,OAIJ,SAAA,CAAU,KAAA,EAAO,UAAA,GAAa,MAAA;EAAA,OAO9B,WAAA,CAAY,KAAA,EAAO,UAAA,GAAa,MAAA;AAAA"}
package/dist/client.d.mts CHANGED
@@ -3,7 +3,6 @@ import { DecryptOptions, EncryptOptions, FetchKeysOptions, GetDerivedKeysOptions
3
3
  import { DerivedKey, KeyServer } from "./key-server.mjs";
4
4
 
5
5
  //#region src/client.d.ts
6
-
7
6
  declare class SealClient {
8
7
  #private;
9
8
  constructor(options: SealClientOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.mts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":";;;;;;AAsGE,cAnDW,UAAA,CAmDX;EACA,CAAA,OAAA;EACA,WAAA,CAAA,OAAA,EA1CoB,iBA0CpB;EACA;;;;;;;;;;;;;EA2DA,OAAA,CAAA;IAAA,OAAA;IAAA,OAAA;IAAA,SAAA;IAAA,SAAA;IAAA,EAAA;IAAA,IAAA;IAAA;EAAA,CAAA,EAvDE,cAuDF,CAAA,EAvDgB,OAuDhB,CAAA;IACA,eAAA,YAAA,YAAA,CAAA;IACE,GAAA,YAAA,YAAA,CAAA;EAAc,CAAA,CAAA;EAAA;;;;;;;;;;;;;;;;;;EA4Qd,OAAA,CAAA;IAAA,IAAA;IAAA,UAAA;IAAA,OAAA;IAAA,qBAAA;IAAA;EAAA,CAAA,EA5QA,cA4QA,CAAA,EA5Qc,OA4Qd,CA5Qc,UA4Qd,CA5Qc,eA4Qd,CAAA,CAAA;EAA4C,aAAA,CAAA,CAAA,EAvNxB,OAuNwB,CAvNhB,GAuNgB,CAAA,MAAA,EAvNJ,SAuNI,CAAA,CAAA;EAAZ;;;;;;;qCAtMM,QAAQ;;;;;;;;;;;;;;;;;;KAsFQ,mBAAgB;;;;;;;;;;;;;;;;KAgHtE,wBAAwB,QAAQ,YAAY"}
1
+ {"version":3,"file":"client.d.mts","names":[],"sources":["../src/client.ts"],"mappings":";;;;;cAmDa,UAAA;EAAA;cAWA,OAAA,EAAS,iBAAA;EAyCpB;;;;;;;;;;;;;EAFK,OAAA,CAAA;IACL,OAAA;IACA,OAAA;IACA,SAAA;IACA,SAAA;IACA,EAAA;IACA,IAAA;IACA;EAAA,GACE,cAAA,GAAc,OAAA;;;;EAyDd;;;;;;;;;;;;;;;;;;EANG,OAAA,CAAA;IACL,IAAA;IACA,UAAA;IACA,OAAA;IACA,qBAAA;IACA;EAAA,GACE,cAAA,GAAc,OAAA,CAAA,UAAA,CAAA,eAAA;EAqDX,aAAA,CAAA,GAAiB,OAAA,CAAQ,GAAA,SAAY,SAAA;EAuNxC;;;;;;;EAtMG,aAAA,CAAc,QAAA,aAAqB,OAAA,CAAQ,SAAA;EA9K5B;;;;;;;;;;;;EAoQf,SAAA,CAAA;IAAY,GAAA;IAAK,OAAA;IAAS,UAAA;IAAY;EAAA,GAAa,gBAAA,GAAgB,OAAA;EAvNxE;;;;;;;;;EAiUK,cAAA,CAAA;IACL,OAAA;IACA,EAAA;IACA,OAAA;IACA,UAAA;IACA;EAAA,GACE,qBAAA,GAAwB,OAAA,CAAQ,GAAA,SAAY,UAAA;AAAA"}
package/dist/client.mjs CHANGED
@@ -10,7 +10,7 @@ import { BonehFranklinBLS12381DerivedKey, fetchKeysForAllIds, retrieveKeyServers
10
10
 
11
11
  //#region src/client.ts
12
12
  var SealClient = class {
13
- #suiClient;
13
+ #haneulClient;
14
14
  #configs;
15
15
  #keyServers = null;
16
16
  #verifyKeyServers;
@@ -19,7 +19,7 @@ var SealClient = class {
19
19
  #timeout;
20
20
  #totalWeight;
21
21
  constructor(options) {
22
- this.#suiClient = options.suiClient;
22
+ this.#haneulClient = options.haneulClient;
23
23
  if (new Set(options.serverConfigs.map((s) => s.objectId)).size !== options.serverConfigs.length) throw new InvalidClientOptionsError("Duplicate object IDs");
24
24
  if (options.serverConfigs.some((s) => s.apiKeyName && !s.apiKey || !s.apiKeyName && s.apiKey)) throw new InvalidClientOptionsError("Both apiKeyName and apiKey must be provided or not provided for all key servers");
25
25
  this.#configs = new Map(options.serverConfigs.map((server) => [server.objectId, server]));
@@ -41,7 +41,7 @@ var SealClient = class {
41
41
  * Since the symmetric key can be used to decrypt, it should not be shared but can be used e.g. for backup.
42
42
  */
43
43
  async encrypt({ kemType = KemType.BonehFranklinBLS12381DemCCA, demType = DemType.AesGcm256, threshold, packageId, id, data, aad = new Uint8Array() }) {
44
- const packageObj = await this.#suiClient.core.getObject({ objectId: packageId });
44
+ const packageObj = await this.#haneulClient.core.getObject({ objectId: packageId });
45
45
  if (String(packageObj.object.version) !== "1") throw new InvalidPackageError(`Package ${packageId} is not the first version`);
46
46
  return encrypt({
47
47
  keyServers: await this.#getWeightedKeyServers(),
@@ -129,7 +129,7 @@ var SealClient = class {
129
129
  const missingKeyServers = services.filter((objectId) => !keyServers.has(objectId) && !this.#cachedPublicKeys.has(objectId));
130
130
  if (missingKeyServers.length > 0) (await retrieveKeyServers({
131
131
  objectIds: missingKeyServers,
132
- client: this.#suiClient,
132
+ client: this.#haneulClient,
133
133
  configs: this.#configs
134
134
  })).forEach((keyServer) => this.#cachedPublicKeys.set(keyServer.objectId, G2Element.fromBytes(keyServer.pk)));
135
135
  return services.map((objectId) => {
@@ -154,7 +154,7 @@ var SealClient = class {
154
154
  async #loadKeyServers() {
155
155
  const keyServers = await retrieveKeyServers({
156
156
  objectIds: [...this.#configs.keys()],
157
- client: this.#suiClient,
157
+ client: this.#haneulClient,
158
158
  configs: this.#configs
159
159
  });
160
160
  if (keyServers.length === 0) throw new InvalidKeyServerError("No key servers found");
@@ -1 +1 @@
1
- {"version":3,"file":"client.mjs","names":["#suiClient","#configs","#totalWeight","#verifyKeyServers","#timeout","#getWeightedKeyServers","#createEncryptionInput","#validateEncryptionServices","#cachedKeys","#weight","#keyServers","#loadKeyServers","#cachedPublicKeys"],"sources":["../src/client.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { EncryptedObject } from './bcs.js';\nimport { G1Element, G2Element } from './bls12381.js';\nimport { decrypt } from './decrypt.js';\nimport type { EncryptionInput } from './dem.js';\nimport { AesGcm256, Hmac256Ctr } from './dem.js';\nimport { DemType, encrypt, KemType } from './encrypt.js';\nimport {\n\tInconsistentKeyServersError,\n\tInvalidClientOptionsError,\n\tInvalidKeyServerError,\n\tInvalidPackageError,\n\tInvalidThresholdError,\n\ttoMajorityError,\n\tTooManyFailedFetchKeyRequestsError,\n} from './error.js';\nimport { BonehFranklinBLS12381Services } from './ibe.js';\nimport {\n\tBonehFranklinBLS12381DerivedKey,\n\tretrieveKeyServers,\n\tverifyKeyServer,\n\tfetchKeysForAllIds,\n} from './key-server.js';\nimport type { DerivedKey, KeyServer } from './key-server.js';\nimport type {\n\tDecryptOptions,\n\tEncryptOptions,\n\tFetchKeysOptions,\n\tGetDerivedKeysOptions,\n\tKeyCacheKey,\n\tKeyServerConfig,\n\tSealClientOptions,\n\tSealCompatibleClient,\n\tSealOptions,\n} from './types.js';\nimport { createFullId, count } from './utils.js';\n\nexport function seal<Name = 'seal'>({ name = 'seal' as Name, ...options }: SealOptions<Name>) {\n\treturn {\n\t\tname,\n\t\tregister: (client: SealCompatibleClient) => {\n\t\t\treturn new SealClient({\n\t\t\t\tsuiClient: client,\n\t\t\t\t...options,\n\t\t\t});\n\t\t},\n\t};\n}\n\nexport class SealClient {\n\t#suiClient: SealCompatibleClient;\n\t#configs: Map<string, KeyServerConfig>;\n\t#keyServers: Promise<Map<string, KeyServer>> | null = null;\n\t#verifyKeyServers: boolean;\n\t// A caching map for: fullId:object_id -> partial key.\n\t#cachedKeys = new Map<KeyCacheKey, G1Element>();\n\t#cachedPublicKeys = new Map<string, G2Element>();\n\t#timeout: number;\n\t#totalWeight: number;\n\n\tconstructor(options: SealClientOptions) {\n\t\tthis.#suiClient = options.suiClient;\n\n\t\tif (\n\t\t\tnew Set(options.serverConfigs.map((s) => s.objectId)).size !== options.serverConfigs.length\n\t\t) {\n\t\t\tthrow new InvalidClientOptionsError('Duplicate object IDs');\n\t\t}\n\n\t\tif (\n\t\t\toptions.serverConfigs.some((s) => (s.apiKeyName && !s.apiKey) || (!s.apiKeyName && s.apiKey))\n\t\t) {\n\t\t\tthrow new InvalidClientOptionsError(\n\t\t\t\t'Both apiKeyName and apiKey must be provided or not provided for all key servers',\n\t\t\t);\n\t\t}\n\n\t\tthis.#configs = new Map(options.serverConfigs.map((server) => [server.objectId, server]));\n\t\tthis.#totalWeight = options.serverConfigs\n\t\t\t.map((server) => server.weight)\n\t\t\t.reduce((sum, term) => sum + term, 0);\n\n\t\tthis.#verifyKeyServers = options.verifyKeyServers ?? true;\n\t\tthis.#timeout = options.timeout ?? 10_000;\n\t}\n\n\t/**\n\t * Return an encrypted message under the identity.\n\t *\n\t * @param kemType - The type of KEM to use.\n\t * @param demType - The type of DEM to use.\n\t * @param threshold - The threshold for the TSS encryption.\n\t * @param packageId - the packageId namespace.\n\t * @param id - the identity to use.\n\t * @param data - the data to encrypt.\n\t * @param aad - optional additional authenticated data.\n\t * @returns The bcs bytes of the encrypted object containing all metadata and the 256-bit symmetric key that was used to encrypt the object.\n\t * \tSince the symmetric key can be used to decrypt, it should not be shared but can be used e.g. for backup.\n\t */\n\tasync encrypt({\n\t\tkemType = KemType.BonehFranklinBLS12381DemCCA,\n\t\tdemType = DemType.AesGcm256,\n\t\tthreshold,\n\t\tpackageId,\n\t\tid,\n\t\tdata,\n\t\taad = new Uint8Array(),\n\t}: EncryptOptions) {\n\t\tconst packageObj = await this.#suiClient.core.getObject({ objectId: packageId });\n\t\tif (String(packageObj.object.version) !== '1') {\n\t\t\tthrow new InvalidPackageError(`Package ${packageId} is not the first version`);\n\t\t}\n\n\t\treturn encrypt({\n\t\t\tkeyServers: await this.#getWeightedKeyServers(),\n\t\t\tkemType,\n\t\t\tthreshold,\n\t\t\tpackageId,\n\t\t\tid,\n\t\t\tencryptionInput: this.#createEncryptionInput(\n\t\t\t\tdemType,\n\t\t\t\tdata as Uint8Array<ArrayBuffer>,\n\t\t\t\taad as Uint8Array<ArrayBuffer>,\n\t\t\t),\n\t\t});\n\t}\n\n\t#createEncryptionInput(\n\t\ttype: DemType,\n\t\tdata: Uint8Array<ArrayBuffer>,\n\t\taad: Uint8Array<ArrayBuffer>,\n\t): EncryptionInput {\n\t\tswitch (type) {\n\t\t\tcase DemType.AesGcm256:\n\t\t\t\treturn new AesGcm256(data, aad);\n\t\t\tcase DemType.Hmac256Ctr:\n\t\t\t\treturn new Hmac256Ctr(data, aad);\n\t\t}\n\t}\n\n\t/**\n\t * Decrypt the given encrypted bytes using cached keys.\n\t * Calls fetchKeys in case one or more of the required keys is not cached yet.\n\t * The function throws an error if the client's key servers are not a subset of\n\t * the encrypted object's key servers or if the threshold cannot be met.\n\t *\n\t * If checkShareConsistency is true, the decrypted shares are checked for consistency, meaning that\n\t * any combination of at least threshold shares should either succesfully combine to the plaintext or fail.\n\t * This is useful in case the encryptor is not trusted and the decryptor wants to ensure all decryptors\n\t * receive the same output (e.g., for onchain encrypted voting).\n\t *\n\t * @param data - The encrypted bytes to decrypt.\n\t * @param sessionKey - The session key to use.\n\t * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).\n\t * @param checkShareConsistency - If true, the shares are checked for consistency.\n\t * @param checkLEEncoding - If true, the encryption is also checked using an LE encoded nonce.\n\t * @returns - The decrypted plaintext corresponding to ciphertext.\n\t */\n\tasync decrypt({\n\t\tdata,\n\t\tsessionKey,\n\t\ttxBytes,\n\t\tcheckShareConsistency,\n\t\tcheckLEEncoding,\n\t}: DecryptOptions) {\n\t\tconst encryptedObject = EncryptedObject.parse(data);\n\n\t\tthis.#validateEncryptionServices(\n\t\t\tencryptedObject.services.map((s) => s[0]),\n\t\t\tencryptedObject.threshold,\n\t\t);\n\n\t\tawait this.fetchKeys({\n\t\t\tids: [encryptedObject.id],\n\t\t\ttxBytes,\n\t\t\tsessionKey,\n\t\t\tthreshold: encryptedObject.threshold,\n\t\t});\n\n\t\tif (checkShareConsistency) {\n\t\t\tconst publicKeys = await this.getPublicKeys(\n\t\t\t\tencryptedObject.services.map(([objectId, _]) => objectId),\n\t\t\t);\n\t\t\treturn decrypt({\n\t\t\t\tencryptedObject,\n\t\t\t\tkeys: this.#cachedKeys,\n\t\t\t\tpublicKeys,\n\t\t\t\tcheckLEEncoding: false, // We intentionally do not support other encodings here\n\t\t\t});\n\t\t}\n\t\treturn decrypt({ encryptedObject, keys: this.#cachedKeys, checkLEEncoding });\n\t}\n\n\t#weight(objectId: string) {\n\t\treturn this.#configs.get(objectId)?.weight ?? 0;\n\t}\n\n\t#validateEncryptionServices(services: string[], threshold: number) {\n\t\t// Check that the client's key servers are a subset of the encrypted object's key servers.\n\t\tif (\n\t\t\tservices.some((objectId) => {\n\t\t\t\tconst countInClient = this.#weight(objectId);\n\t\t\t\treturn countInClient > 0 && countInClient !== count(services, objectId);\n\t\t\t})\n\t\t) {\n\t\t\tthrow new InconsistentKeyServersError(\n\t\t\t\t`Client's key servers must be a subset of the encrypted object's key servers`,\n\t\t\t);\n\t\t}\n\t\t// Check that the threshold can be met with the client's key servers.\n\t\tif (threshold > this.#totalWeight) {\n\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t`Invalid threshold ${threshold} for ${this.#totalWeight} servers`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync getKeyServers(): Promise<Map<string, KeyServer>> {\n\t\tif (!this.#keyServers) {\n\t\t\tthis.#keyServers = this.#loadKeyServers().catch((error) => {\n\t\t\t\tthis.#keyServers = null;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\t}\n\t\treturn this.#keyServers;\n\t}\n\n\t/**\n\t * Get the public keys for the given services.\n\t * If all public keys are not in the cache, they are retrieved.\n\t *\n\t * @param services - The services to get the public keys for.\n\t * @returns The public keys for the given services in the same order as the given services.\n\t */\n\tasync getPublicKeys(services: string[]): Promise<G2Element[]> {\n\t\tconst keyServers = await this.getKeyServers();\n\n\t\t// Collect the key servers not already in store or cache.\n\t\tconst missingKeyServers = services.filter(\n\t\t\t(objectId) => !keyServers.has(objectId) && !this.#cachedPublicKeys.has(objectId),\n\t\t);\n\n\t\t// If there are missing key servers, retrieve them and update the cache.\n\t\tif (missingKeyServers.length > 0) {\n\t\t\t(\n\t\t\t\tawait retrieveKeyServers({\n\t\t\t\t\tobjectIds: missingKeyServers,\n\t\t\t\t\tclient: this.#suiClient,\n\t\t\t\t\tconfigs: this.#configs,\n\t\t\t\t})\n\t\t\t).forEach((keyServer) =>\n\t\t\t\tthis.#cachedPublicKeys.set(keyServer.objectId, G2Element.fromBytes(keyServer.pk)),\n\t\t\t);\n\t\t}\n\n\t\treturn services.map((objectId) => {\n\t\t\tconst keyServer = keyServers.get(objectId);\n\t\t\tif (keyServer) {\n\t\t\t\treturn G2Element.fromBytes(keyServer.pk);\n\t\t\t}\n\t\t\treturn this.#cachedPublicKeys.get(objectId)!;\n\t\t});\n\t}\n\n\t/**\n\t * Returns a list of key servers with multiplicity according to their weights.\n\t * The list is used for encryption.\n\t */\n\tasync #getWeightedKeyServers() {\n\t\tconst keyServers = await this.getKeyServers();\n\t\tconst keyServersWithMultiplicity = [];\n\t\tfor (const [objectId, config] of this.#configs) {\n\t\t\tconst keyServer = keyServers.get(objectId)!;\n\t\t\tfor (let i = 0; i < config.weight; i++) {\n\t\t\t\tkeyServersWithMultiplicity.push(keyServer);\n\t\t\t}\n\t\t}\n\t\treturn keyServersWithMultiplicity;\n\t}\n\n\tasync #loadKeyServers(): Promise<Map<string, KeyServer>> {\n\t\tconst keyServers = await retrieveKeyServers({\n\t\t\tobjectIds: [...this.#configs.keys()],\n\t\t\tclient: this.#suiClient,\n\t\t\tconfigs: this.#configs,\n\t\t});\n\n\t\tif (keyServers.length === 0) {\n\t\t\tthrow new InvalidKeyServerError('No key servers found');\n\t\t}\n\n\t\tif (this.#verifyKeyServers) {\n\t\t\tawait Promise.all(\n\t\t\t\tkeyServers.map(async (server) => {\n\t\t\t\t\t// Skip /service verification for committee key server type since the request goes through an aggregator.\n\t\t\t\t\tif (server.serverType === 'Committee') {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst config = this.#configs.get(server.objectId);\n\t\t\t\t\tif (!(await verifyKeyServer(server, this.#timeout, config?.apiKeyName, config?.apiKey))) {\n\t\t\t\t\t\tthrow new InvalidKeyServerError(`Key server ${server.objectId} is not valid`);\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn new Map(keyServers.map((server) => [server.objectId, server]));\n\t}\n\n\t/**\n\t * Fetch keys from the key servers and update the cache.\n\t *\n\t * It is recommended to call this function once for all ids of all encrypted objects if\n\t * there are multiple, then call decrypt for each object. This avoids calling fetchKey\n\t * individually for each decrypt.\n\t *\n\t * @param ids - The ids of the encrypted objects.\n\t * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).\n\t * @param sessionKey - The session key to use.\n\t * @param threshold - The threshold for the TSS encryptions. The function returns when a threshold of key servers had returned keys for all ids.\n\t */\n\tasync fetchKeys({ ids, txBytes, sessionKey, threshold }: FetchKeysOptions) {\n\t\tif (threshold > this.#totalWeight || threshold < 1) {\n\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t`Invalid threshold ${threshold} servers with weights ${JSON.stringify(this.#configs)}`,\n\t\t\t);\n\t\t}\n\t\tconst keyServers = await this.getKeyServers();\n\t\tconst fullIds = ids.map((id) => createFullId(sessionKey.getPackageId(), id));\n\n\t\t// Count a server as completed if it has keys for all fullIds.\n\t\t// Duplicated key server ids will be counted towards the threshold.\n\t\tlet completedWeight = 0;\n\t\tconst remainingKeyServers = [];\n\t\tlet remainingKeyServersWeight = 0;\n\t\tfor (const objectId of keyServers.keys()) {\n\t\t\tif (fullIds.every((fullId) => this.#cachedKeys.has(`${fullId}:${objectId}`))) {\n\t\t\t\tcompletedWeight += this.#weight(objectId);\n\t\t\t} else {\n\t\t\t\tremainingKeyServers.push(objectId);\n\t\t\t\tremainingKeyServersWeight += this.#weight(objectId);\n\t\t\t}\n\t\t}\n\n\t\t// Return early if we have enough keys from cache.\n\t\tif (completedWeight >= threshold) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst certificate = await sessionKey.getCertificate();\n\t\tconst signedRequest = await sessionKey.createRequestParams(txBytes);\n\n\t\tconst controller = new AbortController();\n\t\tconst errors: Error[] = [];\n\n\t\tconst keyFetches = remainingKeyServers.map(async (objectId) => {\n\t\t\tconst server = keyServers.get(objectId)!;\n\t\t\ttry {\n\t\t\t\tconst config = this.#configs.get(objectId);\n\t\t\t\tconst allKeys = await fetchKeysForAllIds({\n\t\t\t\t\turl: server.url,\n\t\t\t\t\trequestSignature: signedRequest.requestSignature,\n\t\t\t\t\ttransactionBytes: txBytes,\n\t\t\t\t\tencKey: signedRequest.encKey,\n\t\t\t\t\tencKeyPk: signedRequest.encKeyPk,\n\t\t\t\t\tencVerificationKey: signedRequest.encVerificationKey,\n\t\t\t\t\tcertificate,\n\t\t\t\t\ttimeout: this.#timeout,\n\t\t\t\t\tapiKeyName: config?.apiKeyName,\n\t\t\t\t\tapiKey: config?.apiKey,\n\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t});\n\t\t\t\t// Check validity of the keys and add them to the cache.\n\t\t\t\tfor (const { fullId, key } of allKeys) {\n\t\t\t\t\tconst keyElement = G1Element.fromBytes(key);\n\t\t\t\t\tif (\n\t\t\t\t\t\t!BonehFranklinBLS12381Services.verifyUserSecretKey(\n\t\t\t\t\t\t\tkeyElement,\n\t\t\t\t\t\t\tfullId,\n\t\t\t\t\t\t\tG2Element.fromBytes(server.pk),\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tconsole.warn('Received invalid key from key server ' + server.objectId);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tthis.#cachedKeys.set(`${fullId}:${server.objectId}`, keyElement);\n\t\t\t\t}\n\n\t\t\t\t// Check if all the receivedIds are consistent with the requested fullIds.\n\t\t\t\t// If so, consider the key server got all keys and mark as completed.\n\t\t\t\tif (fullIds.every((fullId) => this.#cachedKeys.has(`${fullId}:${server.objectId}`))) {\n\t\t\t\t\tcompletedWeight += this.#weight(objectId);\n\n\t\t\t\t\t// Return early if the completed servers is more than the threshold.\n\t\t\t\t\tif (completedWeight >= threshold) {\n\t\t\t\t\t\tcontroller.abort();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (!controller.signal.aborted) {\n\t\t\t\t\terrors.push(error as Error);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\t// If there are too many errors that the threshold is not attainable, return early with error.\n\t\t\t\tremainingKeyServersWeight -= this.#weight(objectId);\n\t\t\t\tif (remainingKeyServersWeight < threshold - completedWeight) {\n\t\t\t\t\tcontroller.abort(new TooManyFailedFetchKeyRequestsError());\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tawait Promise.allSettled(keyFetches);\n\n\t\tif (completedWeight < threshold) {\n\t\t\tthrow toMajorityError(errors);\n\t\t}\n\t}\n\n\t/**\n\t * Get derived keys from the given services.\n\t *\n\t * @param id - The id of the encrypted object.\n\t * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).\n\t * @param sessionKey - The session key to use.\n\t * @param threshold - The threshold.\n\t * @returns - Derived keys for the given services that are in the cache as a \"service object ID\" -> derived key map. If the call is succesful, exactly threshold keys will be returned.\n\t */\n\tasync getDerivedKeys({\n\t\tkemType = KemType.BonehFranklinBLS12381DemCCA,\n\t\tid,\n\t\ttxBytes,\n\t\tsessionKey,\n\t\tthreshold,\n\t}: GetDerivedKeysOptions): Promise<Map<string, DerivedKey>> {\n\t\tswitch (kemType) {\n\t\t\tcase KemType.BonehFranklinBLS12381DemCCA:\n\t\t\t\tconst keyServers = await this.getKeyServers();\n\t\t\t\tif (threshold > this.#totalWeight) {\n\t\t\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t\t\t`Invalid threshold ${threshold} for ${this.#totalWeight} servers`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tawait this.fetchKeys({\n\t\t\t\t\tids: [id],\n\t\t\t\t\ttxBytes,\n\t\t\t\t\tsessionKey,\n\t\t\t\t\tthreshold,\n\t\t\t\t});\n\n\t\t\t\t// After calling fetchKeys, we can be sure that there are at least `threshold` of the required keys in the cache.\n\t\t\t\t// It is also checked there that the KeyServerType is BonehFranklinBLS12381 for all services.\n\n\t\t\t\tconst fullId = createFullId(sessionKey.getPackageId(), id);\n\n\t\t\t\tconst derivedKeys = new Map();\n\t\t\t\tlet weight = 0;\n\t\t\t\tfor (const objectId of keyServers.keys()) {\n\t\t\t\t\t// The code below assumes that the KeyServerType is BonehFranklinBLS12381.\n\t\t\t\t\tconst cachedKey = this.#cachedKeys.get(`${fullId}:${objectId}`);\n\t\t\t\t\tif (cachedKey) {\n\t\t\t\t\t\tderivedKeys.set(objectId, new BonehFranklinBLS12381DerivedKey(cachedKey));\n\t\t\t\t\t\tweight += this.#weight(objectId);\n\t\t\t\t\t\tif (weight >= threshold) {\n\t\t\t\t\t\t\t// We have enough keys, so we can stop.\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn derivedKeys;\n\t\t}\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.mjs","names":["#haneulClient","#configs","#totalWeight","#verifyKeyServers","#timeout","#getWeightedKeyServers","#createEncryptionInput","#validateEncryptionServices","#cachedKeys","#weight","#keyServers","#loadKeyServers","#cachedPublicKeys"],"sources":["../src/client.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { EncryptedObject } from './bcs.js';\nimport { G1Element, G2Element } from './bls12381.js';\nimport { decrypt } from './decrypt.js';\nimport type { EncryptionInput } from './dem.js';\nimport { AesGcm256, Hmac256Ctr } from './dem.js';\nimport { DemType, encrypt, KemType } from './encrypt.js';\nimport {\n\tInconsistentKeyServersError,\n\tInvalidClientOptionsError,\n\tInvalidKeyServerError,\n\tInvalidPackageError,\n\tInvalidThresholdError,\n\ttoMajorityError,\n\tTooManyFailedFetchKeyRequestsError,\n} from './error.js';\nimport { BonehFranklinBLS12381Services } from './ibe.js';\nimport {\n\tBonehFranklinBLS12381DerivedKey,\n\tretrieveKeyServers,\n\tverifyKeyServer,\n\tfetchKeysForAllIds,\n} from './key-server.js';\nimport type { DerivedKey, KeyServer } from './key-server.js';\nimport type {\n\tDecryptOptions,\n\tEncryptOptions,\n\tFetchKeysOptions,\n\tGetDerivedKeysOptions,\n\tKeyCacheKey,\n\tKeyServerConfig,\n\tSealClientOptions,\n\tSealCompatibleClient,\n\tSealOptions,\n} from './types.js';\nimport { createFullId, count } from './utils.js';\n\nexport function seal<Name = 'seal'>({ name = 'seal' as Name, ...options }: SealOptions<Name>) {\n\treturn {\n\t\tname,\n\t\tregister: (client: SealCompatibleClient) => {\n\t\t\treturn new SealClient({\n\t\t\t\thaneulClient: client,\n\t\t\t\t...options,\n\t\t\t});\n\t\t},\n\t};\n}\n\nexport class SealClient {\n\t#haneulClient: SealCompatibleClient;\n\t#configs: Map<string, KeyServerConfig>;\n\t#keyServers: Promise<Map<string, KeyServer>> | null = null;\n\t#verifyKeyServers: boolean;\n\t// A caching map for: fullId:object_id -> partial key.\n\t#cachedKeys = new Map<KeyCacheKey, G1Element>();\n\t#cachedPublicKeys = new Map<string, G2Element>();\n\t#timeout: number;\n\t#totalWeight: number;\n\n\tconstructor(options: SealClientOptions) {\n\t\tthis.#haneulClient = options.haneulClient;\n\n\t\tif (\n\t\t\tnew Set(options.serverConfigs.map((s) => s.objectId)).size !== options.serverConfigs.length\n\t\t) {\n\t\t\tthrow new InvalidClientOptionsError('Duplicate object IDs');\n\t\t}\n\n\t\tif (\n\t\t\toptions.serverConfigs.some((s) => (s.apiKeyName && !s.apiKey) || (!s.apiKeyName && s.apiKey))\n\t\t) {\n\t\t\tthrow new InvalidClientOptionsError(\n\t\t\t\t'Both apiKeyName and apiKey must be provided or not provided for all key servers',\n\t\t\t);\n\t\t}\n\n\t\tthis.#configs = new Map(options.serverConfigs.map((server) => [server.objectId, server]));\n\t\tthis.#totalWeight = options.serverConfigs\n\t\t\t.map((server) => server.weight)\n\t\t\t.reduce((sum, term) => sum + term, 0);\n\n\t\tthis.#verifyKeyServers = options.verifyKeyServers ?? true;\n\t\tthis.#timeout = options.timeout ?? 10_000;\n\t}\n\n\t/**\n\t * Return an encrypted message under the identity.\n\t *\n\t * @param kemType - The type of KEM to use.\n\t * @param demType - The type of DEM to use.\n\t * @param threshold - The threshold for the TSS encryption.\n\t * @param packageId - the packageId namespace.\n\t * @param id - the identity to use.\n\t * @param data - the data to encrypt.\n\t * @param aad - optional additional authenticated data.\n\t * @returns The bcs bytes of the encrypted object containing all metadata and the 256-bit symmetric key that was used to encrypt the object.\n\t * \tSince the symmetric key can be used to decrypt, it should not be shared but can be used e.g. for backup.\n\t */\n\tasync encrypt({\n\t\tkemType = KemType.BonehFranklinBLS12381DemCCA,\n\t\tdemType = DemType.AesGcm256,\n\t\tthreshold,\n\t\tpackageId,\n\t\tid,\n\t\tdata,\n\t\taad = new Uint8Array(),\n\t}: EncryptOptions) {\n\t\tconst packageObj = await this.#haneulClient.core.getObject({ objectId: packageId });\n\t\tif (String(packageObj.object.version) !== '1') {\n\t\t\tthrow new InvalidPackageError(`Package ${packageId} is not the first version`);\n\t\t}\n\n\t\treturn encrypt({\n\t\t\tkeyServers: await this.#getWeightedKeyServers(),\n\t\t\tkemType,\n\t\t\tthreshold,\n\t\t\tpackageId,\n\t\t\tid,\n\t\t\tencryptionInput: this.#createEncryptionInput(\n\t\t\t\tdemType,\n\t\t\t\tdata as Uint8Array<ArrayBuffer>,\n\t\t\t\taad as Uint8Array<ArrayBuffer>,\n\t\t\t),\n\t\t});\n\t}\n\n\t#createEncryptionInput(\n\t\ttype: DemType,\n\t\tdata: Uint8Array<ArrayBuffer>,\n\t\taad: Uint8Array<ArrayBuffer>,\n\t): EncryptionInput {\n\t\tswitch (type) {\n\t\t\tcase DemType.AesGcm256:\n\t\t\t\treturn new AesGcm256(data, aad);\n\t\t\tcase DemType.Hmac256Ctr:\n\t\t\t\treturn new Hmac256Ctr(data, aad);\n\t\t}\n\t}\n\n\t/**\n\t * Decrypt the given encrypted bytes using cached keys.\n\t * Calls fetchKeys in case one or more of the required keys is not cached yet.\n\t * The function throws an error if the client's key servers are not a subset of\n\t * the encrypted object's key servers or if the threshold cannot be met.\n\t *\n\t * If checkShareConsistency is true, the decrypted shares are checked for consistency, meaning that\n\t * any combination of at least threshold shares should either succesfully combine to the plaintext or fail.\n\t * This is useful in case the encryptor is not trusted and the decryptor wants to ensure all decryptors\n\t * receive the same output (e.g., for onchain encrypted voting).\n\t *\n\t * @param data - The encrypted bytes to decrypt.\n\t * @param sessionKey - The session key to use.\n\t * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).\n\t * @param checkShareConsistency - If true, the shares are checked for consistency.\n\t * @param checkLEEncoding - If true, the encryption is also checked using an LE encoded nonce.\n\t * @returns - The decrypted plaintext corresponding to ciphertext.\n\t */\n\tasync decrypt({\n\t\tdata,\n\t\tsessionKey,\n\t\ttxBytes,\n\t\tcheckShareConsistency,\n\t\tcheckLEEncoding,\n\t}: DecryptOptions) {\n\t\tconst encryptedObject = EncryptedObject.parse(data);\n\n\t\tthis.#validateEncryptionServices(\n\t\t\tencryptedObject.services.map((s) => s[0]),\n\t\t\tencryptedObject.threshold,\n\t\t);\n\n\t\tawait this.fetchKeys({\n\t\t\tids: [encryptedObject.id],\n\t\t\ttxBytes,\n\t\t\tsessionKey,\n\t\t\tthreshold: encryptedObject.threshold,\n\t\t});\n\n\t\tif (checkShareConsistency) {\n\t\t\tconst publicKeys = await this.getPublicKeys(\n\t\t\t\tencryptedObject.services.map(([objectId, _]) => objectId),\n\t\t\t);\n\t\t\treturn decrypt({\n\t\t\t\tencryptedObject,\n\t\t\t\tkeys: this.#cachedKeys,\n\t\t\t\tpublicKeys,\n\t\t\t\tcheckLEEncoding: false, // We intentionally do not support other encodings here\n\t\t\t});\n\t\t}\n\t\treturn decrypt({ encryptedObject, keys: this.#cachedKeys, checkLEEncoding });\n\t}\n\n\t#weight(objectId: string) {\n\t\treturn this.#configs.get(objectId)?.weight ?? 0;\n\t}\n\n\t#validateEncryptionServices(services: string[], threshold: number) {\n\t\t// Check that the client's key servers are a subset of the encrypted object's key servers.\n\t\tif (\n\t\t\tservices.some((objectId) => {\n\t\t\t\tconst countInClient = this.#weight(objectId);\n\t\t\t\treturn countInClient > 0 && countInClient !== count(services, objectId);\n\t\t\t})\n\t\t) {\n\t\t\tthrow new InconsistentKeyServersError(\n\t\t\t\t`Client's key servers must be a subset of the encrypted object's key servers`,\n\t\t\t);\n\t\t}\n\t\t// Check that the threshold can be met with the client's key servers.\n\t\tif (threshold > this.#totalWeight) {\n\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t`Invalid threshold ${threshold} for ${this.#totalWeight} servers`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync getKeyServers(): Promise<Map<string, KeyServer>> {\n\t\tif (!this.#keyServers) {\n\t\t\tthis.#keyServers = this.#loadKeyServers().catch((error) => {\n\t\t\t\tthis.#keyServers = null;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\t}\n\t\treturn this.#keyServers;\n\t}\n\n\t/**\n\t * Get the public keys for the given services.\n\t * If all public keys are not in the cache, they are retrieved.\n\t *\n\t * @param services - The services to get the public keys for.\n\t * @returns The public keys for the given services in the same order as the given services.\n\t */\n\tasync getPublicKeys(services: string[]): Promise<G2Element[]> {\n\t\tconst keyServers = await this.getKeyServers();\n\n\t\t// Collect the key servers not already in store or cache.\n\t\tconst missingKeyServers = services.filter(\n\t\t\t(objectId) => !keyServers.has(objectId) && !this.#cachedPublicKeys.has(objectId),\n\t\t);\n\n\t\t// If there are missing key servers, retrieve them and update the cache.\n\t\tif (missingKeyServers.length > 0) {\n\t\t\t(\n\t\t\t\tawait retrieveKeyServers({\n\t\t\t\t\tobjectIds: missingKeyServers,\n\t\t\t\t\tclient: this.#haneulClient,\n\t\t\t\t\tconfigs: this.#configs,\n\t\t\t\t})\n\t\t\t).forEach((keyServer) =>\n\t\t\t\tthis.#cachedPublicKeys.set(keyServer.objectId, G2Element.fromBytes(keyServer.pk)),\n\t\t\t);\n\t\t}\n\n\t\treturn services.map((objectId) => {\n\t\t\tconst keyServer = keyServers.get(objectId);\n\t\t\tif (keyServer) {\n\t\t\t\treturn G2Element.fromBytes(keyServer.pk);\n\t\t\t}\n\t\t\treturn this.#cachedPublicKeys.get(objectId)!;\n\t\t});\n\t}\n\n\t/**\n\t * Returns a list of key servers with multiplicity according to their weights.\n\t * The list is used for encryption.\n\t */\n\tasync #getWeightedKeyServers() {\n\t\tconst keyServers = await this.getKeyServers();\n\t\tconst keyServersWithMultiplicity = [];\n\t\tfor (const [objectId, config] of this.#configs) {\n\t\t\tconst keyServer = keyServers.get(objectId)!;\n\t\t\tfor (let i = 0; i < config.weight; i++) {\n\t\t\t\tkeyServersWithMultiplicity.push(keyServer);\n\t\t\t}\n\t\t}\n\t\treturn keyServersWithMultiplicity;\n\t}\n\n\tasync #loadKeyServers(): Promise<Map<string, KeyServer>> {\n\t\tconst keyServers = await retrieveKeyServers({\n\t\t\tobjectIds: [...this.#configs.keys()],\n\t\t\tclient: this.#haneulClient,\n\t\t\tconfigs: this.#configs,\n\t\t});\n\n\t\tif (keyServers.length === 0) {\n\t\t\tthrow new InvalidKeyServerError('No key servers found');\n\t\t}\n\n\t\tif (this.#verifyKeyServers) {\n\t\t\tawait Promise.all(\n\t\t\t\tkeyServers.map(async (server) => {\n\t\t\t\t\t// Skip /service verification for committee key server type since the request goes through an aggregator.\n\t\t\t\t\tif (server.serverType === 'Committee') {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst config = this.#configs.get(server.objectId);\n\t\t\t\t\tif (!(await verifyKeyServer(server, this.#timeout, config?.apiKeyName, config?.apiKey))) {\n\t\t\t\t\t\tthrow new InvalidKeyServerError(`Key server ${server.objectId} is not valid`);\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn new Map(keyServers.map((server) => [server.objectId, server]));\n\t}\n\n\t/**\n\t * Fetch keys from the key servers and update the cache.\n\t *\n\t * It is recommended to call this function once for all ids of all encrypted objects if\n\t * there are multiple, then call decrypt for each object. This avoids calling fetchKey\n\t * individually for each decrypt.\n\t *\n\t * @param ids - The ids of the encrypted objects.\n\t * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).\n\t * @param sessionKey - The session key to use.\n\t * @param threshold - The threshold for the TSS encryptions. The function returns when a threshold of key servers had returned keys for all ids.\n\t */\n\tasync fetchKeys({ ids, txBytes, sessionKey, threshold }: FetchKeysOptions) {\n\t\tif (threshold > this.#totalWeight || threshold < 1) {\n\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t`Invalid threshold ${threshold} servers with weights ${JSON.stringify(this.#configs)}`,\n\t\t\t);\n\t\t}\n\t\tconst keyServers = await this.getKeyServers();\n\t\tconst fullIds = ids.map((id) => createFullId(sessionKey.getPackageId(), id));\n\n\t\t// Count a server as completed if it has keys for all fullIds.\n\t\t// Duplicated key server ids will be counted towards the threshold.\n\t\tlet completedWeight = 0;\n\t\tconst remainingKeyServers = [];\n\t\tlet remainingKeyServersWeight = 0;\n\t\tfor (const objectId of keyServers.keys()) {\n\t\t\tif (fullIds.every((fullId) => this.#cachedKeys.has(`${fullId}:${objectId}`))) {\n\t\t\t\tcompletedWeight += this.#weight(objectId);\n\t\t\t} else {\n\t\t\t\tremainingKeyServers.push(objectId);\n\t\t\t\tremainingKeyServersWeight += this.#weight(objectId);\n\t\t\t}\n\t\t}\n\n\t\t// Return early if we have enough keys from cache.\n\t\tif (completedWeight >= threshold) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst certificate = await sessionKey.getCertificate();\n\t\tconst signedRequest = await sessionKey.createRequestParams(txBytes);\n\n\t\tconst controller = new AbortController();\n\t\tconst errors: Error[] = [];\n\n\t\tconst keyFetches = remainingKeyServers.map(async (objectId) => {\n\t\t\tconst server = keyServers.get(objectId)!;\n\t\t\ttry {\n\t\t\t\tconst config = this.#configs.get(objectId);\n\t\t\t\tconst allKeys = await fetchKeysForAllIds({\n\t\t\t\t\turl: server.url,\n\t\t\t\t\trequestSignature: signedRequest.requestSignature,\n\t\t\t\t\ttransactionBytes: txBytes,\n\t\t\t\t\tencKey: signedRequest.encKey,\n\t\t\t\t\tencKeyPk: signedRequest.encKeyPk,\n\t\t\t\t\tencVerificationKey: signedRequest.encVerificationKey,\n\t\t\t\t\tcertificate,\n\t\t\t\t\ttimeout: this.#timeout,\n\t\t\t\t\tapiKeyName: config?.apiKeyName,\n\t\t\t\t\tapiKey: config?.apiKey,\n\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t});\n\t\t\t\t// Check validity of the keys and add them to the cache.\n\t\t\t\tfor (const { fullId, key } of allKeys) {\n\t\t\t\t\tconst keyElement = G1Element.fromBytes(key);\n\t\t\t\t\tif (\n\t\t\t\t\t\t!BonehFranklinBLS12381Services.verifyUserSecretKey(\n\t\t\t\t\t\t\tkeyElement,\n\t\t\t\t\t\t\tfullId,\n\t\t\t\t\t\t\tG2Element.fromBytes(server.pk),\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tconsole.warn('Received invalid key from key server ' + server.objectId);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tthis.#cachedKeys.set(`${fullId}:${server.objectId}`, keyElement);\n\t\t\t\t}\n\n\t\t\t\t// Check if all the receivedIds are consistent with the requested fullIds.\n\t\t\t\t// If so, consider the key server got all keys and mark as completed.\n\t\t\t\tif (fullIds.every((fullId) => this.#cachedKeys.has(`${fullId}:${server.objectId}`))) {\n\t\t\t\t\tcompletedWeight += this.#weight(objectId);\n\n\t\t\t\t\t// Return early if the completed servers is more than the threshold.\n\t\t\t\t\tif (completedWeight >= threshold) {\n\t\t\t\t\t\tcontroller.abort();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (!controller.signal.aborted) {\n\t\t\t\t\terrors.push(error as Error);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\t// If there are too many errors that the threshold is not attainable, return early with error.\n\t\t\t\tremainingKeyServersWeight -= this.#weight(objectId);\n\t\t\t\tif (remainingKeyServersWeight < threshold - completedWeight) {\n\t\t\t\t\tcontroller.abort(new TooManyFailedFetchKeyRequestsError());\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tawait Promise.allSettled(keyFetches);\n\n\t\tif (completedWeight < threshold) {\n\t\t\tthrow toMajorityError(errors);\n\t\t}\n\t}\n\n\t/**\n\t * Get derived keys from the given services.\n\t *\n\t * @param id - The id of the encrypted object.\n\t * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).\n\t * @param sessionKey - The session key to use.\n\t * @param threshold - The threshold.\n\t * @returns - Derived keys for the given services that are in the cache as a \"service object ID\" -> derived key map. If the call is succesful, exactly threshold keys will be returned.\n\t */\n\tasync getDerivedKeys({\n\t\tkemType = KemType.BonehFranklinBLS12381DemCCA,\n\t\tid,\n\t\ttxBytes,\n\t\tsessionKey,\n\t\tthreshold,\n\t}: GetDerivedKeysOptions): Promise<Map<string, DerivedKey>> {\n\t\tswitch (kemType) {\n\t\t\tcase KemType.BonehFranklinBLS12381DemCCA:\n\t\t\t\tconst keyServers = await this.getKeyServers();\n\t\t\t\tif (threshold > this.#totalWeight) {\n\t\t\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t\t\t`Invalid threshold ${threshold} for ${this.#totalWeight} servers`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tawait this.fetchKeys({\n\t\t\t\t\tids: [id],\n\t\t\t\t\ttxBytes,\n\t\t\t\t\tsessionKey,\n\t\t\t\t\tthreshold,\n\t\t\t\t});\n\n\t\t\t\t// After calling fetchKeys, we can be sure that there are at least `threshold` of the required keys in the cache.\n\t\t\t\t// It is also checked there that the KeyServerType is BonehFranklinBLS12381 for all services.\n\n\t\t\t\tconst fullId = createFullId(sessionKey.getPackageId(), id);\n\n\t\t\t\tconst derivedKeys = new Map();\n\t\t\t\tlet weight = 0;\n\t\t\t\tfor (const objectId of keyServers.keys()) {\n\t\t\t\t\t// The code below assumes that the KeyServerType is BonehFranklinBLS12381.\n\t\t\t\t\tconst cachedKey = this.#cachedKeys.get(`${fullId}:${objectId}`);\n\t\t\t\t\tif (cachedKey) {\n\t\t\t\t\t\tderivedKeys.set(objectId, new BonehFranklinBLS12381DerivedKey(cachedKey));\n\t\t\t\t\t\tweight += this.#weight(objectId);\n\t\t\t\t\t\tif (weight >= threshold) {\n\t\t\t\t\t\t\t// We have enough keys, so we can stop.\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn derivedKeys;\n\t\t}\n\t}\n}\n"],"mappings":"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"}
@@ -2,13 +2,12 @@ import "./dem.mjs";
2
2
  import "./key-server.mjs";
3
3
 
4
4
  //#region src/encrypt.d.ts
5
-
6
5
  declare enum KemType {
7
- BonehFranklinBLS12381DemCCA = 0,
6
+ BonehFranklinBLS12381DemCCA = 0
8
7
  }
9
8
  declare enum DemType {
10
9
  AesGcm256 = 0,
11
- Hmac256Ctr = 1,
10
+ Hmac256Ctr = 1
12
11
  }
13
12
  //#endregion
14
13
  export { DemType, KemType };
@@ -1 +1 @@
1
- {"version":3,"file":"encrypt.d.mts","names":[],"sources":["../src/encrypt.ts"],"sourcesContent":[],"mappings":";;;;;aAyGY,OAAA;;;aAIA,OAAA"}
1
+ {"version":3,"file":"encrypt.d.mts","names":[],"sources":["../src/encrypt.ts"],"mappings":";;;;aAyGY,OAAA;EACX,2BAAA;AAAA;AAAA,aAGW,OAAA;EACX,SAAA;EACA,UAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.mts","names":[],"sources":["../src/error.ts"],"sourcesContent":[],"mappings":";cAGa,SAAA,SAAkB,KAAA;AAElB,cAAA,SAAA,SAAkB,SAAA,CAAS;AA+CD,cA5C1B,YAAA,SAAqB,SAAA,CA4CK;EAA2B,CAAA,OAAA;EA5ChC,SAAA,CAAA,EAAA,MAAA,GAAA,SAAA;EAAS,MAAA,CAAA,EAAA,MAAA,GAAA,SAAA;EAiE9B,WAAA,CAAA,OAAgB,EAAA,MAAA,EAAA,SAAoB,CAAZ,EAAA,MAAY,GAAA,SAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,SAAA;EAMpC,OAAA,cAAA,CAAoB,QAAA,EA3BM,QA2BE,EAAA,SAAY,EAAA,MAAA,CAAA,EA3Ba,OA2Bb,CAAA,IAAA,CAAA;AAMrD;AAWa,cAvBA,eAAA,SAAwB,YAAA,CAuBsB;EAM9C,WAAA,CAAA,SAAA,CAAA,EAAA,MAAA,EAAA,OAAwC,CAAR,EAAA,MAAQ;AAMrD;AAOa,cApCA,mBAAA,SAA4B,YAAA,CAoCsB;EAOlD,WAAA,CAAA,SAA0B,CAA1B,EAAA,MAA0B;AAQvC;AAMa,cAnDA,qBAAA,SAA8B,YAAA,CAmDU;EAMxC,WAAA,CAAA,SAA0B,CAA1B,EAAA,MAA0B;AAOvC;AAOa,cA5DA,yBAAA,SAAkC,YAAA,CA4DS;EAO3C,WAAA,CAAA,SAAsB,CAAR,EAAA,MAAQ;AAOnC;AAGa,cAvEA,+BAAA,SAAwC,YAAA,CAuEc;EACtD,WAAA,CAAA,SAAsB,CAAtB,EAAsB,MAAA;AACnC;AACa,cApEA,mBAAA,SAA4B,YAAA,CAoEa;EACzC,WAAA,CAAA,SAAsB,CAAtB,EAAsB,MAAA;AACnC;AACA;AACa,cAjEA,6BAAA,SAAsC,YAAA,CAiEC;EACvC,WAAA,CAAA,SAA4B,CAA5B,EAAA,MAA4B;AACzC;AACA;AACa,cA9DA,yBAAA,SAAkC,YAAA,CA8DkB;EAEjD,WAAA,CAAA,SAAwB,CAAT,EAAA,MAAS;;cAxD3B,sBAAA,SAA+B,YAAA;;;cAM/B,mBAAA,SAA4B,YAAA;;;cAM5B,yBAAA,SAAkC,YAAA;;;;cAOlC,aAAA,SAAsB,YAAA;;;;cAOtB,sBAAA,SAA+B,YAAA;;;;cAO/B,aAAA,SAAsB,YAAA;;;;cAOtB,YAAA,SAAqB,YAAA;cAGrB,oCAAA,SAA6C,SAAA;cAC7C,qBAAA,SAA8B,SAAA;cAC9B,uBAAA,SAAgC,SAAA;cAChC,uBAAA,SAAgC,SAAA;cAChC,qBAAA,SAA8B,SAAA;cAC9B,4BAAA,SAAqC,SAAA;cACrC,sBAAA,SAA+B,SAAA;cAC/B,qBAAA,SAA8B,SAAA;cAC9B,2BAAA,SAAoC,SAAA;cACpC,eAAA,SAAwB,SAAA;cACxB,yBAAA,SAAkC,SAAA;cAClC,kCAAA,SAA2C,SAAA;iBAExC,eAAA,SAAwB,UAAU"}
1
+ {"version":3,"file":"error.d.mts","names":[],"sources":["../src/error.ts"],"mappings":";cAGa,SAAA,SAAkB,KAAA;AAAA,cAElB,SAAA,SAAkB,SAAA;AAAA,cAGlB,YAAA,SAAqB,SAAA;EAAA;EAGzB,SAAA;EACA,MAAA;cAFP,OAAA,UACO,SAAA,uBACA,MAAA;EAAA,OAwCK,cAAA,CAAe,QAAA,EAAU,QAAA,EAAU,SAAA,WAAiB,OAAA;AAAA;AAAA,cAqBrD,eAAA,SAAwB,YAAA;cACxB,SAAA,WAAoB,OAAA;AAAA;AAAA,cAKpB,mBAAA,SAA4B,YAAA;cAC5B,SAAA;AAAA;AAAA,cAKA,qBAAA,SAA8B,YAAA;cAC9B,SAAA;AAAA;AAAA,cAUA,yBAAA,SAAkC,YAAA;cAClC,SAAA;AAAA;AAAA,cAKA,+BAAA,SAAwC,YAAA;cACxC,SAAA;AAAA;AAAA,cAKA,mBAAA,SAA4B,YAAA;cAC5B,SAAA;AAAA;;cAMA,6BAAA,SAAsC,YAAA;cACtC,SAAA;AAAA;;cAMA,yBAAA,SAAkC,YAAA;cAClC,SAAA;AAAA;AAAA,cAOA,sBAAA,SAA+B,YAAA;cAC/B,SAAA;AAAA;AAAA,cAKA,mBAAA,SAA4B,YAAA;cAC5B,SAAA;AAAA;AAAA,cAKA,yBAAA,SAAkC,YAAA;cAClC,SAAA;AAAA;;cAMA,aAAA,SAAsB,YAAA;cACtB,SAAA;AAAA;;cAMA,sBAAA,SAA+B,YAAA;cAC/B,SAAA;AAAA;;cAMA,aAAA,SAAsB,YAAA;cACtB,SAAA;AAAA;;cAMA,YAAA,SAAqB,YAAA;AAAA,cAGrB,oCAAA,SAA6C,SAAA;AAAA,cAC7C,qBAAA,SAA8B,SAAA;AAAA,cAC9B,uBAAA,SAAgC,SAAA;AAAA,cAChC,uBAAA,SAAgC,SAAA;AAAA,cAChC,qBAAA,SAA8B,SAAA;AAAA,cAC9B,4BAAA,SAAqC,SAAA;AAAA,cACrC,sBAAA,SAA+B,SAAA;AAAA,cAC/B,qBAAA,SAA8B,SAAA;AAAA,cAC9B,2BAAA,SAAoC,SAAA;AAAA,cACpC,eAAA,SAAwB,SAAA;AAAA,cACxB,yBAAA,SAAkC,SAAA;AAAA,cAClC,kCAAA,SAA2C,SAAA;AAAA,iBAExC,eAAA,CAAgB,MAAA,EAAQ,KAAA,KAAU,KAAA"}
@@ -12,7 +12,7 @@ type KeyServer = {
12
12
  serverType: ServerType;
13
13
  };
14
14
  declare enum KeyType {
15
- BonehFranklinBLS12381 = 0,
15
+ BonehFranklinBLS12381 = 0
16
16
  }
17
17
  interface DerivedKey {
18
18
  toString(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"key-server.d.mts","names":[],"sources":["../src/key-server.ts"],"sourcesContent":[],"mappings":";;;;AAsBY,KAAA,UAAA,GAAU,aAAA,GAAA,WAAA;AAEV,KAAA,SAAA,GAAS;EAIX,QAAA,EAAA,MAAA;EACM,IAAA,EAAA,MAAA;EAAX,GAAA,EAAA,MAAA;EACQ,OAAA,EAFH,OAEG;EAAU,EAAA,EADlB,UACkB,CADP,WACO,CAAA;EAGX,UAAO,EAHN,UAGM;AAkMnB,CAAA;aAlMY,OAAA;;;UAkMK,UAAA"}
1
+ {"version":3,"file":"key-server.d.mts","names":[],"sources":["../src/key-server.ts"],"mappings":";;;;KAsBY,UAAA;AAAA,KAEA,SAAA;EACX,QAAA;EACA,IAAA;EACA,GAAA;EACA,OAAA,EAAS,OAAA;EACT,EAAA,EAAI,UAAA,CAAW,WAAA;EACf,UAAA,EAAY,UAAA;AAAA;AAAA,aAGD,OAAA;EACX,qBAAA;AAAA;AAAA,UAiMgB,UAAA;EAChB,QAAA;AAAA"}
@@ -3,7 +3,6 @@ import "@haneullabs/bcs";
3
3
  import { Signer } from "@haneullabs/haneul/cryptography";
4
4
 
5
5
  //#region src/session-key.d.ts
6
-
7
6
  type Certificate = {
8
7
  user: string;
9
8
  session_vk: string;
@@ -31,7 +30,7 @@ declare class SessionKey {
31
30
  * @param mvrName - Optional. The name of the MVR, if there is one.
32
31
  * @param ttlMin - The TTL in minutes.
33
32
  * @param signer - Optional. The signer instance, e.g. EnokiSigner.
34
- * @param suiClient - The Haneul client.
33
+ * @param haneulClient - The Haneul client.
35
34
  * @returns A new SessionKey instance.
36
35
  */
37
36
  static create({
@@ -40,14 +39,14 @@ declare class SessionKey {
40
39
  mvrName,
41
40
  ttlMin,
42
41
  signer,
43
- suiClient
42
+ haneulClient
44
43
  }: {
45
44
  address: string;
46
45
  packageId: string;
47
46
  mvrName?: string;
48
47
  ttlMin: number;
49
48
  signer?: Signer;
50
- suiClient: SealCompatibleClient;
49
+ haneulClient: SealCompatibleClient;
51
50
  }): Promise<SessionKey>;
52
51
  isExpired(): boolean;
53
52
  getAddress(): string;
@@ -76,7 +75,7 @@ declare class SessionKey {
76
75
  * Restore a SessionKey instance for the given object.
77
76
  * @returns A new SessionKey instance with restored state
78
77
  */
79
- static import(data: ExportedSessionKey, suiClient: SealCompatibleClient, signer?: Signer): SessionKey;
78
+ static import(data: ExportedSessionKey, haneulClient: SealCompatibleClient, signer?: Signer): SessionKey;
80
79
  }
81
80
  //#endregion
82
81
  export { ExportedSessionKey, SessionKey };
@@ -1 +1 @@
1
- {"version":3,"file":"session-key.d.mts","names":[],"sources":["../src/session-key.ts"],"sourcesContent":[],"mappings":";;;;;;AA2Ca,KAnBD,WAAA,GAmBW;EA4DrB,IAAA,EAAA,MAAA;EACA,UAAA,EAAA,MAAA;EACA,aAAA,EAAA,MAAA;EACA,OAAA,EAAA,MAAA;EACA,SAAA,EAAA,MAAA;EACA,QAAA,CAAA,EAAA,MAAA;CAMS;AACE,KAlFD,kBAAA,GAkFC;EACA,OAAA,EAAA,MAAA;EAAR,SAAA,EAAA,MAAA;EAmCkB,OAAA,CAAA,EAAA,MAAA;EAO4C,cAAA,EAAA,MAAA;EAclC,MAAA,EAAA,MAAA;EAAR,wBAAA,CAAA,EAAA,MAAA;EAyBW,UAAA,EAAA,MAAA;CACf;AAAX,cA3JG,UAAA,CA2JH;EACa,CAAA,OAAA;EAAX,QAAA,WAAA,CAAA;EACqB;;;;;;;;;;;;;;;;;;;;;;aAtFtB;eACE;MACR,QAAQ;;;;;wBAmCU;iEAO4C;oBAc1C,QAAQ;;;;;;;+BAyBG,aAAa;YACvC,WAAW;cACT,WAAW;wBACD,WAAW;;;;;;YA0BtB;;;;;sBAyBH,+BACK,+BACF,SACP"}
1
+ {"version":3,"file":"session-key.d.mts","names":[],"sources":["../src/session-key.ts"],"mappings":";;;;;KAwBY,WAAA;EACX,IAAA;EACA,UAAA;EACA,aAAA;EACA,OAAA;EACA,SAAA;EACA,QAAA;AAAA;AAAA,KAGW,kBAAA;EACX,OAAA;EACA,SAAA;EACA,OAAA;EACA,cAAA;EACA,MAAA;EACA,wBAAA;EACA,UAAA;AAAA;AAAA,cAGY,UAAA;EAAA;UAWL,WAAA,CAAA;EAdP;;;AAGD;;;;;;;EAHC,OA8Da,MAAA,CAAA;IACZ,OAAA;IACA,SAAA;IACA,OAAA;IACA,MAAA;IACA,MAAA;IACA;EAAA;IAEA,OAAA;IACA,SAAA;IACA,OAAA;IACA,MAAA;IACA,MAAA,GAAS,MAAA;IACT,YAAA,EAAc,oBAAA;EAAA,IACX,OAAA,CAAQ,UAAA;EAeZ,SAAA,CAAA;EAKA,UAAA,CAAA;EAIA,cAAA,CAAA;EAOA,YAAA,CAAA;EAIA,kBAAA,CAAA,GAAsB,UAAA;EAOhB,2BAAA,CAA4B,wBAAA,WAAgC,OAAA;EAc5D,cAAA,CAAA,GAAkB,OAAA,CAAQ,WAAA;EA4BA;;;;;;EAH1B,mBAAA,CAAoB,OAAA,EAAS,UAAA,GAAa,OAAA;IAC/C,MAAA,EAAQ,UAAA,CAAW,WAAA;IACnB,QAAA,EAAU,UAAA,CAAW,WAAA;IACrB,kBAAA,EAAoB,UAAA,CAAW,WAAA;IAC/B,gBAAA;EAAA;EAnGY;;;EA4Hb,MAAA,CAAA,GAAU,kBAAA;EA1HT;;;;EAAA,OAkJM,MAAA,CACN,IAAA,EAAM,kBAAA,EACN,YAAA,EAAc,oBAAA,EACd,MAAA,GAAS,MAAA,GACP,UAAA;AAAA"}
@@ -21,12 +21,12 @@ var SessionKey = class SessionKey {
21
21
  #sessionKey;
22
22
  #personalMessageSignature;
23
23
  #signer;
24
- #suiClient;
25
- constructor({ address, packageId, mvrName, ttlMin, signer, suiClient }) {
24
+ #haneulClient;
25
+ constructor({ address, packageId, mvrName, ttlMin, signer, haneulClient }) {
26
26
  if (mvrName && !isValidNamedPackage(mvrName)) throw new UserError(`Invalid package name ${mvrName}`);
27
27
  if (!isValidHaneulObjectId(packageId) || !isValidHaneulAddress(address)) throw new UserError(`Invalid package ID ${packageId} or address ${address}`);
28
28
  if (ttlMin > 30 || ttlMin < 1) throw new UserError(`Invalid TTL ${ttlMin}, must be between 1 and 30`);
29
- if (signer && signer.getPublicKey().toSuiAddress() !== address) throw new UserError("Signer address does not match session key address");
29
+ if (signer && signer.getPublicKey().toHaneulAddress() !== address) throw new UserError("Signer address does not match session key address");
30
30
  this.#address = address;
31
31
  this.#packageId = packageId;
32
32
  this.#mvrName = mvrName;
@@ -34,7 +34,7 @@ var SessionKey = class SessionKey {
34
34
  this.#ttlMin = ttlMin;
35
35
  this.#sessionKey = Ed25519Keypair.generate();
36
36
  this.#signer = signer;
37
- this.#suiClient = suiClient;
37
+ this.#haneulClient = haneulClient;
38
38
  }
39
39
  /**
40
40
  * Create a new SessionKey instance.
@@ -43,11 +43,11 @@ var SessionKey = class SessionKey {
43
43
  * @param mvrName - Optional. The name of the MVR, if there is one.
44
44
  * @param ttlMin - The TTL in minutes.
45
45
  * @param signer - Optional. The signer instance, e.g. EnokiSigner.
46
- * @param suiClient - The Haneul client.
46
+ * @param haneulClient - The Haneul client.
47
47
  * @returns A new SessionKey instance.
48
48
  */
49
- static async create({ address, packageId, mvrName, ttlMin, signer, suiClient }) {
50
- const packageObj = await suiClient.core.getObject({ objectId: packageId });
49
+ static async create({ address, packageId, mvrName, ttlMin, signer, haneulClient }) {
50
+ const packageObj = await haneulClient.core.getObject({ objectId: packageId });
51
51
  if (String(packageObj.object.version) !== "1") throw new InvalidPackageError(`Package ${packageId} is not the first version`);
52
52
  return new SessionKey({
53
53
  address,
@@ -55,7 +55,7 @@ var SessionKey = class SessionKey {
55
55
  mvrName,
56
56
  ttlMin,
57
57
  signer,
58
- suiClient
58
+ haneulClient
59
59
  });
60
60
  }
61
61
  isExpired() {
@@ -80,7 +80,7 @@ var SessionKey = class SessionKey {
80
80
  if (!this.#personalMessageSignature) try {
81
81
  await verifyPersonalMessageSignature(this.getPersonalMessage(), personalMessageSignature, {
82
82
  address: this.#address,
83
- client: this.#suiClient
83
+ client: this.#haneulClient
84
84
  });
85
85
  this.#personalMessageSignature = personalMessageSignature;
86
86
  } catch {
@@ -149,14 +149,14 @@ var SessionKey = class SessionKey {
149
149
  * Restore a SessionKey instance for the given object.
150
150
  * @returns A new SessionKey instance with restored state
151
151
  */
152
- static import(data, suiClient, signer) {
152
+ static import(data, haneulClient, signer) {
153
153
  const instance = new SessionKey({
154
154
  address: data.address,
155
155
  packageId: data.packageId,
156
156
  mvrName: data.mvrName,
157
157
  ttlMin: data.ttlMin,
158
158
  signer,
159
- suiClient
159
+ haneulClient
160
160
  });
161
161
  instance.#creationTimeMs = data.creationTimeMs;
162
162
  instance.#sessionKey = Ed25519Keypair.fromSecretKey(data.sessionKey);
@@ -1 +1 @@
1
- {"version":3,"file":"session-key.mjs","names":["bcs","#address","#packageId","#mvrName","#creationTimeMs","#ttlMin","#sessionKey","#signer","#suiClient","#personalMessageSignature"],"sources":["../src/session-key.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { toBase64 } from '@haneullabs/bcs';\nimport { bcs } from '@haneullabs/haneul/bcs';\nimport type { Signer } from '@haneullabs/haneul/cryptography';\nimport { Ed25519Keypair } from '@haneullabs/haneul/keypairs/ed25519';\nimport { isValidNamedPackage, isValidHaneulAddress, isValidHaneulObjectId } from '@haneullabs/haneul/utils';\nimport { verifyPersonalMessageSignature } from '@haneullabs/haneul/verify';\nimport { generateSecretKey, toPublicKey, toVerificationKey } from './elgamal.js';\nimport {\n\tExpiredSessionKeyError,\n\tInvalidPackageError,\n\tInvalidPersonalMessageSignatureError,\n\tUserError,\n} from './error.js';\nimport type { SealCompatibleClient } from './types.js';\n\nexport const RequestFormat = bcs.struct('RequestFormat', {\n\tptb: bcs.byteVector(),\n\tencKey: bcs.byteVector(),\n\tencVerificationKey: bcs.byteVector(),\n});\n\nexport type Certificate = {\n\tuser: string;\n\tsession_vk: string;\n\tcreation_time: number;\n\tttl_min: number;\n\tsignature: string;\n\tmvr_name?: string;\n};\n\nexport type ExportedSessionKey = {\n\taddress: string;\n\tpackageId: string;\n\tmvrName?: string;\n\tcreationTimeMs: number;\n\tttlMin: number;\n\tpersonalMessageSignature?: string;\n\tsessionKey: string;\n};\n\nexport class SessionKey {\n\t#address: string;\n\t#packageId: string;\n\t#mvrName?: string;\n\t#creationTimeMs: number;\n\t#ttlMin: number;\n\t#sessionKey: Ed25519Keypair;\n\t#personalMessageSignature?: string;\n\t#signer?: Signer;\n\t#suiClient: SealCompatibleClient;\n\n\tprivate constructor({\n\t\taddress,\n\t\tpackageId,\n\t\tmvrName,\n\t\tttlMin,\n\t\tsigner,\n\t\tsuiClient,\n\t}: {\n\t\taddress: string;\n\t\tpackageId: string;\n\t\tmvrName?: string;\n\t\tttlMin: number;\n\t\tsigner?: Signer;\n\t\tsuiClient: SealCompatibleClient;\n\t}) {\n\t\tif (mvrName && !isValidNamedPackage(mvrName)) {\n\t\t\tthrow new UserError(`Invalid package name ${mvrName}`);\n\t\t}\n\t\tif (!isValidHaneulObjectId(packageId) || !isValidHaneulAddress(address)) {\n\t\t\tthrow new UserError(`Invalid package ID ${packageId} or address ${address}`);\n\t\t}\n\t\tif (ttlMin > 30 || ttlMin < 1) {\n\t\t\tthrow new UserError(`Invalid TTL ${ttlMin}, must be between 1 and 30`);\n\t\t}\n\t\tif (signer && signer.getPublicKey().toSuiAddress() !== address) {\n\t\t\tthrow new UserError('Signer address does not match session key address');\n\t\t}\n\n\t\tthis.#address = address;\n\t\tthis.#packageId = packageId;\n\t\tthis.#mvrName = mvrName;\n\t\tthis.#creationTimeMs = Date.now();\n\t\tthis.#ttlMin = ttlMin;\n\t\tthis.#sessionKey = Ed25519Keypair.generate();\n\t\tthis.#signer = signer;\n\t\tthis.#suiClient = suiClient;\n\t}\n\n\t/**\n\t * Create a new SessionKey instance.\n\t * @param address - The address of the user.\n\t * @param packageId - The ID of the package.\n\t * @param mvrName - Optional. The name of the MVR, if there is one.\n\t * @param ttlMin - The TTL in minutes.\n\t * @param signer - Optional. The signer instance, e.g. EnokiSigner.\n\t * @param suiClient - The Haneul client.\n\t * @returns A new SessionKey instance.\n\t */\n\tstatic async create({\n\t\taddress,\n\t\tpackageId,\n\t\tmvrName,\n\t\tttlMin,\n\t\tsigner,\n\t\tsuiClient,\n\t}: {\n\t\taddress: string;\n\t\tpackageId: string;\n\t\tmvrName?: string;\n\t\tttlMin: number;\n\t\tsigner?: Signer;\n\t\tsuiClient: SealCompatibleClient;\n\t}): Promise<SessionKey> {\n\t\tconst packageObj = await suiClient.core.getObject({ objectId: packageId });\n\t\tif (String(packageObj.object.version) !== '1') {\n\t\t\tthrow new InvalidPackageError(`Package ${packageId} is not the first version`);\n\t\t}\n\n\t\treturn new SessionKey({\n\t\t\taddress,\n\t\t\tpackageId,\n\t\t\tmvrName,\n\t\t\tttlMin,\n\t\t\tsigner,\n\t\t\tsuiClient,\n\t\t});\n\t}\n\tisExpired(): boolean {\n\t\t// Allow 10 seconds for clock skew\n\t\treturn this.#creationTimeMs + this.#ttlMin * 60 * 1000 - 10_000 < Date.now();\n\t}\n\n\tgetAddress(): string {\n\t\treturn this.#address;\n\t}\n\n\tgetPackageName(): string {\n\t\tif (this.#mvrName) {\n\t\t\treturn this.#mvrName;\n\t\t}\n\t\treturn this.#packageId;\n\t}\n\n\tgetPackageId(): string {\n\t\treturn this.#packageId;\n\t}\n\n\tgetPersonalMessage(): Uint8Array {\n\t\tconst creationTimeUtc =\n\t\t\tnew Date(this.#creationTimeMs).toISOString().slice(0, 19).replace('T', ' ') + ' UTC';\n\t\tconst message = `Accessing keys of package ${this.getPackageName()} for ${this.#ttlMin} mins from ${creationTimeUtc}, session key ${toBase64(this.#sessionKey.getPublicKey().toRawBytes())}`;\n\t\treturn new TextEncoder().encode(message);\n\t}\n\n\tasync setPersonalMessageSignature(personalMessageSignature: string) {\n\t\tif (!this.#personalMessageSignature) {\n\t\t\ttry {\n\t\t\t\tawait verifyPersonalMessageSignature(this.getPersonalMessage(), personalMessageSignature, {\n\t\t\t\t\taddress: this.#address,\n\t\t\t\t\tclient: this.#suiClient,\n\t\t\t\t});\n\t\t\t\tthis.#personalMessageSignature = personalMessageSignature;\n\t\t\t} catch {\n\t\t\t\tthrow new InvalidPersonalMessageSignatureError('Not valid');\n\t\t\t}\n\t\t}\n\t}\n\n\tasync getCertificate(): Promise<Certificate> {\n\t\tif (!this.#personalMessageSignature) {\n\t\t\tif (this.#signer) {\n\t\t\t\tconst { signature } = await this.#signer.signPersonalMessage(this.getPersonalMessage());\n\t\t\t\tthis.#personalMessageSignature = signature;\n\t\t\t} else {\n\t\t\t\tthrow new InvalidPersonalMessageSignatureError('Personal message signature is not set');\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tuser: this.#address,\n\t\t\tsession_vk: toBase64(this.#sessionKey.getPublicKey().toRawBytes()),\n\t\t\tcreation_time: this.#creationTimeMs,\n\t\t\tttl_min: this.#ttlMin,\n\t\t\tsignature: this.#personalMessageSignature,\n\t\t\tmvr_name: this.#mvrName,\n\t\t};\n\t}\n\n\t/**\n\t * Create request params for the given transaction bytes.\n\t * @param txBytes - The transaction bytes.\n\t * @returns The request params containing the ephemeral secret key,\n\t * its public key and its verification key.\n\t */\n\tasync createRequestParams(txBytes: Uint8Array): Promise<{\n\t\tencKey: Uint8Array<ArrayBuffer>;\n\t\tencKeyPk: Uint8Array<ArrayBuffer>;\n\t\tencVerificationKey: Uint8Array<ArrayBuffer>;\n\t\trequestSignature: string;\n\t}> {\n\t\tif (this.isExpired()) {\n\t\t\tthrow new ExpiredSessionKeyError();\n\t\t}\n\t\tconst encKey = generateSecretKey();\n\t\tconst encKeyPk = toPublicKey(encKey);\n\t\tconst encVerificationKey = toVerificationKey(encKey);\n\n\t\tconst msgToSign = RequestFormat.serialize({\n\t\t\tptb: txBytes.slice(1),\n\t\t\tencKey: encKeyPk,\n\t\t\tencVerificationKey,\n\t\t}).toBytes();\n\t\treturn {\n\t\t\tencKey,\n\t\t\tencKeyPk,\n\t\t\tencVerificationKey,\n\t\t\trequestSignature: toBase64(await this.#sessionKey.sign(msgToSign)),\n\t\t};\n\t}\n\n\t/**\n\t * Export the Session Key object from the instance. Store the object in IndexedDB to persist.\n\t */\n\texport(): ExportedSessionKey {\n\t\tconst obj = {\n\t\t\taddress: this.#address,\n\t\t\tpackageId: this.#packageId,\n\t\t\tmvrName: this.#mvrName,\n\t\t\tcreationTimeMs: this.#creationTimeMs,\n\t\t\tttlMin: this.#ttlMin,\n\t\t\tpersonalMessageSignature: this.#personalMessageSignature,\n\t\t\tsessionKey: this.#sessionKey.getSecretKey(), // bech32 encoded string\n\t\t};\n\n\t\tObject.defineProperty(obj, 'toJSON', {\n\t\t\tenumerable: false,\n\t\t\tvalue: () => {\n\t\t\t\tthrow new Error('This object is not serializable');\n\t\t\t},\n\t\t});\n\t\treturn obj;\n\t}\n\n\t/**\n\t * Restore a SessionKey instance for the given object.\n\t * @returns A new SessionKey instance with restored state\n\t */\n\tstatic import(\n\t\tdata: ExportedSessionKey,\n\t\tsuiClient: SealCompatibleClient,\n\t\tsigner?: Signer,\n\t): SessionKey {\n\t\tconst instance = new SessionKey({\n\t\t\taddress: data.address,\n\t\t\tpackageId: data.packageId,\n\t\t\tmvrName: data.mvrName,\n\t\t\tttlMin: data.ttlMin,\n\t\t\tsigner,\n\t\t\tsuiClient,\n\t\t});\n\n\t\tinstance.#creationTimeMs = data.creationTimeMs;\n\t\tinstance.#sessionKey = Ed25519Keypair.fromSecretKey(data.sessionKey);\n\t\tinstance.#personalMessageSignature = data.personalMessageSignature;\n\n\t\tif (instance.isExpired()) {\n\t\t\tthrow new ExpiredSessionKeyError();\n\t\t}\n\t\treturn instance;\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"session-key.mjs","names":["bcs","#address","#packageId","#mvrName","#creationTimeMs","#ttlMin","#sessionKey","#signer","#haneulClient","#personalMessageSignature"],"sources":["../src/session-key.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { toBase64 } from '@haneullabs/bcs';\nimport { bcs } from '@haneullabs/haneul/bcs';\nimport type { Signer } from '@haneullabs/haneul/cryptography';\nimport { Ed25519Keypair } from '@haneullabs/haneul/keypairs/ed25519';\nimport { isValidNamedPackage, isValidHaneulAddress, isValidHaneulObjectId } from '@haneullabs/haneul/utils';\nimport { verifyPersonalMessageSignature } from '@haneullabs/haneul/verify';\nimport { generateSecretKey, toPublicKey, toVerificationKey } from './elgamal.js';\nimport {\n\tExpiredSessionKeyError,\n\tInvalidPackageError,\n\tInvalidPersonalMessageSignatureError,\n\tUserError,\n} from './error.js';\nimport type { SealCompatibleClient } from './types.js';\n\nexport const RequestFormat = bcs.struct('RequestFormat', {\n\tptb: bcs.byteVector(),\n\tencKey: bcs.byteVector(),\n\tencVerificationKey: bcs.byteVector(),\n});\n\nexport type Certificate = {\n\tuser: string;\n\tsession_vk: string;\n\tcreation_time: number;\n\tttl_min: number;\n\tsignature: string;\n\tmvr_name?: string;\n};\n\nexport type ExportedSessionKey = {\n\taddress: string;\n\tpackageId: string;\n\tmvrName?: string;\n\tcreationTimeMs: number;\n\tttlMin: number;\n\tpersonalMessageSignature?: string;\n\tsessionKey: string;\n};\n\nexport class SessionKey {\n\t#address: string;\n\t#packageId: string;\n\t#mvrName?: string;\n\t#creationTimeMs: number;\n\t#ttlMin: number;\n\t#sessionKey: Ed25519Keypair;\n\t#personalMessageSignature?: string;\n\t#signer?: Signer;\n\t#haneulClient: SealCompatibleClient;\n\n\tprivate constructor({\n\t\taddress,\n\t\tpackageId,\n\t\tmvrName,\n\t\tttlMin,\n\t\tsigner,\n\t\thaneulClient,\n\t}: {\n\t\taddress: string;\n\t\tpackageId: string;\n\t\tmvrName?: string;\n\t\tttlMin: number;\n\t\tsigner?: Signer;\n\t\thaneulClient: SealCompatibleClient;\n\t}) {\n\t\tif (mvrName && !isValidNamedPackage(mvrName)) {\n\t\t\tthrow new UserError(`Invalid package name ${mvrName}`);\n\t\t}\n\t\tif (!isValidHaneulObjectId(packageId) || !isValidHaneulAddress(address)) {\n\t\t\tthrow new UserError(`Invalid package ID ${packageId} or address ${address}`);\n\t\t}\n\t\tif (ttlMin > 30 || ttlMin < 1) {\n\t\t\tthrow new UserError(`Invalid TTL ${ttlMin}, must be between 1 and 30`);\n\t\t}\n\t\tif (signer && signer.getPublicKey().toHaneulAddress() !== address) {\n\t\t\tthrow new UserError('Signer address does not match session key address');\n\t\t}\n\n\t\tthis.#address = address;\n\t\tthis.#packageId = packageId;\n\t\tthis.#mvrName = mvrName;\n\t\tthis.#creationTimeMs = Date.now();\n\t\tthis.#ttlMin = ttlMin;\n\t\tthis.#sessionKey = Ed25519Keypair.generate();\n\t\tthis.#signer = signer;\n\t\tthis.#haneulClient = haneulClient;\n\t}\n\n\t/**\n\t * Create a new SessionKey instance.\n\t * @param address - The address of the user.\n\t * @param packageId - The ID of the package.\n\t * @param mvrName - Optional. The name of the MVR, if there is one.\n\t * @param ttlMin - The TTL in minutes.\n\t * @param signer - Optional. The signer instance, e.g. EnokiSigner.\n\t * @param haneulClient - The Haneul client.\n\t * @returns A new SessionKey instance.\n\t */\n\tstatic async create({\n\t\taddress,\n\t\tpackageId,\n\t\tmvrName,\n\t\tttlMin,\n\t\tsigner,\n\t\thaneulClient,\n\t}: {\n\t\taddress: string;\n\t\tpackageId: string;\n\t\tmvrName?: string;\n\t\tttlMin: number;\n\t\tsigner?: Signer;\n\t\thaneulClient: SealCompatibleClient;\n\t}): Promise<SessionKey> {\n\t\tconst packageObj = await haneulClient.core.getObject({ objectId: packageId });\n\t\tif (String(packageObj.object.version) !== '1') {\n\t\t\tthrow new InvalidPackageError(`Package ${packageId} is not the first version`);\n\t\t}\n\n\t\treturn new SessionKey({\n\t\t\taddress,\n\t\t\tpackageId,\n\t\t\tmvrName,\n\t\t\tttlMin,\n\t\t\tsigner,\n\t\t\thaneulClient,\n\t\t});\n\t}\n\tisExpired(): boolean {\n\t\t// Allow 10 seconds for clock skew\n\t\treturn this.#creationTimeMs + this.#ttlMin * 60 * 1000 - 10_000 < Date.now();\n\t}\n\n\tgetAddress(): string {\n\t\treturn this.#address;\n\t}\n\n\tgetPackageName(): string {\n\t\tif (this.#mvrName) {\n\t\t\treturn this.#mvrName;\n\t\t}\n\t\treturn this.#packageId;\n\t}\n\n\tgetPackageId(): string {\n\t\treturn this.#packageId;\n\t}\n\n\tgetPersonalMessage(): Uint8Array {\n\t\tconst creationTimeUtc =\n\t\t\tnew Date(this.#creationTimeMs).toISOString().slice(0, 19).replace('T', ' ') + ' UTC';\n\t\tconst message = `Accessing keys of package ${this.getPackageName()} for ${this.#ttlMin} mins from ${creationTimeUtc}, session key ${toBase64(this.#sessionKey.getPublicKey().toRawBytes())}`;\n\t\treturn new TextEncoder().encode(message);\n\t}\n\n\tasync setPersonalMessageSignature(personalMessageSignature: string) {\n\t\tif (!this.#personalMessageSignature) {\n\t\t\ttry {\n\t\t\t\tawait verifyPersonalMessageSignature(this.getPersonalMessage(), personalMessageSignature, {\n\t\t\t\t\taddress: this.#address,\n\t\t\t\t\tclient: this.#haneulClient,\n\t\t\t\t});\n\t\t\t\tthis.#personalMessageSignature = personalMessageSignature;\n\t\t\t} catch {\n\t\t\t\tthrow new InvalidPersonalMessageSignatureError('Not valid');\n\t\t\t}\n\t\t}\n\t}\n\n\tasync getCertificate(): Promise<Certificate> {\n\t\tif (!this.#personalMessageSignature) {\n\t\t\tif (this.#signer) {\n\t\t\t\tconst { signature } = await this.#signer.signPersonalMessage(this.getPersonalMessage());\n\t\t\t\tthis.#personalMessageSignature = signature;\n\t\t\t} else {\n\t\t\t\tthrow new InvalidPersonalMessageSignatureError('Personal message signature is not set');\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tuser: this.#address,\n\t\t\tsession_vk: toBase64(this.#sessionKey.getPublicKey().toRawBytes()),\n\t\t\tcreation_time: this.#creationTimeMs,\n\t\t\tttl_min: this.#ttlMin,\n\t\t\tsignature: this.#personalMessageSignature,\n\t\t\tmvr_name: this.#mvrName,\n\t\t};\n\t}\n\n\t/**\n\t * Create request params for the given transaction bytes.\n\t * @param txBytes - The transaction bytes.\n\t * @returns The request params containing the ephemeral secret key,\n\t * its public key and its verification key.\n\t */\n\tasync createRequestParams(txBytes: Uint8Array): Promise<{\n\t\tencKey: Uint8Array<ArrayBuffer>;\n\t\tencKeyPk: Uint8Array<ArrayBuffer>;\n\t\tencVerificationKey: Uint8Array<ArrayBuffer>;\n\t\trequestSignature: string;\n\t}> {\n\t\tif (this.isExpired()) {\n\t\t\tthrow new ExpiredSessionKeyError();\n\t\t}\n\t\tconst encKey = generateSecretKey();\n\t\tconst encKeyPk = toPublicKey(encKey);\n\t\tconst encVerificationKey = toVerificationKey(encKey);\n\n\t\tconst msgToSign = RequestFormat.serialize({\n\t\t\tptb: txBytes.slice(1),\n\t\t\tencKey: encKeyPk,\n\t\t\tencVerificationKey,\n\t\t}).toBytes();\n\t\treturn {\n\t\t\tencKey,\n\t\t\tencKeyPk,\n\t\t\tencVerificationKey,\n\t\t\trequestSignature: toBase64(await this.#sessionKey.sign(msgToSign)),\n\t\t};\n\t}\n\n\t/**\n\t * Export the Session Key object from the instance. Store the object in IndexedDB to persist.\n\t */\n\texport(): ExportedSessionKey {\n\t\tconst obj = {\n\t\t\taddress: this.#address,\n\t\t\tpackageId: this.#packageId,\n\t\t\tmvrName: this.#mvrName,\n\t\t\tcreationTimeMs: this.#creationTimeMs,\n\t\t\tttlMin: this.#ttlMin,\n\t\t\tpersonalMessageSignature: this.#personalMessageSignature,\n\t\t\tsessionKey: this.#sessionKey.getSecretKey(), // bech32 encoded string\n\t\t};\n\n\t\tObject.defineProperty(obj, 'toJSON', {\n\t\t\tenumerable: false,\n\t\t\tvalue: () => {\n\t\t\t\tthrow new Error('This object is not serializable');\n\t\t\t},\n\t\t});\n\t\treturn obj;\n\t}\n\n\t/**\n\t * Restore a SessionKey instance for the given object.\n\t * @returns A new SessionKey instance with restored state\n\t */\n\tstatic import(\n\t\tdata: ExportedSessionKey,\n\t\thaneulClient: SealCompatibleClient,\n\t\tsigner?: Signer,\n\t): SessionKey {\n\t\tconst instance = new SessionKey({\n\t\t\taddress: data.address,\n\t\t\tpackageId: data.packageId,\n\t\t\tmvrName: data.mvrName,\n\t\t\tttlMin: data.ttlMin,\n\t\t\tsigner,\n\t\t\thaneulClient,\n\t\t});\n\n\t\tinstance.#creationTimeMs = data.creationTimeMs;\n\t\tinstance.#sessionKey = Ed25519Keypair.fromSecretKey(data.sessionKey);\n\t\tinstance.#personalMessageSignature = data.personalMessageSignature;\n\n\t\tif (instance.isExpired()) {\n\t\t\tthrow new ExpiredSessionKeyError();\n\t\t}\n\t\treturn instance;\n\t}\n}\n"],"mappings":"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"}
package/dist/types.d.mts CHANGED
@@ -17,7 +17,7 @@ interface KeyServerConfig {
17
17
  }
18
18
  /** Configuration options for initializing a SealClient*/
19
19
  interface SealClientOptions {
20
- suiClient: SealCompatibleClient;
20
+ haneulClient: SealCompatibleClient;
21
21
  /** Array of key server configs consisting of objectId, weight, optional API key name and API key */
22
22
  serverConfigs: KeyServerConfig[];
23
23
  /** Whether to verify the key servers' authenticity. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"sourcesContent":[],"mappings":";;;;;KAQY,oBAAA,GAAuB;EAAvB,IAAA,EACL,UADK;AAeZ,CAAA,CAAA;AA0Ca,UA1CI,eAAA,CA0CJ;EAEH,QAAA,EAAA,MAAA;EAAU,MAAA,EAAA,MAAA;EAOH,UAAA,CAAA,EAAA,MAAgB;EAWhB,MAAA,CAAA,EAAA,MAAA;EACN;;EAME,aAAA,CAAA,EAAA,MAAA;;;UA1DI,iBAAA;aACL;;iBAEI;;;;;;UAOC,cAAA;;YAEN;;YAEA;;;;;;;;QAQJ;;QAEA;;UAGU,cAAA;;QAEV;;cAEM;;WAEH;;;;;;UAOO,gBAAA;;;;WAIP;;cAEG;;;;UAKI,qBAAA;YACN;;;;WAID;;cAEG"}
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;KAQY,oBAAA,GAAuB,oBAAA;EAClC,IAAA,EAAM,UAAA;AAAA;AAAA,UAcU,eAAA;EAChB,QAAA;EACA,MAAA;EACA,UAAA;EACA,MAAA;EAAA;;EAGA,aAAA;AAAA;AAID;AAAA,UAAiB,iBAAA;EAChB,YAAA,EAAc,oBAAA;EAEgB;EAA9B,aAAA,EAAe,eAAA;EAFD;EAId,gBAAA;EAFe;EAIf,OAAA;AAAA;AAAA,UAGgB,cAAA;EAHT;EAKP,OAAA,GAAU,OAAA;EAFoB;EAI9B,OAAA,GAAU,OAAA;EAFA;EAIV,SAAA;EAMM;EAJN,SAAA;EAMgB;EAJhB,EAAA;EARA;EAUA,IAAA,EAAM,UAAA;EARN;EAUA,GAAA,GAAM,UAAA;AAAA;AAAA,UAGU,cAAA;EAPhB;EASA,IAAA,EAAM,UAAA;EAPA;EASN,UAAA,EAAY,UAAA;EAPN;EASN,OAAA,EAAS,UAAA;EATO;EAWhB,qBAAA;EAR8B;EAU9B,eAAA;AAAA;AAAA,UAGgB,gBAAA;EAPP;EAST,GAAA;EATmB;EAWnB,OAAA,EAAS,UAAA;EAfH;EAiBN,UAAA,EAAY,UAAA;EAfA;EAiBZ,SAAA;AAAA;AAAA,UAGgB,qBAAA;EAChB,OAAA,GAAU,OAAA;EAfK;EAiBf,EAAA;EAdgB;EAgBhB,OAAA,EAAS,UAAA;;EAET,UAAA,EAAY,UAAA;EAhBZ;EAkBA,SAAA;AAAA"}
package/dist/version.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/version.ts
2
- const PACKAGE_VERSION = "1.0.1";
2
+ const PACKAGE_VERSION = "1.1.1";
3
3
 
4
4
  //#endregion
5
5
  export { PACKAGE_VERSION };
@@ -1 +1 @@
1
- {"version":3,"file":"version.mjs","names":[],"sources":["../src/version.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\n// This file is generated by genversion.mjs. Do not edit it directly.\n\nexport const PACKAGE_VERSION = '1.0.1';\n"],"mappings":";AAKA,MAAa,kBAAkB"}
1
+ {"version":3,"file":"version.mjs","names":[],"sources":["../src/version.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\n// This file is generated by genversion.mjs. Do not edit it directly.\n\nexport const PACKAGE_VERSION = '1.1.1';\n"],"mappings":";AAKA,MAAa,kBAAkB"}
package/docs/index.md ADDED
@@ -0,0 +1,84 @@
1
+ # Seal SDK
2
+
3
+ > Decentralized secrets management with threshold encryption on Haneul
4
+
5
+ > **Note:** This is a beta version of Seal. See https://github.com/GeunhwaJeong/seal for more
6
+ > details.
7
+
8
+ The Seal SDK provides threshold encryption capabilities for Haneul applications, enabling secure
9
+ data encryption with configurable key servers.
10
+
11
+ ## Installation
12
+
13
+ ```bash npm2yarn
14
+ npm install --save @haneullabs/seal @haneullabs/haneul
15
+ ```
16
+
17
+ ## Setup
18
+
19
+ To use the Seal SDK, create a Haneul client and extend it with the Seal extension:
20
+
21
+ ```ts
22
+ const client = new HaneulGrpcClient({
23
+ network: 'testnet',
24
+ baseUrl: 'https://fullnode.testnet.haneul.io:443',
25
+ }).$extend(
26
+ seal({
27
+ serverConfigs: [
28
+ { objectId: '0x...keyserver1', weight: 1 },
29
+ { objectId: '0x...keyserver2', weight: 1 },
30
+ ],
31
+ }),
32
+ );
33
+ ```
34
+
35
+ ## Configuration Options
36
+
37
+ The `seal()` function accepts the following options:
38
+
39
+ - **`serverConfigs`** (required) - Array of key server configurations with `objectId` and `weight`
40
+ - **`verifyKeyServers`** (optional) - Whether to verify key server authenticity (default: `true`)
41
+ - **`timeout`** (optional) - Timeout in milliseconds for network requests (default: `10000`)
42
+
43
+ ## Basic Usage
44
+
45
+ ### Encrypting Data
46
+
47
+ ```ts
48
+ const data = new Uint8Array([1, 2, 3]);
49
+
50
+ const { encryptedObject } = await client.seal.encrypt({
51
+ threshold: 2, // Number of key servers needed to decrypt
52
+ packageId: '0x...your-package-id',
53
+ id: '0x...your-object-id',
54
+ data,
55
+ });
56
+ ```
57
+
58
+ ### Decrypting Data
59
+
60
+ ```ts
61
+ // Create a session key for decryption
62
+ const sessionKey = await SessionKey.create({
63
+ address: senderAddress,
64
+ packageId: '0x...your-package-id',
65
+ ttlMin: 10, // Time-to-live in minutes
66
+ signer: keypair,
67
+ haneulClient: client,
68
+ });
69
+
70
+ // Build transaction bytes that call seal_approve
71
+ const txBytes = await buildApprovalTransaction(/* ... */);
72
+
73
+ // Decrypt the data
74
+ const decryptedData = await client.seal.decrypt({
75
+ data: encryptedObject,
76
+ sessionKey,
77
+ txBytes,
78
+ });
79
+ ```
80
+
81
+ ## Resources
82
+
83
+ For detailed documentation on threshold encryption and key server setup, see the
84
+ [Seal repository](https://github.com/GeunhwaJeong/seal).
@@ -0,0 +1,6 @@
1
+ # Seal
2
+
3
+ > Use Seal, a decentralized secrets management service that secures your data using threshold
4
+ > encryption and on-chain access control.
5
+
6
+ - [Seal SDK](./index.md): Decentralized secrets management with threshold encryption on Haneul
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haneullabs/seal",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
4
4
  "description": "Seal SDK",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Haneul Labs <build@haneul-labs.com>",
@@ -17,34 +17,36 @@
17
17
  "sideEffects": false,
18
18
  "files": [
19
19
  "CHANGELOG.md",
20
- "dist"
20
+ "dist",
21
+ "docs"
21
22
  ],
22
23
  "repository": {
23
24
  "type": "git",
24
25
  "url": "git+https://github.com/GeunhwaJeong/ts-sdks.git"
25
26
  },
26
27
  "bugs": {
27
- "url": "https://github.com/mystenlabs/ts-sdks/issues"
28
+ "url": "https://github.com/GeunhwaJeong/ts-sdks/issues"
28
29
  },
29
- "homepage": "https://github.com/HaneulLabs/seal#readme",
30
+ "homepage": "https://github.com/GeunhwaJeong/seal#readme",
30
31
  "devDependencies": {
31
32
  "@hey-api/openapi-ts": "^0.90.3",
32
33
  "@types/node": "^25.0.8",
33
34
  "typescript": "^5.9.3",
34
35
  "vitest": "^4.0.17",
35
- "@haneullabs/haneul": "^2.4.0"
36
+ "@haneullabs/haneul": "^2.13.0"
36
37
  },
37
38
  "dependencies": {
38
39
  "@noble/curves": "^2.0.1",
39
40
  "@noble/hashes": "^2.0.1",
40
- "@haneullabs/bcs": "^2.0.2"
41
+ "@haneullabs/bcs": "^2.0.3"
41
42
  },
42
43
  "peerDependencies": {
43
- "@haneullabs/haneul": "^2.4.0"
44
+ "@haneullabs/haneul": "^2.13.0"
44
45
  },
45
46
  "scripts": {
46
47
  "clean": "rm -rf tsconfig.tsbuildinfo ./dist",
47
48
  "build": "node genversion.mjs && rm -rf dist && tsc --noEmit && tsdown",
49
+ "build:docs": "tsx ../docs/scripts/build-docs.ts",
48
50
  "codegen:version": "node genversion.mjs",
49
51
  "vitest": "vitest",
50
52
  "test": "pnpm test:typecheck && pnpm test:unit",