@eluvio/elv-client-js 3.1.83 → 3.1.87

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/src/ElvClient.js CHANGED
@@ -598,15 +598,17 @@ class ElvClient {
598
598
  * @param {string=} authToken - Eluvio authorization token previously issued from OAuth ID token
599
599
  * @param {string=} tenantId - If specified, user will be associated with the tenant
600
600
  * @param {Object=} extraData - Additional data to pass to the login API
601
+ * @param {boolean=} unsignedPublicAuth=false - If specified, the client will use an unsigned static token for calls that don't require authorization (reduces remote signature calls)
601
602
  */
602
- async SetRemoteSigner({idToken, authToken, tenantId, extraData}) {
603
+ async SetRemoteSigner({idToken, authToken, tenantId, extraData, unsignedPublicAuth}) {
603
604
  const signer = new RemoteSigner({
604
605
  rpcUris: this.authServiceURIs,
605
606
  idToken,
606
607
  authToken,
607
608
  tenantId,
608
609
  provider: this.ethClient.provider,
609
- extraData
610
+ extraData,
611
+ unsignedPublicAuth
610
612
  });
611
613
 
612
614
  await signer.Initialize();
@@ -10,11 +10,13 @@ class RemoteSigner extends Ethers.Signer {
10
10
  authToken,
11
11
  tenantId,
12
12
  provider,
13
- extraData={}
13
+ extraData={},
14
+ unsignedPublicAuth=false
14
15
  }) {
15
16
  super();
16
17
 
17
18
  this.remoteSigner = true;
19
+ this.unsignedPublicAuth = unsignedPublicAuth;
18
20
 
19
21
  this.HttpClient = new HttpClient({uris: rpcUris});
20
22
  this.idToken = idToken;
@@ -24,6 +26,8 @@ class RemoteSigner extends Ethers.Signer {
24
26
  this.extraLoginData = extraData || {};
25
27
 
26
28
  this.provider = provider;
29
+
30
+ this.signatureCache = {};
27
31
  }
28
32
 
29
33
  async Initialize() {
@@ -55,7 +59,13 @@ class RemoteSigner extends Ethers.Signer {
55
59
  })
56
60
  );
57
61
 
58
- this.address = Utils.HashToAddress(keys.eth[0]);
62
+ const address = keys.eth[0];
63
+
64
+ if(address && address.startsWith("0x")) {
65
+ this.address = address;
66
+ } else {
67
+ this.address = Utils.HashToAddress(keys.eth[0]);
68
+ }
59
69
  }
60
70
 
61
71
  this.id = this.address ? `ikms${Utils.AddressToHash(this.address)}` : undefined;
@@ -74,23 +84,29 @@ class RemoteSigner extends Ethers.Signer {
74
84
  * @returns - the signed message as a hex string
75
85
  */
76
86
  async signDigest(digest) {
77
- let signature = await Utils.ResponseToJson(
78
- this.HttpClient.Request({
79
- method: "POST",
80
- path: UrlJoin("as", "wlt", "sign", "eth", this.id),
81
- headers: {
82
- Authorization: `Bearer ${this.authToken}`
83
- },
84
- body: {
85
- hash: digest
86
- }
87
- })
88
- );
89
-
90
- signature.v = parseInt(signature.v, 16);
91
- signature.recoveryParam = signature.v - 27;
87
+ if(!this.signatureCache[digest]) {
88
+ this.signatureCache[digest] = new Promise(async resolve => {
89
+ let signature = await Utils.ResponseToJson(
90
+ this.HttpClient.Request({
91
+ method: "POST",
92
+ path: UrlJoin("as", "wlt", "sign", "eth", this.id),
93
+ headers: {
94
+ Authorization: `Bearer ${this.authToken}`
95
+ },
96
+ body: {
97
+ hash: digest
98
+ }
99
+ })
100
+ );
101
+
102
+ signature.v = parseInt(signature.v, 16);
103
+ signature.recoveryParam = signature.v - 27;
104
+
105
+ resolve(signature);
106
+ });
107
+ }
92
108
 
93
- return signature;
109
+ return await this.signatureCache[digest];
94
110
  }
95
111
 
96
112
  async signMessage(message) {
package/src/Utils.js CHANGED
@@ -5,6 +5,10 @@ const BigNumber = require("bignumber.js").default;
5
5
  const VarInt = require("varint");
6
6
  const URI = require("urijs");
7
7
 
8
+ const {
9
+ keccak256
10
+ } = require("ethers").utils;
11
+
8
12
  /**
9
13
  * @namespace
10
14
  * @description This is a utility namespace mostly containing functions for managing
@@ -149,11 +153,12 @@ const Utils = {
149
153
  * Convert contract address to multiformat hash
150
154
  *
151
155
  * @param {string} address - Address of contract
156
+ * @param {boolean} key - Whether or not the first param is a public key. Defaults to address type
152
157
  *
153
158
  * @returns {string} - Hash of contract address
154
159
  */
155
- AddressToHash: (address) => {
156
- address = address.replace("0x", "");
160
+ AddressToHash: (address, key=false) => {
161
+ address = address.replace(key ? "0x04" : "0x", "");
157
162
  return bs58.encode(Buffer.from(address, "hex"));
158
163
  },
159
164
 
@@ -194,12 +199,13 @@ const Utils = {
194
199
  * Convert any content fabric ID to the corresponding contract address
195
200
  *
196
201
  * @param {string} hash - Hash to convert to address
202
+ * @param {boolean} key - Whether or not the first param is a key. Defaults to address type
197
203
  *
198
204
  * @returns {string} - Contract address of item
199
205
  */
200
- HashToAddress: (hash) => {
201
- hash = hash.substr(4);
202
- return Utils.FormatAddress("0x" + bs58.decode(hash).toString("hex"));
206
+ HashToAddress: (hash, key=false) => {
207
+ hash = key ? hash : hash.substr(4);
208
+ return Utils.FormatAddress((key ? "0x04" : "0x") + bs58.decode(hash).toString("hex"));
203
209
  },
204
210
 
205
211
  /**
@@ -505,6 +511,21 @@ const Utils = {
505
511
  }
506
512
  },
507
513
 
514
+ /**
515
+ * Converts the given string to a public address
516
+ *
517
+ * @param key - Public key to convert to a public address
518
+ *
519
+ * @returns {string} - the public address
520
+ */
521
+ PublicKeyToAddress: (key) => {
522
+ const keyData = new Uint8Array(Buffer.from(key.replace("0x04", ""), "hex"));
523
+ const keccakHash = keccak256(keyData);
524
+ const address = "0x" + keccakHash.slice(26);
525
+
526
+ return Utils.FormatAddress(address);
527
+ },
528
+
508
529
  PLATFORM_NODE: "node",
509
530
  PLATFORM_WEB: "web",
510
531
  PLATFORM_REACT_NATIVE: "react-native",
@@ -1325,6 +1325,7 @@ exports.AvailableOfferings = async function({
1325
1325
  * @param {Object=} context - Additional audience data to include in the authorization request.
1326
1326
  * - Note: Context must be a map of string->string
1327
1327
  * @param {Object=} authorizationToken - Additional authorization token for authorizing this request
1328
+ * @param {Object=} options - Additional query parameters to pass when requesting available playout options, such as clipping parameters.
1328
1329
  */
1329
1330
  exports.PlayoutOptions = async function({
1330
1331
  offeringURI,
@@ -1340,7 +1341,8 @@ exports.PlayoutOptions = async function({
1340
1341
  drms=[],
1341
1342
  context,
1342
1343
  hlsjsProfile=true,
1343
- authorizationToken
1344
+ authorizationToken,
1345
+ options={}
1344
1346
  }) {
1345
1347
  if(offeringURI) {
1346
1348
  const uriInfo = offeringURI.match(/(hq__[^/]+)\/rep\/([^/]+)\/([^/]+)\/options.json/);
@@ -1421,7 +1423,8 @@ exports.PlayoutOptions = async function({
1421
1423
 
1422
1424
  let queryParams = {
1423
1425
  authorization,
1424
- resolve: !!linkPath
1426
+ resolve: !!linkPath,
1427
+ ...options
1425
1428
  };
1426
1429
 
1427
1430
  const playoutOptions = Object.values(
@@ -1590,6 +1593,7 @@ exports.PlayoutOptions = async function({
1590
1593
  * @param {Object=} context - Additional audience data to include in the authorization request
1591
1594
  * - Note: Context must be a map of string->string
1592
1595
  * @param {Object=} authorizationToken - Additional authorization token for authorizing this request
1596
+ * @param {Object=} options - Additional query parameters to pass when requesting available playout options, such as clipping parameters.
1593
1597
  */
1594
1598
  exports.BitmovinPlayoutOptions = async function({
1595
1599
  objectId,
@@ -1603,7 +1607,8 @@ exports.BitmovinPlayoutOptions = async function({
1603
1607
  offering="default",
1604
1608
  playoutType,
1605
1609
  context,
1606
- authorizationToken
1610
+ authorizationToken,
1611
+ options={}
1607
1612
  }) {
1608
1613
  versionHash ? ValidateVersion(versionHash) : ValidateObject(objectId);
1609
1614
 
@@ -1624,7 +1629,8 @@ exports.BitmovinPlayoutOptions = async function({
1624
1629
  playoutType,
1625
1630
  hlsjsProfile: false,
1626
1631
  context,
1627
- authorizationToken
1632
+ authorizationToken,
1633
+ options
1628
1634
  });
1629
1635
 
1630
1636
  delete playoutOptions.playoutMethods;
@@ -22,7 +22,6 @@ const {
22
22
  ValidateWriteToken,
23
23
  ValidateParameters,
24
24
  ValidatePresence,
25
- ValidateAddress
26
25
  } = require("../Validation");
27
26
 
28
27
  exports.SetVisibility = async function({id, visibility}) {
@@ -243,6 +242,7 @@ exports.CreateContentType = async function({name, metadata={}, bitcode}) {
243
242
  * @param {Object=} metadata - Metadata of library object
244
243
  * @param {string=} kmsId - ID of the KMS to use for content in this library. If not specified,
245
244
  * the default KMS will be used.
245
+ * @param {string=} tenantId - ID of the tenant to use for this library
246
246
  *
247
247
  * @returns {Promise<string>} - Library ID of created library
248
248
  */
@@ -253,6 +253,7 @@ exports.CreateContentLibrary = async function({
253
253
  imageName,
254
254
  metadata={},
255
255
  kmsId,
256
+ tenantId
256
257
  }) {
257
258
  if(!kmsId) {
258
259
  kmsId = `ikms${this.utils.AddressToHash(await this.DefaultKMSAddress())}`;
@@ -265,7 +266,10 @@ exports.CreateContentLibrary = async function({
265
266
 
266
267
 
267
268
  // Set tenant ID on the library if the user is associated with a tenant
268
- const tenantId = await this.userProfileClient.TenantId();
269
+ if(!tenantId) {
270
+ tenantId = await this.userProfileClient.TenantId();
271
+ }
272
+
269
273
  if(tenantId) {
270
274
  await this.CallContractMethod({
271
275
  contractAddress,
@@ -691,13 +695,11 @@ exports.CopyContentObject = async function({libraryId, originalVersionHash, opti
691
695
  * @param {string} libraryId - ID of the library
692
696
  * @param {string} objectId - ID of the object
693
697
  * @param {string} publicKey - Public key for the target cap
694
- * @param {string} publicAddress - Public address for the target cap key
695
698
  * @param {string} writeToken - Write token for the content object - If specified, info will be retrieved from the write draft instead of creating a new draft and finalizing
696
699
  *
697
700
  * @returns {Promise<Object>}
698
701
  */
699
- exports.CreateNonOwnerCap = async function({objectId, libraryId, publicKey, publicAddress, writeToken}) {
700
- publicAddress = ValidateAddress(publicAddress);
702
+ exports.CreateNonOwnerCap = async function({objectId, libraryId, publicKey, writeToken}) {
701
703
  const userCapKey = `eluv.caps.iusr${this.utils.AddressToHash(this.signer.address)}`;
702
704
  const userCapValue = await this.ContentObjectMetadata({objectId, libraryId, metadataSubtree: userCapKey});
703
705
 
@@ -707,6 +709,8 @@ exports.CreateNonOwnerCap = async function({objectId, libraryId, publicKey, publ
707
709
 
708
710
  const userConk = await this.Crypto.DecryptCap(userCapValue, this.signer.signingKey.privateKey);
709
711
 
712
+ const publicAddress = this.utils.PublicKeyToAddress(publicKey);
713
+
710
714
  const targetUserCapKey = `eluv.caps.iusr${this.utils.AddressToHash(publicAddress)}`;
711
715
  const targetUserCapValue = await this.Crypto.EncryptConk(userConk, publicKey);
712
716
 
@@ -16,7 +16,6 @@ const reportTypes = [
16
16
 
17
17
  const liveTypes = [
18
18
  { name: "Eluvio LIVE Drop Event Site", spec: require("../typeSpecs/DropEventSite") },
19
- { name: "Eluvio LIVE Event Site", spec: require("../typeSpecs/EventSite") },
20
19
  { name: "Eluvio LIVE Marketplace", spec: require("../typeSpecs/Marketplace") },
21
20
  { name: "Eluvio LIVE Tenant", spec: require("../typeSpecs/EventTenant") },
22
21
  { name: "NFT Collection", spec: require("../typeSpecs/NFTCollection") },