@sage-protocol/cli 0.3.7 → 0.3.10
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/cli/claude-desktop-config.json +1 -1
- package/dist/cli/commands/bounty.js +123 -85
- package/dist/cli/commands/doctor.js +18 -7
- package/dist/cli/commands/personal.js +154 -103
- package/dist/cli/commands/premium-pre.js +23 -875
- package/dist/cli/commands/premium.js +237 -667
- package/dist/cli/commands/sxxx.js +103 -0
- package/dist/cli/commands/timelock.js +17 -186
- package/dist/cli/index.js +1 -5
- package/dist/cli/mcp-setup.md +2 -2
- package/dist/cli/utils/aliases.js +3 -1
- package/dist/cli/utils/error-handler.js +9 -9
- package/dist/cli/utils/lit.js +103 -0
- package/dist/cli/utils/personal-helpers.js +1 -1
- package/package.json +1 -1
|
@@ -7,6 +7,7 @@ const { formatJson } = require('../utils/format');
|
|
|
7
7
|
const { getProvider, getWallet } = require('../utils/provider');
|
|
8
8
|
const { loadAbi } = require('../utils/abi-loader');
|
|
9
9
|
const { buildAccessControlConditions, receiptIdToHex } = require('../utils/personal-helpers');
|
|
10
|
+
const { buildNodeAuthSig } = require('../utils/lit');
|
|
10
11
|
const ConfigManager = require('../config');
|
|
11
12
|
|
|
12
13
|
if (ConfigManager && typeof ConfigManager.loadEnv === 'function') {
|
|
@@ -100,9 +101,6 @@ function resolveSubgraphUrl(override) {
|
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
async function createAction(opts) {
|
|
103
|
-
if (process.env.SAGE_ENABLE_PERSONAL !== '1') {
|
|
104
|
-
throw new Error('Personal libraries are disabled. Set SAGE_ENABLE_PERSONAL=1 to enable experimental commands.');
|
|
105
|
-
}
|
|
106
104
|
const provider = await getProvider();
|
|
107
105
|
const wallet = await getWallet(provider);
|
|
108
106
|
const diamond = getConfigAddress('SUBDAO_FACTORY_ADDRESS');
|
|
@@ -117,7 +115,7 @@ async function createAction(opts) {
|
|
|
117
115
|
try { return contract.interface.parseLog(l); } catch (_) { return null; }
|
|
118
116
|
}).find(Boolean);
|
|
119
117
|
const out = {
|
|
120
|
-
txHash: receipt.
|
|
118
|
+
txHash: receipt.hash,
|
|
121
119
|
registry: evt && evt.args ? evt.args.registry : undefined,
|
|
122
120
|
policy,
|
|
123
121
|
};
|
|
@@ -129,9 +127,6 @@ async function createAction(opts) {
|
|
|
129
127
|
}
|
|
130
128
|
|
|
131
129
|
async function setPriceAction(key, price, opts) {
|
|
132
|
-
if (process.env.SAGE_ENABLE_PERSONAL !== '1') {
|
|
133
|
-
throw new Error('Personal libraries are disabled. Set SAGE_ENABLE_PERSONAL=1 to enable experimental commands.');
|
|
134
|
-
}
|
|
135
130
|
const provider = await getProvider();
|
|
136
131
|
const wallet = await getWallet(provider);
|
|
137
132
|
const mkt = getConfigAddress('PERSONAL_MARKETPLACE_ADDRESS');
|
|
@@ -146,7 +141,7 @@ async function setPriceAction(key, price, opts) {
|
|
|
146
141
|
key,
|
|
147
142
|
price,
|
|
148
143
|
priceWei: priceWei.toString(),
|
|
149
|
-
txHash: receipt.
|
|
144
|
+
txHash: receipt.hash,
|
|
150
145
|
};
|
|
151
146
|
if (opts && opts.json) {
|
|
152
147
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -157,9 +152,6 @@ async function setPriceAction(key, price, opts) {
|
|
|
157
152
|
}
|
|
158
153
|
|
|
159
154
|
async function sellAction(key, price, opts = {}) {
|
|
160
|
-
if (process.env.SAGE_ENABLE_PERSONAL !== '1') {
|
|
161
|
-
throw new Error('Personal libraries are disabled. Set SAGE_ENABLE_PERSONAL=1 to enable experimental commands.');
|
|
162
|
-
}
|
|
163
155
|
|
|
164
156
|
if (!price || Number.isNaN(Number(price))) {
|
|
165
157
|
throw new Error('Price must be a numeric value (in SXXX).');
|
|
@@ -181,7 +173,7 @@ async function sellAction(key, price, opts = {}) {
|
|
|
181
173
|
const tx = await facet.createPersonalRegistry(policy);
|
|
182
174
|
const rcpt = await tx.wait();
|
|
183
175
|
if (!opts.json) {
|
|
184
|
-
console.log(`📚 Personal registry created (policy=${policy}) -> tx ${rcpt.
|
|
176
|
+
console.log(`📚 Personal registry created (policy=${policy}) -> tx ${rcpt.hash}`);
|
|
185
177
|
}
|
|
186
178
|
}
|
|
187
179
|
|
|
@@ -253,10 +245,12 @@ async function sellAction(key, price, opts = {}) {
|
|
|
253
245
|
throw new Error('Lit encryption helpers not available. Ensure @lit-protocol/encryption is installed.');
|
|
254
246
|
}
|
|
255
247
|
|
|
256
|
-
const litNetwork = opts.litNetwork || process.env.LIT_NETWORK || '
|
|
257
|
-
const client = new LitNodeClient({ litNetwork });
|
|
248
|
+
const litNetwork = opts.litNetwork || process.env.LIT_NETWORK || 'datil-test';
|
|
249
|
+
const client = new LitNodeClient({ litNetwork, debug: false });
|
|
258
250
|
await client.connect();
|
|
259
251
|
|
|
252
|
+
const litChain = await inferLitChain(provider, opts.chain);
|
|
253
|
+
|
|
260
254
|
let sessionSigs = null;
|
|
261
255
|
if (opts.session) {
|
|
262
256
|
sessionSigs = loadJsonFile(opts.session, '--session');
|
|
@@ -270,13 +264,14 @@ async function sellAction(key, price, opts = {}) {
|
|
|
270
264
|
authSig = loadJsonFile(opts.authSig, '--auth-sig');
|
|
271
265
|
} else if (process.env.LIT_AUTH_SIG) {
|
|
272
266
|
authSig = loadJsonFile(process.env.LIT_AUTH_SIG, 'LIT_AUTH_SIG');
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
|
|
267
|
+
} else {
|
|
268
|
+
// Auto-generate authSig from connected wallet
|
|
269
|
+
if (!opts.json) {
|
|
270
|
+
console.log('🔐 Generating Lit auth signature from wallet...');
|
|
271
|
+
}
|
|
272
|
+
authSig = await buildNodeAuthSig(wallet, litChain);
|
|
276
273
|
}
|
|
277
274
|
}
|
|
278
|
-
|
|
279
|
-
const litChain = await inferLitChain(provider, opts.chain);
|
|
280
275
|
const accessConditions = buildAccessControlConditions(receiptAddress, receiptId, litChain);
|
|
281
276
|
|
|
282
277
|
const encResp = await encryptUint8Array({
|
|
@@ -337,12 +332,12 @@ async function sellAction(key, price, opts = {}) {
|
|
|
337
332
|
const marketplace = new Contract(marketplaceAddress, marketplaceAbi, wallet);
|
|
338
333
|
const priceTx = await marketplace.setPrice(keyHash, priceWei);
|
|
339
334
|
const priceReceipt = await priceTx.wait();
|
|
340
|
-
result.txHash = priceReceipt.
|
|
335
|
+
result.txHash = priceReceipt.hash;
|
|
341
336
|
|
|
342
337
|
if (opts.json) {
|
|
343
338
|
console.log(JSON.stringify(result, null, 2));
|
|
344
339
|
} else {
|
|
345
|
-
console.log(`✅ Listed ${key} for ${price} SXXX (${priceReceipt.
|
|
340
|
+
console.log(`✅ Listed ${key} for ${price} SXXX (tx: ${priceReceipt.hash})`);
|
|
346
341
|
if (result.encryptedCid) {
|
|
347
342
|
console.log(`🔒 Encrypted CID: ${result.encryptedCid}`);
|
|
348
343
|
console.log(`🗃️ Manifest CID: ${result.manifestCid}`);
|
|
@@ -357,9 +352,6 @@ async function unsellAction(key, opts = {}) {
|
|
|
357
352
|
}
|
|
358
353
|
|
|
359
354
|
async function priceAction(creator, key, opts = {}) {
|
|
360
|
-
if (process.env.SAGE_ENABLE_PERSONAL !== '1') {
|
|
361
|
-
throw new Error('Personal libraries are disabled. Set SAGE_ENABLE_PERSONAL=1 to enable experimental commands.');
|
|
362
|
-
}
|
|
363
355
|
|
|
364
356
|
const provider = await getProvider();
|
|
365
357
|
const marketplaceAddress = getConfigAddress('PERSONAL_MARKETPLACE_ADDRESS');
|
|
@@ -406,9 +398,6 @@ async function priceAction(creator, key, opts = {}) {
|
|
|
406
398
|
}
|
|
407
399
|
|
|
408
400
|
async function listAction(opts = {}) {
|
|
409
|
-
if (process.env.SAGE_ENABLE_PERSONAL !== '1') {
|
|
410
|
-
throw new Error('Personal libraries are disabled. Set SAGE_ENABLE_PERSONAL=1 to enable experimental commands.');
|
|
411
|
-
}
|
|
412
401
|
|
|
413
402
|
const provider = await getProvider();
|
|
414
403
|
const wallet = await getWallet(provider);
|
|
@@ -445,7 +434,48 @@ async function listAction(opts = {}) {
|
|
|
445
434
|
let personalResourceMap = new Map();
|
|
446
435
|
|
|
447
436
|
if (!explicitKeys.length && subgraphUrl) {
|
|
448
|
-
|
|
437
|
+
// First try to get all listings (PriceSet events)
|
|
438
|
+
const listingsQuery = `
|
|
439
|
+
query($creator: Bytes!, $first: Int!) {
|
|
440
|
+
personalListings(where: { creator: $creator, listed: true }, first: $first, orderBy: updatedAt, orderDirection: desc) {
|
|
441
|
+
id
|
|
442
|
+
creator
|
|
443
|
+
key
|
|
444
|
+
price
|
|
445
|
+
listed
|
|
446
|
+
createdAt
|
|
447
|
+
updatedAt
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
`;
|
|
451
|
+
try {
|
|
452
|
+
const listingsData = await subgraphQuery(subgraphUrl, listingsQuery, {
|
|
453
|
+
creator: creatorAddress.toLowerCase(),
|
|
454
|
+
first: limit,
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
for (const listing of listingsData?.personalListings || []) {
|
|
458
|
+
const keyHash = String(listing.key);
|
|
459
|
+
const idKey = `hash:${keyHash}`;
|
|
460
|
+
if (!entries.has(idKey)) {
|
|
461
|
+
entries.set(idKey, {
|
|
462
|
+
type: 'hash',
|
|
463
|
+
keyHash,
|
|
464
|
+
priceFromListing: listing.price ? BigInt(String(listing.price)) : null,
|
|
465
|
+
listedAt: listing.createdAt ? Number(listing.createdAt) : null,
|
|
466
|
+
updatedAt: listing.updatedAt ? Number(listing.updatedAt) : null,
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
} catch (listingError) {
|
|
471
|
+
// PersonalListing entity may not exist yet, fall back to purchases
|
|
472
|
+
if (!listingError.message?.includes('Cannot query field')) {
|
|
473
|
+
console.warn(`⚠️ Listings query: ${listingError.message}`);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// Also fetch purchases for additional metadata
|
|
478
|
+
const purchasesQuery = `
|
|
449
479
|
query($creator: Bytes!, $first: Int!) {
|
|
450
480
|
licensePurchases(where: { creator: $creator }, first: $first, orderBy: blockTimestamp, orderDirection: desc) {
|
|
451
481
|
key
|
|
@@ -459,7 +489,7 @@ async function listAction(opts = {}) {
|
|
|
459
489
|
}
|
|
460
490
|
`;
|
|
461
491
|
try {
|
|
462
|
-
const data = await subgraphQuery(subgraphUrl,
|
|
492
|
+
const data = await subgraphQuery(subgraphUrl, purchasesQuery, {
|
|
463
493
|
creator: creatorAddress.toLowerCase(),
|
|
464
494
|
first: limit,
|
|
465
495
|
});
|
|
@@ -467,7 +497,15 @@ async function listAction(opts = {}) {
|
|
|
467
497
|
for (const purchase of data?.licensePurchases || []) {
|
|
468
498
|
const keyHash = String(purchase.key);
|
|
469
499
|
const idKey = `hash:${keyHash}`;
|
|
470
|
-
|
|
500
|
+
const existing = entries.get(idKey);
|
|
501
|
+
if (existing) {
|
|
502
|
+
// Enrich existing listing with purchase data
|
|
503
|
+
existing.receiptId = purchase.receiptId ? BigInt(String(purchase.receiptId)) : existing.receiptId;
|
|
504
|
+
existing.lastBuyer = purchase.buyer ? getAddress(purchase.buyer) : existing.lastBuyer;
|
|
505
|
+
existing.lastPurchaseAt = purchase.blockTimestamp ? Number(purchase.blockTimestamp) : existing.lastPurchaseAt;
|
|
506
|
+
existing.encryptedCid = purchase.encryptedCid || existing.encryptedCid;
|
|
507
|
+
existing.metadata = purchase.metadata || existing.metadata;
|
|
508
|
+
} else {
|
|
471
509
|
entries.set(idKey, {
|
|
472
510
|
type: 'hash',
|
|
473
511
|
keyHash,
|
|
@@ -516,7 +554,10 @@ async function listAction(opts = {}) {
|
|
|
516
554
|
}
|
|
517
555
|
|
|
518
556
|
if (!entries.size) {
|
|
519
|
-
console.log('ℹ️ No listings found.
|
|
557
|
+
console.log('ℹ️ No listings found.');
|
|
558
|
+
console.log(' Use --key <name> to check a specific listing by key.');
|
|
559
|
+
console.log(' Example: sage personal list --mine --key "my-prompt"');
|
|
560
|
+
console.log(' Note: Listings appear in subgraph after first purchase.');
|
|
520
561
|
return [];
|
|
521
562
|
}
|
|
522
563
|
|
|
@@ -592,9 +633,6 @@ async function listAction(opts = {}) {
|
|
|
592
633
|
}
|
|
593
634
|
|
|
594
635
|
async function myLicensesAction(opts = {}) {
|
|
595
|
-
if (process.env.SAGE_ENABLE_PERSONAL !== '1') {
|
|
596
|
-
throw new Error('Personal libraries are disabled. Set SAGE_ENABLE_PERSONAL=1 to enable experimental commands.');
|
|
597
|
-
}
|
|
598
636
|
|
|
599
637
|
const provider = await getProvider();
|
|
600
638
|
const wallet = await getWallet(provider);
|
|
@@ -712,9 +750,6 @@ async function myLicensesAction(opts = {}) {
|
|
|
712
750
|
}
|
|
713
751
|
|
|
714
752
|
async function buyAction(creator, key, expectedPriceArg, opts = {}) {
|
|
715
|
-
if (process.env.SAGE_ENABLE_PERSONAL !== '1') {
|
|
716
|
-
throw new Error('Personal libraries are disabled. Set SAGE_ENABLE_PERSONAL=1 to enable experimental commands.');
|
|
717
|
-
}
|
|
718
753
|
|
|
719
754
|
const provider = await getProvider();
|
|
720
755
|
const wallet = await getWallet(provider);
|
|
@@ -772,7 +807,7 @@ async function buyAction(creator, key, expectedPriceArg, opts = {}) {
|
|
|
772
807
|
const approveTx = await sxxx.approve(marketplaceAddress, approveAmount);
|
|
773
808
|
const approveReceipt = await approveTx.wait();
|
|
774
809
|
if (!opts.json) {
|
|
775
|
-
console.log(`✅ SXXX approval tx ${approveReceipt.
|
|
810
|
+
console.log(`✅ SXXX approval tx ${approveReceipt.hash}`);
|
|
776
811
|
}
|
|
777
812
|
}
|
|
778
813
|
|
|
@@ -799,7 +834,7 @@ async function buyAction(creator, key, expectedPriceArg, opts = {}) {
|
|
|
799
834
|
: sdk.personal.computeReceiptId(creatorAddress, key);
|
|
800
835
|
|
|
801
836
|
const result = {
|
|
802
|
-
txHash: receipt.
|
|
837
|
+
txHash: receipt.hash,
|
|
803
838
|
creator: creatorAddress,
|
|
804
839
|
buyer: buyerAddress,
|
|
805
840
|
key,
|
|
@@ -827,9 +862,6 @@ async function buyAction(creator, key, expectedPriceArg, opts = {}) {
|
|
|
827
862
|
}
|
|
828
863
|
|
|
829
864
|
async function accessAction(creator, key, opts) {
|
|
830
|
-
if (process.env.SAGE_ENABLE_PERSONAL !== '1') {
|
|
831
|
-
throw new Error('Personal libraries are disabled. Set SAGE_ENABLE_PERSONAL=1 to enable experimental commands.');
|
|
832
|
-
}
|
|
833
865
|
|
|
834
866
|
const provider = await getProvider();
|
|
835
867
|
const wallet = await getWallet(provider);
|
|
@@ -903,10 +935,12 @@ async function accessAction(creator, key, opts) {
|
|
|
903
935
|
|
|
904
936
|
if (!opts.skipDecrypt && payloadObject) {
|
|
905
937
|
const { LitNodeClient } = requireLit();
|
|
906
|
-
const litNetwork = opts.litNetwork || process.env.LIT_NETWORK || '
|
|
907
|
-
const client = new LitNodeClient({ litNetwork });
|
|
938
|
+
const litNetwork = opts.litNetwork || process.env.LIT_NETWORK || 'datil-test';
|
|
939
|
+
const client = new LitNodeClient({ litNetwork, debug: false });
|
|
908
940
|
await client.connect();
|
|
909
941
|
|
|
942
|
+
const litChain = await inferLitChain(provider, opts.chain);
|
|
943
|
+
|
|
910
944
|
let sessionSigs = null;
|
|
911
945
|
if (opts.session) {
|
|
912
946
|
sessionSigs = loadJsonFile(opts.session, '--session');
|
|
@@ -915,13 +949,20 @@ async function accessAction(creator, key, opts) {
|
|
|
915
949
|
}
|
|
916
950
|
|
|
917
951
|
let authSig = null;
|
|
918
|
-
if (
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
952
|
+
if (!sessionSigs) {
|
|
953
|
+
if (opts.authSig) {
|
|
954
|
+
authSig = loadJsonFile(opts.authSig, '--auth-sig');
|
|
955
|
+
} else if (process.env.LIT_AUTH_SIG) {
|
|
956
|
+
authSig = loadJsonFile(process.env.LIT_AUTH_SIG, 'LIT_AUTH_SIG');
|
|
957
|
+
} else {
|
|
958
|
+
// Auto-generate authSig from connected wallet
|
|
959
|
+
if (!opts.json) {
|
|
960
|
+
console.log('🔐 Generating Lit auth signature from wallet...');
|
|
961
|
+
}
|
|
962
|
+
authSig = await buildNodeAuthSig(wallet, litChain);
|
|
963
|
+
}
|
|
922
964
|
}
|
|
923
965
|
|
|
924
|
-
const litChain = await inferLitChain(provider, opts.chain);
|
|
925
966
|
decrypted = await sdk.personal.decryptWithLit({
|
|
926
967
|
encryptedCid: payloadObject,
|
|
927
968
|
receiptId,
|
|
@@ -993,59 +1034,21 @@ async function accessAction(creator, key, opts) {
|
|
|
993
1034
|
}
|
|
994
1035
|
|
|
995
1036
|
function register(program) {
|
|
996
|
-
const
|
|
1037
|
+
const { Command } = require('commander');
|
|
1038
|
+
const cmd = program.command('personal').description('Manage personal prompts and premium content');
|
|
1039
|
+
|
|
1040
|
+
// --- Registry management ---
|
|
997
1041
|
cmd
|
|
998
1042
|
.command('create')
|
|
999
1043
|
.description('Create a personal registry (owned by your EOA)')
|
|
1000
1044
|
.option('--policy <n>', 'Fork policy (0=open,1=gov_only,2=disabled)', '0')
|
|
1001
1045
|
.action((opts) => createAction(opts).catch((err) => { console.error(err.message); process.exit(1); }));
|
|
1002
|
-
cmd
|
|
1003
|
-
.command('set-price <key> <price>')
|
|
1004
|
-
.description('Set price in SXXX (18 decimals) for a content key')
|
|
1005
|
-
.option('--json', 'Emit machine-readable JSON output', false)
|
|
1006
|
-
.action((key, price, opts) => setPriceAction(key, price, opts).catch((err) => { console.error(err.message); process.exit(1); }));
|
|
1007
|
-
cmd
|
|
1008
|
-
.command('sell <key> <price>')
|
|
1009
|
-
.description('List a personal prompt key for sale and optionally encrypt the payload')
|
|
1010
|
-
.option('--encrypt', 'Encrypt content and upload manifest to IPFS', false)
|
|
1011
|
-
.option('--file <path>', 'Path to plaintext prompt/content (required with --encrypt)')
|
|
1012
|
-
.option('--name <name>', 'Friendly name for the encrypted payload')
|
|
1013
|
-
.option('--description <text>', 'Description stored alongside the encrypted payload')
|
|
1014
|
-
.option('--metadata <file>', 'Path to JSON metadata to embed in the manifest')
|
|
1015
|
-
.option('--manifest <file>', 'Write manifest JSON to this path')
|
|
1016
|
-
.option('--policy <n>', 'Optional: create personal registry with policy (0=open,1=gov_only,2=disabled) before selling')
|
|
1017
|
-
.option('--session <file>', 'Lit session signatures JSON (preferred)')
|
|
1018
|
-
.option('--auth-sig <file>', 'Lit AuthSig JSON (fallback if no session signatures)')
|
|
1019
|
-
.option('--chain <litChain>', 'Override Lit chain key (default: infer)')
|
|
1020
|
-
.option('--lit-network <name>', 'Lit network (serrano | datil-test | datil-dev)', process.env.LIT_NETWORK || 'serrano')
|
|
1021
|
-
.option('--json', 'Emit machine-readable JSON output', false)
|
|
1022
|
-
.action((key, price, opts) => sellAction(key, price, opts).catch((err) => { console.error(err.message); process.exit(1); }));
|
|
1023
|
-
cmd
|
|
1024
|
-
.command('unsell <key>')
|
|
1025
|
-
.description('Remove a price listing (sets price to 0)')
|
|
1026
|
-
.option('--json', 'Emit machine-readable JSON output', false)
|
|
1027
|
-
.action((key, opts) => unsellAction(key, opts).catch((err) => { console.error(err.message); process.exit(1); }));
|
|
1028
|
-
cmd
|
|
1029
|
-
.command('buy <creator> <key> [expectedPrice]')
|
|
1030
|
-
.description('Buy a license for a content key')
|
|
1031
|
-
.option('--max-price <sxxx>', 'Maximum price you are willing to pay (SXXX)')
|
|
1032
|
-
.option('--deadline <seconds>', 'Relative deadline window in seconds (default: 600)', '600')
|
|
1033
|
-
.option('--auto-approve', 'Automatically approve SXXX allowance if needed', false)
|
|
1034
|
-
.option('--unlimited', 'When auto-approving, approve unlimited allowance', false)
|
|
1035
|
-
.option('--json', 'Emit machine-readable JSON output', false)
|
|
1036
|
-
.action((creator, key, expectedPrice, opts) => buyAction(creator, key, expectedPrice, opts).catch((err) => { console.error(err.message); process.exit(1); }));
|
|
1037
|
-
|
|
1038
|
-
cmd
|
|
1039
|
-
.command('price <creator> <key>')
|
|
1040
|
-
.description('Show current listing price and fee breakdown for a key')
|
|
1041
|
-
.option('--json', 'Emit machine-readable JSON output', false)
|
|
1042
|
-
.action((creator, key, opts) => priceAction(creator, key, opts).catch((err) => { console.error(err.message); process.exit(1); }));
|
|
1043
1046
|
|
|
1044
1047
|
cmd
|
|
1045
1048
|
.command('list')
|
|
1046
|
-
.description('List
|
|
1049
|
+
.description('List personal prompts for a creator')
|
|
1047
1050
|
.option('--creator <address>', 'Creator address to inspect')
|
|
1048
|
-
.option('--mine', 'List
|
|
1051
|
+
.option('--mine', 'List prompts for the active wallet')
|
|
1049
1052
|
.option('--keys <keys...>', 'Explicit plaintext keys to list (skips subgraph)')
|
|
1050
1053
|
.option('--key <key>', 'Single plaintext key to list')
|
|
1051
1054
|
.option('--limit <n>', 'Maximum records to pull from subgraph (default 25)')
|
|
@@ -1055,28 +1058,76 @@ function register(program) {
|
|
|
1055
1058
|
|
|
1056
1059
|
cmd
|
|
1057
1060
|
.command('my-licenses')
|
|
1058
|
-
.description('Show
|
|
1061
|
+
.description('Show premium licenses owned by the active wallet')
|
|
1059
1062
|
.option('--holder <address>', 'Override holder address')
|
|
1060
1063
|
.option('--limit <n>', 'Maximum records to pull (default 25)')
|
|
1061
1064
|
.option('--subgraph <url>', 'Override subgraph endpoint')
|
|
1062
1065
|
.option('--json', 'Emit machine-readable JSON output', false)
|
|
1063
1066
|
.action((opts) => myLicensesAction(opts).catch((err) => { console.error(err.message); process.exit(1); }));
|
|
1064
1067
|
|
|
1065
|
-
|
|
1068
|
+
// --- Premium subcommand group ---
|
|
1069
|
+
const premium = new Command('premium').description('Premium (paid) personal prompts');
|
|
1070
|
+
|
|
1071
|
+
premium
|
|
1072
|
+
.command('publish <key>')
|
|
1073
|
+
.description('Publish premium content for sale (encrypted, requires purchase)')
|
|
1074
|
+
.requiredOption('--price <sxxx>', 'Price in SXXX (18 decimals)')
|
|
1075
|
+
.requiredOption('--file <path>', 'Path to content file to encrypt')
|
|
1076
|
+
.option('--name <name>', 'Friendly name for the content')
|
|
1077
|
+
.option('--description <text>', 'Description of the content')
|
|
1078
|
+
.option('--metadata <file>', 'Path to JSON metadata to embed in the manifest')
|
|
1079
|
+
.option('--manifest <file>', 'Write manifest JSON to this path')
|
|
1080
|
+
.option('--policy <n>', 'Create personal registry with policy before publishing')
|
|
1081
|
+
.option('--session <file>', 'Lit session signatures JSON (preferred)')
|
|
1082
|
+
.option('--auth-sig <file>', 'Lit AuthSig JSON (fallback)')
|
|
1083
|
+
.option('--chain <litChain>', 'Override Lit chain key (default: infer)')
|
|
1084
|
+
.option('--lit-network <name>', 'Lit network (datil-test | datil-dev)', process.env.LIT_NETWORK || 'datil-test')
|
|
1085
|
+
.option('--json', 'Emit machine-readable JSON output', false)
|
|
1086
|
+
.action((key, opts) => {
|
|
1087
|
+
// Call sellAction with encrypt always true for premium
|
|
1088
|
+
const sellOpts = { ...opts, encrypt: true };
|
|
1089
|
+
sellAction(key, opts.price, sellOpts).catch((err) => { console.error(err.message); process.exit(1); });
|
|
1090
|
+
});
|
|
1091
|
+
|
|
1092
|
+
premium
|
|
1093
|
+
.command('buy <creator> <key> [expectedPrice]')
|
|
1094
|
+
.description('Purchase a license for premium content')
|
|
1095
|
+
.option('--max-price <sxxx>', 'Maximum price you are willing to pay (SXXX)')
|
|
1096
|
+
.option('--deadline <seconds>', 'Relative deadline window in seconds (default: 600)', '600')
|
|
1097
|
+
.option('--auto-approve', 'Automatically approve SXXX allowance if needed', false)
|
|
1098
|
+
.option('--unlimited', 'When auto-approving, approve unlimited allowance', false)
|
|
1099
|
+
.option('--json', 'Emit machine-readable JSON output', false)
|
|
1100
|
+
.action((creator, key, expectedPrice, opts) => buyAction(creator, key, expectedPrice, opts).catch((err) => { console.error(err.message); process.exit(1); }));
|
|
1101
|
+
|
|
1102
|
+
premium
|
|
1066
1103
|
.command('access <creator> <key>')
|
|
1067
|
-
.description('
|
|
1104
|
+
.description('Decrypt and view purchased premium content')
|
|
1068
1105
|
.option('--holder <address>', 'Override holder address (defaults to active wallet)')
|
|
1069
|
-
.option('--subgraph <url>', 'Override subgraph endpoint
|
|
1070
|
-
.option('--gateway <url>', 'IPFS gateway for
|
|
1106
|
+
.option('--subgraph <url>', 'Override subgraph endpoint')
|
|
1107
|
+
.option('--gateway <url>', 'IPFS gateway for payload fetch')
|
|
1071
1108
|
.option('--session <file>', 'Path to Lit session signatures JSON')
|
|
1072
|
-
.option('--auth-sig <file>', 'Path to Lit AuthSig JSON (fallback
|
|
1073
|
-
.option('--chain <litChain>', 'Lit chain identifier
|
|
1074
|
-
.option('--lit-network <name>', 'Lit network (
|
|
1109
|
+
.option('--auth-sig <file>', 'Path to Lit AuthSig JSON (fallback)')
|
|
1110
|
+
.option('--chain <litChain>', 'Lit chain identifier')
|
|
1111
|
+
.option('--lit-network <name>', 'Lit network (datil-test | datil-dev)', process.env.LIT_NETWORK || 'datil-test')
|
|
1075
1112
|
.option('--out <file>', 'Write decrypted output to file')
|
|
1076
|
-
.option('--skip-decrypt', 'Skip
|
|
1077
|
-
.option('--encrypted-cid <cid>', 'Override encrypted CID
|
|
1113
|
+
.option('--skip-decrypt', 'Skip decryption and only report license status')
|
|
1114
|
+
.option('--encrypted-cid <cid>', 'Override encrypted CID')
|
|
1078
1115
|
.option('--json', 'Emit machine-readable JSON report', false)
|
|
1079
1116
|
.action((creator, key, opts) => accessAction(creator, key, opts).catch((err) => { console.error(err.message); process.exit(1); }));
|
|
1117
|
+
|
|
1118
|
+
premium
|
|
1119
|
+
.command('price <creator> <key>')
|
|
1120
|
+
.description('Show price and fee breakdown for premium content')
|
|
1121
|
+
.option('--json', 'Emit machine-readable JSON output', false)
|
|
1122
|
+
.action((creator, key, opts) => priceAction(creator, key, opts).catch((err) => { console.error(err.message); process.exit(1); }));
|
|
1123
|
+
|
|
1124
|
+
premium
|
|
1125
|
+
.command('unlist <key>')
|
|
1126
|
+
.description('Remove a premium listing (sets price to 0)')
|
|
1127
|
+
.option('--json', 'Emit machine-readable JSON output', false)
|
|
1128
|
+
.action((key, opts) => unsellAction(key, opts).catch((err) => { console.error(err.message); process.exit(1); }));
|
|
1129
|
+
|
|
1130
|
+
cmd.addCommand(premium);
|
|
1080
1131
|
}
|
|
1081
1132
|
|
|
1082
1133
|
module.exports = { register };
|