@eluvio/elv-client-js 4.0.79 → 4.0.81
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/dist/ElvClient-min.js +2 -2
- package/dist/ElvClient-node-min.js +2 -2
- package/dist/ElvWalletClient-min.js +3 -3
- package/dist/ElvWalletClient-node-min.js +4 -4
- package/dist/src/ElvClient.js +252 -160
- package/dist/src/client/LiveConf.js +27 -5
- package/dist/src/client/LiveStream.js +1 -1
- package/dist/src/walletClient/ClientMethods.js +281 -187
- package/dist/src/walletClient/index.js +15 -0
- package/package.json +1 -1
- package/src/ElvClient.js +65 -0
- package/src/client/LiveConf.js +26 -5
- package/src/client/LiveStream.js +1 -1
- package/src/walletClient/ClientMethods.js +48 -0
- package/src/walletClient/index.js +12 -0
- package/testScripts/CreateAndDecodeSignedMessage.js +51 -0
- package/utilities/GenerateFabricToken.js +4 -1
|
@@ -1739,6 +1739,21 @@ var ElvWalletClient = /*#__PURE__*/function () {
|
|
|
1739
1739
|
if (op === "nft-offer-redeem") {
|
|
1740
1740
|
offerId = status.op.split(":")[3];
|
|
1741
1741
|
}
|
|
1742
|
+
if (op === "nft-claim-entitlement") {
|
|
1743
|
+
var _status$op$split3 = status.op.split(":"),
|
|
1744
|
+
_status$op$split4 = _slicedToArray(_status$op$split3, 4),
|
|
1745
|
+
_op = _status$op$split4[0],
|
|
1746
|
+
marketplace = _status$op$split4[1],
|
|
1747
|
+
sku = _status$op$split4[2],
|
|
1748
|
+
purchaseId = _status$op$split4[3];
|
|
1749
|
+
confirmationId = purchaseId;
|
|
1750
|
+
if (status.extra && status.extra["0"]) {
|
|
1751
|
+
address = status.extra["0"].token_addr;
|
|
1752
|
+
tokenId = status.extra["0"].token_id;
|
|
1753
|
+
address = address.startsWith("0x") ? Utils.FormatAddress(address) : address;
|
|
1754
|
+
status.marketplaceId = marketplace;
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1742
1757
|
return _objectSpread(_objectSpread({}, status), {}, {
|
|
1743
1758
|
timestamp: new Date(status.ts),
|
|
1744
1759
|
state: status.state && _typeof(status.state) === "object" ? Object.values(status.state) : status.state,
|
package/package.json
CHANGED
package/src/ElvClient.js
CHANGED
|
@@ -975,6 +975,71 @@ class ElvClient {
|
|
|
975
975
|
]))}`;
|
|
976
976
|
}
|
|
977
977
|
|
|
978
|
+
|
|
979
|
+
/**
|
|
980
|
+
* Build a signed message (JSON) using the current signer.
|
|
981
|
+
* Signed messages have a similar format to signed access tokens and they include the message itself
|
|
982
|
+
* such that they can be both verified and decoded by the receiving entity.
|
|
983
|
+
*
|
|
984
|
+
* Messages can be encoded and signed using different methods, and the encoding and signature types
|
|
985
|
+
* are described in the header of the resulting signed message blob.
|
|
986
|
+
*
|
|
987
|
+
* Note this type of message can not be verified and decoded on chain.
|
|
988
|
+
*
|
|
989
|
+
* @methodGroup Authorization
|
|
990
|
+
* @namedParams
|
|
991
|
+
* @param {string} messasge - A JSON object representing the message to sign
|
|
992
|
+
*/
|
|
993
|
+
async CreateSignedMessageJSON({
|
|
994
|
+
message
|
|
995
|
+
}) {
|
|
996
|
+
|
|
997
|
+
// Only one kind of signature supported currently
|
|
998
|
+
const type = "mje_" // JSON message, EIP192 signature
|
|
999
|
+
|
|
1000
|
+
const msg = JSON.stringify(message);
|
|
1001
|
+
const signature = await this.PersonalSign({message: msg, addEthereumPrefix: true});
|
|
1002
|
+
return `${type}${Utils.B58(
|
|
1003
|
+
Buffer.concat([
|
|
1004
|
+
Buffer.from(signature.replace(/^0x/, ""), "hex"),
|
|
1005
|
+
Buffer.from(msg)
|
|
1006
|
+
])
|
|
1007
|
+
)}`;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* Verify and decode a signed message (JSON).
|
|
1012
|
+
*
|
|
1013
|
+
* @methodGroup Authorization
|
|
1014
|
+
* @namedParams
|
|
1015
|
+
* @param {string} signedMessage - a signed message as created by CreateSignedMessageJSON
|
|
1016
|
+
* @returns {Promise<Object>} - The decoded message, signer address, signature and signature type
|
|
1017
|
+
*/
|
|
1018
|
+
async DecodeSignedMessageJSON({
|
|
1019
|
+
signedMessage
|
|
1020
|
+
}) {
|
|
1021
|
+
const type = signedMessage.slice(0,4);
|
|
1022
|
+
switch(type) {
|
|
1023
|
+
case "mje_":
|
|
1024
|
+
const msgBytes = Utils.FromB58(signedMessage.slice(4));
|
|
1025
|
+
const signature = msgBytes.slice(0, 65);
|
|
1026
|
+
const msg = msgBytes.slice(65);
|
|
1027
|
+
const obj = JSON.parse(msg);
|
|
1028
|
+
|
|
1029
|
+
const prefixedMsgHash = Ethers.utils.keccak256(Buffer.from(`\x19Ethereum Signed Message:\n${msg.length}${msg}`, "utf-8"));
|
|
1030
|
+
const signerAddr = Ethers.utils.recoverAddress(prefixedMsgHash, signature);
|
|
1031
|
+
|
|
1032
|
+
return {
|
|
1033
|
+
type: type,
|
|
1034
|
+
message: obj,
|
|
1035
|
+
signerAddress: signerAddr,
|
|
1036
|
+
signature: "0x" + signature.toString("hex")
|
|
1037
|
+
};
|
|
1038
|
+
default:
|
|
1039
|
+
throw new Error(`Bad message type: ${type}`);
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
|
|
978
1043
|
/**
|
|
979
1044
|
* Get the account address of the current signer
|
|
980
1045
|
*
|
package/src/client/LiveConf.js
CHANGED
|
@@ -209,6 +209,17 @@ class LiveConf {
|
|
|
209
209
|
return seg;
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
+
/*
|
|
213
|
+
* Calculate output timebase from the encoder (codec) timebase. The videoTimeBase parameter
|
|
214
|
+
* represents the encoder timebase. The format muxer will change it so it is greater than 10000.
|
|
215
|
+
*/
|
|
216
|
+
calcOutputTimebase(codecTimebase) {
|
|
217
|
+
let outputTimebase = codecTimebase;
|
|
218
|
+
while (outputTimebase < 10000)
|
|
219
|
+
outputTimebase = outputTimebase * 2;
|
|
220
|
+
return outputTimebase;
|
|
221
|
+
}
|
|
222
|
+
|
|
212
223
|
calcSegDurationMpegts({sourceTimescale}) {
|
|
213
224
|
let videoStream = this.getStreamDataForCodecType("video");
|
|
214
225
|
let frameRate = videoStream.frame_rate;
|
|
@@ -270,7 +281,9 @@ class LiveConf {
|
|
|
270
281
|
|
|
271
282
|
switch(frameRate) {
|
|
272
283
|
case "24":
|
|
273
|
-
seg.
|
|
284
|
+
seg.videoTimeBase = 1536; // Output timebase: 12288
|
|
285
|
+
seg.videoFrameDurationTs = 512;
|
|
286
|
+
seg.video = this.calcOutputTimebase(seg.videoTimeBase) * 30;
|
|
274
287
|
seg.keyint = 48;
|
|
275
288
|
seg.duration = "30";
|
|
276
289
|
break;
|
|
@@ -280,7 +293,9 @@ class LiveConf {
|
|
|
280
293
|
seg.duration = "30";
|
|
281
294
|
break;
|
|
282
295
|
case "30":
|
|
283
|
-
seg.
|
|
296
|
+
seg.videoTimeBase = 960; // Output timebase: 15360
|
|
297
|
+
seg.videoFrameDurationTs = 512;
|
|
298
|
+
seg.video = this.calcOutputTimebase(seg.videoTimeBase) * 30;
|
|
284
299
|
seg.keyint = 60;
|
|
285
300
|
seg.duration = "30";
|
|
286
301
|
break;
|
|
@@ -290,7 +305,9 @@ class LiveConf {
|
|
|
290
305
|
seg.duration = "30.03";
|
|
291
306
|
break;
|
|
292
307
|
case "48":
|
|
293
|
-
seg.
|
|
308
|
+
seg.videoTimeBase = 1536; // Output timebase: 12288
|
|
309
|
+
seg.videoFrameDurationTs = 256;
|
|
310
|
+
seg.video = this.calcOutputTimebase(seg.videoTimeBase) * 30;
|
|
294
311
|
seg.keyint = 96;
|
|
295
312
|
seg.duration = "30";
|
|
296
313
|
break;
|
|
@@ -300,7 +317,9 @@ class LiveConf {
|
|
|
300
317
|
seg.duration = "30";
|
|
301
318
|
break;
|
|
302
319
|
case "60":
|
|
303
|
-
seg.
|
|
320
|
+
seg.videoTimeBase = 960; // Output timebase: 15360
|
|
321
|
+
seg.videoFrameDurationTs = 256;
|
|
322
|
+
seg.video = this.calcOutputTimebase(seg.videoTimeBase) * 30;
|
|
304
323
|
seg.keyint = 120;
|
|
305
324
|
seg.duration = "30";
|
|
306
325
|
break;
|
|
@@ -397,7 +416,9 @@ class LiveConf {
|
|
|
397
416
|
// Optional override output timebase and frame duration (ts)
|
|
398
417
|
if(segDurations.videoTimeBase) {
|
|
399
418
|
conf.live_recording.recording_config.recording_params.xc_params.video_time_base = segDurations.videoTimeBase;
|
|
400
|
-
|
|
419
|
+
|
|
420
|
+
// Note 'source_timescale' needs to be set to the output timebase and is used by playout
|
|
421
|
+
conf.live_recording.recording_config.recording_params.source_timescale = this.calcOutputTimebase(segDurations.videoTimeBase);
|
|
401
422
|
}
|
|
402
423
|
if(segDurations.videoFrameDurationTs) {
|
|
403
424
|
conf.live_recording.recording_config.recording_params.xc_params.video_frame_duration_ts = segDurations.videoFrameDurationTs;
|
package/src/client/LiveStream.js
CHANGED
|
@@ -1322,7 +1322,7 @@ exports.StreamConfig = async function({name, customSettings={}}) {
|
|
|
1322
1322
|
const hostName = userConfig.url.replace("udp://", "").replace("rtmp://", "").replace("srt://", "").split(":")[0];
|
|
1323
1323
|
const streamUrl = new URL(userConfig.url);
|
|
1324
1324
|
|
|
1325
|
-
console.log("Retrieving nodes
|
|
1325
|
+
console.log("Retrieving nodes - matching", hostName);
|
|
1326
1326
|
let nodes = await this.SpaceNodes({matchEndpoint: hostName});
|
|
1327
1327
|
if(nodes.length < 1) {
|
|
1328
1328
|
status.error = "No node matching stream URL " + streamUrl.href;
|
|
@@ -1371,6 +1371,54 @@ exports.GiftClaimStatus = async function({marketplaceParams, confirmationId, gif
|
|
|
1371
1371
|
}
|
|
1372
1372
|
};
|
|
1373
1373
|
|
|
1374
|
+
/**
|
|
1375
|
+
* Return status of the specified entitlement claim
|
|
1376
|
+
*
|
|
1377
|
+
* @methodGroup Status
|
|
1378
|
+
* @namedParams
|
|
1379
|
+
* @param {Object} marketplaceParams - Parameters of the marketplace
|
|
1380
|
+
* @param {string} purchaseId - The purchase ID of the entitlement, for confirmation of status
|
|
1381
|
+
*
|
|
1382
|
+
* @returns {Promise<Object>} - The mint status of the entitlement claim
|
|
1383
|
+
*/
|
|
1384
|
+
exports.EntitlementClaimStatus = async function({marketplaceParams, purchaseId}) {
|
|
1385
|
+
try {
|
|
1386
|
+
const marketplaceInfo = await this.MarketplaceInfo({marketplaceParams});
|
|
1387
|
+
const statuses = await this.MintingStatus({tenantId: marketplaceInfo.tenantId});
|
|
1388
|
+
|
|
1389
|
+
const responses = statuses.filter(status => status.op === "nft-claim-entitlement"
|
|
1390
|
+
&& (purchaseId && purchaseId == status.confirmationId)) || { status: "none" };
|
|
1391
|
+
|
|
1392
|
+
if(responses.length === 0) {
|
|
1393
|
+
return { status: "none" };
|
|
1394
|
+
} else {
|
|
1395
|
+
if(responses.find(response => response.status === "complete")) {
|
|
1396
|
+
return {
|
|
1397
|
+
status: "complete",
|
|
1398
|
+
op: "nft-claim-entitlement",
|
|
1399
|
+
items: [{
|
|
1400
|
+
token_addr: responses[0].address,
|
|
1401
|
+
token_id: responses[0].tokenId
|
|
1402
|
+
}]
|
|
1403
|
+
};
|
|
1404
|
+
} else if(responses.find(response => response.status === "error")) {
|
|
1405
|
+
return {
|
|
1406
|
+
status: "error",
|
|
1407
|
+
op: "nft-claim-entitlement",
|
|
1408
|
+
};
|
|
1409
|
+
} else {
|
|
1410
|
+
return {
|
|
1411
|
+
status: "pending",
|
|
1412
|
+
op: "nft-claim-entitlement",
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
} catch(error) {
|
|
1417
|
+
this.Log(error, true);
|
|
1418
|
+
return { status: "unknown" };
|
|
1419
|
+
}
|
|
1420
|
+
};
|
|
1421
|
+
|
|
1374
1422
|
/**
|
|
1375
1423
|
* Return status of the specified pack opening
|
|
1376
1424
|
*
|
|
@@ -1326,6 +1326,18 @@ class ElvWalletClient {
|
|
|
1326
1326
|
offerId = status.op.split(":")[3];
|
|
1327
1327
|
}
|
|
1328
1328
|
|
|
1329
|
+
if(op === "nft-claim-entitlement") {
|
|
1330
|
+
let [op, marketplace, sku, purchaseId ] = status.op.split(":");
|
|
1331
|
+
confirmationId = purchaseId
|
|
1332
|
+
if(status.extra && status.extra["0"]) {
|
|
1333
|
+
address = status.extra["0"].token_addr;
|
|
1334
|
+
tokenId = status.extra["0"].token_id;
|
|
1335
|
+
|
|
1336
|
+
address = address.startsWith("0x") ? Utils.FormatAddress(address) : address;
|
|
1337
|
+
status.marketplaceId = marketplace;
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1329
1341
|
return {
|
|
1330
1342
|
...status,
|
|
1331
1343
|
timestamp: new Date(status.ts),
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const { ElvClient } = require("../src/ElvClient");
|
|
2
|
+
|
|
3
|
+
const yargs = require("yargs");
|
|
4
|
+
const argv = yargs
|
|
5
|
+
.option("msg", {
|
|
6
|
+
description: "message to be signed and decoded",
|
|
7
|
+
type: "string"
|
|
8
|
+
})
|
|
9
|
+
.option("config-url", {
|
|
10
|
+
type: "string",
|
|
11
|
+
description: "URL pointing to the Fabric configuration. i.e. https://main.net955210.contentfabric.io/config"
|
|
12
|
+
})
|
|
13
|
+
.demandOption(
|
|
14
|
+
["msg"],
|
|
15
|
+
"\nUsage: PRIVATE_KEY=<private-key> node CreateAndDecodeSignedMessage.js --msg <message>\n"
|
|
16
|
+
)
|
|
17
|
+
.strict().argv;
|
|
18
|
+
const ClientConfiguration = (!argv["config-url"]) ? (require("../TestConfiguration.json")) : {"config-url": argv["config-url"]};
|
|
19
|
+
|
|
20
|
+
const CreateAndDecodeSignedMessage = async ({msg}) => {
|
|
21
|
+
try {
|
|
22
|
+
const client = await ElvClient.FromConfigurationUrl({
|
|
23
|
+
configUrl: ClientConfiguration["config-url"],
|
|
24
|
+
});
|
|
25
|
+
const wallet = client.GenerateWallet();
|
|
26
|
+
const signer = wallet.AddAccount({
|
|
27
|
+
privateKey: process.env.PRIVATE_KEY
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
client.SetSigner({signer});
|
|
31
|
+
|
|
32
|
+
const signedMessage = await client.CreateSignedMessageJSON({
|
|
33
|
+
message:msg,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const decodedMessage = await client.DecodeSignedMessageJSON({
|
|
37
|
+
signedMessage,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
console.log(signedMessage);
|
|
42
|
+
console.log(decodedMessage);
|
|
43
|
+
} catch(error) {
|
|
44
|
+
console.error(error);
|
|
45
|
+
console.error(JSON.stringify(error, null, 2));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
process.exit(0);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
CreateAndDecodeSignedMessage({msg: argv.msg});
|
|
@@ -11,7 +11,10 @@ const GenerateFabricToken = async () => {
|
|
|
11
11
|
|
|
12
12
|
client.SetSigner({signer});
|
|
13
13
|
|
|
14
|
-
console.log(await client.CreateFabricToken({
|
|
14
|
+
console.log(await client.CreateFabricToken({
|
|
15
|
+
duration: parseInt(process.env.DURATION),
|
|
16
|
+
//context: {email:"xyz@eluv.io"}
|
|
17
|
+
}));
|
|
15
18
|
} catch(error) {
|
|
16
19
|
console.error(error);
|
|
17
20
|
console.error(JSON.stringify(error, null, 2));
|