@feralfile/cli 2.6.0 → 2.7.0
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/config.json.example +1 -1
- package/dist/package.json +1 -1
- package/dist/src/commands/find.js +2 -35
- package/dist/src/commands/helpers/playlist-display.js +3 -36
- package/dist/src/commands/publish.js +2 -35
- package/dist/src/commands/ssh.js +1 -34
- package/dist/src/utilities/feed-fetcher.js +1 -0
- package/dist/src/utilities/functions.js +4 -36
- package/dist/src/utilities/index.js +2 -34
- package/dist/src/utilities/nft-indexer.js +127 -30
- package/dist/src/utilities/playlist-builder.js +1 -0
- package/dist/src/utilities/playlist-cast.js +1 -34
- package/dist/src/utilities/playlist-send.js +2 -35
- package/dist/src/utilities/playlist-signer.js +2 -34
- package/dist/src/utilities/playlist-signing-role.js +1 -0
- package/dist/src/utilities/playlist-verifier.js +4 -37
- package/docs/CONFIGURATION.md +2 -2
- package/docs/PROJECT_SPEC.md +10 -0
- package/package.json +1 -1
package/config.json.example
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
],
|
|
16
16
|
"playlist": {
|
|
17
17
|
"privateKey": "YOUR_ED25519_PRIVATE_KEY__base64_PKCS8_DER_recommended__or_32byte_raw_seed_as_hex_or_base64__run_ff-cli_setup_to_generate",
|
|
18
|
-
"role": "
|
|
18
|
+
"role": "curator",
|
|
19
19
|
"curatorName": "YOUR_CURATOR_NAME"
|
|
20
20
|
},
|
|
21
21
|
"ff1Relayer": {
|
package/dist/package.json
CHANGED
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
@@ -595,8 +562,8 @@ async function doPlay(playlist, deviceName, skipVerify) {
|
|
|
595
562
|
}
|
|
596
563
|
async function doPublish(savedPath, serverArg, nonInteractive) {
|
|
597
564
|
console.log(chalk_1.default.blue('Publish to feed'));
|
|
598
|
-
const { getFeedConfig } = await
|
|
599
|
-
const { publishPlaylist } = await
|
|
565
|
+
const { getFeedConfig } = await import('../config.js');
|
|
566
|
+
const { publishPlaylist } = await import('../utilities/playlist-publisher.js');
|
|
600
567
|
const feedConfig = getFeedConfig();
|
|
601
568
|
if (!feedConfig.baseURLs || feedConfig.baseURLs.length === 0) {
|
|
602
569
|
console.error(chalk_1.default.red('No feed servers configured.'));
|
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
@@ -98,7 +65,7 @@ function printPlaylistVerificationFailure(verifyResult, source) {
|
|
|
98
65
|
*/
|
|
99
66
|
async function validatePlaylistSource(source) {
|
|
100
67
|
const loaded = await (0, playlist_source_1.loadPlaylistSource)(source);
|
|
101
|
-
const verifier = await
|
|
68
|
+
const verifier = await import('../../utilities/playlist-verifier.js');
|
|
102
69
|
const { validatePlaylist } = verifier;
|
|
103
70
|
const verifyResult = await validatePlaylist(loaded.playlist);
|
|
104
71
|
return {
|
|
@@ -113,7 +80,7 @@ async function validatePlaylistSource(source) {
|
|
|
113
80
|
async function runValidateCommand(source) {
|
|
114
81
|
try {
|
|
115
82
|
console.log(chalk_1.default.blue('\nValidate playlist\n'));
|
|
116
|
-
const verifier = await
|
|
83
|
+
const verifier = await import('../../utilities/playlist-verifier.js');
|
|
117
84
|
const { printVerificationResult } = verifier;
|
|
118
85
|
const result = await validatePlaylistSource(source);
|
|
119
86
|
printVerificationResult(result, source, { failureKind: 'structure' });
|
|
@@ -138,7 +105,7 @@ async function runValidateCommand(source) {
|
|
|
138
105
|
async function runVerifyCommand(source, publicKey) {
|
|
139
106
|
try {
|
|
140
107
|
console.log(chalk_1.default.blue('\nVerify playlist\n'));
|
|
141
|
-
const verifier = await
|
|
108
|
+
const verifier = await import('../../utilities/playlist-verifier.js');
|
|
142
109
|
const { printVerificationResult } = verifier;
|
|
143
110
|
const result = await validatePlaylistSource(source);
|
|
144
111
|
if (!result.valid) {
|
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
@@ -47,8 +14,8 @@ exports.publishCommand = new commander_1.Command('publish')
|
|
|
47
14
|
.action(async (file, options) => {
|
|
48
15
|
try {
|
|
49
16
|
console.log(chalk_1.default.blue('\nPublish playlist\n'));
|
|
50
|
-
const { getFeedConfig } = await
|
|
51
|
-
const { publishPlaylist } = await
|
|
17
|
+
const { getFeedConfig } = await import('../config.js');
|
|
18
|
+
const { publishPlaylist } = await import('../utilities/playlist-publisher.js');
|
|
52
19
|
const feedConfig = getFeedConfig();
|
|
53
20
|
if (!feedConfig.baseURLs || feedConfig.baseURLs.length === 0) {
|
|
54
21
|
console.error(chalk_1.default.red('\nNo feed servers configured'));
|
package/dist/src/commands/ssh.js
CHANGED
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
@@ -71,7 +38,7 @@ exports.sshCommand = new commander_1.Command('ssh')
|
|
|
71
38
|
if (options.ttl) {
|
|
72
39
|
ttlSeconds = (0, ssh_helpers_1.parseTtlSeconds)(options.ttl);
|
|
73
40
|
}
|
|
74
|
-
const { sendSshAccessCommand } = await
|
|
41
|
+
const { sendSshAccessCommand } = await import('../utilities/ssh-access.js');
|
|
75
42
|
const result = await sendSshAccessCommand({
|
|
76
43
|
enabled: isEnable,
|
|
77
44
|
deviceName: options.device,
|
|
@@ -1,40 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Function Calling Layer
|
|
3
4
|
* These are the actual implementations called by AI orchestrator via function calling
|
|
4
5
|
*/
|
|
5
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
-
}
|
|
11
|
-
Object.defineProperty(o, k2, desc);
|
|
12
|
-
}) : (function(o, m, k, k2) {
|
|
13
|
-
if (k2 === undefined) k2 = k;
|
|
14
|
-
o[k2] = m[k];
|
|
15
|
-
}));
|
|
16
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
-
}) : function(o, v) {
|
|
19
|
-
o["default"] = v;
|
|
20
|
-
});
|
|
21
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
-
var ownKeys = function(o) {
|
|
23
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
-
var ar = [];
|
|
25
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
-
return ar;
|
|
27
|
-
};
|
|
28
|
-
return ownKeys(o);
|
|
29
|
-
};
|
|
30
|
-
return function (mod) {
|
|
31
|
-
if (mod && mod.__esModule) return mod;
|
|
32
|
-
var result = {};
|
|
33
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
-
__setModuleDefault(result, mod);
|
|
35
|
-
return result;
|
|
36
|
-
};
|
|
37
|
-
})();
|
|
38
6
|
const chalk = require('chalk');
|
|
39
7
|
const playlistBuilder = require('./playlist-builder');
|
|
40
8
|
const ff1Device = require('./ff1-device');
|
|
@@ -162,7 +130,7 @@ async function verifyPlaylist(params) {
|
|
|
162
130
|
}
|
|
163
131
|
logger.verbose(chalk.cyan('\nValidate playlist'));
|
|
164
132
|
// Dynamic import to avoid circular dependency
|
|
165
|
-
const playlistVerifier = await
|
|
133
|
+
const playlistVerifier = await import('./playlist-verifier.js');
|
|
166
134
|
const validate = playlistVerifier.validatePlaylist ||
|
|
167
135
|
(playlistVerifier.default && playlistVerifier.default.validatePlaylist) ||
|
|
168
136
|
playlistVerifier.default;
|
|
@@ -226,7 +194,7 @@ async function verifyAddresses(params) {
|
|
|
226
194
|
};
|
|
227
195
|
}
|
|
228
196
|
// Dynamic import to avoid circular dependency
|
|
229
|
-
const addressValidator = await
|
|
197
|
+
const addressValidator = await import('./address-validator.js');
|
|
230
198
|
const validateAddresses = addressValidator.validateAddresses ||
|
|
231
199
|
(addressValidator.default && addressValidator.default.validateAddresses) ||
|
|
232
200
|
addressValidator.default;
|
|
@@ -268,7 +236,7 @@ async function verifyAddresses(params) {
|
|
|
268
236
|
* }
|
|
269
237
|
*/
|
|
270
238
|
async function getConfiguredDevices() {
|
|
271
|
-
const configModule = await
|
|
239
|
+
const configModule = await import('../config.js');
|
|
272
240
|
const getFF1DeviceConfig = configModule.getFF1DeviceConfig ||
|
|
273
241
|
(configModule.default && configModule.default.getFF1DeviceConfig) ||
|
|
274
242
|
configModule.default;
|
|
@@ -1,40 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Utilities - Actual function implementations
|
|
3
4
|
* Contains the real logic for querying NFTs and building playlists
|
|
4
5
|
*/
|
|
5
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
-
}
|
|
11
|
-
Object.defineProperty(o, k2, desc);
|
|
12
|
-
}) : (function(o, m, k, k2) {
|
|
13
|
-
if (k2 === undefined) k2 = k;
|
|
14
|
-
o[k2] = m[k];
|
|
15
|
-
}));
|
|
16
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
-
}) : function(o, v) {
|
|
19
|
-
o["default"] = v;
|
|
20
|
-
});
|
|
21
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
-
var ownKeys = function(o) {
|
|
23
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
-
var ar = [];
|
|
25
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
-
return ar;
|
|
27
|
-
};
|
|
28
|
-
return ownKeys(o);
|
|
29
|
-
};
|
|
30
|
-
return function (mod) {
|
|
31
|
-
if (mod && mod.__esModule) return mod;
|
|
32
|
-
var result = {};
|
|
33
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
-
__setModuleDefault(result, mod);
|
|
35
|
-
return result;
|
|
36
|
-
};
|
|
37
|
-
})();
|
|
38
6
|
const chalk = require('chalk');
|
|
39
7
|
const nftIndexer = require('./nft-indexer');
|
|
40
8
|
const feedFetcher = require('./feed-fetcher');
|
|
@@ -400,7 +368,7 @@ async function buildDP1Playlist(items, title, slug) {
|
|
|
400
368
|
* @returns {Promise<Object>} Result
|
|
401
369
|
*/
|
|
402
370
|
async function sendToDevice(playlist, deviceName) {
|
|
403
|
-
const playlistVerifier = await
|
|
371
|
+
const playlistVerifier = await import('./playlist-verifier.js');
|
|
404
372
|
const verifyPlaylist = playlistVerifier.verifyPlaylist ||
|
|
405
373
|
(playlistVerifier.default && playlistVerifier.default.verifyPlaylist) ||
|
|
406
374
|
playlistVerifier.default;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* NFT Indexer Client
|
|
3
4
|
* This module provides functions to interact with NFT indexing services
|
|
@@ -48,8 +49,15 @@ const JOB_STATUS_QUERY = `
|
|
|
48
49
|
/**
|
|
49
50
|
* buildTokensListQuery builds the `tokens { items { ... } }` request body used by queryTokens.
|
|
50
51
|
*
|
|
51
|
-
*
|
|
52
|
-
* into `display`; the client does not repeat that merge by fetching raw metadata fields.
|
|
52
|
+
* Presentation comes only from `display` and `media_assets`. The indexer merges metadata and
|
|
53
|
+
* enrichment into `display`; the client does not repeat that merge by fetching raw metadata fields.
|
|
54
|
+
*
|
|
55
|
+
* `chain` and `standard` are selected because the row is the only place either fact is known.
|
|
56
|
+
* `detectTokenStandard` has an address and a chain name and nothing else, so it answers `erc721` for
|
|
57
|
+
* every EVM contract — which wrote `erc721` into playlists for every ERC-1155 token `find` reached by
|
|
58
|
+
* owner or by contract. The indexer stores what the token actually is (`erc721`, `erc1155`, `fa2`)
|
|
59
|
+
* beside its CAIP-2 `chain` (`eip155:1`, `tezos:mainnet`), so the row answers both questions and
|
|
60
|
+
* detection drops to a fallback. Do not remove these two fields from the selection.
|
|
53
61
|
*
|
|
54
62
|
* @param {Object} [params]
|
|
55
63
|
* @param {Array<string>} [params.token_cids]
|
|
@@ -74,6 +82,8 @@ function buildTokensListQuery(params = {}) {
|
|
|
74
82
|
token_number
|
|
75
83
|
current_owner
|
|
76
84
|
burned
|
|
85
|
+
chain
|
|
86
|
+
standard
|
|
77
87
|
display {
|
|
78
88
|
name
|
|
79
89
|
description
|
|
@@ -106,10 +116,18 @@ function initializeIndexer(_config) {
|
|
|
106
116
|
logger.debug('[NFT Indexer] Using endpoint:', GRAPHQL_ENDPOINT);
|
|
107
117
|
}
|
|
108
118
|
/**
|
|
109
|
-
*
|
|
119
|
+
* detectTokenStandard guesses a token standard from a chain name and an address.
|
|
120
|
+
*
|
|
121
|
+
* This is the last-resort fallback, not the answer. It sees no token — only a
|
|
122
|
+
* chain name and an address format — so it cannot tell ERC-721 from ERC-1155
|
|
123
|
+
* and answers `erc721` for every EVM contract. It is still needed in two
|
|
124
|
+
* places: a lookup by coordinate has to build *some* CID before the indexer has
|
|
125
|
+
* been asked anything (see buildTokenCID), and a token row that arrived without
|
|
126
|
+
* a `standard` field has nothing better to offer.
|
|
110
127
|
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
128
|
+
* Prefer, in order: the indexer row's own `standard`, a caller's assertion, and
|
|
129
|
+
* only then this. On-chain detection is deliberately not attempted here — the
|
|
130
|
+
* indexer already stores the answer and selecting it costs nothing.
|
|
113
131
|
*
|
|
114
132
|
* @param {string} chain - Blockchain network
|
|
115
133
|
* @param {string} contractAddress - Contract address
|
|
@@ -121,18 +139,34 @@ function detectTokenStandard(chain, contractAddress) {
|
|
|
121
139
|
if (lowerChain === 'tezos' || contractAddress.startsWith('KT')) {
|
|
122
140
|
return 'fa2';
|
|
123
141
|
}
|
|
124
|
-
// Ethereum
|
|
125
|
-
//
|
|
142
|
+
// Ethereum: erc721 is a guess, not a reading. Only the indexer row or a
|
|
143
|
+
// caller's assertion can distinguish an ERC-1155 token from an ERC-721 one.
|
|
126
144
|
if (lowerChain === 'ethereum') {
|
|
127
145
|
return 'erc721';
|
|
128
146
|
}
|
|
129
147
|
return 'other';
|
|
130
148
|
}
|
|
131
149
|
/**
|
|
132
|
-
* Token standards the indexer keys CIDs on.
|
|
133
|
-
*
|
|
150
|
+
* Token standards the indexer keys CIDs on. A standard outside this set —
|
|
151
|
+
* asserted by a caller or arriving on a row — says nothing the CID can carry,
|
|
152
|
+
* so detection decides instead.
|
|
134
153
|
*/
|
|
135
154
|
const CID_STANDARDS = new Set(['erc721', 'erc1155', 'fa2']);
|
|
155
|
+
/**
|
|
156
|
+
* normalizeCidStandard returns a standard the CID format can carry, or ''.
|
|
157
|
+
*
|
|
158
|
+
* Both the indexer row and a caller's assertion are untrusted strings from
|
|
159
|
+
* outside this module ('ERC1155', ' fa2 ', 'ERC-1155', undefined). Anything not
|
|
160
|
+
* in CID_STANDARDS is treated as absent rather than passed through, so a
|
|
161
|
+
* misspelled standard never reaches a CID or a DP-1 `provenance.contract`.
|
|
162
|
+
*
|
|
163
|
+
* @param {unknown} value - Candidate standard
|
|
164
|
+
* @returns {string} Normalized standard, or '' when it is not one we can use
|
|
165
|
+
*/
|
|
166
|
+
function normalizeCidStandard(value) {
|
|
167
|
+
const normalized = typeof value === 'string' ? value.trim().toLowerCase() : '';
|
|
168
|
+
return CID_STANDARDS.has(normalized) ? normalized : '';
|
|
169
|
+
}
|
|
136
170
|
/**
|
|
137
171
|
* resolveTokenStandard picks the standard a CID is built with.
|
|
138
172
|
*
|
|
@@ -149,11 +183,77 @@ const CID_STANDARDS = new Set(['erc721', 'erc1155', 'fa2']);
|
|
|
149
183
|
* @returns {string} Token standard for the CID
|
|
150
184
|
*/
|
|
151
185
|
function resolveTokenStandard(chain, contractAddress, asserted) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
186
|
+
return normalizeCidStandard(asserted) || detectTokenStandard(chain, contractAddress);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* CAIP-2 namespaces mapped to the chain values DP-1 `provenance.contract` allows.
|
|
190
|
+
*
|
|
191
|
+
* The indexer names a token's chain in CAIP-2 (`eip155:1`, `tezos:mainnet`),
|
|
192
|
+
* which is authoritative: it comes from the row rather than from the caller's
|
|
193
|
+
* guess at which network an address belongs to. Namespaces outside this map
|
|
194
|
+
* have no DP-1 equivalent, so they fall back to the caller's chain name.
|
|
195
|
+
*/
|
|
196
|
+
const CAIP2_NAMESPACE_TO_DP1_CHAIN = {
|
|
197
|
+
eip155: 'evm',
|
|
198
|
+
tezos: 'tezos',
|
|
199
|
+
bitmark: 'bitmark',
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* dp1ChainFromCaip2 derives a DP-1 chain from a CAIP-2 chain id.
|
|
203
|
+
*
|
|
204
|
+
* @param {unknown} caip2Chain - CAIP-2 chain id from an indexer row, e.g. `eip155:1`
|
|
205
|
+
* @returns {string} DP-1 chain (`evm`, `tezos`, `bitmark`), or '' when unknown or absent
|
|
206
|
+
*/
|
|
207
|
+
function dp1ChainFromCaip2(caip2Chain) {
|
|
208
|
+
if (typeof caip2Chain !== 'string') {
|
|
209
|
+
return '';
|
|
155
210
|
}
|
|
156
|
-
|
|
211
|
+
const namespace = caip2Chain.trim().toLowerCase().split(':')[0];
|
|
212
|
+
return CAIP2_NAMESPACE_TO_DP1_CHAIN[namespace] || '';
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Client chain names mapped to the chain values DP-1 `provenance.contract` allows.
|
|
216
|
+
*
|
|
217
|
+
* This is for DP-1 provenance output, NOT for indexer queries: the indexer uses
|
|
218
|
+
* `eth`/`tez`/`bmk` while DP-1 uses `evm`/`tezos`/`bitmark`. It answers only for
|
|
219
|
+
* tokens that reached us without an indexer row — a caller-supplied coordinate.
|
|
220
|
+
*/
|
|
221
|
+
const CHAIN_NAME_TO_DP1_CHAIN = {
|
|
222
|
+
ethereum: 'evm',
|
|
223
|
+
polygon: 'evm',
|
|
224
|
+
arbitrum: 'evm',
|
|
225
|
+
optimism: 'evm',
|
|
226
|
+
base: 'evm',
|
|
227
|
+
zora: 'evm',
|
|
228
|
+
tezos: 'tezos', // DP1 spec uses 'tezos', not 'tez'
|
|
229
|
+
bitmark: 'bitmark', // DP1 spec uses 'bitmark', not 'bmk'
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* resolveDp1Chain picks the DP-1 chain for a token's `provenance.contract`.
|
|
233
|
+
*
|
|
234
|
+
* The row's CAIP-2 chain and the caller's chain name are not two guesses to try
|
|
235
|
+
* in turn — they are different claims, and the row's is the network the indexer
|
|
236
|
+
* recorded. So a token carrying a row chain is answered from that chain alone:
|
|
237
|
+
* a namespace with no DP-1 equivalent becomes `other`, never the caller's name.
|
|
238
|
+
* Falling through would be actively wrong, because the owner and contract paths
|
|
239
|
+
* label every non-KT address `ethereum` before mapping — a Solana row would
|
|
240
|
+
* inherit that label and be published as an EVM contract. `other` is a true
|
|
241
|
+
* statement about a chain DP-1 cannot name; `evm` is a false one.
|
|
242
|
+
*
|
|
243
|
+
* The name map answers only when the token has no row chain at all, which is a
|
|
244
|
+
* token assembled from a caller-supplied coordinate rather than an indexer row.
|
|
245
|
+
*
|
|
246
|
+
* @param {Object} token - Token in the internal standard format
|
|
247
|
+
* @param {string} [token.caip2Chain] - CAIP-2 chain from the indexer row, when it came from one
|
|
248
|
+
* @param {string} [token.chain] - Client chain name the caller inferred
|
|
249
|
+
* @returns {string} DP-1 chain (`evm`, `tezos`, `bitmark`, or `other`)
|
|
250
|
+
*/
|
|
251
|
+
function resolveDp1Chain(token) {
|
|
252
|
+
const rowChain = typeof token.caip2Chain === 'string' ? token.caip2Chain.trim() : '';
|
|
253
|
+
if (rowChain) {
|
|
254
|
+
return dp1ChainFromCaip2(rowChain) || 'other';
|
|
255
|
+
}
|
|
256
|
+
return CHAIN_NAME_TO_DP1_CHAIN[String(token.chain || '').toLowerCase()] || 'other';
|
|
157
257
|
}
|
|
158
258
|
/**
|
|
159
259
|
* Build CAIP-2 token CID for indexer v2
|
|
@@ -348,9 +448,16 @@ function getBestMediaUrl(display = {}, mediaAssets = []) {
|
|
|
348
448
|
* is null or partial, we only use what is present (for example `Token #${token_number}` for name);
|
|
349
449
|
* we do not splice in raw `metadata` or enrichment because those are not selected from GraphQL.
|
|
350
450
|
*
|
|
451
|
+
* The row's own `standard` and `chain` outrank both the asserted `standard` and the `chain`
|
|
452
|
+
* argument, because they are the token's identity as the indexer recorded it while the arguments are
|
|
453
|
+
* the caller's inference — `find` by owner or by contract only knows "the address starts with 0x, so
|
|
454
|
+
* ethereum". Precedence for the standard is row → asserted → detection; the CAIP-2 `chain` is kept
|
|
455
|
+
* beside the caller's chain name (not in place of it) as `caip2Chain`, because the name still selects
|
|
456
|
+
* the CID prefix and the detection fallback while the CAIP-2 value answers DP-1's chain enum.
|
|
457
|
+
*
|
|
351
458
|
* @param {Object} indexerData - Token fields from indexer GraphQL
|
|
352
|
-
* @param {string} chain - Blockchain network
|
|
353
|
-
* @param {string} [standard] - Asserted token standard;
|
|
459
|
+
* @param {string} chain - Blockchain network the caller inferred
|
|
460
|
+
* @param {string} [standard] - Asserted token standard; used when the row carries none
|
|
354
461
|
* @returns {Object} Standardized token data
|
|
355
462
|
*/
|
|
356
463
|
function mapIndexerDataToStandardFormat(indexerData, chain, standard) {
|
|
@@ -366,11 +473,14 @@ function mapIndexerDataToStandardFormat(indexerData, chain, standard) {
|
|
|
366
473
|
const artistName = extractArtistName(display.artists);
|
|
367
474
|
const name = display.name || `Token #${indexerData.token_number}`;
|
|
368
475
|
const description = display.description || '';
|
|
369
|
-
const resolvedStandard =
|
|
476
|
+
const resolvedStandard = normalizeCidStandard(indexerData.standard) ||
|
|
477
|
+
resolveTokenStandard(chain, indexerData.contract_address, standard);
|
|
478
|
+
const caip2Chain = typeof indexerData.chain === 'string' ? indexerData.chain : '';
|
|
370
479
|
return {
|
|
371
480
|
success: true,
|
|
372
481
|
token: {
|
|
373
482
|
chain,
|
|
483
|
+
caip2Chain,
|
|
374
484
|
contractAddress: indexerData.contract_address,
|
|
375
485
|
tokenId: indexerData.token_number,
|
|
376
486
|
standard: resolvedStandard,
|
|
@@ -470,26 +580,13 @@ function convertToDP1Item(tokenData, duration) {
|
|
|
470
580
|
error: `Source URL too long (${sourceUrl.length} chars, max 1024)`,
|
|
471
581
|
};
|
|
472
582
|
}
|
|
473
|
-
// Map chain name to DP1 format (according to DP1 spec)
|
|
474
|
-
// NOTE: This is for DP1 provenance output, NOT for indexer queries
|
|
475
|
-
// The indexer uses 'eth'/'tez'/'bmk', but DP1 spec uses 'evm'/'tezos'/'bitmark'
|
|
476
|
-
const chainMap = {
|
|
477
|
-
ethereum: 'evm',
|
|
478
|
-
polygon: 'evm',
|
|
479
|
-
arbitrum: 'evm',
|
|
480
|
-
optimism: 'evm',
|
|
481
|
-
base: 'evm',
|
|
482
|
-
zora: 'evm',
|
|
483
|
-
tezos: 'tezos', // DP1 spec uses 'tezos', not 'tez'
|
|
484
|
-
bitmark: 'bitmark', // DP1 spec uses 'bitmark', not 'bmk'
|
|
485
|
-
};
|
|
486
583
|
// Build via dp1-js PlaylistItemBuilder so leaf blocks match DP-1 AJV schema.
|
|
487
584
|
const itemBuilder = new PlaylistItemBuilder()
|
|
488
585
|
.id(itemId)
|
|
489
586
|
.source(sourceUrl)
|
|
490
587
|
.license('open')
|
|
491
588
|
.provenance(new ProvenanceBuilder().type('onChain').contract(new ContractBuilder()
|
|
492
|
-
.chain(
|
|
589
|
+
.chain(resolveDp1Chain(token))
|
|
493
590
|
.standard(token.standard || detectTokenStandard(token.chain, token.contractAddress))
|
|
494
591
|
.address(token.contractAddress)
|
|
495
592
|
.tokenId(String(token.tokenId))));
|
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.castPlaylist = castPlaylist;
|
|
37
4
|
/**
|
|
@@ -106,7 +73,7 @@ async function castPlaylist(playlist, options = {}) {
|
|
|
106
73
|
};
|
|
107
74
|
}
|
|
108
75
|
}
|
|
109
|
-
const { verifyPlaylist } = await
|
|
76
|
+
const { verifyPlaylist } = await import('./playlist-verifier.js');
|
|
110
77
|
const verifyResult = await verifyPlaylist(current);
|
|
111
78
|
if (!verifyResult.valid) {
|
|
112
79
|
return {
|
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
@@ -46,7 +13,7 @@ const playlist_source_1 = require("./playlist-source");
|
|
|
46
13
|
*/
|
|
47
14
|
async function getAvailableDevices() {
|
|
48
15
|
try {
|
|
49
|
-
const configModule = (await
|
|
16
|
+
const configModule = (await import('../config.js'));
|
|
50
17
|
const getFF1DeviceConfig = configModule.getFF1DeviceConfig ||
|
|
51
18
|
(configModule.default && configModule.default.getFF1DeviceConfig) ||
|
|
52
19
|
configModule.default;
|
|
@@ -146,7 +113,7 @@ async function confirmPlaylistForSending(filePath, deviceName) {
|
|
|
146
113
|
// Parse / structure validation only (same as `validate`; use `verify` CLI for signatures)
|
|
147
114
|
console.log(chalk_1.default.cyan('Validation'));
|
|
148
115
|
// Dynamic import to avoid circular dependency
|
|
149
|
-
const { validatePlaylist } = await
|
|
116
|
+
const { validatePlaylist } = await import('./playlist-verifier.js');
|
|
150
117
|
const validateResult = await validatePlaylist(playlist);
|
|
151
118
|
if (!validateResult.valid) {
|
|
152
119
|
console.log(chalk_1.default.red('Playlist validation failed'));
|
|
@@ -1,40 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Playlist Signing Utility.
|
|
3
4
|
* Uses the DP-1 v1.1.0 signing contract via the `dp1-js` package.
|
|
4
5
|
*/
|
|
5
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
-
}
|
|
11
|
-
Object.defineProperty(o, k2, desc);
|
|
12
|
-
}) : (function(o, m, k, k2) {
|
|
13
|
-
if (k2 === undefined) k2 = k;
|
|
14
|
-
o[k2] = m[k];
|
|
15
|
-
}));
|
|
16
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
-
}) : function(o, v) {
|
|
19
|
-
o["default"] = v;
|
|
20
|
-
});
|
|
21
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
-
var ownKeys = function(o) {
|
|
23
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
-
var ar = [];
|
|
25
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
-
return ar;
|
|
27
|
-
};
|
|
28
|
-
return ownKeys(o);
|
|
29
|
-
};
|
|
30
|
-
return function (mod) {
|
|
31
|
-
if (mod && mod.__esModule) return mod;
|
|
32
|
-
var result = {};
|
|
33
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
-
__setModuleDefault(result, mod);
|
|
35
|
-
return result;
|
|
36
|
-
};
|
|
37
|
-
})();
|
|
38
6
|
const { getPlaylistConfig } = require('../config');
|
|
39
7
|
const { isDp1PlaylistSigningRole } = require('./playlist-signing-role');
|
|
40
8
|
const { parsePlaylistPrivateKeyToKeyObject } = require('./ed25519-key-derive');
|
|
@@ -261,7 +229,7 @@ async function verifySignedPlaylistEnvelope(signedPlaylist, dp1) {
|
|
|
261
229
|
* instead of leaving a runtime require that can't resolve.
|
|
262
230
|
*/
|
|
263
231
|
async function loadDp1() {
|
|
264
|
-
return
|
|
232
|
+
return import('dp1-js');
|
|
265
233
|
}
|
|
266
234
|
function currentTimestamp() {
|
|
267
235
|
return new Date().toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
@@ -4,39 +4,6 @@
|
|
|
4
4
|
* Delegates signature-shape handling to dp1-js and keeps the CLI as a thin
|
|
5
5
|
* orchestration layer.
|
|
6
6
|
*/
|
|
7
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
-
if (k2 === undefined) k2 = k;
|
|
9
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
-
}
|
|
13
|
-
Object.defineProperty(o, k2, desc);
|
|
14
|
-
}) : (function(o, m, k, k2) {
|
|
15
|
-
if (k2 === undefined) k2 = k;
|
|
16
|
-
o[k2] = m[k];
|
|
17
|
-
}));
|
|
18
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
-
}) : function(o, v) {
|
|
21
|
-
o["default"] = v;
|
|
22
|
-
});
|
|
23
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
-
var ownKeys = function(o) {
|
|
25
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
-
var ar = [];
|
|
27
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
-
return ar;
|
|
29
|
-
};
|
|
30
|
-
return ownKeys(o);
|
|
31
|
-
};
|
|
32
|
-
return function (mod) {
|
|
33
|
-
if (mod && mod.__esModule) return mod;
|
|
34
|
-
var result = {};
|
|
35
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
-
__setModuleDefault(result, mod);
|
|
37
|
-
return result;
|
|
38
|
-
};
|
|
39
|
-
})();
|
|
40
7
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
41
8
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
42
9
|
};
|
|
@@ -84,10 +51,10 @@ async function verifyPlaylist(playlist, publicKey) {
|
|
|
84
51
|
let key = publicKey?.trim() || undefined;
|
|
85
52
|
if (!key) {
|
|
86
53
|
try {
|
|
87
|
-
const { getPlaylistConfig } = await
|
|
54
|
+
const { getPlaylistConfig } = await import('../config.js');
|
|
88
55
|
const privateKeyMaterial = getPlaylistConfig().privateKey;
|
|
89
56
|
if (privateKeyMaterial) {
|
|
90
|
-
const { deriveEd25519PublicKeyForVerify } = await
|
|
57
|
+
const { deriveEd25519PublicKeyForVerify } = await import('./ed25519-key-derive.js');
|
|
91
58
|
key = deriveEd25519PublicKeyForVerify(privateKeyMaterial);
|
|
92
59
|
}
|
|
93
60
|
}
|
|
@@ -98,7 +65,7 @@ async function verifyPlaylist(playlist, publicKey) {
|
|
|
98
65
|
}
|
|
99
66
|
if (key) {
|
|
100
67
|
try {
|
|
101
|
-
const { normalizeVerifyPublicKeyToPem } = await
|
|
68
|
+
const { normalizeVerifyPublicKeyToPem } = await import('./ed25519-key-derive.js');
|
|
102
69
|
key = normalizeVerifyPublicKeyToPem(key);
|
|
103
70
|
}
|
|
104
71
|
catch (err) {
|
|
@@ -162,7 +129,7 @@ async function parseDp1Playlist(playlist) {
|
|
|
162
129
|
* stays lazy, so dp1-js's transitive deps don't load on unrelated commands.
|
|
163
130
|
*/
|
|
164
131
|
async function loadDp1() {
|
|
165
|
-
return (await
|
|
132
|
+
return (await import('dp1-js'));
|
|
166
133
|
}
|
|
167
134
|
/**
|
|
168
135
|
* Verify playlist file
|
package/docs/CONFIGURATION.md
CHANGED
|
@@ -63,7 +63,7 @@ Used for signing DP‑1 playlists.
|
|
|
63
63
|
`PLAYLIST_PRIVATE_KEY` even when no config file exists yet, and `ff-cli status --key <privateKey>`
|
|
64
64
|
reports it for an explicit key — the one `sign --key` would use.
|
|
65
65
|
|
|
66
|
-
- `playlist.role` (string): DP-1 signing role used by `ff-cli sign`.
|
|
66
|
+
- `playlist.role` (string): DP-1 signing role used by `ff-cli sign`. The shipped `config.json.example` sets `curator`, because a document signed as `agent` is ownerless to a role-aware feed and `ff-cli publish` refuses it. The code default when the key is omitted entirely is still `agent`. You can also set this via `PLAYLIST_ROLE` in `.env`. Guided `ff-cli setup`, `config validate`, and `sign --role` only accept the usual DP-1 signing roles (`agent`, `feed`, `curator`, `institution`, `licensor`). It does **not** apply to `find` and `build`, which always sign as `curator` — see [Signing role and ownership](#signing-role-and-ownership).
|
|
67
67
|
|
|
68
68
|
### Generate an Ed25519 private key
|
|
69
69
|
|
|
@@ -267,7 +267,7 @@ Minimal `config.json` example (selected fields):
|
|
|
267
267
|
"defaultDuration": 10,
|
|
268
268
|
"playlist": {
|
|
269
269
|
"privateKey": "your_ed25519_private_key_hex_or_base64_here",
|
|
270
|
-
"role": "
|
|
270
|
+
"role": "curator"
|
|
271
271
|
},
|
|
272
272
|
"feed": {
|
|
273
273
|
"baseURLs": ["https://dp1-feed-operator-api-prod.autonomy-system.workers.dev/api/v1"]
|
package/docs/PROJECT_SPEC.md
CHANGED
|
@@ -159,6 +159,16 @@ Today the CLI groups into these workflow areas:
|
|
|
159
159
|
- `find`
|
|
160
160
|
- `build`
|
|
161
161
|
|
|
162
|
+
An item's `provenance.contract` is read from the indexer row, not inferred. Each
|
|
163
|
+
row carries the token's own `standard` (`erc721`, `erc1155`, `fa2`) and its
|
|
164
|
+
CAIP-2 `chain` (`eip155:1`, `tezos:mainnet`), and both are written through. The
|
|
165
|
+
client's own detection sees a chain name and an address and nothing else, so it
|
|
166
|
+
answers `erc721` for every EVM contract; it applies only to rows that carry no
|
|
167
|
+
standard, and to the CID a lookup by coordinate must build before the indexer
|
|
168
|
+
has been asked anything. A row naming a chain DP-1 has no word for is recorded
|
|
169
|
+
as `other` — the item is still built, and the client's guess is never
|
|
170
|
+
substituted for a chain the row already named.
|
|
171
|
+
|
|
162
172
|
### DP-1 output integrity
|
|
163
173
|
|
|
164
174
|
- `verify`
|