@sage-protocol/cli 0.3.9 â 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.
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"RPC_URL": "https://sepolia.base.org",
|
|
8
8
|
"LIBRARY_REGISTRY_ADDRESS": "0x032F2E93549640a319163Ba600fc50bA1AFBE50F",
|
|
9
9
|
"SUBDAO_FACTORY_ADDRESS": "0x6bb6A83149F84Df0584aC863e5fE3416AFb214aC",
|
|
10
|
-
"SUBGRAPH_URL": "https://api.goldsky.com/api/public/project_cmhxp0fppsbdd01q56xp2gqw9/subgraphs/sxxx-protocol/1.0.
|
|
10
|
+
"SUBGRAPH_URL": "https://api.goldsky.com/api/public/project_cmhxp0fppsbdd01q56xp2gqw9/subgraphs/sxxx-protocol/1.0.1/gn",
|
|
11
11
|
"PINATA_JWT": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mb3JtYXRpb24iOnsiaWQiOiI4ODE2MWM1Ni05NTYzLTQyNTUtYTU4Ni0xMzBiMTUyMWIxNmIiLCJlbWFpbCI6InRlcnJlbmV0d2VsbHM0N0BnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwicGluX3BvbGljeSI6eyJyZWdpb25zIjpbeyJkZXNpcmVkUmVwbGljYXRpb25Db3VudCI6MSwiaWQiOiJGUkExIn0seyJkZXNpcmVkUmVwbGljYXRpb25Db3VudCI6MSwiaWQiOiJOWUMxIn1dLCJ2ZXJzaW9uIjoxfSwibWZhX2VuYWJsZWQiOmZhbHNlLCJzdGF0dXMiOiJBQ1RJVkUifSwiYXV0aGVudGljYXRpb25UeXBlIjoic2NvcGVkS2V5Iiwic2NvcGVkS2V5S2V5IjoiMDRjZWY4NzE5OTg1ODE1M2U5Y2IiLCJzY29wZWRLZXlTZWNyZXQiOiJmNDFjMDVhZTNjN2EzMTliOTAxZjhiNGI3YjMxMDljMThmNjgyZmRkZGY3OGU1ZmZkZjQ4MTM4OTQ0OWUyOGVjIiwiZXhwIjoxNzk1NTMzNTA4fQ.tQKFU7aZ3EKb7RkB99QTaWVduaaKaKjEa1nk43aeSlo"
|
|
12
12
|
}
|
|
13
13
|
}
|
|
@@ -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') {
|
|
@@ -114,7 +115,7 @@ async function createAction(opts) {
|
|
|
114
115
|
try { return contract.interface.parseLog(l); } catch (_) { return null; }
|
|
115
116
|
}).find(Boolean);
|
|
116
117
|
const out = {
|
|
117
|
-
txHash: receipt.
|
|
118
|
+
txHash: receipt.hash,
|
|
118
119
|
registry: evt && evt.args ? evt.args.registry : undefined,
|
|
119
120
|
policy,
|
|
120
121
|
};
|
|
@@ -140,7 +141,7 @@ async function setPriceAction(key, price, opts) {
|
|
|
140
141
|
key,
|
|
141
142
|
price,
|
|
142
143
|
priceWei: priceWei.toString(),
|
|
143
|
-
txHash: receipt.
|
|
144
|
+
txHash: receipt.hash,
|
|
144
145
|
};
|
|
145
146
|
if (opts && opts.json) {
|
|
146
147
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -172,7 +173,7 @@ async function sellAction(key, price, opts = {}) {
|
|
|
172
173
|
const tx = await facet.createPersonalRegistry(policy);
|
|
173
174
|
const rcpt = await tx.wait();
|
|
174
175
|
if (!opts.json) {
|
|
175
|
-
console.log(`đ Personal registry created (policy=${policy}) -> tx ${rcpt.
|
|
176
|
+
console.log(`đ Personal registry created (policy=${policy}) -> tx ${rcpt.hash}`);
|
|
176
177
|
}
|
|
177
178
|
}
|
|
178
179
|
|
|
@@ -244,10 +245,12 @@ async function sellAction(key, price, opts = {}) {
|
|
|
244
245
|
throw new Error('Lit encryption helpers not available. Ensure @lit-protocol/encryption is installed.');
|
|
245
246
|
}
|
|
246
247
|
|
|
247
|
-
const litNetwork = opts.litNetwork || process.env.LIT_NETWORK || '
|
|
248
|
-
const client = new LitNodeClient({ litNetwork });
|
|
248
|
+
const litNetwork = opts.litNetwork || process.env.LIT_NETWORK || 'datil-test';
|
|
249
|
+
const client = new LitNodeClient({ litNetwork, debug: false });
|
|
249
250
|
await client.connect();
|
|
250
251
|
|
|
252
|
+
const litChain = await inferLitChain(provider, opts.chain);
|
|
253
|
+
|
|
251
254
|
let sessionSigs = null;
|
|
252
255
|
if (opts.session) {
|
|
253
256
|
sessionSigs = loadJsonFile(opts.session, '--session');
|
|
@@ -261,13 +264,14 @@ async function sellAction(key, price, opts = {}) {
|
|
|
261
264
|
authSig = loadJsonFile(opts.authSig, '--auth-sig');
|
|
262
265
|
} else if (process.env.LIT_AUTH_SIG) {
|
|
263
266
|
authSig = loadJsonFile(process.env.LIT_AUTH_SIG, 'LIT_AUTH_SIG');
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
|
|
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);
|
|
267
273
|
}
|
|
268
274
|
}
|
|
269
|
-
|
|
270
|
-
const litChain = await inferLitChain(provider, opts.chain);
|
|
271
275
|
const accessConditions = buildAccessControlConditions(receiptAddress, receiptId, litChain);
|
|
272
276
|
|
|
273
277
|
const encResp = await encryptUint8Array({
|
|
@@ -328,12 +332,12 @@ async function sellAction(key, price, opts = {}) {
|
|
|
328
332
|
const marketplace = new Contract(marketplaceAddress, marketplaceAbi, wallet);
|
|
329
333
|
const priceTx = await marketplace.setPrice(keyHash, priceWei);
|
|
330
334
|
const priceReceipt = await priceTx.wait();
|
|
331
|
-
result.txHash = priceReceipt.
|
|
335
|
+
result.txHash = priceReceipt.hash;
|
|
332
336
|
|
|
333
337
|
if (opts.json) {
|
|
334
338
|
console.log(JSON.stringify(result, null, 2));
|
|
335
339
|
} else {
|
|
336
|
-
console.log(`â
Listed ${key} for ${price} SXXX (${priceReceipt.
|
|
340
|
+
console.log(`â
Listed ${key} for ${price} SXXX (tx: ${priceReceipt.hash})`);
|
|
337
341
|
if (result.encryptedCid) {
|
|
338
342
|
console.log(`đ Encrypted CID: ${result.encryptedCid}`);
|
|
339
343
|
console.log(`đī¸ Manifest CID: ${result.manifestCid}`);
|
|
@@ -430,7 +434,48 @@ async function listAction(opts = {}) {
|
|
|
430
434
|
let personalResourceMap = new Map();
|
|
431
435
|
|
|
432
436
|
if (!explicitKeys.length && subgraphUrl) {
|
|
433
|
-
|
|
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 = `
|
|
434
479
|
query($creator: Bytes!, $first: Int!) {
|
|
435
480
|
licensePurchases(where: { creator: $creator }, first: $first, orderBy: blockTimestamp, orderDirection: desc) {
|
|
436
481
|
key
|
|
@@ -444,7 +489,7 @@ async function listAction(opts = {}) {
|
|
|
444
489
|
}
|
|
445
490
|
`;
|
|
446
491
|
try {
|
|
447
|
-
const data = await subgraphQuery(subgraphUrl,
|
|
492
|
+
const data = await subgraphQuery(subgraphUrl, purchasesQuery, {
|
|
448
493
|
creator: creatorAddress.toLowerCase(),
|
|
449
494
|
first: limit,
|
|
450
495
|
});
|
|
@@ -452,7 +497,15 @@ async function listAction(opts = {}) {
|
|
|
452
497
|
for (const purchase of data?.licensePurchases || []) {
|
|
453
498
|
const keyHash = String(purchase.key);
|
|
454
499
|
const idKey = `hash:${keyHash}`;
|
|
455
|
-
|
|
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 {
|
|
456
509
|
entries.set(idKey, {
|
|
457
510
|
type: 'hash',
|
|
458
511
|
keyHash,
|
|
@@ -501,7 +554,10 @@ async function listAction(opts = {}) {
|
|
|
501
554
|
}
|
|
502
555
|
|
|
503
556
|
if (!entries.size) {
|
|
504
|
-
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.');
|
|
505
561
|
return [];
|
|
506
562
|
}
|
|
507
563
|
|
|
@@ -751,7 +807,7 @@ async function buyAction(creator, key, expectedPriceArg, opts = {}) {
|
|
|
751
807
|
const approveTx = await sxxx.approve(marketplaceAddress, approveAmount);
|
|
752
808
|
const approveReceipt = await approveTx.wait();
|
|
753
809
|
if (!opts.json) {
|
|
754
|
-
console.log(`â
SXXX approval tx ${approveReceipt.
|
|
810
|
+
console.log(`â
SXXX approval tx ${approveReceipt.hash}`);
|
|
755
811
|
}
|
|
756
812
|
}
|
|
757
813
|
|
|
@@ -778,7 +834,7 @@ async function buyAction(creator, key, expectedPriceArg, opts = {}) {
|
|
|
778
834
|
: sdk.personal.computeReceiptId(creatorAddress, key);
|
|
779
835
|
|
|
780
836
|
const result = {
|
|
781
|
-
txHash: receipt.
|
|
837
|
+
txHash: receipt.hash,
|
|
782
838
|
creator: creatorAddress,
|
|
783
839
|
buyer: buyerAddress,
|
|
784
840
|
key,
|
|
@@ -879,10 +935,12 @@ async function accessAction(creator, key, opts) {
|
|
|
879
935
|
|
|
880
936
|
if (!opts.skipDecrypt && payloadObject) {
|
|
881
937
|
const { LitNodeClient } = requireLit();
|
|
882
|
-
const litNetwork = opts.litNetwork || process.env.LIT_NETWORK || '
|
|
883
|
-
const client = new LitNodeClient({ litNetwork });
|
|
938
|
+
const litNetwork = opts.litNetwork || process.env.LIT_NETWORK || 'datil-test';
|
|
939
|
+
const client = new LitNodeClient({ litNetwork, debug: false });
|
|
884
940
|
await client.connect();
|
|
885
941
|
|
|
942
|
+
const litChain = await inferLitChain(provider, opts.chain);
|
|
943
|
+
|
|
886
944
|
let sessionSigs = null;
|
|
887
945
|
if (opts.session) {
|
|
888
946
|
sessionSigs = loadJsonFile(opts.session, '--session');
|
|
@@ -891,13 +949,20 @@ async function accessAction(creator, key, opts) {
|
|
|
891
949
|
}
|
|
892
950
|
|
|
893
951
|
let authSig = null;
|
|
894
|
-
if (
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
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
|
+
}
|
|
898
964
|
}
|
|
899
965
|
|
|
900
|
-
const litChain = await inferLitChain(provider, opts.chain);
|
|
901
966
|
decrypted = await sdk.personal.decryptWithLit({
|
|
902
967
|
encryptedCid: payloadObject,
|
|
903
968
|
receiptId,
|
package/dist/cli/mcp-setup.md
CHANGED
|
@@ -18,7 +18,7 @@ Create or update your `.env` file with the required configuration:
|
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
# Subgraph (preferred) + Blockchain
|
|
21
|
-
SUBGRAPH_URL=https://api.goldsky.com/api/public/project_cmhxp0fppsbdd01q56xp2gqw9/subgraphs/sxxx-protocol/1.0.
|
|
21
|
+
SUBGRAPH_URL=https://api.goldsky.com/api/public/project_cmhxp0fppsbdd01q56xp2gqw9/subgraphs/sxxx-protocol/1.0.1/gn
|
|
22
22
|
RPC_URL=https://sepolia.base.org
|
|
23
23
|
LIBRARY_REGISTRY_ADDRESS=0x032F2E93549640a319163Ba600fc50bA1AFBE50F
|
|
24
24
|
SUBDAO_FACTORY_ADDRESS=0x6bb6A83149F84Df0584aC863e5fE3416AFb214aC
|
|
@@ -65,7 +65,7 @@ You should see a JSON response listing the available tools.
|
|
|
65
65
|
"command": "node",
|
|
66
66
|
"args": ["/absolute/path/to/sage-protocol/cli/mcp-server-stdio.js"],
|
|
67
67
|
"env": {
|
|
68
|
-
"SUBGRAPH_URL": "https://api.goldsky.com/api/public/project_cmhxp0fppsbdd01q56xp2gqw9/subgraphs/sxxx-protocol/1.0.
|
|
68
|
+
"SUBGRAPH_URL": "https://api.goldsky.com/api/public/project_cmhxp0fppsbdd01q56xp2gqw9/subgraphs/sxxx-protocol/1.0.1/gn",
|
|
69
69
|
"RPC_URL": "https://sepolia.base.org",
|
|
70
70
|
"LIBRARY_REGISTRY_ADDRESS": "0x032F2E93549640a319163Ba600fc50bA1AFBE50F",
|
|
71
71
|
"SUBDAO_FACTORY_ADDRESS": "0x6bb6A83149F84Df0584aC863e5fE3416AFb214aC"
|