@sage-protocol/sdk 0.0.8 → 0.1.2
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/README.md +79 -0
- package/dist/browser/index.mjs +6355 -0
- package/dist/index.cjs +232 -14
- package/dist/index.mjs +234 -16
- package/dist/node/index.cjs +8240 -0
- package/dist/node/index.mjs +8251 -0
- package/package.json +21 -3
- package/types/index.d.ts +20 -0
package/dist/index.cjs
CHANGED
|
@@ -14,7 +14,7 @@ var require_package = __commonJS({
|
|
|
14
14
|
"package.json"(exports2, module2) {
|
|
15
15
|
module2.exports = {
|
|
16
16
|
name: "@sage-protocol/sdk",
|
|
17
|
-
version: "0.
|
|
17
|
+
version: "0.1.2",
|
|
18
18
|
description: "Backend-agnostic SDK for interacting with the Sage Protocol (governance, SubDAOs, tokens).",
|
|
19
19
|
main: "dist/index.cjs",
|
|
20
20
|
module: "dist/index.mjs",
|
|
@@ -24,9 +24,21 @@ var require_package = __commonJS({
|
|
|
24
24
|
exports: {
|
|
25
25
|
".": {
|
|
26
26
|
types: "./types/index.d.ts",
|
|
27
|
-
|
|
27
|
+
browser: "./dist/browser/index.mjs",
|
|
28
28
|
import: "./dist/index.mjs",
|
|
29
|
-
|
|
29
|
+
require: "./dist/index.cjs",
|
|
30
|
+
default: "./dist/index.mjs"
|
|
31
|
+
},
|
|
32
|
+
"./browser": {
|
|
33
|
+
types: "./types/index.d.ts",
|
|
34
|
+
import: "./dist/browser/index.mjs",
|
|
35
|
+
default: "./dist/browser/index.mjs"
|
|
36
|
+
},
|
|
37
|
+
"./node": {
|
|
38
|
+
types: "./types/index.d.ts",
|
|
39
|
+
import: "./dist/node/index.mjs",
|
|
40
|
+
require: "./dist/node/index.cjs",
|
|
41
|
+
default: "./dist/node/index.mjs"
|
|
30
42
|
},
|
|
31
43
|
"./package.json": "./package.json",
|
|
32
44
|
"./types/*": "./types/*"
|
|
@@ -37,6 +49,12 @@ var require_package = __commonJS({
|
|
|
37
49
|
"README.md"
|
|
38
50
|
],
|
|
39
51
|
sideEffects: false,
|
|
52
|
+
browser: {
|
|
53
|
+
fs: false,
|
|
54
|
+
path: false,
|
|
55
|
+
os: false,
|
|
56
|
+
child_process: false
|
|
57
|
+
},
|
|
40
58
|
repository: {
|
|
41
59
|
type: "git",
|
|
42
60
|
url: "git+https://github.com/sage-protocol/sdk.git"
|
|
@@ -848,7 +866,17 @@ var require_ipfs = __commonJS({
|
|
|
848
866
|
pinUrl: removeTrailingSlash(options.workerPinUrl || env.SAGE_IPFS_WORKER_PIN_URL || ""),
|
|
849
867
|
warmUrl: removeTrailingSlash(options.workerWarmUrl || env.SAGE_IPFS_WORKER_WARM_URL || ""),
|
|
850
868
|
signer: options.workerSigner || options.signer || null,
|
|
851
|
-
getAuth: options.workerGetAuth || null
|
|
869
|
+
getAuth: options.workerGetAuth || null,
|
|
870
|
+
address: options.workerAddress || env.SAGE_SANDBOX_ADDRESS || "",
|
|
871
|
+
discoveryEventsPath: options.workerDiscoveryEventsPath || env.SAGE_IPFS_WORKER_DISCOVERY_EVENTS_PATH || "/discover/events",
|
|
872
|
+
discoveryMcpPath: options.workerDiscoveryMcpPath || env.SAGE_IPFS_WORKER_DISCOVERY_MCP_PATH || "/discover/mcp",
|
|
873
|
+
discoveryLaunchPath: options.workerDiscoveryLaunchPath || env.SAGE_IPFS_WORKER_DISCOVERY_LAUNCH_PATH || "/discover/launch",
|
|
874
|
+
discoveryFeedPath: options.workerDiscoveryFeedPath || env.SAGE_IPFS_WORKER_DISCOVERY_FEED_PATH || "/discover",
|
|
875
|
+
discoveryMetricsPath: options.workerDiscoveryMetricsPath || env.SAGE_IPFS_WORKER_DISCOVERY_METRICS_PATH || "/discover/metrics",
|
|
876
|
+
governanceReportPath: options.workerGovernanceReportPath || env.SAGE_IPFS_WORKER_GOVERNANCE_REPORT_PATH || "/governance/report",
|
|
877
|
+
governanceReportsPath: options.workerGovernanceReportsPath || env.SAGE_IPFS_WORKER_GOVERNANCE_REPORTS_PATH || "/governance/reports",
|
|
878
|
+
governanceReviewPath: options.workerGovernanceReviewPath || env.SAGE_IPFS_WORKER_GOVERNANCE_REVIEW_PATH || "/governance/report/review",
|
|
879
|
+
governanceBatchPath: options.workerGovernanceBatchPath || env.SAGE_IPFS_WORKER_GOVERNANCE_BATCH_PATH || "/governance/report/batch"
|
|
852
880
|
},
|
|
853
881
|
web3: {
|
|
854
882
|
token: options.web3Token || env.W3S_TOKEN || env.WEB3_STORAGE_TOKEN || ""
|
|
@@ -892,6 +920,28 @@ var require_ipfs = __commonJS({
|
|
|
892
920
|
if (kind === "delete" && config.worker.pinUrl) return `${ensureEndsWith(config.worker.pinUrl, "/pin")}/${cid}`;
|
|
893
921
|
throw new Error(`Worker endpoint for ${kind} not configured`);
|
|
894
922
|
}
|
|
923
|
+
function workerPath(key, fallback) {
|
|
924
|
+
return ensureLeadingSlash(config.worker[key] || fallback);
|
|
925
|
+
}
|
|
926
|
+
function workerEndpoint(key, fallback) {
|
|
927
|
+
const base = workerBaseUrl();
|
|
928
|
+
if (!base) throw new Error("worker_base_url_required");
|
|
929
|
+
return `${base}${workerPath(key, fallback)}`;
|
|
930
|
+
}
|
|
931
|
+
async function postWorkerJson(pathKey, fallback, payload = {}, extraHeaders = {}) {
|
|
932
|
+
const url = workerEndpoint(pathKey, fallback);
|
|
933
|
+
const { headers, auth } = await buildWorkerAuthHeaders({ ...extraHeaders, "Content-Type": "application/json" });
|
|
934
|
+
const body = { ...payload };
|
|
935
|
+
if (auth && body.auth == null) body.auth = auth;
|
|
936
|
+
const response = await axiosInstance.post(url, body, { headers, timeout: config.timeoutMs });
|
|
937
|
+
return response?.data;
|
|
938
|
+
}
|
|
939
|
+
async function getWorkerJson(pathKey, fallback, params = {}, extraHeaders = {}) {
|
|
940
|
+
const url = workerEndpoint(pathKey, fallback);
|
|
941
|
+
const { headers } = await buildWorkerAuthHeaders({ "Accept": "application/json", ...extraHeaders });
|
|
942
|
+
const response = await axiosInstance.get(url, { headers, params, timeout: config.timeoutMs });
|
|
943
|
+
return response?.data;
|
|
944
|
+
}
|
|
895
945
|
async function buildWorkerAuthHeaders(extraHeaders = {}) {
|
|
896
946
|
if (config.worker.token) {
|
|
897
947
|
return { headers: { ...extraHeaders, Authorization: `Bearer ${config.worker.token}` }, auth: null };
|
|
@@ -1168,6 +1218,83 @@ var require_ipfs = __commonJS({
|
|
|
1168
1218
|
}
|
|
1169
1219
|
return { provider: null, ok: true };
|
|
1170
1220
|
}
|
|
1221
|
+
async function recordDiscoveryEvent(event = {}) {
|
|
1222
|
+
if (!event || typeof event !== "object") throw new Error("event required");
|
|
1223
|
+
const promptId = typeof event.promptId === "string" ? event.promptId.trim() : "";
|
|
1224
|
+
if (!promptId) throw new Error("promptId required");
|
|
1225
|
+
const payload = { ...event, promptId };
|
|
1226
|
+
return postWorkerJson("discoveryEventsPath", "/discover/events", payload);
|
|
1227
|
+
}
|
|
1228
|
+
async function recordMcpUsageEvent({ promptId, metadata, address } = {}) {
|
|
1229
|
+
const id = typeof promptId === "string" ? promptId.trim() : "";
|
|
1230
|
+
if (!id) throw new Error("promptId required");
|
|
1231
|
+
const payload = { promptId: id };
|
|
1232
|
+
if (metadata && typeof metadata === "object") payload.metadata = metadata;
|
|
1233
|
+
const actor = address || config.worker.address;
|
|
1234
|
+
if (actor) payload.address = actor;
|
|
1235
|
+
return postWorkerJson("discoveryMcpPath", "/discover/mcp", payload);
|
|
1236
|
+
}
|
|
1237
|
+
async function recordLaunchEvent({ promptId, metadata, address } = {}) {
|
|
1238
|
+
const id = typeof promptId === "string" ? promptId.trim() : "";
|
|
1239
|
+
if (!id) throw new Error("promptId required");
|
|
1240
|
+
const payload = { promptId: id };
|
|
1241
|
+
if (metadata && typeof metadata === "object") payload.metadata = metadata;
|
|
1242
|
+
const actor = address || config.worker.address;
|
|
1243
|
+
if (actor) payload.address = actor;
|
|
1244
|
+
return postWorkerJson("discoveryLaunchPath", "/discover/launch", payload);
|
|
1245
|
+
}
|
|
1246
|
+
async function submitGovernanceReport(payload = {}) {
|
|
1247
|
+
if (!payload || typeof payload !== "object") throw new Error("payload required");
|
|
1248
|
+
const promptId = typeof payload.promptId === "string" ? payload.promptId.trim() : "";
|
|
1249
|
+
if (!promptId) throw new Error("promptId required");
|
|
1250
|
+
const body = { promptId };
|
|
1251
|
+
const reporter = payload.address || config.worker.address;
|
|
1252
|
+
if (reporter) body.address = reporter;
|
|
1253
|
+
if (typeof payload.reason === "string") body.reason = payload.reason;
|
|
1254
|
+
if (typeof payload.note === "string") body.note = payload.note;
|
|
1255
|
+
if (payload.weight !== void 0) {
|
|
1256
|
+
const weight = Number(payload.weight);
|
|
1257
|
+
if (Number.isFinite(weight) && weight > 0) body.weight = weight;
|
|
1258
|
+
}
|
|
1259
|
+
return postWorkerJson("governanceReportPath", "/governance/report", body);
|
|
1260
|
+
}
|
|
1261
|
+
async function listGovernanceReports(params = {}) {
|
|
1262
|
+
const query = {};
|
|
1263
|
+
if (params.status) query.status = params.status;
|
|
1264
|
+
if (params.limit !== void 0) query.limit = params.limit;
|
|
1265
|
+
if (params.cursor !== void 0) query.cursor = params.cursor;
|
|
1266
|
+
return getWorkerJson("governanceReportsPath", "/governance/reports", query);
|
|
1267
|
+
}
|
|
1268
|
+
async function reviewGovernanceReport(payload = {}) {
|
|
1269
|
+
if (!payload || typeof payload !== "object") throw new Error("payload required");
|
|
1270
|
+
const id = typeof payload.id === "string" ? payload.id.trim() : "";
|
|
1271
|
+
if (!id) throw new Error("report id required");
|
|
1272
|
+
const status = typeof payload.status === "string" ? payload.status.trim() : "";
|
|
1273
|
+
if (!status) throw new Error("status required");
|
|
1274
|
+
const body = { id, status };
|
|
1275
|
+
if (typeof payload.note === "string") body.note = payload.note;
|
|
1276
|
+
if (typeof payload.action === "string") body.action = payload.action;
|
|
1277
|
+
return postWorkerJson("governanceReviewPath", "/governance/report/review", body);
|
|
1278
|
+
}
|
|
1279
|
+
async function batchGovernanceReports(payload = {}) {
|
|
1280
|
+
if (!payload || typeof payload !== "object") throw new Error("payload required");
|
|
1281
|
+
const ids = Array.isArray(payload.ids) ? payload.ids.map(String).filter(Boolean) : [];
|
|
1282
|
+
if (!ids.length) throw new Error("ids required");
|
|
1283
|
+
const action = typeof payload.action === "string" ? payload.action.trim() : "";
|
|
1284
|
+
if (!action) throw new Error("action required");
|
|
1285
|
+
const body = { ids, action };
|
|
1286
|
+
if (typeof payload.note === "string") body.note = payload.note;
|
|
1287
|
+
return postWorkerJson("governanceBatchPath", "/governance/report/batch", body);
|
|
1288
|
+
}
|
|
1289
|
+
async function fetchDiscovery(params = {}) {
|
|
1290
|
+
const query = {};
|
|
1291
|
+
if (params.filter) query.filter = params.filter;
|
|
1292
|
+
if (params.limit !== void 0) query.limit = params.limit;
|
|
1293
|
+
return getWorkerJson("discoveryFeedPath", "/discover", query);
|
|
1294
|
+
}
|
|
1295
|
+
async function fetchDiscoveryMetrics(params = {}) {
|
|
1296
|
+
return getWorkerJson("discoveryMetricsPath", "/discover/metrics", params);
|
|
1297
|
+
}
|
|
1171
1298
|
return {
|
|
1172
1299
|
config,
|
|
1173
1300
|
hasPinataCreds,
|
|
@@ -1180,6 +1307,15 @@ var require_ipfs = __commonJS({
|
|
|
1180
1307
|
warmGateways,
|
|
1181
1308
|
buildGatewayUrls: (cid, extra) => buildGatewayUrls(cid, config.gateway, extra),
|
|
1182
1309
|
pin,
|
|
1310
|
+
recordDiscoveryEvent,
|
|
1311
|
+
recordMcpUsage: recordMcpUsageEvent,
|
|
1312
|
+
recordLaunchEvent,
|
|
1313
|
+
submitGovernanceReport,
|
|
1314
|
+
listGovernanceReports,
|
|
1315
|
+
reviewGovernanceReport,
|
|
1316
|
+
batchGovernanceReports,
|
|
1317
|
+
fetchDiscovery,
|
|
1318
|
+
fetchDiscoveryMetrics,
|
|
1183
1319
|
generateCid
|
|
1184
1320
|
};
|
|
1185
1321
|
}
|
|
@@ -3120,7 +3256,12 @@ var require_operations = __commonJS({
|
|
|
3120
3256
|
proposalId,
|
|
3121
3257
|
refresh = false,
|
|
3122
3258
|
cache = null,
|
|
3123
|
-
fromBlock = 0
|
|
3259
|
+
fromBlock = 0,
|
|
3260
|
+
helperAddress = null,
|
|
3261
|
+
hints = {},
|
|
3262
|
+
chunkSizeBlocks = 1e4,
|
|
3263
|
+
lookBackBlocks = 2e3,
|
|
3264
|
+
lookAheadBlocks = 2e3
|
|
3124
3265
|
}) {
|
|
3125
3266
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
3126
3267
|
const govAddr = normaliseGovernor(governor);
|
|
@@ -3130,6 +3271,30 @@ var require_operations = __commonJS({
|
|
|
3130
3271
|
const cached = await cacheAdapter.load(govAddr, id);
|
|
3131
3272
|
if (cached) return cached;
|
|
3132
3273
|
}
|
|
3274
|
+
if (helperAddress) {
|
|
3275
|
+
try {
|
|
3276
|
+
const helperAbi = [
|
|
3277
|
+
"function getProposalTuple(uint256) view returns (address[] targets,uint256[] values,bytes[] calldatas,bytes32 descriptionHash,bool exists)"
|
|
3278
|
+
];
|
|
3279
|
+
const helper = new Contract(helperAddress, helperAbi, provider);
|
|
3280
|
+
const res = await helper.getProposalTuple(id);
|
|
3281
|
+
if (res && res.exists) {
|
|
3282
|
+
const tuple2 = {
|
|
3283
|
+
id,
|
|
3284
|
+
governor: normaliseGovernor(governor),
|
|
3285
|
+
targets: res.targets || [],
|
|
3286
|
+
values: (res.values || []).map((v) => BigInt(v)),
|
|
3287
|
+
calldatas: (res.calldatas || []).map(String),
|
|
3288
|
+
description: "",
|
|
3289
|
+
descriptionHash: res.descriptionHash || null,
|
|
3290
|
+
createdBlock: null
|
|
3291
|
+
};
|
|
3292
|
+
if (cacheAdapter) await cacheAdapter.save(governor, id, tuple2);
|
|
3293
|
+
return tuple2;
|
|
3294
|
+
}
|
|
3295
|
+
} catch (_) {
|
|
3296
|
+
}
|
|
3297
|
+
}
|
|
3133
3298
|
let metadata = null;
|
|
3134
3299
|
try {
|
|
3135
3300
|
metadata = await governance2.getProposalMetadata({ provider, governor: govAddr, id });
|
|
@@ -3137,14 +3302,66 @@ var require_operations = __commonJS({
|
|
|
3137
3302
|
metadata = null;
|
|
3138
3303
|
}
|
|
3139
3304
|
if (!metadata) {
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3305
|
+
let lower = fromBlock || 0;
|
|
3306
|
+
try {
|
|
3307
|
+
const govAbi = new Interface(ABI.Governor);
|
|
3308
|
+
const govC = new Contract(govAddr, govAbi, provider);
|
|
3309
|
+
const snapshot = hints.snapshot ?? await govC.proposalSnapshot(id).catch(() => null);
|
|
3310
|
+
const votingDelay = hints.votingDelay ?? await govC.votingDelay().catch(() => null);
|
|
3311
|
+
if (snapshot !== null && votingDelay !== null) {
|
|
3312
|
+
const approxCreation = Number(snapshot) - Number(votingDelay);
|
|
3313
|
+
lower = approxCreation > 0 ? approxCreation : 0;
|
|
3314
|
+
const upper = lower + Number(lookAheadBlocks);
|
|
3315
|
+
const from = lower > lookBackBlocks ? lower - Number(lookBackBlocks) : 0;
|
|
3316
|
+
const toBlock = await provider.getBlockNumber();
|
|
3317
|
+
const max = Math.min(upper + Number(lookBackBlocks), Number(toBlock));
|
|
3318
|
+
const topic = govC.interface.getEvent("ProposalCreated").topicHash;
|
|
3319
|
+
for (let start = from; start <= max; start += Number(chunkSizeBlocks)) {
|
|
3320
|
+
const end = Math.min(max, start + Number(chunkSizeBlocks));
|
|
3321
|
+
try {
|
|
3322
|
+
const logs = await provider.getLogs({
|
|
3323
|
+
address: govAddr,
|
|
3324
|
+
topics: [topic],
|
|
3325
|
+
fromBlock: start,
|
|
3326
|
+
toBlock: end
|
|
3327
|
+
});
|
|
3328
|
+
for (const log of logs) {
|
|
3329
|
+
try {
|
|
3330
|
+
const parsed = govC.interface.parseLog(log);
|
|
3331
|
+
const pid = normaliseProposalId(parsed.args.proposalId);
|
|
3332
|
+
if (pid === id) {
|
|
3333
|
+
metadata = {
|
|
3334
|
+
id,
|
|
3335
|
+
governor: govAddr,
|
|
3336
|
+
targets: Array.from(parsed.args.targets || [], String),
|
|
3337
|
+
values: Array.from(parsed.args.values || [], (v) => BigInt(v.toString())),
|
|
3338
|
+
calldatas: Array.from(parsed.args.calldatas || [], (b) => String(b)),
|
|
3339
|
+
description: String(parsed.args.description || ""),
|
|
3340
|
+
descriptionHash: governance2.hashDescription ? governance2.hashDescription(String(parsed.args.description || "")) : keccak256(toUtf8Bytes(String(parsed.args.description || ""))),
|
|
3341
|
+
createdBlock: log.blockNumber
|
|
3342
|
+
};
|
|
3343
|
+
break;
|
|
3344
|
+
}
|
|
3345
|
+
} catch (_) {
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3348
|
+
if (metadata) break;
|
|
3349
|
+
} catch (_) {
|
|
3350
|
+
}
|
|
3351
|
+
}
|
|
3146
3352
|
}
|
|
3147
|
-
})
|
|
3353
|
+
} catch (_) {
|
|
3354
|
+
}
|
|
3355
|
+
if (!metadata) {
|
|
3356
|
+
const page = await governance2.listProposals({ provider, governor: govAddr, fromBlock, toBlock: "latest" });
|
|
3357
|
+
metadata = page.find((entry) => {
|
|
3358
|
+
try {
|
|
3359
|
+
return normaliseProposalId(entry.id || entry.proposalId) === id;
|
|
3360
|
+
} catch (_) {
|
|
3361
|
+
return false;
|
|
3362
|
+
}
|
|
3363
|
+
}) || null;
|
|
3364
|
+
}
|
|
3148
3365
|
}
|
|
3149
3366
|
if (!metadata) {
|
|
3150
3367
|
throw new SageSDKError(CODES.NOT_FOUND, "proposal tuple not found");
|
|
@@ -3342,10 +3559,11 @@ var require_operations = __commonJS({
|
|
|
3342
3559
|
proposalId,
|
|
3343
3560
|
refresh = false,
|
|
3344
3561
|
cache = null,
|
|
3345
|
-
includeTimeline = false
|
|
3562
|
+
includeTimeline = false,
|
|
3563
|
+
helperAddress = null
|
|
3346
3564
|
}) {
|
|
3347
3565
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
3348
|
-
const tuple = await resolveProposalTuple({ provider, governor, proposalId, refresh, cache });
|
|
3566
|
+
const tuple = await resolveProposalTuple({ provider, governor, proposalId, refresh, cache, helperAddress });
|
|
3349
3567
|
let proposal = null;
|
|
3350
3568
|
try {
|
|
3351
3569
|
proposal = await governance2.getProposal({ provider, governor: tuple.governor, id: tuple.id });
|
package/dist/index.mjs
CHANGED
|
@@ -20,7 +20,7 @@ var require_package = __commonJS({
|
|
|
20
20
|
"package.json"(exports, module) {
|
|
21
21
|
module.exports = {
|
|
22
22
|
name: "@sage-protocol/sdk",
|
|
23
|
-
version: "0.
|
|
23
|
+
version: "0.1.2",
|
|
24
24
|
description: "Backend-agnostic SDK for interacting with the Sage Protocol (governance, SubDAOs, tokens).",
|
|
25
25
|
main: "dist/index.cjs",
|
|
26
26
|
module: "dist/index.mjs",
|
|
@@ -30,9 +30,21 @@ var require_package = __commonJS({
|
|
|
30
30
|
exports: {
|
|
31
31
|
".": {
|
|
32
32
|
types: "./types/index.d.ts",
|
|
33
|
-
|
|
33
|
+
browser: "./dist/browser/index.mjs",
|
|
34
34
|
import: "./dist/index.mjs",
|
|
35
|
-
|
|
35
|
+
require: "./dist/index.cjs",
|
|
36
|
+
default: "./dist/index.mjs"
|
|
37
|
+
},
|
|
38
|
+
"./browser": {
|
|
39
|
+
types: "./types/index.d.ts",
|
|
40
|
+
import: "./dist/browser/index.mjs",
|
|
41
|
+
default: "./dist/browser/index.mjs"
|
|
42
|
+
},
|
|
43
|
+
"./node": {
|
|
44
|
+
types: "./types/index.d.ts",
|
|
45
|
+
import: "./dist/node/index.mjs",
|
|
46
|
+
require: "./dist/node/index.cjs",
|
|
47
|
+
default: "./dist/node/index.mjs"
|
|
36
48
|
},
|
|
37
49
|
"./package.json": "./package.json",
|
|
38
50
|
"./types/*": "./types/*"
|
|
@@ -43,6 +55,12 @@ var require_package = __commonJS({
|
|
|
43
55
|
"README.md"
|
|
44
56
|
],
|
|
45
57
|
sideEffects: false,
|
|
58
|
+
browser: {
|
|
59
|
+
fs: false,
|
|
60
|
+
path: false,
|
|
61
|
+
os: false,
|
|
62
|
+
child_process: false
|
|
63
|
+
},
|
|
46
64
|
repository: {
|
|
47
65
|
type: "git",
|
|
48
66
|
url: "git+https://github.com/sage-protocol/sdk.git"
|
|
@@ -854,7 +872,17 @@ var require_ipfs = __commonJS({
|
|
|
854
872
|
pinUrl: removeTrailingSlash(options.workerPinUrl || env.SAGE_IPFS_WORKER_PIN_URL || ""),
|
|
855
873
|
warmUrl: removeTrailingSlash(options.workerWarmUrl || env.SAGE_IPFS_WORKER_WARM_URL || ""),
|
|
856
874
|
signer: options.workerSigner || options.signer || null,
|
|
857
|
-
getAuth: options.workerGetAuth || null
|
|
875
|
+
getAuth: options.workerGetAuth || null,
|
|
876
|
+
address: options.workerAddress || env.SAGE_SANDBOX_ADDRESS || "",
|
|
877
|
+
discoveryEventsPath: options.workerDiscoveryEventsPath || env.SAGE_IPFS_WORKER_DISCOVERY_EVENTS_PATH || "/discover/events",
|
|
878
|
+
discoveryMcpPath: options.workerDiscoveryMcpPath || env.SAGE_IPFS_WORKER_DISCOVERY_MCP_PATH || "/discover/mcp",
|
|
879
|
+
discoveryLaunchPath: options.workerDiscoveryLaunchPath || env.SAGE_IPFS_WORKER_DISCOVERY_LAUNCH_PATH || "/discover/launch",
|
|
880
|
+
discoveryFeedPath: options.workerDiscoveryFeedPath || env.SAGE_IPFS_WORKER_DISCOVERY_FEED_PATH || "/discover",
|
|
881
|
+
discoveryMetricsPath: options.workerDiscoveryMetricsPath || env.SAGE_IPFS_WORKER_DISCOVERY_METRICS_PATH || "/discover/metrics",
|
|
882
|
+
governanceReportPath: options.workerGovernanceReportPath || env.SAGE_IPFS_WORKER_GOVERNANCE_REPORT_PATH || "/governance/report",
|
|
883
|
+
governanceReportsPath: options.workerGovernanceReportsPath || env.SAGE_IPFS_WORKER_GOVERNANCE_REPORTS_PATH || "/governance/reports",
|
|
884
|
+
governanceReviewPath: options.workerGovernanceReviewPath || env.SAGE_IPFS_WORKER_GOVERNANCE_REVIEW_PATH || "/governance/report/review",
|
|
885
|
+
governanceBatchPath: options.workerGovernanceBatchPath || env.SAGE_IPFS_WORKER_GOVERNANCE_BATCH_PATH || "/governance/report/batch"
|
|
858
886
|
},
|
|
859
887
|
web3: {
|
|
860
888
|
token: options.web3Token || env.W3S_TOKEN || env.WEB3_STORAGE_TOKEN || ""
|
|
@@ -898,6 +926,28 @@ var require_ipfs = __commonJS({
|
|
|
898
926
|
if (kind === "delete" && config.worker.pinUrl) return `${ensureEndsWith(config.worker.pinUrl, "/pin")}/${cid}`;
|
|
899
927
|
throw new Error(`Worker endpoint for ${kind} not configured`);
|
|
900
928
|
}
|
|
929
|
+
function workerPath(key, fallback) {
|
|
930
|
+
return ensureLeadingSlash(config.worker[key] || fallback);
|
|
931
|
+
}
|
|
932
|
+
function workerEndpoint(key, fallback) {
|
|
933
|
+
const base = workerBaseUrl();
|
|
934
|
+
if (!base) throw new Error("worker_base_url_required");
|
|
935
|
+
return `${base}${workerPath(key, fallback)}`;
|
|
936
|
+
}
|
|
937
|
+
async function postWorkerJson(pathKey, fallback, payload = {}, extraHeaders = {}) {
|
|
938
|
+
const url = workerEndpoint(pathKey, fallback);
|
|
939
|
+
const { headers, auth } = await buildWorkerAuthHeaders({ ...extraHeaders, "Content-Type": "application/json" });
|
|
940
|
+
const body = { ...payload };
|
|
941
|
+
if (auth && body.auth == null) body.auth = auth;
|
|
942
|
+
const response = await axiosInstance.post(url, body, { headers, timeout: config.timeoutMs });
|
|
943
|
+
return response?.data;
|
|
944
|
+
}
|
|
945
|
+
async function getWorkerJson(pathKey, fallback, params = {}, extraHeaders = {}) {
|
|
946
|
+
const url = workerEndpoint(pathKey, fallback);
|
|
947
|
+
const { headers } = await buildWorkerAuthHeaders({ "Accept": "application/json", ...extraHeaders });
|
|
948
|
+
const response = await axiosInstance.get(url, { headers, params, timeout: config.timeoutMs });
|
|
949
|
+
return response?.data;
|
|
950
|
+
}
|
|
901
951
|
async function buildWorkerAuthHeaders(extraHeaders = {}) {
|
|
902
952
|
if (config.worker.token) {
|
|
903
953
|
return { headers: { ...extraHeaders, Authorization: `Bearer ${config.worker.token}` }, auth: null };
|
|
@@ -1174,6 +1224,83 @@ var require_ipfs = __commonJS({
|
|
|
1174
1224
|
}
|
|
1175
1225
|
return { provider: null, ok: true };
|
|
1176
1226
|
}
|
|
1227
|
+
async function recordDiscoveryEvent(event = {}) {
|
|
1228
|
+
if (!event || typeof event !== "object") throw new Error("event required");
|
|
1229
|
+
const promptId = typeof event.promptId === "string" ? event.promptId.trim() : "";
|
|
1230
|
+
if (!promptId) throw new Error("promptId required");
|
|
1231
|
+
const payload = { ...event, promptId };
|
|
1232
|
+
return postWorkerJson("discoveryEventsPath", "/discover/events", payload);
|
|
1233
|
+
}
|
|
1234
|
+
async function recordMcpUsageEvent({ promptId, metadata, address } = {}) {
|
|
1235
|
+
const id = typeof promptId === "string" ? promptId.trim() : "";
|
|
1236
|
+
if (!id) throw new Error("promptId required");
|
|
1237
|
+
const payload = { promptId: id };
|
|
1238
|
+
if (metadata && typeof metadata === "object") payload.metadata = metadata;
|
|
1239
|
+
const actor = address || config.worker.address;
|
|
1240
|
+
if (actor) payload.address = actor;
|
|
1241
|
+
return postWorkerJson("discoveryMcpPath", "/discover/mcp", payload);
|
|
1242
|
+
}
|
|
1243
|
+
async function recordLaunchEvent({ promptId, metadata, address } = {}) {
|
|
1244
|
+
const id = typeof promptId === "string" ? promptId.trim() : "";
|
|
1245
|
+
if (!id) throw new Error("promptId required");
|
|
1246
|
+
const payload = { promptId: id };
|
|
1247
|
+
if (metadata && typeof metadata === "object") payload.metadata = metadata;
|
|
1248
|
+
const actor = address || config.worker.address;
|
|
1249
|
+
if (actor) payload.address = actor;
|
|
1250
|
+
return postWorkerJson("discoveryLaunchPath", "/discover/launch", payload);
|
|
1251
|
+
}
|
|
1252
|
+
async function submitGovernanceReport(payload = {}) {
|
|
1253
|
+
if (!payload || typeof payload !== "object") throw new Error("payload required");
|
|
1254
|
+
const promptId = typeof payload.promptId === "string" ? payload.promptId.trim() : "";
|
|
1255
|
+
if (!promptId) throw new Error("promptId required");
|
|
1256
|
+
const body = { promptId };
|
|
1257
|
+
const reporter = payload.address || config.worker.address;
|
|
1258
|
+
if (reporter) body.address = reporter;
|
|
1259
|
+
if (typeof payload.reason === "string") body.reason = payload.reason;
|
|
1260
|
+
if (typeof payload.note === "string") body.note = payload.note;
|
|
1261
|
+
if (payload.weight !== void 0) {
|
|
1262
|
+
const weight = Number(payload.weight);
|
|
1263
|
+
if (Number.isFinite(weight) && weight > 0) body.weight = weight;
|
|
1264
|
+
}
|
|
1265
|
+
return postWorkerJson("governanceReportPath", "/governance/report", body);
|
|
1266
|
+
}
|
|
1267
|
+
async function listGovernanceReports(params = {}) {
|
|
1268
|
+
const query = {};
|
|
1269
|
+
if (params.status) query.status = params.status;
|
|
1270
|
+
if (params.limit !== void 0) query.limit = params.limit;
|
|
1271
|
+
if (params.cursor !== void 0) query.cursor = params.cursor;
|
|
1272
|
+
return getWorkerJson("governanceReportsPath", "/governance/reports", query);
|
|
1273
|
+
}
|
|
1274
|
+
async function reviewGovernanceReport(payload = {}) {
|
|
1275
|
+
if (!payload || typeof payload !== "object") throw new Error("payload required");
|
|
1276
|
+
const id = typeof payload.id === "string" ? payload.id.trim() : "";
|
|
1277
|
+
if (!id) throw new Error("report id required");
|
|
1278
|
+
const status = typeof payload.status === "string" ? payload.status.trim() : "";
|
|
1279
|
+
if (!status) throw new Error("status required");
|
|
1280
|
+
const body = { id, status };
|
|
1281
|
+
if (typeof payload.note === "string") body.note = payload.note;
|
|
1282
|
+
if (typeof payload.action === "string") body.action = payload.action;
|
|
1283
|
+
return postWorkerJson("governanceReviewPath", "/governance/report/review", body);
|
|
1284
|
+
}
|
|
1285
|
+
async function batchGovernanceReports(payload = {}) {
|
|
1286
|
+
if (!payload || typeof payload !== "object") throw new Error("payload required");
|
|
1287
|
+
const ids = Array.isArray(payload.ids) ? payload.ids.map(String).filter(Boolean) : [];
|
|
1288
|
+
if (!ids.length) throw new Error("ids required");
|
|
1289
|
+
const action = typeof payload.action === "string" ? payload.action.trim() : "";
|
|
1290
|
+
if (!action) throw new Error("action required");
|
|
1291
|
+
const body = { ids, action };
|
|
1292
|
+
if (typeof payload.note === "string") body.note = payload.note;
|
|
1293
|
+
return postWorkerJson("governanceBatchPath", "/governance/report/batch", body);
|
|
1294
|
+
}
|
|
1295
|
+
async function fetchDiscovery(params = {}) {
|
|
1296
|
+
const query = {};
|
|
1297
|
+
if (params.filter) query.filter = params.filter;
|
|
1298
|
+
if (params.limit !== void 0) query.limit = params.limit;
|
|
1299
|
+
return getWorkerJson("discoveryFeedPath", "/discover", query);
|
|
1300
|
+
}
|
|
1301
|
+
async function fetchDiscoveryMetrics(params = {}) {
|
|
1302
|
+
return getWorkerJson("discoveryMetricsPath", "/discover/metrics", params);
|
|
1303
|
+
}
|
|
1177
1304
|
return {
|
|
1178
1305
|
config,
|
|
1179
1306
|
hasPinataCreds,
|
|
@@ -1186,6 +1313,15 @@ var require_ipfs = __commonJS({
|
|
|
1186
1313
|
warmGateways,
|
|
1187
1314
|
buildGatewayUrls: (cid, extra) => buildGatewayUrls(cid, config.gateway, extra),
|
|
1188
1315
|
pin,
|
|
1316
|
+
recordDiscoveryEvent,
|
|
1317
|
+
recordMcpUsage: recordMcpUsageEvent,
|
|
1318
|
+
recordLaunchEvent,
|
|
1319
|
+
submitGovernanceReport,
|
|
1320
|
+
listGovernanceReports,
|
|
1321
|
+
reviewGovernanceReport,
|
|
1322
|
+
batchGovernanceReports,
|
|
1323
|
+
fetchDiscovery,
|
|
1324
|
+
fetchDiscoveryMetrics,
|
|
1189
1325
|
generateCid
|
|
1190
1326
|
};
|
|
1191
1327
|
}
|
|
@@ -3126,7 +3262,12 @@ var require_operations = __commonJS({
|
|
|
3126
3262
|
proposalId,
|
|
3127
3263
|
refresh = false,
|
|
3128
3264
|
cache = null,
|
|
3129
|
-
fromBlock = 0
|
|
3265
|
+
fromBlock = 0,
|
|
3266
|
+
helperAddress = null,
|
|
3267
|
+
hints = {},
|
|
3268
|
+
chunkSizeBlocks = 1e4,
|
|
3269
|
+
lookBackBlocks = 2e3,
|
|
3270
|
+
lookAheadBlocks = 2e3
|
|
3130
3271
|
}) {
|
|
3131
3272
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
3132
3273
|
const govAddr = normaliseGovernor(governor);
|
|
@@ -3136,6 +3277,30 @@ var require_operations = __commonJS({
|
|
|
3136
3277
|
const cached = await cacheAdapter.load(govAddr, id);
|
|
3137
3278
|
if (cached) return cached;
|
|
3138
3279
|
}
|
|
3280
|
+
if (helperAddress) {
|
|
3281
|
+
try {
|
|
3282
|
+
const helperAbi = [
|
|
3283
|
+
"function getProposalTuple(uint256) view returns (address[] targets,uint256[] values,bytes[] calldatas,bytes32 descriptionHash,bool exists)"
|
|
3284
|
+
];
|
|
3285
|
+
const helper = new Contract(helperAddress, helperAbi, provider);
|
|
3286
|
+
const res = await helper.getProposalTuple(id);
|
|
3287
|
+
if (res && res.exists) {
|
|
3288
|
+
const tuple2 = {
|
|
3289
|
+
id,
|
|
3290
|
+
governor: normaliseGovernor(governor),
|
|
3291
|
+
targets: res.targets || [],
|
|
3292
|
+
values: (res.values || []).map((v) => BigInt(v)),
|
|
3293
|
+
calldatas: (res.calldatas || []).map(String),
|
|
3294
|
+
description: "",
|
|
3295
|
+
descriptionHash: res.descriptionHash || null,
|
|
3296
|
+
createdBlock: null
|
|
3297
|
+
};
|
|
3298
|
+
if (cacheAdapter) await cacheAdapter.save(governor, id, tuple2);
|
|
3299
|
+
return tuple2;
|
|
3300
|
+
}
|
|
3301
|
+
} catch (_) {
|
|
3302
|
+
}
|
|
3303
|
+
}
|
|
3139
3304
|
let metadata = null;
|
|
3140
3305
|
try {
|
|
3141
3306
|
metadata = await governance.getProposalMetadata({ provider, governor: govAddr, id });
|
|
@@ -3143,14 +3308,66 @@ var require_operations = __commonJS({
|
|
|
3143
3308
|
metadata = null;
|
|
3144
3309
|
}
|
|
3145
3310
|
if (!metadata) {
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3311
|
+
let lower = fromBlock || 0;
|
|
3312
|
+
try {
|
|
3313
|
+
const govAbi = new Interface(ABI.Governor);
|
|
3314
|
+
const govC = new Contract(govAddr, govAbi, provider);
|
|
3315
|
+
const snapshot = hints.snapshot ?? await govC.proposalSnapshot(id).catch(() => null);
|
|
3316
|
+
const votingDelay = hints.votingDelay ?? await govC.votingDelay().catch(() => null);
|
|
3317
|
+
if (snapshot !== null && votingDelay !== null) {
|
|
3318
|
+
const approxCreation = Number(snapshot) - Number(votingDelay);
|
|
3319
|
+
lower = approxCreation > 0 ? approxCreation : 0;
|
|
3320
|
+
const upper = lower + Number(lookAheadBlocks);
|
|
3321
|
+
const from = lower > lookBackBlocks ? lower - Number(lookBackBlocks) : 0;
|
|
3322
|
+
const toBlock = await provider.getBlockNumber();
|
|
3323
|
+
const max = Math.min(upper + Number(lookBackBlocks), Number(toBlock));
|
|
3324
|
+
const topic = govC.interface.getEvent("ProposalCreated").topicHash;
|
|
3325
|
+
for (let start = from; start <= max; start += Number(chunkSizeBlocks)) {
|
|
3326
|
+
const end = Math.min(max, start + Number(chunkSizeBlocks));
|
|
3327
|
+
try {
|
|
3328
|
+
const logs = await provider.getLogs({
|
|
3329
|
+
address: govAddr,
|
|
3330
|
+
topics: [topic],
|
|
3331
|
+
fromBlock: start,
|
|
3332
|
+
toBlock: end
|
|
3333
|
+
});
|
|
3334
|
+
for (const log of logs) {
|
|
3335
|
+
try {
|
|
3336
|
+
const parsed = govC.interface.parseLog(log);
|
|
3337
|
+
const pid = normaliseProposalId(parsed.args.proposalId);
|
|
3338
|
+
if (pid === id) {
|
|
3339
|
+
metadata = {
|
|
3340
|
+
id,
|
|
3341
|
+
governor: govAddr,
|
|
3342
|
+
targets: Array.from(parsed.args.targets || [], String),
|
|
3343
|
+
values: Array.from(parsed.args.values || [], (v) => BigInt(v.toString())),
|
|
3344
|
+
calldatas: Array.from(parsed.args.calldatas || [], (b) => String(b)),
|
|
3345
|
+
description: String(parsed.args.description || ""),
|
|
3346
|
+
descriptionHash: governance.hashDescription ? governance.hashDescription(String(parsed.args.description || "")) : keccak256(toUtf8Bytes(String(parsed.args.description || ""))),
|
|
3347
|
+
createdBlock: log.blockNumber
|
|
3348
|
+
};
|
|
3349
|
+
break;
|
|
3350
|
+
}
|
|
3351
|
+
} catch (_) {
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
if (metadata) break;
|
|
3355
|
+
} catch (_) {
|
|
3356
|
+
}
|
|
3357
|
+
}
|
|
3152
3358
|
}
|
|
3153
|
-
})
|
|
3359
|
+
} catch (_) {
|
|
3360
|
+
}
|
|
3361
|
+
if (!metadata) {
|
|
3362
|
+
const page = await governance.listProposals({ provider, governor: govAddr, fromBlock, toBlock: "latest" });
|
|
3363
|
+
metadata = page.find((entry) => {
|
|
3364
|
+
try {
|
|
3365
|
+
return normaliseProposalId(entry.id || entry.proposalId) === id;
|
|
3366
|
+
} catch (_) {
|
|
3367
|
+
return false;
|
|
3368
|
+
}
|
|
3369
|
+
}) || null;
|
|
3370
|
+
}
|
|
3154
3371
|
}
|
|
3155
3372
|
if (!metadata) {
|
|
3156
3373
|
throw new SageSDKError(CODES.NOT_FOUND, "proposal tuple not found");
|
|
@@ -3348,10 +3565,11 @@ var require_operations = __commonJS({
|
|
|
3348
3565
|
proposalId,
|
|
3349
3566
|
refresh = false,
|
|
3350
3567
|
cache = null,
|
|
3351
|
-
includeTimeline = false
|
|
3568
|
+
includeTimeline = false,
|
|
3569
|
+
helperAddress = null
|
|
3352
3570
|
}) {
|
|
3353
3571
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
3354
|
-
const tuple = await resolveProposalTuple({ provider, governor, proposalId, refresh, cache });
|
|
3572
|
+
const tuple = await resolveProposalTuple({ provider, governor, proposalId, refresh, cache, helperAddress });
|
|
3355
3573
|
let proposal = null;
|
|
3356
3574
|
try {
|
|
3357
3575
|
proposal = await governance.getProposal({ provider, governor: tuple.governor, id: tuple.id });
|
|
@@ -7923,7 +8141,7 @@ var require_doppler = __commonJS({
|
|
|
7923
8141
|
});
|
|
7924
8142
|
|
|
7925
8143
|
// src/index.js
|
|
7926
|
-
var
|
|
8144
|
+
var require_src = __commonJS({
|
|
7927
8145
|
"src/index.js"(exports, module) {
|
|
7928
8146
|
var pkg = require_package();
|
|
7929
8147
|
var abi = require_abi();
|
|
@@ -8023,4 +8241,4 @@ var require_index = __commonJS({
|
|
|
8023
8241
|
};
|
|
8024
8242
|
}
|
|
8025
8243
|
});
|
|
8026
|
-
export default
|
|
8244
|
+
export default require_src();
|