@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/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.0.8",
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
- require: "./dist/index.cjs",
27
+ browser: "./dist/browser/index.mjs",
28
28
  import: "./dist/index.mjs",
29
- default: "./dist/index.cjs"
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 SageTreasury = [
230
- "function totalReserves() view returns (uint256)",
231
- "function totalPOL() view returns (uint256)",
232
- "function totalDebt() view returns (uint256)",
233
- "function canonicalPool() view returns (address)",
234
- "function routerOrVault() view returns (address)",
235
- "function maxWithdrawalRate() view returns (uint256)",
236
- "function emergencyWithdrawalLimit() view returns (uint256)",
237
- "function getReserveTokens() view returns (address[])",
238
- "function getReserve(address token) view returns (address tokenAddress,uint256 amount,uint256 value,bool isLP,bool isActive)",
239
- "function pendingWithdrawals(uint256) view returns (address token,address recipient,uint256 amount,uint256 value,address requester,uint256 balanceBefore,uint256 recipientBalanceBefore,uint256 depositSnapshot,bool isLP,bool isEmergency,bool exists)",
240
- "function nextWithdrawalId() view returns (uint256)",
241
- "function manualPrices(address token) view returns (uint256 price,uint256 expiresAt,bool active)",
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
- SageTreasury,
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 id === "bigint" ? id.toString() : String(id);
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(id) });
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(path, fallback = "") {
811
- const value = path || fallback;
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 = ethers.keccak256(content);
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 = (path) => path.startsWith("/") ? path : `/${path}`;
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
- path.join(process.cwd(), "docs", "schemas", "manifest.schema.json"),
1470
- path.join(__dirname, "..", "..", "docs", "schemas", "manifest.schema.json")
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(fs, file) {
1585
+ function safeJsonParse(fs2, file) {
1474
1586
  try {
1475
- const raw = fs.readFileSync(file, "utf8");
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 (!fs.existsSync(schemaPath)) continue;
1511
- const schema = safeJsonParse(fs, schemaPath);
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(fs, manifestPath);
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 = path.isAbsolute(file) ? file : manifestPath ? path.join(path.dirname(manifestPath), file) : file;
1618
- if (!fs.existsSync(resolved)) {
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(fs, manifestPath);
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 = keccak256(toUtf8Bytes(`${sub.toLowerCase()}::${libraryId}`));
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 id === "bigint" ? id : String(id).startsWith("0x") ? BigInt(id) : BigInt(String(id));
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 id === "bigint" ? id : String(id).startsWith("0x") ? BigInt(id) : BigInt(String(id));
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 id = typeof proposalId === "bigint" ? proposalId : String(proposalId).startsWith("0x") ? BigInt(proposalId) : BigInt(String(proposalId));
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)", [id, s, String(reason)]) : iface.encodeFunctionData("castVote(uint256,uint8)", [id, s]);
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 id = typeof proposalId === "bigint" ? proposalId : String(proposalId).startsWith("0x") ? BigInt(proposalId) : BigInt(String(proposalId));
1974
- const data = iface.encodeFunctionData("queue(uint256)", [id]);
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 id = typeof proposalId === "bigint" ? proposalId : String(proposalId).startsWith("0x") ? BigInt(proposalId) : BigInt(String(proposalId));
1981
- const data = iface.encodeFunctionData("execute(uint256)", [id]);
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 id = BigInt(parsed.args.id.toString());
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 id === "bigint" ? id : String(id).startsWith("0x") ? BigInt(id) : BigInt(String(id));
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(id) {
3074
- if (typeof id === "bigint") return id;
3075
- const value = String(id);
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, id, metadata) {
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 id = normaliseProposalId(proposalId);
3317
+ const id2 = normaliseProposalId(proposalId);
3128
3318
  const cacheAdapter = wrapCache(cache);
3129
3319
  if (!refresh && cacheAdapter) {
3130
- const cached = await cacheAdapter.load(govAddr, id);
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
- const page = await governance2.listProposals({ provider, governor: govAddr, fromBlock, toBlock: "latest" });
3141
- metadata = page.find((entry) => {
3142
- try {
3143
- return normaliseProposalId(entry.id || entry.proposalId) === id;
3144
- } catch (_) {
3145
- return false;
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
- }) || null;
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, id, metadata);
3418
+ const tuple = normaliseTuple(govAddr, id2, metadata);
3153
3419
  if (cacheAdapter) {
3154
- await cacheAdapter.save(govAddr, id, tuple);
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 id = parsed.args.id;
3512
- const op = operations.get(id) || { id, scheduled: [], executed: [], cancelled: false };
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(id, op);
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 (!id) throw new SageSDKError(CODES.INVALID_ARGS, "operation id required");
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", [id]);
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 id of ids) {
3670
- const template = await moduleContract.getTemplateStruct(id);
4021
+ for (const id2 of ids) {
4022
+ const template = await moduleContract.getTemplateStruct(id2);
3671
4023
  templates.push({
3672
- id: Number(id),
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 id of ids) {
4128
- const key = await contract.getPromptKey(id).catch(() => null);
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 id of ids) {
4141
- const key = await contract.getPromptKey(id).catch(() => null);
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 id of ids) {
4154
- const key = await contract.getPromptKey(id).catch(() => null);
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 id of ids) {
4167
- const key = await contract.getPromptKey(id).catch(() => null);
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(path) {
4258
- if (!path) return "/";
4259
- return path.startsWith("/") ? path : `/${path}`;
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(path, axiosInstance, gateways, { timeout, attempts = 3, baseDelay = 500, jitterMs = 250 } = {}) {
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 = path.replace(/^\/+/, "");
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 ${path} from gateways`);
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 id(key);
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 id = typeof receiptId === "bigint" ? receiptId : BigInt(receiptId);
4847
- const balance = await contract.balanceOf(holderAddress, id);
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 id of idList) {
5227
- const entry = await contract.pendingWithdrawals(id).catch(() => null);
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(id),
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(id));
5760
+ const tx = await contract.confirmWithdrawal(Number(id2));
5409
5761
  const receipt = await waitForReceipt({ signer, tx, waitMs });
5410
- return { transaction: tx, receipt, id: Number(id) };
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(id));
5766
+ const tx = await contract.cancelWithdrawal(Number(id2));
5415
5767
  const receipt = await waitForReceipt({ signer, tx, waitMs });
5416
- return { transaction: tx, receipt, id: Number(id) };
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 id = BigInt(bountyId);
5683
- const tx = await bountyContract.approveBountyCompletion(id, String(deliverable));
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 id = BigInt(bountyId);
5702
- const data = iface.encodeFunctionData("approveBountyCompletion", [id, String(deliverable)]);
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=${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 ethers.Wallet(pk, provider);
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 ethers.Wallet(pk.startsWith("0x") ? pk : "0x" + pk, provider);
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 ethers.BrowserProvider(window.ethereum);
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 = ethers.Wallet.createRandom();
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 ethers.Wallet(pk);
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 = ethers.HDNodeWallet.fromPhrase(opts.mnemonic, opts.path);
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 ethers.Wallet.fromEncryptedJson(opts.json, opts.password);
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"(exports2, module2) {
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
- let cfgModule;
6358
- try {
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
- let cliConfig;
6450
- try {
6451
- ({ ConfigManager: cliConfig } = require("@sage-protocol/shared"));
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 } = require("./utils/rpc-health");
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
- module2.exports = CastWalletManager;
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 fs = require("fs");
7456
- var path = require("path");
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 = path.join(process.cwd(), ".cdp-wallet.json");
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 (fs.existsSync(this._profilePath)) {
7651
+ if (fs2.existsSync(this._profilePath)) {
7510
7652
  try {
7511
- const x = JSON.parse(fs.readFileSync(this._profilePath, "utf8"));
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
- fs.writeFileSync(this._profilePath, JSON.stringify(payload, null, 2));
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 ethers.JsonRpcProvider(rpc);
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 || ethers.Wallet.createRandom().address;
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:", ethers.formatEther(bal), "ETH");
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:", ethers.formatEther(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
- return await trade.buy({ auctionAddress, numeraireAmount });
7918
+ try {
7919
+ return await trade.buy({ auctionAddress, numeraireAmount });
7920
+ } catch (e) {
7921
+ }
7752
7922
  }
7753
- throw new Error("Buy is not supported by the current doppler-sdk version");
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,