@sage-protocol/sdk 0.0.8 → 0.1.6
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 +6464 -0
- package/dist/index.cjs +599 -428
- package/dist/index.mjs +694 -523
- package/dist/node/index.cjs +8193 -0
- package/dist/node/index.mjs +8204 -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.6",
|
|
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"
|
|
@@ -226,20 +244,19 @@ var require_abi = __commonJS({
|
|
|
226
244
|
var PersonalLicenseReceipt = [
|
|
227
245
|
"function balanceOf(address account, uint256 id) view returns (uint256)"
|
|
228
246
|
];
|
|
229
|
-
var
|
|
230
|
-
"function
|
|
231
|
-
"function
|
|
232
|
-
"function
|
|
233
|
-
"function
|
|
234
|
-
"function
|
|
235
|
-
"function
|
|
236
|
-
"
|
|
237
|
-
"
|
|
238
|
-
"
|
|
239
|
-
"
|
|
240
|
-
"
|
|
241
|
-
"
|
|
242
|
-
"function lpContributions(address,address) view returns (uint256)"
|
|
247
|
+
var TreasuryWrapper = [
|
|
248
|
+
"function execute(address,uint256,bytes,bytes32) returns (bool)",
|
|
249
|
+
"function allowedTargets(address) view returns (bool)",
|
|
250
|
+
"function allowedSelectors(bytes4) view returns (bool)",
|
|
251
|
+
"function owners(address) view returns (bool)",
|
|
252
|
+
"function ownerCount() view returns (uint256)",
|
|
253
|
+
"function registry() view returns (address)",
|
|
254
|
+
"event TreasuryAction(address indexed caller, address indexed target, uint256 value, bytes data, bytes32 refId)",
|
|
255
|
+
"event AllowedTargetUpdated(address indexed target, bool allowed)",
|
|
256
|
+
"event AllowedSelectorUpdated(bytes4 indexed selector, bool allowed)",
|
|
257
|
+
"event OwnerAdded(address indexed owner)",
|
|
258
|
+
"event OwnerRemoved(address indexed owner)",
|
|
259
|
+
"event TokensSwept(address indexed token, address indexed to, uint256 amount)"
|
|
243
260
|
];
|
|
244
261
|
var GovernanceBoostMerkle = [
|
|
245
262
|
"function getProposalConfig(uint256) view returns (tuple(uint256 proposalId,address token,uint256 totalAmount,uint64 startTime,uint64 endTime,uint256 merkleRoot))",
|
|
@@ -251,29 +268,6 @@ var require_abi = __commonJS({
|
|
|
251
268
|
"function create(uint256 proposalId, address token, uint256 perVoter, uint256 maxVoters)",
|
|
252
269
|
"function fund(uint256 proposalId, uint256 amount)"
|
|
253
270
|
];
|
|
254
|
-
var BondDepository = [
|
|
255
|
-
// Core getters
|
|
256
|
-
"function payoutToken() view returns (address)",
|
|
257
|
-
"function principalToken() view returns (address)",
|
|
258
|
-
"function treasury() view returns (address)",
|
|
259
|
-
// Terms
|
|
260
|
-
"function terms() view returns (tuple(uint256 controlVariable,uint256 minimumPrice,uint256 maxPayout,uint256 maxDebt,uint256 vestingTerm,uint256 fee))",
|
|
261
|
-
"function totalDebt(address) view returns (uint256)",
|
|
262
|
-
// Pricing
|
|
263
|
-
"function bondPrice() view returns (uint256)",
|
|
264
|
-
"function bondPrice(address) view returns (uint256)",
|
|
265
|
-
"function bondPriceInUSD() view returns (uint256)",
|
|
266
|
-
"function currentDebt() view returns (uint256)",
|
|
267
|
-
"function debtRatio() view returns (uint256)",
|
|
268
|
-
"function standardizedDebtRatio() view returns (uint256)",
|
|
269
|
-
// User views
|
|
270
|
-
"function bondInfo(address) view returns (tuple(uint256 payout,uint256 vesting,uint256 lastBlock,uint256 pricePaid))",
|
|
271
|
-
"function pendingPayout(address) view returns (uint256)",
|
|
272
|
-
"function percentVestedFor(address) view returns (uint256)",
|
|
273
|
-
// Actions
|
|
274
|
-
"function deposit(uint256 _amount, uint256 _maxPrice) returns (uint256 payout_)",
|
|
275
|
-
"function redeem(address _recipient, bool _stake) returns (uint256)"
|
|
276
|
-
];
|
|
277
271
|
var Events = {
|
|
278
272
|
ProposalCreated: "event ProposalCreated(uint256 id, address proposer, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, uint256 startBlock, uint256 endBlock, string description)"
|
|
279
273
|
};
|
|
@@ -292,10 +286,10 @@ var require_abi = __commonJS({
|
|
|
292
286
|
PersonalLibraryFacet,
|
|
293
287
|
PersonalMarketplace,
|
|
294
288
|
PersonalLicenseReceipt,
|
|
295
|
-
|
|
289
|
+
TreasuryWrapper,
|
|
290
|
+
// Protocol treasury (replaces SageTreasury)
|
|
296
291
|
GovernanceBoostMerkle,
|
|
297
292
|
GovernanceBoostDirect,
|
|
298
|
-
BondDepository,
|
|
299
293
|
Events
|
|
300
294
|
};
|
|
301
295
|
}
|
|
@@ -511,9 +505,9 @@ var require_subgraph = __commonJS({
|
|
|
511
505
|
* Canonical proposal timeline. Tries common fields first, then event-style fallbacks.
|
|
512
506
|
* Returns { id, createdAt, queuedAt, executedAt, canceledAt, eta, state } (numbers/strings may be null when unavailable).
|
|
513
507
|
*/
|
|
514
|
-
async getProposalTimeline({ url, id }) {
|
|
508
|
+
async getProposalTimeline({ url, id: id2 }) {
|
|
515
509
|
if (!url) throw new Error("subgraph url required");
|
|
516
|
-
const pid = typeof
|
|
510
|
+
const pid = typeof id2 === "bigint" ? id2.toString() : String(id2);
|
|
517
511
|
try {
|
|
518
512
|
const data = await query(url, `
|
|
519
513
|
query($id: ID!) {
|
|
@@ -701,10 +695,10 @@ var require_subgraph = __commonJS({
|
|
|
701
695
|
updatedAt: Number(p.updatedAt || 0)
|
|
702
696
|
} : null;
|
|
703
697
|
},
|
|
704
|
-
async getProposalById({ url, id }) {
|
|
698
|
+
async getProposalById({ url, id: id2 }) {
|
|
705
699
|
if (!url) throw new Error("subgraph url required");
|
|
706
700
|
const doc = `query($id: ID!){ proposal(id:$id){ id proposer description createdAt updatedAt state eta targets values calldatas } }`;
|
|
707
|
-
const data = await query(url, doc, { id: String(
|
|
701
|
+
const data = await query(url, doc, { id: String(id2) });
|
|
708
702
|
const p = data?.proposal;
|
|
709
703
|
if (!p) return null;
|
|
710
704
|
return {
|
|
@@ -752,7 +746,7 @@ var require_ipfs = __commonJS({
|
|
|
752
746
|
"src/ipfs/index.js"(exports2, module2) {
|
|
753
747
|
var axiosDefault = require("axios");
|
|
754
748
|
var FormData = require("form-data");
|
|
755
|
-
var { ethers } = require("ethers");
|
|
749
|
+
var { ethers: ethers2 } = require("ethers");
|
|
756
750
|
var DEFAULT_GATEWAY = "https://ipfs.dev.sageprotocol.io/ipfs";
|
|
757
751
|
function toLowerSafe(value, fallback = "") {
|
|
758
752
|
if (value == null) return fallback;
|
|
@@ -807,14 +801,14 @@ var require_ipfs = __commonJS({
|
|
|
807
801
|
}
|
|
808
802
|
return Array.from(urls);
|
|
809
803
|
}
|
|
810
|
-
function ensureLeadingSlash(
|
|
811
|
-
const value =
|
|
804
|
+
function ensureLeadingSlash(path2, fallback = "") {
|
|
805
|
+
const value = path2 || fallback;
|
|
812
806
|
if (!value) return fallback;
|
|
813
807
|
return value.startsWith("/") ? value : `/${value}`;
|
|
814
808
|
}
|
|
815
809
|
function generateDeterministicCid(payload) {
|
|
816
810
|
const content = Buffer.isBuffer(payload) ? payload : typeof payload === "string" ? Buffer.from(payload) : Buffer.from(JSON.stringify(payload));
|
|
817
|
-
const hash =
|
|
811
|
+
const hash = ethers2.keccak256(content);
|
|
818
812
|
const hashStr = hash.slice(2);
|
|
819
813
|
const cidSuffix = (hashStr + hashStr).slice(0, 44);
|
|
820
814
|
return `Qm${cidSuffix}`;
|
|
@@ -848,7 +842,17 @@ var require_ipfs = __commonJS({
|
|
|
848
842
|
pinUrl: removeTrailingSlash(options.workerPinUrl || env.SAGE_IPFS_WORKER_PIN_URL || ""),
|
|
849
843
|
warmUrl: removeTrailingSlash(options.workerWarmUrl || env.SAGE_IPFS_WORKER_WARM_URL || ""),
|
|
850
844
|
signer: options.workerSigner || options.signer || null,
|
|
851
|
-
getAuth: options.workerGetAuth || null
|
|
845
|
+
getAuth: options.workerGetAuth || null,
|
|
846
|
+
address: options.workerAddress || env.SAGE_SANDBOX_ADDRESS || "",
|
|
847
|
+
discoveryEventsPath: options.workerDiscoveryEventsPath || env.SAGE_IPFS_WORKER_DISCOVERY_EVENTS_PATH || "/discover/events",
|
|
848
|
+
discoveryMcpPath: options.workerDiscoveryMcpPath || env.SAGE_IPFS_WORKER_DISCOVERY_MCP_PATH || "/discover/mcp",
|
|
849
|
+
discoveryLaunchPath: options.workerDiscoveryLaunchPath || env.SAGE_IPFS_WORKER_DISCOVERY_LAUNCH_PATH || "/discover/launch",
|
|
850
|
+
discoveryFeedPath: options.workerDiscoveryFeedPath || env.SAGE_IPFS_WORKER_DISCOVERY_FEED_PATH || "/discover",
|
|
851
|
+
discoveryMetricsPath: options.workerDiscoveryMetricsPath || env.SAGE_IPFS_WORKER_DISCOVERY_METRICS_PATH || "/discover/metrics",
|
|
852
|
+
governanceReportPath: options.workerGovernanceReportPath || env.SAGE_IPFS_WORKER_GOVERNANCE_REPORT_PATH || "/governance/report",
|
|
853
|
+
governanceReportsPath: options.workerGovernanceReportsPath || env.SAGE_IPFS_WORKER_GOVERNANCE_REPORTS_PATH || "/governance/reports",
|
|
854
|
+
governanceReviewPath: options.workerGovernanceReviewPath || env.SAGE_IPFS_WORKER_GOVERNANCE_REVIEW_PATH || "/governance/report/review",
|
|
855
|
+
governanceBatchPath: options.workerGovernanceBatchPath || env.SAGE_IPFS_WORKER_GOVERNANCE_BATCH_PATH || "/governance/report/batch"
|
|
852
856
|
},
|
|
853
857
|
web3: {
|
|
854
858
|
token: options.web3Token || env.W3S_TOKEN || env.WEB3_STORAGE_TOKEN || ""
|
|
@@ -876,7 +880,7 @@ var require_ipfs = __commonJS({
|
|
|
876
880
|
}
|
|
877
881
|
function workerUrl(kind, cid) {
|
|
878
882
|
const base = workerBaseUrl();
|
|
879
|
-
const ensure = (
|
|
883
|
+
const ensure = (path2) => path2.startsWith("/") ? path2 : `/${path2}`;
|
|
880
884
|
if (base) {
|
|
881
885
|
if (kind === "challenge") return `${base}${ensure(config.worker.challengePath || "/auth/challenge")}`;
|
|
882
886
|
if (kind === "upload") return `${base}${ensure(config.worker.uploadPath || "/ipfs/upload")}`;
|
|
@@ -892,6 +896,28 @@ var require_ipfs = __commonJS({
|
|
|
892
896
|
if (kind === "delete" && config.worker.pinUrl) return `${ensureEndsWith(config.worker.pinUrl, "/pin")}/${cid}`;
|
|
893
897
|
throw new Error(`Worker endpoint for ${kind} not configured`);
|
|
894
898
|
}
|
|
899
|
+
function workerPath(key, fallback) {
|
|
900
|
+
return ensureLeadingSlash(config.worker[key] || fallback);
|
|
901
|
+
}
|
|
902
|
+
function workerEndpoint(key, fallback) {
|
|
903
|
+
const base = workerBaseUrl();
|
|
904
|
+
if (!base) throw new Error("worker_base_url_required");
|
|
905
|
+
return `${base}${workerPath(key, fallback)}`;
|
|
906
|
+
}
|
|
907
|
+
async function postWorkerJson(pathKey, fallback, payload = {}, extraHeaders = {}) {
|
|
908
|
+
const url = workerEndpoint(pathKey, fallback);
|
|
909
|
+
const { headers, auth } = await buildWorkerAuthHeaders({ ...extraHeaders, "Content-Type": "application/json" });
|
|
910
|
+
const body = { ...payload };
|
|
911
|
+
if (auth && body.auth == null) body.auth = auth;
|
|
912
|
+
const response = await axiosInstance.post(url, body, { headers, timeout: config.timeoutMs });
|
|
913
|
+
return response?.data;
|
|
914
|
+
}
|
|
915
|
+
async function getWorkerJson(pathKey, fallback, params = {}, extraHeaders = {}) {
|
|
916
|
+
const url = workerEndpoint(pathKey, fallback);
|
|
917
|
+
const { headers } = await buildWorkerAuthHeaders({ "Accept": "application/json", ...extraHeaders });
|
|
918
|
+
const response = await axiosInstance.get(url, { headers, params, timeout: config.timeoutMs });
|
|
919
|
+
return response?.data;
|
|
920
|
+
}
|
|
895
921
|
async function buildWorkerAuthHeaders(extraHeaders = {}) {
|
|
896
922
|
if (config.worker.token) {
|
|
897
923
|
return { headers: { ...extraHeaders, Authorization: `Bearer ${config.worker.token}` }, auth: null };
|
|
@@ -1168,6 +1194,83 @@ var require_ipfs = __commonJS({
|
|
|
1168
1194
|
}
|
|
1169
1195
|
return { provider: null, ok: true };
|
|
1170
1196
|
}
|
|
1197
|
+
async function recordDiscoveryEvent(event = {}) {
|
|
1198
|
+
if (!event || typeof event !== "object") throw new Error("event required");
|
|
1199
|
+
const promptId = typeof event.promptId === "string" ? event.promptId.trim() : "";
|
|
1200
|
+
if (!promptId) throw new Error("promptId required");
|
|
1201
|
+
const payload = { ...event, promptId };
|
|
1202
|
+
return postWorkerJson("discoveryEventsPath", "/discover/events", payload);
|
|
1203
|
+
}
|
|
1204
|
+
async function recordMcpUsageEvent({ promptId, metadata, address } = {}) {
|
|
1205
|
+
const id2 = typeof promptId === "string" ? promptId.trim() : "";
|
|
1206
|
+
if (!id2) throw new Error("promptId required");
|
|
1207
|
+
const payload = { promptId: id2 };
|
|
1208
|
+
if (metadata && typeof metadata === "object") payload.metadata = metadata;
|
|
1209
|
+
const actor = address || config.worker.address;
|
|
1210
|
+
if (actor) payload.address = actor;
|
|
1211
|
+
return postWorkerJson("discoveryMcpPath", "/discover/mcp", payload);
|
|
1212
|
+
}
|
|
1213
|
+
async function recordLaunchEvent({ promptId, metadata, address } = {}) {
|
|
1214
|
+
const id2 = typeof promptId === "string" ? promptId.trim() : "";
|
|
1215
|
+
if (!id2) throw new Error("promptId required");
|
|
1216
|
+
const payload = { promptId: id2 };
|
|
1217
|
+
if (metadata && typeof metadata === "object") payload.metadata = metadata;
|
|
1218
|
+
const actor = address || config.worker.address;
|
|
1219
|
+
if (actor) payload.address = actor;
|
|
1220
|
+
return postWorkerJson("discoveryLaunchPath", "/discover/launch", payload);
|
|
1221
|
+
}
|
|
1222
|
+
async function submitGovernanceReport(payload = {}) {
|
|
1223
|
+
if (!payload || typeof payload !== "object") throw new Error("payload required");
|
|
1224
|
+
const promptId = typeof payload.promptId === "string" ? payload.promptId.trim() : "";
|
|
1225
|
+
if (!promptId) throw new Error("promptId required");
|
|
1226
|
+
const body = { promptId };
|
|
1227
|
+
const reporter = payload.address || config.worker.address;
|
|
1228
|
+
if (reporter) body.address = reporter;
|
|
1229
|
+
if (typeof payload.reason === "string") body.reason = payload.reason;
|
|
1230
|
+
if (typeof payload.note === "string") body.note = payload.note;
|
|
1231
|
+
if (payload.weight !== void 0) {
|
|
1232
|
+
const weight = Number(payload.weight);
|
|
1233
|
+
if (Number.isFinite(weight) && weight > 0) body.weight = weight;
|
|
1234
|
+
}
|
|
1235
|
+
return postWorkerJson("governanceReportPath", "/governance/report", body);
|
|
1236
|
+
}
|
|
1237
|
+
async function listGovernanceReports(params = {}) {
|
|
1238
|
+
const query = {};
|
|
1239
|
+
if (params.status) query.status = params.status;
|
|
1240
|
+
if (params.limit !== void 0) query.limit = params.limit;
|
|
1241
|
+
if (params.cursor !== void 0) query.cursor = params.cursor;
|
|
1242
|
+
return getWorkerJson("governanceReportsPath", "/governance/reports", query);
|
|
1243
|
+
}
|
|
1244
|
+
async function reviewGovernanceReport(payload = {}) {
|
|
1245
|
+
if (!payload || typeof payload !== "object") throw new Error("payload required");
|
|
1246
|
+
const id2 = typeof payload.id === "string" ? payload.id.trim() : "";
|
|
1247
|
+
if (!id2) throw new Error("report id required");
|
|
1248
|
+
const status = typeof payload.status === "string" ? payload.status.trim() : "";
|
|
1249
|
+
if (!status) throw new Error("status required");
|
|
1250
|
+
const body = { id: id2, status };
|
|
1251
|
+
if (typeof payload.note === "string") body.note = payload.note;
|
|
1252
|
+
if (typeof payload.action === "string") body.action = payload.action;
|
|
1253
|
+
return postWorkerJson("governanceReviewPath", "/governance/report/review", body);
|
|
1254
|
+
}
|
|
1255
|
+
async function batchGovernanceReports(payload = {}) {
|
|
1256
|
+
if (!payload || typeof payload !== "object") throw new Error("payload required");
|
|
1257
|
+
const ids = Array.isArray(payload.ids) ? payload.ids.map(String).filter(Boolean) : [];
|
|
1258
|
+
if (!ids.length) throw new Error("ids required");
|
|
1259
|
+
const action = typeof payload.action === "string" ? payload.action.trim() : "";
|
|
1260
|
+
if (!action) throw new Error("action required");
|
|
1261
|
+
const body = { ids, action };
|
|
1262
|
+
if (typeof payload.note === "string") body.note = payload.note;
|
|
1263
|
+
return postWorkerJson("governanceBatchPath", "/governance/report/batch", body);
|
|
1264
|
+
}
|
|
1265
|
+
async function fetchDiscovery(params = {}) {
|
|
1266
|
+
const query = {};
|
|
1267
|
+
if (params.filter) query.filter = params.filter;
|
|
1268
|
+
if (params.limit !== void 0) query.limit = params.limit;
|
|
1269
|
+
return getWorkerJson("discoveryFeedPath", "/discover", query);
|
|
1270
|
+
}
|
|
1271
|
+
async function fetchDiscoveryMetrics(params = {}) {
|
|
1272
|
+
return getWorkerJson("discoveryMetricsPath", "/discover/metrics", params);
|
|
1273
|
+
}
|
|
1171
1274
|
return {
|
|
1172
1275
|
config,
|
|
1173
1276
|
hasPinataCreds,
|
|
@@ -1180,6 +1283,15 @@ var require_ipfs = __commonJS({
|
|
|
1180
1283
|
warmGateways,
|
|
1181
1284
|
buildGatewayUrls: (cid, extra) => buildGatewayUrls(cid, config.gateway, extra),
|
|
1182
1285
|
pin,
|
|
1286
|
+
recordDiscoveryEvent,
|
|
1287
|
+
recordMcpUsage: recordMcpUsageEvent,
|
|
1288
|
+
recordLaunchEvent,
|
|
1289
|
+
submitGovernanceReport,
|
|
1290
|
+
listGovernanceReports,
|
|
1291
|
+
reviewGovernanceReport,
|
|
1292
|
+
batchGovernanceReports,
|
|
1293
|
+
fetchDiscovery,
|
|
1294
|
+
fetchDiscoveryMetrics,
|
|
1183
1295
|
generateCid
|
|
1184
1296
|
};
|
|
1185
1297
|
}
|
|
@@ -1461,18 +1573,18 @@ var require_validation = __commonJS({
|
|
|
1461
1573
|
} catch (_) {
|
|
1462
1574
|
}
|
|
1463
1575
|
}
|
|
1464
|
-
function normaliseSchemaPaths(schemaPaths, { path }) {
|
|
1576
|
+
function normaliseSchemaPaths(schemaPaths, { path: path2 }) {
|
|
1465
1577
|
if (Array.isArray(schemaPaths) && schemaPaths.length) {
|
|
1466
1578
|
return schemaPaths;
|
|
1467
1579
|
}
|
|
1468
1580
|
return [
|
|
1469
|
-
|
|
1470
|
-
|
|
1581
|
+
path2.join(process.cwd(), "docs", "schemas", "manifest.schema.json"),
|
|
1582
|
+
path2.join(__dirname, "..", "..", "docs", "schemas", "manifest.schema.json")
|
|
1471
1583
|
];
|
|
1472
1584
|
}
|
|
1473
|
-
function safeJsonParse(
|
|
1585
|
+
function safeJsonParse(fs2, file) {
|
|
1474
1586
|
try {
|
|
1475
|
-
const raw =
|
|
1587
|
+
const raw = fs2.readFileSync(file, "utf8");
|
|
1476
1588
|
return JSON.parse(raw);
|
|
1477
1589
|
} catch (_) {
|
|
1478
1590
|
return null;
|
|
@@ -1498,17 +1610,17 @@ var require_validation = __commonJS({
|
|
|
1498
1610
|
}
|
|
1499
1611
|
function createManifestValidator(options = {}) {
|
|
1500
1612
|
const {
|
|
1501
|
-
fs = fsDefault,
|
|
1502
|
-
path = pathDefault,
|
|
1613
|
+
fs: fs2 = fsDefault,
|
|
1614
|
+
path: path2 = pathDefault,
|
|
1503
1615
|
ajvFactory = defaultAjvFactory,
|
|
1504
1616
|
addFormats = defaultAddFormats,
|
|
1505
1617
|
schemaPaths
|
|
1506
1618
|
} = options;
|
|
1507
|
-
const searchPaths = normaliseSchemaPaths(schemaPaths, { path });
|
|
1619
|
+
const searchPaths = normaliseSchemaPaths(schemaPaths, { path: path2 });
|
|
1508
1620
|
function loadSchema() {
|
|
1509
1621
|
for (const schemaPath of searchPaths) {
|
|
1510
|
-
if (!
|
|
1511
|
-
const schema = safeJsonParse(
|
|
1622
|
+
if (!fs2.existsSync(schemaPath)) continue;
|
|
1623
|
+
const schema = safeJsonParse(fs2, schemaPath);
|
|
1512
1624
|
if (schema) return { schema, schemaPath };
|
|
1513
1625
|
}
|
|
1514
1626
|
return { schema: null, schemaPath: null };
|
|
@@ -1581,7 +1693,7 @@ var require_validation = __commonJS({
|
|
|
1581
1693
|
if (!manifestPath) {
|
|
1582
1694
|
throw new Error("manifestPath required");
|
|
1583
1695
|
}
|
|
1584
|
-
const data = safeJsonParse(
|
|
1696
|
+
const data = safeJsonParse(fs2, manifestPath);
|
|
1585
1697
|
if (!data) {
|
|
1586
1698
|
return {
|
|
1587
1699
|
ok: false,
|
|
@@ -1614,8 +1726,8 @@ var require_validation = __commonJS({
|
|
|
1614
1726
|
seenKeys.add(key);
|
|
1615
1727
|
const files = Array.isArray(prompt2.files) ? prompt2.files : [];
|
|
1616
1728
|
for (const file of files) {
|
|
1617
|
-
const resolved =
|
|
1618
|
-
if (!
|
|
1729
|
+
const resolved = path2.isAbsolute(file) ? file : manifestPath ? path2.join(path2.dirname(manifestPath), file) : file;
|
|
1730
|
+
if (!fs2.existsSync(resolved)) {
|
|
1619
1731
|
issues.push({
|
|
1620
1732
|
type: "missing_file",
|
|
1621
1733
|
message: `File not found: ${file}`,
|
|
@@ -1638,7 +1750,7 @@ var require_validation = __commonJS({
|
|
|
1638
1750
|
}
|
|
1639
1751
|
function bestPracticeCheckFile(manifestPath, options2 = {}) {
|
|
1640
1752
|
if (!manifestPath) throw new Error("manifestPath required");
|
|
1641
|
-
const data = safeJsonParse(
|
|
1753
|
+
const data = safeJsonParse(fs2, manifestPath);
|
|
1642
1754
|
if (!data) {
|
|
1643
1755
|
return [{ type: "parse_error", message: `Failed to parse JSON at ${manifestPath}`, manifestPath }];
|
|
1644
1756
|
}
|
|
@@ -1661,7 +1773,7 @@ var require_validation = __commonJS({
|
|
|
1661
1773
|
// src/library/index.js
|
|
1662
1774
|
var require_library = __commonJS({
|
|
1663
1775
|
"src/library/index.js"(exports2, module2) {
|
|
1664
|
-
var { Contract, getAddress, keccak256, toUtf8Bytes } = require("ethers");
|
|
1776
|
+
var { Contract, getAddress, keccak256, toUtf8Bytes, AbiCoder } = require("ethers");
|
|
1665
1777
|
var { Interface } = require("ethers");
|
|
1666
1778
|
var ABI = require_abi();
|
|
1667
1779
|
var { SageSDKError, CODES } = require_errors();
|
|
@@ -1700,17 +1812,31 @@ var require_library = __commonJS({
|
|
|
1700
1812
|
promptCount: Number(promptCount)
|
|
1701
1813
|
};
|
|
1702
1814
|
}
|
|
1815
|
+
function _computeLibraryKey(subdao2, libraryId) {
|
|
1816
|
+
const coder = AbiCoder.defaultAbiCoder ? AbiCoder.defaultAbiCoder() : new AbiCoder();
|
|
1817
|
+
const encoded = coder.encode(["address", "string"], [getAddress(subdao2), String(libraryId)]);
|
|
1818
|
+
return keccak256(encoded);
|
|
1819
|
+
}
|
|
1703
1820
|
async function getLatestLibrary({ provider, registry, subdao: subdao2, libraryId = "main" }) {
|
|
1704
1821
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
1705
1822
|
const addr = normalise(registry, "registry");
|
|
1706
1823
|
const sub = normalise(subdao2, "subdao");
|
|
1707
1824
|
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
1708
|
-
const key =
|
|
1825
|
+
const key = _computeLibraryKey(sub, libraryId);
|
|
1709
1826
|
const latestCID = await contract.subdaoLibraryLatest(key).catch(() => "");
|
|
1710
1827
|
if (!latestCID || latestCID.length === 0) return null;
|
|
1711
1828
|
const info = await getManifestInfo({ provider, registry: addr, manifestCID: latestCID });
|
|
1712
1829
|
return info;
|
|
1713
1830
|
}
|
|
1831
|
+
async function getBeforeAfterForUpdate({ provider, registry, subdao: subdao2, libraryId = "main", newCid }) {
|
|
1832
|
+
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
1833
|
+
const addr = normalise(registry, "registry");
|
|
1834
|
+
const sub = normalise(subdao2, "subdao");
|
|
1835
|
+
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
1836
|
+
const key = _computeLibraryKey(sub, libraryId);
|
|
1837
|
+
const prev = await contract.subdaoLibraryLatest(key).catch(() => "");
|
|
1838
|
+
return { previousCID: prev || null, newCID: String(newCid), libraryId: String(libraryId) };
|
|
1839
|
+
}
|
|
1714
1840
|
async function hasScopedOwnership({ provider, registry, subdao: subdao2, manifestCID }) {
|
|
1715
1841
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
1716
1842
|
const addr = normalise(registry, "registry");
|
|
@@ -1736,6 +1862,8 @@ var require_library = __commonJS({
|
|
|
1736
1862
|
getLatestLibrary,
|
|
1737
1863
|
hasScopedOwnership,
|
|
1738
1864
|
buildUpdateLibraryForSubDAOTx,
|
|
1865
|
+
_computeLibraryKey,
|
|
1866
|
+
getBeforeAfterForUpdate,
|
|
1739
1867
|
/** Build an authorizeTimelock(timelock, subdao) call for a LibraryRegistry. */
|
|
1740
1868
|
buildAuthorizeTimelockTx: function buildAuthorizeTimelockTx({ registry, timelock: timelock2, subdao: subdao2 }) {
|
|
1741
1869
|
const to = normalise(registry, "registry");
|
|
@@ -1822,11 +1950,11 @@ var require_governance = __commonJS({
|
|
|
1822
1950
|
stakeAmount
|
|
1823
1951
|
};
|
|
1824
1952
|
}
|
|
1825
|
-
async function getProposal({ provider, governor, id }) {
|
|
1953
|
+
async function getProposal({ provider, governor, id: id2 }) {
|
|
1826
1954
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
1827
1955
|
const addr = normaliseGovernor(governor);
|
|
1828
1956
|
const g = new Contract(addr, ABI.Governor, provider);
|
|
1829
|
-
const pid = typeof
|
|
1957
|
+
const pid = typeof id2 === "bigint" ? id2 : String(id2).startsWith("0x") ? BigInt(id2) : BigInt(String(id2));
|
|
1830
1958
|
const [state, snapshot, deadline, votes] = await Promise.all([
|
|
1831
1959
|
g.state(pid),
|
|
1832
1960
|
g.proposalSnapshot(pid),
|
|
@@ -1880,12 +2008,12 @@ var require_governance = __commonJS({
|
|
|
1880
2008
|
}
|
|
1881
2009
|
return proposals;
|
|
1882
2010
|
}
|
|
1883
|
-
async function getProposalMetadata({ provider, governor, id, fromBlock = 0, toBlock = "latest" }) {
|
|
2011
|
+
async function getProposalMetadata({ provider, governor, id: id2, fromBlock = 0, toBlock = "latest" }) {
|
|
1884
2012
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
1885
2013
|
const addr = normaliseGovernor(governor);
|
|
1886
2014
|
const iface = new Interface([ABI.Events.ProposalCreated]);
|
|
1887
2015
|
const topic = iface.getEvent("ProposalCreated").topicHash;
|
|
1888
|
-
const pid = typeof
|
|
2016
|
+
const pid = typeof id2 === "bigint" ? id2 : String(id2).startsWith("0x") ? BigInt(id2) : BigInt(String(id2));
|
|
1889
2017
|
const logs = await provider.getLogs({ address: addr, fromBlock, toBlock, topics: [topic] });
|
|
1890
2018
|
for (const log of logs) {
|
|
1891
2019
|
try {
|
|
@@ -1946,10 +2074,10 @@ var require_governance = __commonJS({
|
|
|
1946
2074
|
function buildCastVoteTx({ governor, proposalId, support, reason }) {
|
|
1947
2075
|
const addr = normaliseGovernor(governor);
|
|
1948
2076
|
const iface = new Interface(ABI.Governor);
|
|
1949
|
-
const
|
|
2077
|
+
const id2 = typeof proposalId === "bigint" ? proposalId : String(proposalId).startsWith("0x") ? BigInt(proposalId) : BigInt(String(proposalId));
|
|
1950
2078
|
const s = Number(support);
|
|
1951
2079
|
const hasReason = reason && String(reason).length > 0;
|
|
1952
|
-
const data = hasReason ? iface.encodeFunctionData("castVoteWithReason(uint256,uint8,string)", [
|
|
2080
|
+
const data = hasReason ? iface.encodeFunctionData("castVoteWithReason(uint256,uint8,string)", [id2, s, String(reason)]) : iface.encodeFunctionData("castVote(uint256,uint8)", [id2, s]);
|
|
1953
2081
|
return { to: addr, data, value: BigIntZero };
|
|
1954
2082
|
}
|
|
1955
2083
|
function cueTx(fn, { governor, targets = [], values = [], calldatas = [], descriptionOrHash = "" }) {
|
|
@@ -1970,17 +2098,73 @@ var require_governance = __commonJS({
|
|
|
1970
2098
|
function buildQueueByIdTx({ governor, proposalId }) {
|
|
1971
2099
|
const addr = normaliseGovernor(governor);
|
|
1972
2100
|
const iface = new Interface(ABI.Governor);
|
|
1973
|
-
const
|
|
1974
|
-
const data = iface.encodeFunctionData("queue(uint256)", [
|
|
2101
|
+
const id2 = typeof proposalId === "bigint" ? proposalId : String(proposalId).startsWith("0x") ? BigInt(proposalId) : BigInt(String(proposalId));
|
|
2102
|
+
const data = iface.encodeFunctionData("queue(uint256)", [id2]);
|
|
1975
2103
|
return { to: addr, data, value: BigIntZero };
|
|
1976
2104
|
}
|
|
1977
2105
|
function buildExecuteByIdTx({ governor, proposalId }) {
|
|
1978
2106
|
const addr = normaliseGovernor(governor);
|
|
1979
2107
|
const iface = new Interface(ABI.Governor);
|
|
1980
|
-
const
|
|
1981
|
-
const data = iface.encodeFunctionData("execute(uint256)", [
|
|
2108
|
+
const id2 = typeof proposalId === "bigint" ? proposalId : String(proposalId).startsWith("0x") ? BigInt(proposalId) : BigInt(String(proposalId));
|
|
2109
|
+
const data = iface.encodeFunctionData("execute(uint256)", [id2]);
|
|
1982
2110
|
return { to: addr, data, value: BigIntZero };
|
|
1983
2111
|
}
|
|
2112
|
+
async function decodeProposalEffects({ provider, governor, proposalId, fromBlock = 0, toBlock = "latest" }) {
|
|
2113
|
+
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2114
|
+
const govAddr = normaliseGovernor(governor);
|
|
2115
|
+
const iface = new Interface([ABI.Events.ProposalCreated]);
|
|
2116
|
+
const topic = iface.getEvent("ProposalCreated").topicHash;
|
|
2117
|
+
const id2 = typeof proposalId === "bigint" ? proposalId : String(proposalId).startsWith("0x") ? BigInt(proposalId) : BigInt(String(proposalId));
|
|
2118
|
+
let parsed = null;
|
|
2119
|
+
let logTxHash = null;
|
|
2120
|
+
const logs = await provider.getLogs({ address: govAddr, fromBlock, toBlock, topics: [topic] });
|
|
2121
|
+
for (const log of logs) {
|
|
2122
|
+
try {
|
|
2123
|
+
const p = iface.parseLog(log);
|
|
2124
|
+
if (BigInt(p.args.id.toString()) === id2) {
|
|
2125
|
+
parsed = p;
|
|
2126
|
+
logTxHash = log.transactionHash;
|
|
2127
|
+
break;
|
|
2128
|
+
}
|
|
2129
|
+
} catch (_) {
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
if (!parsed) throw new Error("ProposalCreated event not found");
|
|
2133
|
+
const targets = parsed.args.targets.map(getAddress);
|
|
2134
|
+
const calldatas = parsed.args.calldatas.map((d) => typeof d === "string" ? d : "0x" + Buffer.from(d).toString("hex"));
|
|
2135
|
+
const LibraryIface = new Interface(["function updateLibraryForSubDAO(address,string,string,uint256)", "function subdaoLibraryLatest(bytes32) view returns (string)"]);
|
|
2136
|
+
const PromptIface = new Interface(["function updatePromptByGovernance(string,string)"]);
|
|
2137
|
+
const coder = AbiCoder.defaultAbiCoder ? AbiCoder.defaultAbiCoder() : new AbiCoder();
|
|
2138
|
+
const effects = [];
|
|
2139
|
+
for (let i = 0; i < calldatas.length; i++) {
|
|
2140
|
+
const data = calldatas[i];
|
|
2141
|
+
const sel = data.slice(0, 10);
|
|
2142
|
+
try {
|
|
2143
|
+
const decoded = LibraryIface.decodeFunctionData("updateLibraryForSubDAO", data);
|
|
2144
|
+
const [subdao2, libraryId, newCid, promptCount] = decoded;
|
|
2145
|
+
let previousCID = null;
|
|
2146
|
+
try {
|
|
2147
|
+
const reg = new Contract(targets[i], ["function subdaoLibraryLatest(bytes32) view returns (string)"], provider);
|
|
2148
|
+
const key = keccak256(coder.encode(["address", "string"], [getAddress(subdao2), String(libraryId)]));
|
|
2149
|
+
const prev = await reg.subdaoLibraryLatest(key).catch(() => "");
|
|
2150
|
+
previousCID = prev && prev.length ? String(prev) : null;
|
|
2151
|
+
} catch (_) {
|
|
2152
|
+
}
|
|
2153
|
+
effects.push({ type: "libraryUpdate", index: i, target: targets[i], subdao: getAddress(subdao2), libraryId: String(libraryId), previousCid: previousCID, newCid: String(newCid), promptCount: Number(promptCount) });
|
|
2154
|
+
continue;
|
|
2155
|
+
} catch (_) {
|
|
2156
|
+
}
|
|
2157
|
+
try {
|
|
2158
|
+
const decodedP = PromptIface.decodeFunctionData("updatePromptByGovernance", data);
|
|
2159
|
+
const [key, newCid] = decodedP;
|
|
2160
|
+
effects.push({ type: "promptUpdate", index: i, target: targets[i], key: String(key), newCid: String(newCid) });
|
|
2161
|
+
continue;
|
|
2162
|
+
} catch (_) {
|
|
2163
|
+
}
|
|
2164
|
+
effects.push({ type: "unknown", index: i, target: targets[i], selector: sel });
|
|
2165
|
+
}
|
|
2166
|
+
return { governor: govAddr, proposalId: id2, tx: logTxHash, actions: { count: calldatas.length }, effects };
|
|
2167
|
+
}
|
|
1984
2168
|
async function getQuorumAt({ provider, governor, blockTag }) {
|
|
1985
2169
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
1986
2170
|
const addr = normaliseGovernor(governor);
|
|
@@ -2110,6 +2294,7 @@ var require_governance = __commonJS({
|
|
|
2110
2294
|
buildExecuteTx,
|
|
2111
2295
|
buildQueueByIdTx,
|
|
2112
2296
|
buildExecuteByIdTx,
|
|
2297
|
+
decodeProposalEffects,
|
|
2113
2298
|
makeProposalDescription,
|
|
2114
2299
|
stripProposalSalt,
|
|
2115
2300
|
getQuorumAt,
|
|
@@ -2816,7 +3001,7 @@ var require_openzeppelin = __commonJS({
|
|
|
2816
3001
|
for (const log of logs) {
|
|
2817
3002
|
try {
|
|
2818
3003
|
const parsed = iface.parseLog(log);
|
|
2819
|
-
const
|
|
3004
|
+
const id2 = BigInt(parsed.args.id.toString());
|
|
2820
3005
|
const proposer = getAddress(parsed.args.proposer);
|
|
2821
3006
|
const targets = parsed.args.targets.map(getAddress);
|
|
2822
3007
|
const values = parsed.args.values.map((v) => BigInt(v.toString()));
|
|
@@ -2826,7 +3011,7 @@ var require_openzeppelin = __commonJS({
|
|
|
2826
3011
|
const block = await provider.getBlock(log.blockNumber).catch(() => ({ timestamp: 0 }));
|
|
2827
3012
|
const quorum = await governance2.getQuorumAt({ provider, governor: addr, blockTag: BigInt(endBlock || log.blockNumber) }).catch(() => null);
|
|
2828
3013
|
const signatures = await getSignatureList({ provider, targets, calldatas, abiResolver, selectorResolver, chainId: resolvedChainId });
|
|
2829
|
-
items.push({ id, proposer, createdAt: Number(block.timestamp || 0), startBlock, endBlock, quorum, txHash: log.transactionHash, targets, values, calldatas, signatures });
|
|
3014
|
+
items.push({ id: id2, proposer, createdAt: Number(block.timestamp || 0), startBlock, endBlock, quorum, txHash: log.transactionHash, targets, values, calldatas, signatures });
|
|
2830
3015
|
} catch (_) {
|
|
2831
3016
|
}
|
|
2832
3017
|
}
|
|
@@ -2834,10 +3019,10 @@ var require_openzeppelin = __commonJS({
|
|
|
2834
3019
|
}
|
|
2835
3020
|
return { items, nextCursor: null };
|
|
2836
3021
|
}
|
|
2837
|
-
async function getTimelineOnchain({ provider, governor, id, fromBlock = 0, toBlock = "latest" }) {
|
|
3022
|
+
async function getTimelineOnchain({ provider, governor, id: id2, fromBlock = 0, toBlock = "latest" }) {
|
|
2838
3023
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2839
3024
|
const addr = normaliseGovernor(governor);
|
|
2840
|
-
const pid = typeof
|
|
3025
|
+
const pid = typeof id2 === "bigint" ? id2 : String(id2).startsWith("0x") ? BigInt(id2) : BigInt(String(id2));
|
|
2841
3026
|
const iface = new Interface([Events.ProposalQueued, Events.ProposalExecuted, Events.ProposalCanceled]);
|
|
2842
3027
|
const topics = [
|
|
2843
3028
|
iface.getEvent("ProposalQueued").topicHash,
|
|
@@ -3070,9 +3255,9 @@ var require_operations = __commonJS({
|
|
|
3070
3255
|
throw new SageSDKError(CODES.INVALID_ARGS, "invalid governor address", { cause: error });
|
|
3071
3256
|
}
|
|
3072
3257
|
}
|
|
3073
|
-
function normaliseProposalId(
|
|
3074
|
-
if (typeof
|
|
3075
|
-
const value = String(
|
|
3258
|
+
function normaliseProposalId(id2) {
|
|
3259
|
+
if (typeof id2 === "bigint") return id2;
|
|
3260
|
+
const value = String(id2);
|
|
3076
3261
|
try {
|
|
3077
3262
|
return value.startsWith("0x") ? BigInt(value) : BigInt(value);
|
|
3078
3263
|
} catch (error) {
|
|
@@ -3094,7 +3279,7 @@ var require_operations = __commonJS({
|
|
|
3094
3279
|
if (!load || !save) return null;
|
|
3095
3280
|
return { load, save };
|
|
3096
3281
|
}
|
|
3097
|
-
function normaliseTuple(governor,
|
|
3282
|
+
function normaliseTuple(governor, id2, metadata) {
|
|
3098
3283
|
const targets = Array.isArray(metadata.targets) ? metadata.targets.map((t) => getAddress(t)) : [];
|
|
3099
3284
|
let values = Array.isArray(metadata.values) ? metadata.values.map((v) => BigInt(v)) : new Array(targets.length).fill(BigIntZero);
|
|
3100
3285
|
const calldatas = Array.isArray(metadata.calldatas) ? metadata.calldatas.map(String) : [];
|
|
@@ -3104,7 +3289,7 @@ var require_operations = __commonJS({
|
|
|
3104
3289
|
const description = metadata.description || metadata.body || "";
|
|
3105
3290
|
const descriptionHash = metadata.descriptionHash || (typeof metadata.hashDescription === "function" ? metadata.hashDescription(description) : keccak256(toUtf8Bytes(String(description || ""))));
|
|
3106
3291
|
return {
|
|
3107
|
-
id,
|
|
3292
|
+
id: id2,
|
|
3108
3293
|
governor,
|
|
3109
3294
|
targets,
|
|
3110
3295
|
values,
|
|
@@ -3120,38 +3305,119 @@ var require_operations = __commonJS({
|
|
|
3120
3305
|
proposalId,
|
|
3121
3306
|
refresh = false,
|
|
3122
3307
|
cache = null,
|
|
3123
|
-
fromBlock = 0
|
|
3308
|
+
fromBlock = 0,
|
|
3309
|
+
helperAddress = null,
|
|
3310
|
+
hints = {},
|
|
3311
|
+
chunkSizeBlocks = 1e4,
|
|
3312
|
+
lookBackBlocks = 2e3,
|
|
3313
|
+
lookAheadBlocks = 2e3
|
|
3124
3314
|
}) {
|
|
3125
3315
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
3126
3316
|
const govAddr = normaliseGovernor(governor);
|
|
3127
|
-
const
|
|
3317
|
+
const id2 = normaliseProposalId(proposalId);
|
|
3128
3318
|
const cacheAdapter = wrapCache(cache);
|
|
3129
3319
|
if (!refresh && cacheAdapter) {
|
|
3130
|
-
const cached = await cacheAdapter.load(govAddr,
|
|
3320
|
+
const cached = await cacheAdapter.load(govAddr, id2);
|
|
3131
3321
|
if (cached) return cached;
|
|
3132
3322
|
}
|
|
3323
|
+
if (helperAddress) {
|
|
3324
|
+
try {
|
|
3325
|
+
const helperAbi = [
|
|
3326
|
+
"function getProposalTuple(uint256) view returns (address[] targets,uint256[] values,bytes[] calldatas,bytes32 descriptionHash,bool exists)"
|
|
3327
|
+
];
|
|
3328
|
+
const helper = new Contract(helperAddress, helperAbi, provider);
|
|
3329
|
+
const res = await helper.getProposalTuple(id2);
|
|
3330
|
+
if (res && res.exists) {
|
|
3331
|
+
const tuple2 = {
|
|
3332
|
+
id: id2,
|
|
3333
|
+
governor: normaliseGovernor(governor),
|
|
3334
|
+
targets: res.targets || [],
|
|
3335
|
+
values: (res.values || []).map((v) => BigInt(v)),
|
|
3336
|
+
calldatas: (res.calldatas || []).map(String),
|
|
3337
|
+
description: "",
|
|
3338
|
+
descriptionHash: res.descriptionHash || null,
|
|
3339
|
+
createdBlock: null
|
|
3340
|
+
};
|
|
3341
|
+
if (cacheAdapter) await cacheAdapter.save(governor, id2, tuple2);
|
|
3342
|
+
return tuple2;
|
|
3343
|
+
}
|
|
3344
|
+
} catch (_) {
|
|
3345
|
+
}
|
|
3346
|
+
}
|
|
3133
3347
|
let metadata = null;
|
|
3134
3348
|
try {
|
|
3135
|
-
metadata = await governance2.getProposalMetadata({ provider, governor: govAddr, id });
|
|
3349
|
+
metadata = await governance2.getProposalMetadata({ provider, governor: govAddr, id: id2 });
|
|
3136
3350
|
} catch (_) {
|
|
3137
3351
|
metadata = null;
|
|
3138
3352
|
}
|
|
3139
3353
|
if (!metadata) {
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3354
|
+
let lower = fromBlock || 0;
|
|
3355
|
+
try {
|
|
3356
|
+
const govAbi = new Interface(ABI.Governor);
|
|
3357
|
+
const govC = new Contract(govAddr, govAbi, provider);
|
|
3358
|
+
const snapshot = hints.snapshot ?? await govC.proposalSnapshot(id2).catch(() => null);
|
|
3359
|
+
const votingDelay = hints.votingDelay ?? await govC.votingDelay().catch(() => null);
|
|
3360
|
+
if (snapshot !== null && votingDelay !== null) {
|
|
3361
|
+
const approxCreation = Number(snapshot) - Number(votingDelay);
|
|
3362
|
+
lower = approxCreation > 0 ? approxCreation : 0;
|
|
3363
|
+
const upper = lower + Number(lookAheadBlocks);
|
|
3364
|
+
const from = lower > lookBackBlocks ? lower - Number(lookBackBlocks) : 0;
|
|
3365
|
+
const toBlock = await provider.getBlockNumber();
|
|
3366
|
+
const max = Math.min(upper + Number(lookBackBlocks), Number(toBlock));
|
|
3367
|
+
const topic = govC.interface.getEvent("ProposalCreated").topicHash;
|
|
3368
|
+
for (let start = from; start <= max; start += Number(chunkSizeBlocks)) {
|
|
3369
|
+
const end = Math.min(max, start + Number(chunkSizeBlocks));
|
|
3370
|
+
try {
|
|
3371
|
+
const logs = await provider.getLogs({
|
|
3372
|
+
address: govAddr,
|
|
3373
|
+
topics: [topic],
|
|
3374
|
+
fromBlock: start,
|
|
3375
|
+
toBlock: end
|
|
3376
|
+
});
|
|
3377
|
+
for (const log of logs) {
|
|
3378
|
+
try {
|
|
3379
|
+
const parsed = govC.interface.parseLog(log);
|
|
3380
|
+
const pid = normaliseProposalId(parsed.args.proposalId);
|
|
3381
|
+
if (pid === id2) {
|
|
3382
|
+
metadata = {
|
|
3383
|
+
id: id2,
|
|
3384
|
+
governor: govAddr,
|
|
3385
|
+
targets: Array.from(parsed.args.targets || [], String),
|
|
3386
|
+
values: Array.from(parsed.args.values || [], (v) => BigInt(v.toString())),
|
|
3387
|
+
calldatas: Array.from(parsed.args.calldatas || [], (b) => String(b)),
|
|
3388
|
+
description: String(parsed.args.description || ""),
|
|
3389
|
+
descriptionHash: governance2.hashDescription ? governance2.hashDescription(String(parsed.args.description || "")) : keccak256(toUtf8Bytes(String(parsed.args.description || ""))),
|
|
3390
|
+
createdBlock: log.blockNumber
|
|
3391
|
+
};
|
|
3392
|
+
break;
|
|
3393
|
+
}
|
|
3394
|
+
} catch (_) {
|
|
3395
|
+
}
|
|
3396
|
+
}
|
|
3397
|
+
if (metadata) break;
|
|
3398
|
+
} catch (_) {
|
|
3399
|
+
}
|
|
3400
|
+
}
|
|
3146
3401
|
}
|
|
3147
|
-
})
|
|
3402
|
+
} catch (_) {
|
|
3403
|
+
}
|
|
3404
|
+
if (!metadata) {
|
|
3405
|
+
const page = await governance2.listProposals({ provider, governor: govAddr, fromBlock, toBlock: "latest" });
|
|
3406
|
+
metadata = page.find((entry) => {
|
|
3407
|
+
try {
|
|
3408
|
+
return normaliseProposalId(entry.id || entry.proposalId) === id2;
|
|
3409
|
+
} catch (_) {
|
|
3410
|
+
return false;
|
|
3411
|
+
}
|
|
3412
|
+
}) || null;
|
|
3413
|
+
}
|
|
3148
3414
|
}
|
|
3149
3415
|
if (!metadata) {
|
|
3150
3416
|
throw new SageSDKError(CODES.NOT_FOUND, "proposal tuple not found");
|
|
3151
3417
|
}
|
|
3152
|
-
const tuple = normaliseTuple(govAddr,
|
|
3418
|
+
const tuple = normaliseTuple(govAddr, id2, metadata);
|
|
3153
3419
|
if (cacheAdapter) {
|
|
3154
|
-
await cacheAdapter.save(govAddr,
|
|
3420
|
+
await cacheAdapter.save(govAddr, id2, tuple);
|
|
3155
3421
|
}
|
|
3156
3422
|
return tuple;
|
|
3157
3423
|
}
|
|
@@ -3342,10 +3608,11 @@ var require_operations = __commonJS({
|
|
|
3342
3608
|
proposalId,
|
|
3343
3609
|
refresh = false,
|
|
3344
3610
|
cache = null,
|
|
3345
|
-
includeTimeline = false
|
|
3611
|
+
includeTimeline = false,
|
|
3612
|
+
helperAddress = null
|
|
3346
3613
|
}) {
|
|
3347
3614
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
3348
|
-
const tuple = await resolveProposalTuple({ provider, governor, proposalId, refresh, cache });
|
|
3615
|
+
const tuple = await resolveProposalTuple({ provider, governor, proposalId, refresh, cache, helperAddress });
|
|
3349
3616
|
let proposal = null;
|
|
3350
3617
|
try {
|
|
3351
3618
|
proposal = await governance2.getProposal({ provider, governor: tuple.governor, id: tuple.id });
|
|
@@ -3446,6 +3713,91 @@ var require_operations = __commonJS({
|
|
|
3446
3713
|
}
|
|
3447
3714
|
});
|
|
3448
3715
|
|
|
3716
|
+
// src/governance/grants.js
|
|
3717
|
+
var require_grants = __commonJS({
|
|
3718
|
+
"src/governance/grants.js"(exports2, module2) {
|
|
3719
|
+
var { Interface, getAddress, isAddress, parseUnits } = require("ethers");
|
|
3720
|
+
var { SageSDKError, CODES } = require_errors();
|
|
3721
|
+
function normalizeAddress(label, value) {
|
|
3722
|
+
if (!value) throw new SageSDKError(CODES.INVALID_ARGS, `${label} required`);
|
|
3723
|
+
if (!isAddress(value)) throw new SageSDKError(CODES.INVALID_ARGS, `${label} invalid`);
|
|
3724
|
+
return getAddress(value);
|
|
3725
|
+
}
|
|
3726
|
+
async function buildGrantProposal({ provider = null, vault, token: token2, recipient, amount, decimals = null, raw = false, description = null }) {
|
|
3727
|
+
const vaultAddr = normalizeAddress("vault", vault);
|
|
3728
|
+
const tokenAddr = normalizeAddress("token", token2);
|
|
3729
|
+
const rcptAddr = normalizeAddress("recipient", recipient);
|
|
3730
|
+
if (amount == null) throw new SageSDKError(CODES.INVALID_ARGS, "amount required");
|
|
3731
|
+
let resolvedDecimals = decimals != null ? Number(decimals) : null;
|
|
3732
|
+
let symbol = null;
|
|
3733
|
+
if (provider && resolvedDecimals == null) {
|
|
3734
|
+
try {
|
|
3735
|
+
const erc20 = new (require("ethers")).Contract(tokenAddr, ["function decimals() view returns (uint8)", "function symbol() view returns (string)"], provider);
|
|
3736
|
+
resolvedDecimals = Number(await erc20.decimals());
|
|
3737
|
+
symbol = await erc20.symbol().catch(() => null);
|
|
3738
|
+
} catch (_) {
|
|
3739
|
+
}
|
|
3740
|
+
}
|
|
3741
|
+
if (resolvedDecimals == null) resolvedDecimals = 18;
|
|
3742
|
+
let amtWei;
|
|
3743
|
+
if (raw) {
|
|
3744
|
+
amtWei = BigInt(String(amount));
|
|
3745
|
+
} else {
|
|
3746
|
+
amtWei = parseUnits(String(amount), resolvedDecimals);
|
|
3747
|
+
}
|
|
3748
|
+
const iface = new Interface(["function withdraw(address token,uint256 amount,address recipient)"]);
|
|
3749
|
+
const data = iface.encodeFunctionData("withdraw", [tokenAddr, amtWei, rcptAddr]);
|
|
3750
|
+
const targets = [vaultAddr];
|
|
3751
|
+
const values = [0n];
|
|
3752
|
+
const calldatas = [data];
|
|
3753
|
+
const desc = description && description.length ? description : `Grant ${String(amount)}${symbol ? " " + symbol : ""} to ${rcptAddr}`;
|
|
3754
|
+
return { targets, values, calldatas, description: desc };
|
|
3755
|
+
}
|
|
3756
|
+
module2.exports = {
|
|
3757
|
+
buildGrantProposal,
|
|
3758
|
+
/**
|
|
3759
|
+
* Build a batched proposal for multiple grants. Each item can specify its own vault
|
|
3760
|
+
* or inherit from defaultVault. Decimals are resolved per-token when provider is present.
|
|
3761
|
+
* items: Array<{ vault?, token, recipient, amount, decimals?, raw? }>
|
|
3762
|
+
*/
|
|
3763
|
+
buildBatchGrantProposal: async function buildBatchGrantProposal({ provider = null, items = [], defaultVault = null, description = null }) {
|
|
3764
|
+
if (!Array.isArray(items) || items.length === 0) {
|
|
3765
|
+
throw new SageSDKError(CODES.INVALID_ARGS, "items required");
|
|
3766
|
+
}
|
|
3767
|
+
const targets = [];
|
|
3768
|
+
const values = [];
|
|
3769
|
+
const calldatas = [];
|
|
3770
|
+
const iface = new Interface(["function withdraw(address token,uint256 amount,address recipient)"]);
|
|
3771
|
+
for (const [i, it] of items.entries()) {
|
|
3772
|
+
const vault = it.vault || defaultVault;
|
|
3773
|
+
if (!vault) throw new SageSDKError(CODES.INVALID_ARGS, `item[${i}]: vault missing and no defaultVault provided`);
|
|
3774
|
+
const vaultAddr = normalizeAddress("vault", vault);
|
|
3775
|
+
const tokenAddr = normalizeAddress("token", it.token);
|
|
3776
|
+
const rcptAddr = normalizeAddress("recipient", it.recipient);
|
|
3777
|
+
let resolvedDecimals = it.decimals != null ? Number(it.decimals) : null;
|
|
3778
|
+
if (provider && resolvedDecimals == null && !it.raw) {
|
|
3779
|
+
try {
|
|
3780
|
+
const erc20 = new (require("ethers")).Contract(tokenAddr, ["function decimals() view returns (uint8)"], provider);
|
|
3781
|
+
resolvedDecimals = Number(await erc20.decimals());
|
|
3782
|
+
} catch (_) {
|
|
3783
|
+
}
|
|
3784
|
+
}
|
|
3785
|
+
if (resolvedDecimals == null) resolvedDecimals = 18;
|
|
3786
|
+
let amtWei;
|
|
3787
|
+
if (it.raw) amtWei = BigInt(String(it.amount));
|
|
3788
|
+
else amtWei = parseUnits(String(it.amount), resolvedDecimals);
|
|
3789
|
+
const data = iface.encodeFunctionData("withdraw", [tokenAddr, amtWei, rcptAddr]);
|
|
3790
|
+
targets.push(vaultAddr);
|
|
3791
|
+
values.push(0n);
|
|
3792
|
+
calldatas.push(data);
|
|
3793
|
+
}
|
|
3794
|
+
const desc = description && description.length ? description : `Batch Grants: ${items.length} transfer(s)`;
|
|
3795
|
+
return { targets, values, calldatas, description: desc };
|
|
3796
|
+
}
|
|
3797
|
+
};
|
|
3798
|
+
}
|
|
3799
|
+
});
|
|
3800
|
+
|
|
3449
3801
|
// src/timelock/index.js
|
|
3450
3802
|
var require_timelock = __commonJS({
|
|
3451
3803
|
"src/timelock/index.js"(exports2, module2) {
|
|
@@ -3508,8 +3860,8 @@ var require_timelock = __commonJS({
|
|
|
3508
3860
|
for (const log of logs) {
|
|
3509
3861
|
try {
|
|
3510
3862
|
const parsed = iface.parseLog(log);
|
|
3511
|
-
const
|
|
3512
|
-
const op = operations.get(
|
|
3863
|
+
const id2 = parsed.args.id;
|
|
3864
|
+
const op = operations.get(id2) || { id: id2, scheduled: [], executed: [], cancelled: false };
|
|
3513
3865
|
if (parsed.name === "CallScheduled") {
|
|
3514
3866
|
op.scheduled.push({
|
|
3515
3867
|
index: Number(parsed.args.index),
|
|
@@ -3531,7 +3883,7 @@ var require_timelock = __commonJS({
|
|
|
3531
3883
|
} else if (parsed.name === "Cancelled") {
|
|
3532
3884
|
op.cancelled = true;
|
|
3533
3885
|
}
|
|
3534
|
-
operations.set(
|
|
3886
|
+
operations.set(id2, op);
|
|
3535
3887
|
} catch (err) {
|
|
3536
3888
|
continue;
|
|
3537
3889
|
}
|
|
@@ -3554,10 +3906,10 @@ var require_timelock = __commonJS({
|
|
|
3554
3906
|
]);
|
|
3555
3907
|
return { to, data: payload, value: 0n };
|
|
3556
3908
|
},
|
|
3557
|
-
buildCancelTx: ({ timelock: timelock2, id }) => {
|
|
3558
|
-
if (!
|
|
3909
|
+
buildCancelTx: ({ timelock: timelock2, id: id2 }) => {
|
|
3910
|
+
if (!id2) throw new SageSDKError(CODES.INVALID_ARGS, "operation id required");
|
|
3559
3911
|
const addr = normalise(timelock2, "timelock");
|
|
3560
|
-
const payload = TimelockInterface.encodeFunctionData("cancel", [
|
|
3912
|
+
const payload = TimelockInterface.encodeFunctionData("cancel", [id2]);
|
|
3561
3913
|
return { to: addr, data: payload, value: 0n };
|
|
3562
3914
|
},
|
|
3563
3915
|
buildExecuteTx: ({ timelock: timelock2, target, value = 0n, data = "0x", predecessor = "0x0000000000000000000000000000000000000000000000000000000000000000", salt = "0x0000000000000000000000000000000000000000000000000000000000000000" }) => {
|
|
@@ -3666,10 +4018,10 @@ var require_factory = __commonJS({
|
|
|
3666
4018
|
const moduleContract = new Contract(templateAddr, ABI.TemplateModule, provider);
|
|
3667
4019
|
const ids = await moduleContract.getActiveTemplates().catch(() => []);
|
|
3668
4020
|
const templates = [];
|
|
3669
|
-
for (const
|
|
3670
|
-
const template = await moduleContract.getTemplateStruct(
|
|
4021
|
+
for (const id2 of ids) {
|
|
4022
|
+
const template = await moduleContract.getTemplateStruct(id2);
|
|
3671
4023
|
templates.push({
|
|
3672
|
-
id: Number(
|
|
4024
|
+
id: Number(id2),
|
|
3673
4025
|
name: template[0],
|
|
3674
4026
|
description: template[1],
|
|
3675
4027
|
accessModel: Number(template[2]),
|
|
@@ -4124,8 +4476,8 @@ var require_prompt = __commonJS({
|
|
|
4124
4476
|
for (let i = 1; i <= upto; i++) ids.push(i);
|
|
4125
4477
|
}
|
|
4126
4478
|
const results = [];
|
|
4127
|
-
for (const
|
|
4128
|
-
const key = await contract.getPromptKey(
|
|
4479
|
+
for (const id2 of ids) {
|
|
4480
|
+
const key = await contract.getPromptKey(id2).catch(() => null);
|
|
4129
4481
|
if (!key) continue;
|
|
4130
4482
|
results.push(await getPromptData({ provider, registry: addr, key }));
|
|
4131
4483
|
}
|
|
@@ -4137,8 +4489,8 @@ var require_prompt = __commonJS({
|
|
|
4137
4489
|
const contract = new Contract(addr, ABI.PromptRegistry, provider);
|
|
4138
4490
|
const ids = await contract.getByTagPage(tagHash, BigInt(offset), BigInt(Math.min(Number(limit), 100)));
|
|
4139
4491
|
const out = [];
|
|
4140
|
-
for (const
|
|
4141
|
-
const key = await contract.getPromptKey(
|
|
4492
|
+
for (const id2 of ids) {
|
|
4493
|
+
const key = await contract.getPromptKey(id2).catch(() => null);
|
|
4142
4494
|
if (!key) continue;
|
|
4143
4495
|
out.push(await getPromptData({ provider, registry: addr, key }));
|
|
4144
4496
|
}
|
|
@@ -4150,8 +4502,8 @@ var require_prompt = __commonJS({
|
|
|
4150
4502
|
const contract = new Contract(addr, ABI.PromptRegistry, provider);
|
|
4151
4503
|
const ids = await contract.getByCreatorPage(getAddress(creator), BigInt(offset), BigInt(Math.min(Number(limit), 100)));
|
|
4152
4504
|
const out = [];
|
|
4153
|
-
for (const
|
|
4154
|
-
const key = await contract.getPromptKey(
|
|
4505
|
+
for (const id2 of ids) {
|
|
4506
|
+
const key = await contract.getPromptKey(id2).catch(() => null);
|
|
4155
4507
|
if (!key) continue;
|
|
4156
4508
|
out.push(await getPromptData({ provider, registry: addr, key }));
|
|
4157
4509
|
}
|
|
@@ -4163,8 +4515,8 @@ var require_prompt = __commonJS({
|
|
|
4163
4515
|
const contract = new Contract(addr, ABI.PromptRegistry, provider);
|
|
4164
4516
|
const ids = await contract.getByCategoryPage(Number(category), BigInt(offset), BigInt(Math.min(Number(limit), 100)));
|
|
4165
4517
|
const out = [];
|
|
4166
|
-
for (const
|
|
4167
|
-
const key = await contract.getPromptKey(
|
|
4518
|
+
for (const id2 of ids) {
|
|
4519
|
+
const key = await contract.getPromptKey(id2).catch(() => null);
|
|
4168
4520
|
if (!key) continue;
|
|
4169
4521
|
out.push(await getPromptData({ provider, registry: addr, key }));
|
|
4170
4522
|
}
|
|
@@ -4254,9 +4606,9 @@ var require_ipns = __commonJS({
|
|
|
4254
4606
|
function removeTrailingSlash(str) {
|
|
4255
4607
|
return str ? str.replace(/\/$/, "") : str;
|
|
4256
4608
|
}
|
|
4257
|
-
function ensureLeadingSlash(
|
|
4258
|
-
if (!
|
|
4259
|
-
return
|
|
4609
|
+
function ensureLeadingSlash(path2) {
|
|
4610
|
+
if (!path2) return "/";
|
|
4611
|
+
return path2.startsWith("/") ? path2 : `/${path2}`;
|
|
4260
4612
|
}
|
|
4261
4613
|
function dedupe(list = []) {
|
|
4262
4614
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -4351,10 +4703,10 @@ var require_ipns = __commonJS({
|
|
|
4351
4703
|
}
|
|
4352
4704
|
return null;
|
|
4353
4705
|
}
|
|
4354
|
-
async function fetchWithGateways(
|
|
4706
|
+
async function fetchWithGateways(path2, axiosInstance, gateways, { timeout, attempts = 3, baseDelay = 500, jitterMs = 250 } = {}) {
|
|
4355
4707
|
const errors2 = [];
|
|
4356
4708
|
const unique = dedupe(gateways);
|
|
4357
|
-
const suffix =
|
|
4709
|
+
const suffix = path2.replace(/^\/+/, "");
|
|
4358
4710
|
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
4359
4711
|
const delayMs = attempt === 0 ? 0 : jitter(baseDelay * attempt, jitterMs);
|
|
4360
4712
|
if (delayMs) await delay(delayMs);
|
|
@@ -4376,7 +4728,7 @@ var require_ipns = __commonJS({
|
|
|
4376
4728
|
}
|
|
4377
4729
|
}
|
|
4378
4730
|
}
|
|
4379
|
-
const failure = new Error(`Failed to fetch ${
|
|
4731
|
+
const failure = new Error(`Failed to fetch ${path2} from gateways`);
|
|
4380
4732
|
failure.attempts = errors2;
|
|
4381
4733
|
throw failure;
|
|
4382
4734
|
}
|
|
@@ -4803,7 +5155,7 @@ var require_token = __commonJS({
|
|
|
4803
5155
|
// src/personal/helpers.js
|
|
4804
5156
|
var require_helpers = __commonJS({
|
|
4805
5157
|
"src/personal/helpers.js"(exports2, module2) {
|
|
4806
|
-
var { getAddress, ZeroAddress, id } = require("ethers");
|
|
5158
|
+
var { getAddress, ZeroAddress, id: id2 } = require("ethers");
|
|
4807
5159
|
function normaliseAddress(addr, label) {
|
|
4808
5160
|
if (!addr) throw new Error(`[personal] missing ${label}`);
|
|
4809
5161
|
const value = addr.toString();
|
|
@@ -4814,7 +5166,7 @@ var require_helpers = __commonJS({
|
|
|
4814
5166
|
if (typeof key === "string" && key.startsWith("0x") && key.length === 66) {
|
|
4815
5167
|
return key;
|
|
4816
5168
|
}
|
|
4817
|
-
return
|
|
5169
|
+
return id2(key);
|
|
4818
5170
|
}
|
|
4819
5171
|
module2.exports = {
|
|
4820
5172
|
normaliseAddress,
|
|
@@ -4843,8 +5195,8 @@ var require_receipt = __commonJS({
|
|
|
4843
5195
|
const receiptAddress = normaliseAddress(receipt, "receipt");
|
|
4844
5196
|
const holderAddress = normaliseAddress(holder, "holder");
|
|
4845
5197
|
const contract = new Contract(receiptAddress, ABI.PersonalLicenseReceipt, provider);
|
|
4846
|
-
const
|
|
4847
|
-
const balance = await contract.balanceOf(holderAddress,
|
|
5198
|
+
const id2 = typeof receiptId === "bigint" ? receiptId : BigInt(receiptId);
|
|
5199
|
+
const balance = await contract.balanceOf(holderAddress, id2);
|
|
4848
5200
|
return typeof balance === "bigint" ? balance : BigInt(balance.toString());
|
|
4849
5201
|
}
|
|
4850
5202
|
module2.exports = {
|
|
@@ -5223,12 +5575,12 @@ var require_treasury = __commonJS({
|
|
|
5223
5575
|
idList = Array.from({ length: total - start }, (_, i) => start + i);
|
|
5224
5576
|
}
|
|
5225
5577
|
const withdrawals = [];
|
|
5226
|
-
for (const
|
|
5227
|
-
const entry = await contract.pendingWithdrawals(
|
|
5578
|
+
for (const id2 of idList) {
|
|
5579
|
+
const entry = await contract.pendingWithdrawals(id2).catch(() => null);
|
|
5228
5580
|
if (!entry || !entry.exists) continue;
|
|
5229
5581
|
const [token2, recipient, amount, value, requester, balanceBefore, recipientBalanceBefore, depositSnapshot, isLP, isEmergency] = entry;
|
|
5230
5582
|
withdrawals.push({
|
|
5231
|
-
id: Number(
|
|
5583
|
+
id: Number(id2),
|
|
5232
5584
|
token: token2 && token2 !== ZERO_ADDRESS ? getAddress(token2) : null,
|
|
5233
5585
|
recipient: recipient && recipient !== ZERO_ADDRESS ? getAddress(recipient) : null,
|
|
5234
5586
|
amount: toBigInt(amount),
|
|
@@ -5403,17 +5755,17 @@ var require_treasury = __commonJS({
|
|
|
5403
5755
|
id: parsed?.id != null ? Number(parsed.id) : null
|
|
5404
5756
|
};
|
|
5405
5757
|
}
|
|
5406
|
-
async function confirmWithdrawal({ signer, treasury: treasury2, id, waitMs }) {
|
|
5758
|
+
async function confirmWithdrawal({ signer, treasury: treasury2, id: id2, waitMs }) {
|
|
5407
5759
|
const contract = createWriteContract({ signer, treasury: treasury2 });
|
|
5408
|
-
const tx = await contract.confirmWithdrawal(Number(
|
|
5760
|
+
const tx = await contract.confirmWithdrawal(Number(id2));
|
|
5409
5761
|
const receipt = await waitForReceipt({ signer, tx, waitMs });
|
|
5410
|
-
return { transaction: tx, receipt, id: Number(
|
|
5762
|
+
return { transaction: tx, receipt, id: Number(id2) };
|
|
5411
5763
|
}
|
|
5412
|
-
async function cancelWithdrawal({ signer, treasury: treasury2, id, waitMs }) {
|
|
5764
|
+
async function cancelWithdrawal({ signer, treasury: treasury2, id: id2, waitMs }) {
|
|
5413
5765
|
const contract = createWriteContract({ signer, treasury: treasury2 });
|
|
5414
|
-
const tx = await contract.cancelWithdrawal(Number(
|
|
5766
|
+
const tx = await contract.cancelWithdrawal(Number(id2));
|
|
5415
5767
|
const receipt = await waitForReceipt({ signer, tx, waitMs });
|
|
5416
|
-
return { transaction: tx, receipt, id: Number(
|
|
5768
|
+
return { transaction: tx, receipt, id: Number(id2) };
|
|
5417
5769
|
}
|
|
5418
5770
|
async function setPriceOverride({ signer, treasury: treasury2, token: token2, price, ttlSeconds, waitMs }) {
|
|
5419
5771
|
const contract = createWriteContract({ signer, treasury: treasury2 });
|
|
@@ -5467,7 +5819,23 @@ var require_treasury = __commonJS({
|
|
|
5467
5819
|
confirmWithdrawal,
|
|
5468
5820
|
cancelWithdrawal,
|
|
5469
5821
|
setPriceOverride,
|
|
5470
|
-
clearPriceOverride
|
|
5822
|
+
clearPriceOverride,
|
|
5823
|
+
// TX builders for app usage
|
|
5824
|
+
buildApproveTx: ({ token: token2, spender, amount, decimals = 18 }) => {
|
|
5825
|
+
if (!token2 || !spender) throw new SageSDKError(CODES.INVALID_ARGS, "token and spender required");
|
|
5826
|
+
const iface = new Interface(["function approve(address,uint256)"]);
|
|
5827
|
+
return { to: getAddress(token2), data: iface.encodeFunctionData("approve", [getAddress(spender), BigInt(amount.toString ? amount.toString() : amount)]), value: 0n };
|
|
5828
|
+
},
|
|
5829
|
+
buildTransferTx: ({ token: token2, to, amount, decimals = 18 }) => {
|
|
5830
|
+
if (!token2 || !to) throw new SageSDKError(CODES.INVALID_ARGS, "token and to required");
|
|
5831
|
+
const iface = new Interface(["function transfer(address,uint256)"]);
|
|
5832
|
+
return { to: getAddress(token2), data: iface.encodeFunctionData("transfer", [getAddress(to), BigInt(amount.toString ? amount.toString() : amount)]), value: 0n };
|
|
5833
|
+
},
|
|
5834
|
+
buildWrapEthTx: ({ weth, amountWei }) => {
|
|
5835
|
+
if (!weth) throw new SageSDKError(CODES.INVALID_ARGS, "weth required");
|
|
5836
|
+
const iface = new Interface(["function deposit() payable"]);
|
|
5837
|
+
return { to: getAddress(weth), data: iface.encodeFunctionData("deposit", []), value: BigInt(amountWei.toString ? amountWei.toString() : amountWei) };
|
|
5838
|
+
}
|
|
5471
5839
|
};
|
|
5472
5840
|
}
|
|
5473
5841
|
});
|
|
@@ -5679,8 +6047,8 @@ var require_bounty = __commonJS({
|
|
|
5679
6047
|
["function approveBountyCompletion(uint256,string)"],
|
|
5680
6048
|
signer
|
|
5681
6049
|
);
|
|
5682
|
-
const
|
|
5683
|
-
const tx = await bountyContract.approveBountyCompletion(
|
|
6050
|
+
const id2 = BigInt(bountyId);
|
|
6051
|
+
const tx = await bountyContract.approveBountyCompletion(id2, String(deliverable));
|
|
5684
6052
|
return tx.wait();
|
|
5685
6053
|
}
|
|
5686
6054
|
async function proposeApproveWinner({
|
|
@@ -5698,14 +6066,14 @@ var require_bounty = __commonJS({
|
|
|
5698
6066
|
const context = await subdao2.getSubDAOInfo({ provider, subdao: subdaoAddress });
|
|
5699
6067
|
const governor = normaliseAddress("governor", context.governor);
|
|
5700
6068
|
const iface = new Interface(["function approveBountyCompletion(uint256,string)"]);
|
|
5701
|
-
const
|
|
5702
|
-
const data = iface.encodeFunctionData("approveBountyCompletion", [
|
|
6069
|
+
const id2 = BigInt(bountyId);
|
|
6070
|
+
const data = iface.encodeFunctionData("approveBountyCompletion", [id2, String(deliverable)]);
|
|
5703
6071
|
const proposalCall = governance2.buildProposeTx({
|
|
5704
6072
|
governor,
|
|
5705
6073
|
targets: [bountySystemAddress],
|
|
5706
6074
|
values: [0n],
|
|
5707
6075
|
calldatas: [data],
|
|
5708
|
-
description: `Approve bounty completion for id=${
|
|
6076
|
+
description: `Approve bounty completion for id=${id2}`
|
|
5709
6077
|
});
|
|
5710
6078
|
return { governor, proposalCall };
|
|
5711
6079
|
}
|
|
@@ -5718,248 +6086,6 @@ var require_bounty = __commonJS({
|
|
|
5718
6086
|
}
|
|
5719
6087
|
});
|
|
5720
6088
|
|
|
5721
|
-
// src/bond/index.js
|
|
5722
|
-
var require_bond = __commonJS({
|
|
5723
|
-
"src/bond/index.js"(exports2, module2) {
|
|
5724
|
-
var {
|
|
5725
|
-
Contract,
|
|
5726
|
-
Interface,
|
|
5727
|
-
MaxUint256,
|
|
5728
|
-
WeiPerEther,
|
|
5729
|
-
formatUnits,
|
|
5730
|
-
getAddress,
|
|
5731
|
-
parseUnits
|
|
5732
|
-
} = require("ethers");
|
|
5733
|
-
var ABI = require_abi();
|
|
5734
|
-
var { SageSDKError, CODES } = require_errors();
|
|
5735
|
-
function normalise(address, label) {
|
|
5736
|
-
if (!address) throw new SageSDKError(CODES.INVALID_ARGS, `${label} required`);
|
|
5737
|
-
try {
|
|
5738
|
-
return getAddress(address);
|
|
5739
|
-
} catch (err) {
|
|
5740
|
-
throw new SageSDKError(CODES.INVALID_ARGS, `invalid ${label}`, { cause: err });
|
|
5741
|
-
}
|
|
5742
|
-
}
|
|
5743
|
-
var ERC20 = [
|
|
5744
|
-
"function decimals() view returns (uint8)",
|
|
5745
|
-
"function allowance(address owner, address spender) view returns (uint256)",
|
|
5746
|
-
"function approve(address spender, uint256 value) returns (bool)",
|
|
5747
|
-
"function balanceOf(address) view returns (uint256)"
|
|
5748
|
-
];
|
|
5749
|
-
var BondInterface = new Interface(ABI.BondDepository);
|
|
5750
|
-
async function getInfo({ provider, bond: bond2 }) {
|
|
5751
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
5752
|
-
const addr = normalise(bond2, "bond");
|
|
5753
|
-
const c = new Contract(addr, ABI.BondDepository, provider);
|
|
5754
|
-
const [terms, price, priceUsd, totalDebt, payoutToken, principalToken, treasury2] = await Promise.all([
|
|
5755
|
-
c.terms(),
|
|
5756
|
-
c.bondPrice(),
|
|
5757
|
-
c.bondPriceInUSD().catch(() => 0n),
|
|
5758
|
-
// totalDebt is keyed by payout token in this implementation
|
|
5759
|
-
c.payoutToken().then((pt) => c.totalDebt(pt)).catch(() => 0n),
|
|
5760
|
-
c.payoutToken(),
|
|
5761
|
-
c.principalToken(),
|
|
5762
|
-
c.treasury()
|
|
5763
|
-
]);
|
|
5764
|
-
return {
|
|
5765
|
-
bond: addr,
|
|
5766
|
-
payoutToken,
|
|
5767
|
-
principalToken,
|
|
5768
|
-
treasury: treasury2,
|
|
5769
|
-
terms: {
|
|
5770
|
-
controlVariable: BigInt(terms.controlVariable?.toString?.() || terms[0]?.toString?.() || "0"),
|
|
5771
|
-
minimumPrice: BigInt(terms.minimumPrice?.toString?.() || terms[1]?.toString?.() || "0"),
|
|
5772
|
-
maxPayoutBps: BigInt(terms.maxPayout?.toString?.() || terms[2]?.toString?.() || "0"),
|
|
5773
|
-
maxDebt: BigInt(terms.maxDebt?.toString?.() || terms[3]?.toString?.() || "0"),
|
|
5774
|
-
vestingTerm: BigInt(terms.vestingTerm?.toString?.() || terms[4]?.toString?.() || "0"),
|
|
5775
|
-
feeBps: BigInt(terms.fee?.toString?.() || terms[5]?.toString?.() || "0")
|
|
5776
|
-
},
|
|
5777
|
-
price: BigInt(price.toString()),
|
|
5778
|
-
priceUSD: BigInt(priceUsd.toString()),
|
|
5779
|
-
totalDebt: BigInt(totalDebt.toString())
|
|
5780
|
-
};
|
|
5781
|
-
}
|
|
5782
|
-
async function getPrice({ provider, bond: bond2 }) {
|
|
5783
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
5784
|
-
const c = new Contract(normalise(bond2, "bond"), ABI.BondDepository, provider);
|
|
5785
|
-
return c.bondPrice();
|
|
5786
|
-
}
|
|
5787
|
-
async function getUserStatus({ provider, bond: bond2, user }) {
|
|
5788
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
5789
|
-
const addr = normalise(bond2, "bond");
|
|
5790
|
-
const who = normalise(user, "user");
|
|
5791
|
-
const c = new Contract(addr, ABI.BondDepository, provider);
|
|
5792
|
-
const [info, pending, vested] = await Promise.all([
|
|
5793
|
-
c.bondInfo(who),
|
|
5794
|
-
c.pendingPayout(who),
|
|
5795
|
-
c.percentVestedFor(who).catch(() => 0n)
|
|
5796
|
-
]);
|
|
5797
|
-
return {
|
|
5798
|
-
address: who,
|
|
5799
|
-
bond: addr,
|
|
5800
|
-
payoutRemaining: BigInt(info?.payout?.toString?.() || info[0]?.toString?.() || "0"),
|
|
5801
|
-
vestingBlocks: BigInt(info?.vesting?.toString?.() || info[1]?.toString?.() || "0"),
|
|
5802
|
-
lastInteractionBlock: BigInt(info?.lastBlock?.toString?.() || info[2]?.toString?.() || "0"),
|
|
5803
|
-
pricePaid: BigInt(info?.pricePaid?.toString?.() || info[3]?.toString?.() || "0"),
|
|
5804
|
-
pendingPayout: BigInt(pending.toString()),
|
|
5805
|
-
percentVestedBps: BigInt(vested.toString())
|
|
5806
|
-
};
|
|
5807
|
-
}
|
|
5808
|
-
function buildDepositTx({ bond: bond2, amount, maxPrice }) {
|
|
5809
|
-
const to = normalise(bond2, "bond");
|
|
5810
|
-
const iface = new Interface(ABI.BondDepository);
|
|
5811
|
-
const data = iface.encodeFunctionData("deposit", [
|
|
5812
|
-
BigInt(amount ?? 0n),
|
|
5813
|
-
// principal amount in token units
|
|
5814
|
-
BigInt(maxPrice ?? 0n)
|
|
5815
|
-
// scaled by 1e18
|
|
5816
|
-
]);
|
|
5817
|
-
return { to, data, value: 0n };
|
|
5818
|
-
}
|
|
5819
|
-
function buildRedeemTx({ bond: bond2, recipient, stake = false }) {
|
|
5820
|
-
const to = normalise(bond2, "bond");
|
|
5821
|
-
const iface = new Interface(ABI.BondDepository);
|
|
5822
|
-
const data = iface.encodeFunctionData("redeem", [normalise(recipient, "recipient"), !!stake]);
|
|
5823
|
-
return { to, data, value: 0n };
|
|
5824
|
-
}
|
|
5825
|
-
async function getTokenDecimals({ provider, token: token2 }) {
|
|
5826
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
5827
|
-
const c = new Contract(normalise(token2, "token"), ERC20, provider);
|
|
5828
|
-
const d = await c.decimals().catch(() => 18);
|
|
5829
|
-
return Number(d);
|
|
5830
|
-
}
|
|
5831
|
-
async function getPrincipalAndPayout({ provider, bond: bond2 }) {
|
|
5832
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
5833
|
-
const c = new Contract(normalise(bond2, "bond"), ABI.BondDepository, provider);
|
|
5834
|
-
const [payoutToken, principalToken] = await Promise.all([
|
|
5835
|
-
c.payoutToken(),
|
|
5836
|
-
c.principalToken()
|
|
5837
|
-
]);
|
|
5838
|
-
return { payoutToken, principalToken };
|
|
5839
|
-
}
|
|
5840
|
-
async function estimatePayout({ provider, bond: bond2, amount, principalDecimals, payoutDecimals }) {
|
|
5841
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
5842
|
-
if (amount == null) throw new SageSDKError(CODES.INVALID_ARGS, "amount required");
|
|
5843
|
-
const { principalToken, payoutToken } = await getPrincipalAndPayout({ provider, bond: bond2 });
|
|
5844
|
-
const principalDec = principalDecimals ?? await getTokenDecimals({ provider, token: principalToken });
|
|
5845
|
-
const payoutDec = payoutDecimals ?? await getTokenDecimals({ provider, token: payoutToken });
|
|
5846
|
-
const amountUnits = parseUnits(String(amount), principalDec);
|
|
5847
|
-
const price = await getPrice({ provider, bond: bond2 });
|
|
5848
|
-
if (price === 0n) {
|
|
5849
|
-
throw new SageSDKError(CODES.RPC_ERROR, "bond price returned zero");
|
|
5850
|
-
}
|
|
5851
|
-
const payoutUnits = amountUnits * WeiPerEther / price;
|
|
5852
|
-
return {
|
|
5853
|
-
inputAmount: String(amount),
|
|
5854
|
-
expectedPayout: formatUnits(payoutUnits, payoutDec),
|
|
5855
|
-
bondPrice: formatUnits(price, 18),
|
|
5856
|
-
principalToken,
|
|
5857
|
-
payoutToken,
|
|
5858
|
-
principalDecimals: principalDec,
|
|
5859
|
-
payoutDecimals: payoutDec
|
|
5860
|
-
};
|
|
5861
|
-
}
|
|
5862
|
-
async function ensurePrincipalAllowance({ signer, bond: bond2, amount, principalToken }) {
|
|
5863
|
-
if (!signer) throw new SageSDKError(CODES.INVALID_ARGS, "signer required");
|
|
5864
|
-
const owner = await signer.getAddress();
|
|
5865
|
-
const provider = signer.provider;
|
|
5866
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "signer requires provider");
|
|
5867
|
-
const bondAddress = normalise(bond2, "bond");
|
|
5868
|
-
const tokenAddress = principalToken ? normalise(principalToken, "principalToken") : (await getPrincipalAndPayout({ provider, bond: bondAddress })).principalToken;
|
|
5869
|
-
const principal = new Contract(tokenAddress, ERC20, signer);
|
|
5870
|
-
const allowance = await principal.allowance(owner, bondAddress);
|
|
5871
|
-
if (allowance >= amount) {
|
|
5872
|
-
return { approved: false, transactionHash: null };
|
|
5873
|
-
}
|
|
5874
|
-
const approvalTx = await principal.approve(bondAddress, MaxUint256);
|
|
5875
|
-
const receipt = await approvalTx.wait();
|
|
5876
|
-
return {
|
|
5877
|
-
approved: true,
|
|
5878
|
-
transactionHash: receipt.hash ?? approvalTx.hash ?? null
|
|
5879
|
-
};
|
|
5880
|
-
}
|
|
5881
|
-
async function purchase({ signer, bond: bond2, amount, maxPrice }) {
|
|
5882
|
-
if (!signer) throw new SageSDKError(CODES.INVALID_ARGS, "signer required");
|
|
5883
|
-
if (amount == null) throw new SageSDKError(CODES.INVALID_ARGS, "amount required");
|
|
5884
|
-
if (maxPrice == null) throw new SageSDKError(CODES.INVALID_ARGS, "maxPrice required");
|
|
5885
|
-
const provider = signer.provider;
|
|
5886
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "signer requires provider");
|
|
5887
|
-
const bondAddress = normalise(bond2, "bond");
|
|
5888
|
-
const bondContract = new Contract(bondAddress, ABI.BondDepository, signer);
|
|
5889
|
-
const { principalToken, payoutToken } = await getPrincipalAndPayout({ provider, bond: bondAddress });
|
|
5890
|
-
const principalDec = await getTokenDecimals({ provider, token: principalToken });
|
|
5891
|
-
const payoutDec = await getTokenDecimals({ provider, token: payoutToken });
|
|
5892
|
-
const amountUnits = parseUnits(String(amount), principalDec);
|
|
5893
|
-
const maxPriceUnits = parseUnits(String(maxPrice), 18);
|
|
5894
|
-
const currentPrice = await getPrice({ provider, bond: bondAddress });
|
|
5895
|
-
if (currentPrice > maxPriceUnits) {
|
|
5896
|
-
throw new SageSDKError(CODES.INVALID_ARGS, "current bond price exceeds max price", {
|
|
5897
|
-
currentPrice: formatUnits(currentPrice, 18),
|
|
5898
|
-
maxPrice: String(maxPrice)
|
|
5899
|
-
});
|
|
5900
|
-
}
|
|
5901
|
-
await ensurePrincipalAllowance({ signer, bond: bondAddress, amount: amountUnits, principalToken });
|
|
5902
|
-
const tx = await bondContract.deposit(amountUnits, maxPriceUnits);
|
|
5903
|
-
const receipt = await tx.wait();
|
|
5904
|
-
let depositEvent = null;
|
|
5905
|
-
for (const log of receipt.logs || []) {
|
|
5906
|
-
try {
|
|
5907
|
-
const parsed = BondInterface.parseLog(log);
|
|
5908
|
-
if (parsed?.name === "BondCreated") {
|
|
5909
|
-
depositEvent = parsed.args;
|
|
5910
|
-
break;
|
|
5911
|
-
}
|
|
5912
|
-
} catch (_) {
|
|
5913
|
-
}
|
|
5914
|
-
}
|
|
5915
|
-
return {
|
|
5916
|
-
transactionHash: receipt.hash ?? tx.hash ?? null,
|
|
5917
|
-
deposit: formatUnits(depositEvent?.deposit ?? amountUnits, principalDec),
|
|
5918
|
-
payout: depositEvent?.payout != null ? formatUnits(depositEvent.payout, payoutDec) : null,
|
|
5919
|
-
expires: depositEvent?.expires ?? null,
|
|
5920
|
-
price: formatUnits(currentPrice, 18)
|
|
5921
|
-
};
|
|
5922
|
-
}
|
|
5923
|
-
async function redeem({ signer, bond: bond2, recipient, stake = false }) {
|
|
5924
|
-
if (!signer) throw new SageSDKError(CODES.INVALID_ARGS, "signer required");
|
|
5925
|
-
const provider = signer.provider;
|
|
5926
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "signer requires provider");
|
|
5927
|
-
const bondAddress = normalise(bond2, "bond");
|
|
5928
|
-
const user = normalise(recipient || await signer.getAddress(), "recipient");
|
|
5929
|
-
const bondContract = new Contract(bondAddress, ABI.BondDepository, signer);
|
|
5930
|
-
const { payoutToken } = await getPrincipalAndPayout({ provider, bond: bondAddress });
|
|
5931
|
-
const payoutDec = await getTokenDecimals({ provider, token: payoutToken });
|
|
5932
|
-
const pending = await bondContract.pendingPayout(user);
|
|
5933
|
-
if (pending === 0n) {
|
|
5934
|
-
return {
|
|
5935
|
-
transactionHash: null,
|
|
5936
|
-
redeemed: "0",
|
|
5937
|
-
message: "No bonds available for redemption"
|
|
5938
|
-
};
|
|
5939
|
-
}
|
|
5940
|
-
const tx = await bondContract.redeem(user, !!stake);
|
|
5941
|
-
const receipt = await tx.wait();
|
|
5942
|
-
return {
|
|
5943
|
-
transactionHash: receipt.hash ?? tx.hash ?? null,
|
|
5944
|
-
redeemed: formatUnits(pending, payoutDec)
|
|
5945
|
-
};
|
|
5946
|
-
}
|
|
5947
|
-
module2.exports = {
|
|
5948
|
-
getInfo,
|
|
5949
|
-
getPrice,
|
|
5950
|
-
getUserStatus,
|
|
5951
|
-
buildDepositTx,
|
|
5952
|
-
buildRedeemTx,
|
|
5953
|
-
getTokenDecimals,
|
|
5954
|
-
getPrincipalAndPayout,
|
|
5955
|
-
estimatePayout,
|
|
5956
|
-
ensurePrincipalAllowance,
|
|
5957
|
-
purchase,
|
|
5958
|
-
redeem
|
|
5959
|
-
};
|
|
5960
|
-
}
|
|
5961
|
-
});
|
|
5962
|
-
|
|
5963
6089
|
// src/utils/provider.js
|
|
5964
6090
|
var require_provider = __commonJS({
|
|
5965
6091
|
"src/utils/provider.js"(exports2, module2) {
|
|
@@ -5983,7 +6109,7 @@ var require_provider = __commonJS({
|
|
|
5983
6109
|
// src/wallet/index.js
|
|
5984
6110
|
var require_wallet = __commonJS({
|
|
5985
6111
|
"src/wallet/index.js"(exports2, module2) {
|
|
5986
|
-
var { ethers } = require("ethers");
|
|
6112
|
+
var { ethers: ethers2 } = require("ethers");
|
|
5987
6113
|
var { SageSDKError, CODES } = require_errors();
|
|
5988
6114
|
var { getProvider } = require_provider();
|
|
5989
6115
|
function isBrowser() {
|
|
@@ -6010,7 +6136,7 @@ var require_wallet = __commonJS({
|
|
|
6010
6136
|
const rpcUrl = src.rpcUrl || getDefaultRpc();
|
|
6011
6137
|
const provider = getProvider({ rpcUrl });
|
|
6012
6138
|
const pk = src.privateKey.startsWith("0x") ? src.privateKey : "0x" + src.privateKey;
|
|
6013
|
-
const signer = new
|
|
6139
|
+
const signer = new ethers2.Wallet(pk, provider);
|
|
6014
6140
|
return { signer, provider };
|
|
6015
6141
|
}
|
|
6016
6142
|
case "pkEnv": {
|
|
@@ -6019,7 +6145,7 @@ var require_wallet = __commonJS({
|
|
|
6019
6145
|
if (!pk) throw new SageSDKError(CODES.INVALID_ARGS, `${envName} not set`);
|
|
6020
6146
|
const rpcUrl = src.rpcUrl || getDefaultRpc();
|
|
6021
6147
|
const provider = getProvider({ rpcUrl });
|
|
6022
|
-
const signer = new
|
|
6148
|
+
const signer = new ethers2.Wallet(pk.startsWith("0x") ? pk : "0x" + pk, provider);
|
|
6023
6149
|
return { signer, provider };
|
|
6024
6150
|
}
|
|
6025
6151
|
case "rpc": {
|
|
@@ -6030,7 +6156,7 @@ var require_wallet = __commonJS({
|
|
|
6030
6156
|
case "injected": {
|
|
6031
6157
|
if (!isBrowser()) throw new SageSDKError(CODES.MISSING_DEPENDENCY, "Injected provider only available in browser");
|
|
6032
6158
|
try {
|
|
6033
|
-
const provider = new
|
|
6159
|
+
const provider = new ethers2.BrowserProvider(window.ethereum);
|
|
6034
6160
|
const signer = await provider.getSigner();
|
|
6035
6161
|
return { signer, provider };
|
|
6036
6162
|
} catch (e) {
|
|
@@ -6058,7 +6184,7 @@ var require_wallet = __commonJS({
|
|
|
6058
6184
|
return process.env.RPC_URL || process.env.BASE_SEPOLIA_RPC_URL || process.env.BASE_SEPOLIA_RPC || "https://base-sepolia.publicnode.com";
|
|
6059
6185
|
}
|
|
6060
6186
|
function create() {
|
|
6061
|
-
const wallet2 =
|
|
6187
|
+
const wallet2 = ethers2.Wallet.createRandom();
|
|
6062
6188
|
return {
|
|
6063
6189
|
address: wallet2.address,
|
|
6064
6190
|
// Intentionally do not expose privateKey by default to avoid accidental leaks
|
|
@@ -6071,7 +6197,7 @@ var require_wallet = __commonJS({
|
|
|
6071
6197
|
throw new SageSDKError(CODES.INVALID_ARGS, "secret required to import wallet");
|
|
6072
6198
|
}
|
|
6073
6199
|
const pk = secret.startsWith("0x") ? secret : "0x" + secret;
|
|
6074
|
-
const wallet2 = new
|
|
6200
|
+
const wallet2 = new ethers2.Wallet(pk);
|
|
6075
6201
|
return { address: wallet2.address, _wallet: wallet2 };
|
|
6076
6202
|
}
|
|
6077
6203
|
function exportWallet(w) {
|
|
@@ -6106,7 +6232,7 @@ var require_wallet = __commonJS({
|
|
|
6106
6232
|
} catch (_) {
|
|
6107
6233
|
if (!opts || !opts.mnemonic || !opts.rpcUrl) throw new SageSDKError(CODES.INVALID_ARGS, "mnemonic and rpcUrl required");
|
|
6108
6234
|
const provider = getProvider({ rpcUrl: opts.rpcUrl });
|
|
6109
|
-
const wallet2 =
|
|
6235
|
+
const wallet2 = ethers2.HDNodeWallet.fromPhrase(opts.mnemonic, opts.path);
|
|
6110
6236
|
const signer = wallet2.connect(provider);
|
|
6111
6237
|
return { signer, provider };
|
|
6112
6238
|
}
|
|
@@ -6118,7 +6244,7 @@ var require_wallet = __commonJS({
|
|
|
6118
6244
|
} catch (_) {
|
|
6119
6245
|
if (!opts || !opts.json || !opts.password || !opts.rpcUrl) throw new SageSDKError(CODES.INVALID_ARGS, "json, password, rpcUrl required");
|
|
6120
6246
|
const provider = getProvider({ rpcUrl: opts.rpcUrl });
|
|
6121
|
-
const signer = await
|
|
6247
|
+
const signer = await ethers2.Wallet.fromEncryptedJson(opts.json, opts.password);
|
|
6122
6248
|
return { signer: signer.connect(provider), provider };
|
|
6123
6249
|
}
|
|
6124
6250
|
},
|
|
@@ -6203,7 +6329,7 @@ var require_session = __commonJS({
|
|
|
6203
6329
|
|
|
6204
6330
|
// src/wallet/cast-manager.js
|
|
6205
6331
|
var require_cast_manager = __commonJS({
|
|
6206
|
-
"src/wallet/cast-manager.js"(
|
|
6332
|
+
"src/wallet/cast-manager.js"(exports, module) {
|
|
6207
6333
|
var { spawn } = require("child_process");
|
|
6208
6334
|
var { ethers } = require("ethers");
|
|
6209
6335
|
var fs = require("fs");
|
|
@@ -6220,6 +6346,32 @@ var require_cast_manager = __commonJS({
|
|
|
6220
6346
|
blue: (text) => `\x1B[34m${text}\x1B[0m`,
|
|
6221
6347
|
cyan: (text) => `\x1B[36m${text}\x1B[0m`
|
|
6222
6348
|
};
|
|
6349
|
+
function optionalRequire(id) {
|
|
6350
|
+
try {
|
|
6351
|
+
const req = typeof __non_webpack_require__ === "function" ? __non_webpack_require__ : eval("require");
|
|
6352
|
+
return req(id);
|
|
6353
|
+
} catch (_) {
|
|
6354
|
+
return null;
|
|
6355
|
+
}
|
|
6356
|
+
}
|
|
6357
|
+
function loadConfigBridge() {
|
|
6358
|
+
const shared = optionalRequire("@sage-protocol/shared");
|
|
6359
|
+
if (shared) {
|
|
6360
|
+
if (shared.ConfigManager) return shared.ConfigManager;
|
|
6361
|
+
if (typeof shared.getProjectDir === "function" || typeof shared.readProfiles === "function") {
|
|
6362
|
+
return shared;
|
|
6363
|
+
}
|
|
6364
|
+
}
|
|
6365
|
+
const local = optionalRequire("./config");
|
|
6366
|
+
if (local) {
|
|
6367
|
+
if (local.ConfigManager) return local.ConfigManager;
|
|
6368
|
+
return local;
|
|
6369
|
+
}
|
|
6370
|
+
return {
|
|
6371
|
+
getProjectDir: () => process.cwd(),
|
|
6372
|
+
readProfiles: () => ({ profiles: {}, activeProfile: "default" })
|
|
6373
|
+
};
|
|
6374
|
+
}
|
|
6223
6375
|
var CastSigner = class extends ethers.VoidSigner {
|
|
6224
6376
|
constructor(address, provider, castWalletManager) {
|
|
6225
6377
|
super(address, provider);
|
|
@@ -6354,13 +6506,8 @@ var require_cast_manager = __commonJS({
|
|
|
6354
6506
|
if (!address) return;
|
|
6355
6507
|
try {
|
|
6356
6508
|
const normalized = ethers.getAddress(address);
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
({ ConfigManager: cfgModule } = require("@sage-protocol/shared"));
|
|
6360
|
-
} catch (_) {
|
|
6361
|
-
cfgModule = require("./config");
|
|
6362
|
-
}
|
|
6363
|
-
const projectDir = cfgModule.getProjectDir ? cfgModule.getProjectDir() : process.cwd();
|
|
6509
|
+
const cfgModule = loadConfigBridge();
|
|
6510
|
+
const projectDir = typeof cfgModule.getProjectDir === "function" ? cfgModule.getProjectDir() : process.cwd();
|
|
6364
6511
|
const cfgPath = path.join(projectDir, ".sage", "config.json");
|
|
6365
6512
|
const current = fs.existsSync(cfgPath) ? JSON.parse(fs.readFileSync(cfgPath, "utf8") || "{}") : {};
|
|
6366
6513
|
const active = current.activeProfile || "default";
|
|
@@ -6446,14 +6593,9 @@ var require_cast_manager = __commonJS({
|
|
|
6446
6593
|
console.log(colors.blue("\u{1F517} Connecting wallet using Cast keystore..."));
|
|
6447
6594
|
this.ensureKeystoreDir();
|
|
6448
6595
|
try {
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
} catch (_) {
|
|
6453
|
-
cliConfig = require("./config");
|
|
6454
|
-
}
|
|
6455
|
-
const profiles = cliConfig.readProfiles();
|
|
6456
|
-
const active = profiles.activeProfile || "default";
|
|
6596
|
+
const cliConfig = loadConfigBridge();
|
|
6597
|
+
const profiles = typeof cliConfig.readProfiles === "function" ? cliConfig.readProfiles() : { profiles: {}, activeProfile: "default" };
|
|
6598
|
+
const active = profiles?.activeProfile || "default";
|
|
6457
6599
|
const wanted = profiles?.profiles?.[active]?.wallet?.defaultAccount;
|
|
6458
6600
|
if (wanted && this.keystoreDir && fs.existsSync(this.keystoreDir)) {
|
|
6459
6601
|
const files = fs.readdirSync(this.keystoreDir);
|
|
@@ -6489,7 +6631,7 @@ var require_cast_manager = __commonJS({
|
|
|
6489
6631
|
this.ensureAccountSynced(walletData.address, walletData.keystorePath, { silent: true });
|
|
6490
6632
|
}
|
|
6491
6633
|
try {
|
|
6492
|
-
const { checkRpcHealth } =
|
|
6634
|
+
const { checkRpcHealth } = optionalRequire("./utils/rpc-health") || {};
|
|
6493
6635
|
const candidates = [
|
|
6494
6636
|
this.rpcUrl,
|
|
6495
6637
|
process.env.BASE_SEPOLIA_RPC,
|
|
@@ -7445,16 +7587,16 @@ ${error}` : ""}`;
|
|
|
7445
7587
|
return fullPath;
|
|
7446
7588
|
}
|
|
7447
7589
|
};
|
|
7448
|
-
|
|
7590
|
+
module.exports = CastWalletManager;
|
|
7449
7591
|
}
|
|
7450
7592
|
});
|
|
7451
7593
|
|
|
7452
7594
|
// src/wallet/cdp-manager.js
|
|
7453
7595
|
var require_cdp_manager = __commonJS({
|
|
7454
7596
|
"src/wallet/cdp-manager.js"(exports2, module2) {
|
|
7455
|
-
var
|
|
7456
|
-
var
|
|
7457
|
-
var { ethers } = require("ethers");
|
|
7597
|
+
var fs2 = require("fs");
|
|
7598
|
+
var path2 = require("path");
|
|
7599
|
+
var { ethers: ethers2 } = require("ethers");
|
|
7458
7600
|
var MinimalCdpSigner = class {
|
|
7459
7601
|
constructor(manager, provider) {
|
|
7460
7602
|
this._mgr = manager;
|
|
@@ -7483,7 +7625,7 @@ var require_cdp_manager = __commonJS({
|
|
|
7483
7625
|
this.provider = null;
|
|
7484
7626
|
this.signer = null;
|
|
7485
7627
|
this.connected = false;
|
|
7486
|
-
this._profilePath =
|
|
7628
|
+
this._profilePath = path2.join(process.cwd(), ".cdp-wallet.json");
|
|
7487
7629
|
this._client = null;
|
|
7488
7630
|
this._userId = null;
|
|
7489
7631
|
this._walletId = null;
|
|
@@ -7506,9 +7648,9 @@ var require_cdp_manager = __commonJS({
|
|
|
7506
7648
|
}
|
|
7507
7649
|
}
|
|
7508
7650
|
_loadProfile() {
|
|
7509
|
-
if (
|
|
7651
|
+
if (fs2.existsSync(this._profilePath)) {
|
|
7510
7652
|
try {
|
|
7511
|
-
const x = JSON.parse(
|
|
7653
|
+
const x = JSON.parse(fs2.readFileSync(this._profilePath, "utf8"));
|
|
7512
7654
|
this._userId = x.userId || null;
|
|
7513
7655
|
this._walletId = x.walletId || null;
|
|
7514
7656
|
this.account = x.address || null;
|
|
@@ -7518,14 +7660,14 @@ var require_cdp_manager = __commonJS({
|
|
|
7518
7660
|
}
|
|
7519
7661
|
_saveProfile() {
|
|
7520
7662
|
const payload = { userId: this._userId, walletId: this._walletId, address: this.account };
|
|
7521
|
-
|
|
7663
|
+
fs2.writeFileSync(this._profilePath, JSON.stringify(payload, null, 2));
|
|
7522
7664
|
}
|
|
7523
7665
|
async connect() {
|
|
7524
7666
|
if (!process.env.CDP_API_KEY_ID || !process.env.CDP_API_KEY_SECRET) {
|
|
7525
7667
|
throw new Error("Missing CDP_API_KEY_ID/CDP_API_KEY_SECRET in env");
|
|
7526
7668
|
}
|
|
7527
7669
|
const rpc = process.env.RPC_URL || "https://base-sepolia.publicnode.com";
|
|
7528
|
-
this.provider = new
|
|
7670
|
+
this.provider = new ethers2.JsonRpcProvider(rpc);
|
|
7529
7671
|
this._loadProfile();
|
|
7530
7672
|
let client;
|
|
7531
7673
|
try {
|
|
@@ -7537,7 +7679,7 @@ var require_cdp_manager = __commonJS({
|
|
|
7537
7679
|
const email = process.env.CDP_USER_EMAIL || await this._promptEmail();
|
|
7538
7680
|
const fakeUserId = `user_${Buffer.from(email).toString("hex").slice(0, 8)}`;
|
|
7539
7681
|
const fakeWalletId = `w_${Date.now()}`;
|
|
7540
|
-
const fakeAddress = this.account ||
|
|
7682
|
+
const fakeAddress = this.account || ethers2.Wallet.createRandom().address;
|
|
7541
7683
|
this._userId = fakeUserId;
|
|
7542
7684
|
this._walletId = fakeWalletId;
|
|
7543
7685
|
this.account = fakeAddress;
|
|
@@ -7551,7 +7693,7 @@ var require_cdp_manager = __commonJS({
|
|
|
7551
7693
|
console.log("\u{1F4CD} Address:", this.account);
|
|
7552
7694
|
try {
|
|
7553
7695
|
const bal = await this.getBalance();
|
|
7554
|
-
console.log("\u{1F4B0} Balance:",
|
|
7696
|
+
console.log("\u{1F4B0} Balance:", ethers2.formatEther(bal), "ETH");
|
|
7555
7697
|
} catch (_) {
|
|
7556
7698
|
}
|
|
7557
7699
|
}
|
|
@@ -7576,7 +7718,7 @@ var require_cdp_manager = __commonJS({
|
|
|
7576
7718
|
if (!process.env.SAGE_QUIET_JSON) {
|
|
7577
7719
|
console.log("\u{1F4DD} Transaction Details:");
|
|
7578
7720
|
console.log("To:", to);
|
|
7579
|
-
console.log("Value:",
|
|
7721
|
+
console.log("Value:", ethers2.formatEther(value));
|
|
7580
7722
|
console.log("Data:", data);
|
|
7581
7723
|
console.log("\u{1F4E8} Check your email/app to approve the transaction...");
|
|
7582
7724
|
}
|
|
@@ -7628,7 +7770,7 @@ var require_cdp_manager = __commonJS({
|
|
|
7628
7770
|
// src/wallet/typed.js
|
|
7629
7771
|
var require_typed = __commonJS({
|
|
7630
7772
|
"src/wallet/typed.js"(exports2, module2) {
|
|
7631
|
-
var { ethers } = require("ethers");
|
|
7773
|
+
var { ethers: ethers2 } = require("ethers");
|
|
7632
7774
|
function buildGovernorDomain({ name, chainId, verifyingContract }) {
|
|
7633
7775
|
if (!name || !chainId || !verifyingContract) throw new Error("name, chainId, verifyingContract required");
|
|
7634
7776
|
return { name, version: "1", chainId: Number(chainId), verifyingContract };
|
|
@@ -7745,12 +7887,40 @@ var require_doppler = __commonJS({
|
|
|
7745
7887
|
}
|
|
7746
7888
|
return { auctionAddress, note: "Lens API not available in this doppler-sdk version" };
|
|
7747
7889
|
}
|
|
7890
|
+
async function listAuctions(sdk, { limit = 10, cursor } = {}) {
|
|
7891
|
+
const lens = sdk.lens;
|
|
7892
|
+
if (lens) {
|
|
7893
|
+
if (typeof lens.listAuctions === "function") {
|
|
7894
|
+
try {
|
|
7895
|
+
return await lens.listAuctions({ limit, cursor });
|
|
7896
|
+
} catch (e) {
|
|
7897
|
+
}
|
|
7898
|
+
}
|
|
7899
|
+
if (typeof lens.getAuctions === "function") {
|
|
7900
|
+
try {
|
|
7901
|
+
return await lens.getAuctions({ limit, cursor });
|
|
7902
|
+
} catch (e) {
|
|
7903
|
+
}
|
|
7904
|
+
}
|
|
7905
|
+
}
|
|
7906
|
+
const fac = sdk.factory;
|
|
7907
|
+
if (fac && typeof fac.listAuctions === "function") {
|
|
7908
|
+
try {
|
|
7909
|
+
return await fac.listAuctions({ limit, cursor });
|
|
7910
|
+
} catch (e) {
|
|
7911
|
+
}
|
|
7912
|
+
}
|
|
7913
|
+
return { ok: false, error: "LIST_UNSUPPORTED", message: "Listing auctions not supported by this doppler-sdk version" };
|
|
7914
|
+
}
|
|
7748
7915
|
async function buyTokens(sdk, { auctionAddress, numeraireAmount }) {
|
|
7749
7916
|
const trade = sdk.trade || sdk.swap || sdk.auction;
|
|
7750
7917
|
if (trade && typeof trade.buy === "function") {
|
|
7751
|
-
|
|
7918
|
+
try {
|
|
7919
|
+
return await trade.buy({ auctionAddress, numeraireAmount });
|
|
7920
|
+
} catch (e) {
|
|
7921
|
+
}
|
|
7752
7922
|
}
|
|
7753
|
-
|
|
7923
|
+
return { ok: false, error: "BUY_UNSUPPORTED", message: "Buy not supported by this doppler-sdk version. Use executeV3BuyExactIn/urExecute helpers or upgrade doppler-sdk." };
|
|
7754
7924
|
}
|
|
7755
7925
|
async function migrate(sdk, asset) {
|
|
7756
7926
|
if (sdk.airlock && typeof sdk.airlock.migrate === "function") {
|
|
@@ -7762,6 +7932,7 @@ var require_doppler = __commonJS({
|
|
|
7762
7932
|
initDoppler,
|
|
7763
7933
|
deployDynamicAuction,
|
|
7764
7934
|
getAuctionStatus,
|
|
7935
|
+
listAuctions,
|
|
7765
7936
|
buyTokens,
|
|
7766
7937
|
migrate
|
|
7767
7938
|
};
|
|
@@ -7923,6 +8094,7 @@ var governance = require_governance();
|
|
|
7923
8094
|
governance.intents = require_intents();
|
|
7924
8095
|
var governanceTemplates = require_templates();
|
|
7925
8096
|
governance.operations = require_operations();
|
|
8097
|
+
governance.grants = require_grants();
|
|
7926
8098
|
var subdao = require_subdao();
|
|
7927
8099
|
var timelock = require_timelock();
|
|
7928
8100
|
var factory = require_factory();
|
|
@@ -7939,7 +8111,6 @@ var safe = require_safe();
|
|
|
7939
8111
|
var treasury = require_treasury();
|
|
7940
8112
|
var boost = require_boost();
|
|
7941
8113
|
var bounty = require_bounty();
|
|
7942
|
-
var bond = require_bond();
|
|
7943
8114
|
var wallet = require_wallet();
|
|
7944
8115
|
wallet.session = require_session();
|
|
7945
8116
|
var walletCastManager = require_cast_manager();
|
|
@@ -7972,7 +8143,7 @@ module.exports = {
|
|
|
7972
8143
|
personal,
|
|
7973
8144
|
treasury,
|
|
7974
8145
|
boost,
|
|
7975
|
-
bond
|
|
8146
|
+
// bond module removed; bonds deprecated in CLI/SDK
|
|
7976
8147
|
subgraph,
|
|
7977
8148
|
utils: { ...utils, privateTx, safe },
|
|
7978
8149
|
bounty,
|