@sage-protocol/sdk 0.1.2 → 0.1.7
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 +288 -0
- package/dist/browser/index.mjs +155 -10
- package/dist/index.cjs +1351 -394
- package/dist/index.mjs +1444 -487
- package/dist/node/index.cjs +1351 -394
- package/dist/node/index.mjs +1446 -489
- package/package.json +15 -3
package/dist/index.mjs
CHANGED
|
@@ -17,10 +17,10 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
17
17
|
|
|
18
18
|
// package.json
|
|
19
19
|
var require_package = __commonJS({
|
|
20
|
-
"package.json"(
|
|
21
|
-
|
|
20
|
+
"package.json"(exports2, module2) {
|
|
21
|
+
module2.exports = {
|
|
22
22
|
name: "@sage-protocol/sdk",
|
|
23
|
-
version: "0.1.
|
|
23
|
+
version: "0.1.4",
|
|
24
24
|
description: "Backend-agnostic SDK for interacting with the Sage Protocol (governance, SubDAOs, tokens).",
|
|
25
25
|
main: "dist/index.cjs",
|
|
26
26
|
module: "dist/index.mjs",
|
|
@@ -56,10 +56,10 @@ var require_package = __commonJS({
|
|
|
56
56
|
],
|
|
57
57
|
sideEffects: false,
|
|
58
58
|
browser: {
|
|
59
|
+
child_process: false,
|
|
59
60
|
fs: false,
|
|
60
|
-
path: false,
|
|
61
61
|
os: false,
|
|
62
|
-
|
|
62
|
+
path: false
|
|
63
63
|
},
|
|
64
64
|
repository: {
|
|
65
65
|
type: "git",
|
|
@@ -88,6 +88,18 @@ var require_package = __commonJS({
|
|
|
88
88
|
sinon: "^17.0.1",
|
|
89
89
|
tsup: "^8.1.0",
|
|
90
90
|
typescript: "^5.4.0"
|
|
91
|
+
},
|
|
92
|
+
peerDependencies: {
|
|
93
|
+
react: "^18.0.0 || ^19.0.0",
|
|
94
|
+
swr: "^2.0.0"
|
|
95
|
+
},
|
|
96
|
+
peerDependenciesMeta: {
|
|
97
|
+
react: {
|
|
98
|
+
optional: true
|
|
99
|
+
},
|
|
100
|
+
swr: {
|
|
101
|
+
optional: true
|
|
102
|
+
}
|
|
91
103
|
}
|
|
92
104
|
};
|
|
93
105
|
}
|
|
@@ -95,7 +107,7 @@ var require_package = __commonJS({
|
|
|
95
107
|
|
|
96
108
|
// src/abi/index.js
|
|
97
109
|
var require_abi = __commonJS({
|
|
98
|
-
"src/abi/index.js"(
|
|
110
|
+
"src/abi/index.js"(exports2, module2) {
|
|
99
111
|
var SubDAO = [
|
|
100
112
|
"function governor() view returns (address)",
|
|
101
113
|
"function timelock() view returns (address)",
|
|
@@ -301,7 +313,7 @@ var require_abi = __commonJS({
|
|
|
301
313
|
var Events = {
|
|
302
314
|
ProposalCreated: "event ProposalCreated(uint256 id, address proposer, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, uint256 startBlock, uint256 endBlock, string description)"
|
|
303
315
|
};
|
|
304
|
-
|
|
316
|
+
module2.exports = {
|
|
305
317
|
SubDAO,
|
|
306
318
|
Factory,
|
|
307
319
|
FactoryRead,
|
|
@@ -327,9 +339,9 @@ var require_abi = __commonJS({
|
|
|
327
339
|
|
|
328
340
|
// src/types.js
|
|
329
341
|
var require_types = __commonJS({
|
|
330
|
-
"src/types.js"(
|
|
342
|
+
"src/types.js"(exports2, module2) {
|
|
331
343
|
var BigIntZero = 0n;
|
|
332
|
-
|
|
344
|
+
module2.exports = {
|
|
333
345
|
BigIntZero
|
|
334
346
|
};
|
|
335
347
|
}
|
|
@@ -337,7 +349,7 @@ var require_types = __commonJS({
|
|
|
337
349
|
|
|
338
350
|
// src/utils/errors.js
|
|
339
351
|
var require_errors = __commonJS({
|
|
340
|
-
"src/utils/errors.js"(
|
|
352
|
+
"src/utils/errors.js"(exports2, module2) {
|
|
341
353
|
var SageSDKError = class extends Error {
|
|
342
354
|
constructor(code, message, details) {
|
|
343
355
|
super(message);
|
|
@@ -354,7 +366,7 @@ var require_errors = __commonJS({
|
|
|
354
366
|
MISSING_DEPENDENCY: "ERR_MISSING_DEPENDENCY",
|
|
355
367
|
API_REQUEST_FAILED: "ERR_API_REQUEST_FAILED"
|
|
356
368
|
};
|
|
357
|
-
|
|
369
|
+
module2.exports = {
|
|
358
370
|
SageSDKError,
|
|
359
371
|
CODES
|
|
360
372
|
};
|
|
@@ -363,7 +375,7 @@ var require_errors = __commonJS({
|
|
|
363
375
|
|
|
364
376
|
// src/utils/description.js
|
|
365
377
|
var require_description = __commonJS({
|
|
366
|
-
"src/utils/description.js"(
|
|
378
|
+
"src/utils/description.js"(exports2, module2) {
|
|
367
379
|
var { randomBytes, hexlify } = __require("ethers");
|
|
368
380
|
var SALT_RE = /\n\n\[SALT:0x[0-9a-fA-F]{64}\]$/;
|
|
369
381
|
function generateSaltHex() {
|
|
@@ -394,7 +406,7 @@ var require_description = __commonJS({
|
|
|
394
406
|
return String(desc || "");
|
|
395
407
|
}
|
|
396
408
|
}
|
|
397
|
-
|
|
409
|
+
module2.exports = {
|
|
398
410
|
makeProposalDescription,
|
|
399
411
|
stripProposalSalt
|
|
400
412
|
};
|
|
@@ -403,7 +415,7 @@ var require_description = __commonJS({
|
|
|
403
415
|
|
|
404
416
|
// src/subgraph/index.js
|
|
405
417
|
var require_subgraph = __commonJS({
|
|
406
|
-
"src/subgraph/index.js"(
|
|
418
|
+
"src/subgraph/index.js"(exports2, module2) {
|
|
407
419
|
var axios = __require("axios");
|
|
408
420
|
var { getAddress } = __require("ethers");
|
|
409
421
|
var { keccak256, toUtf8Bytes } = __require("ethers");
|
|
@@ -526,7 +538,7 @@ var require_subgraph = __commonJS({
|
|
|
526
538
|
createdAt: Number(lib.createdAt || 0)
|
|
527
539
|
}));
|
|
528
540
|
}
|
|
529
|
-
|
|
541
|
+
module2.exports = {
|
|
530
542
|
query,
|
|
531
543
|
listProposals,
|
|
532
544
|
listProposalsFiltered,
|
|
@@ -535,9 +547,9 @@ var require_subgraph = __commonJS({
|
|
|
535
547
|
* Canonical proposal timeline. Tries common fields first, then event-style fallbacks.
|
|
536
548
|
* Returns { id, createdAt, queuedAt, executedAt, canceledAt, eta, state } (numbers/strings may be null when unavailable).
|
|
537
549
|
*/
|
|
538
|
-
async getProposalTimeline({ url, id }) {
|
|
550
|
+
async getProposalTimeline({ url, id: id2 }) {
|
|
539
551
|
if (!url) throw new Error("subgraph url required");
|
|
540
|
-
const pid = typeof
|
|
552
|
+
const pid = typeof id2 === "bigint" ? id2.toString() : String(id2);
|
|
541
553
|
try {
|
|
542
554
|
const data = await query(url, `
|
|
543
555
|
query($id: ID!) {
|
|
@@ -725,10 +737,10 @@ var require_subgraph = __commonJS({
|
|
|
725
737
|
updatedAt: Number(p.updatedAt || 0)
|
|
726
738
|
} : null;
|
|
727
739
|
},
|
|
728
|
-
async getProposalById({ url, id }) {
|
|
740
|
+
async getProposalById({ url, id: id2 }) {
|
|
729
741
|
if (!url) throw new Error("subgraph url required");
|
|
730
742
|
const doc = `query($id: ID!){ proposal(id:$id){ id proposer description createdAt updatedAt state eta targets values calldatas } }`;
|
|
731
|
-
const data = await query(url, doc, { id: String(
|
|
743
|
+
const data = await query(url, doc, { id: String(id2) });
|
|
732
744
|
const p = data?.proposal;
|
|
733
745
|
if (!p) return null;
|
|
734
746
|
return {
|
|
@@ -750,7 +762,7 @@ var require_subgraph = __commonJS({
|
|
|
750
762
|
|
|
751
763
|
// src/adapters/transports.js
|
|
752
764
|
var require_transports = __commonJS({
|
|
753
|
-
"src/adapters/transports.js"(
|
|
765
|
+
"src/adapters/transports.js"(exports2, module2) {
|
|
754
766
|
function createTransports({ provider, signer = null, subgraph = null }) {
|
|
755
767
|
return function resolve(kind) {
|
|
756
768
|
switch (kind) {
|
|
@@ -765,7 +777,7 @@ var require_transports = __commonJS({
|
|
|
765
777
|
}
|
|
766
778
|
};
|
|
767
779
|
}
|
|
768
|
-
|
|
780
|
+
module2.exports = {
|
|
769
781
|
createTransports
|
|
770
782
|
};
|
|
771
783
|
}
|
|
@@ -773,10 +785,10 @@ var require_transports = __commonJS({
|
|
|
773
785
|
|
|
774
786
|
// src/ipfs/index.js
|
|
775
787
|
var require_ipfs = __commonJS({
|
|
776
|
-
"src/ipfs/index.js"(
|
|
788
|
+
"src/ipfs/index.js"(exports2, module2) {
|
|
777
789
|
var axiosDefault = __require("axios");
|
|
778
790
|
var FormData = __require("form-data");
|
|
779
|
-
var { ethers } = __require("ethers");
|
|
791
|
+
var { ethers: ethers2 } = __require("ethers");
|
|
780
792
|
var DEFAULT_GATEWAY = "https://ipfs.dev.sageprotocol.io/ipfs";
|
|
781
793
|
function toLowerSafe(value, fallback = "") {
|
|
782
794
|
if (value == null) return fallback;
|
|
@@ -831,14 +843,14 @@ var require_ipfs = __commonJS({
|
|
|
831
843
|
}
|
|
832
844
|
return Array.from(urls);
|
|
833
845
|
}
|
|
834
|
-
function ensureLeadingSlash(
|
|
835
|
-
const value =
|
|
846
|
+
function ensureLeadingSlash(path2, fallback = "") {
|
|
847
|
+
const value = path2 || fallback;
|
|
836
848
|
if (!value) return fallback;
|
|
837
849
|
return value.startsWith("/") ? value : `/${value}`;
|
|
838
850
|
}
|
|
839
851
|
function generateDeterministicCid(payload) {
|
|
840
852
|
const content = Buffer.isBuffer(payload) ? payload : typeof payload === "string" ? Buffer.from(payload) : Buffer.from(JSON.stringify(payload));
|
|
841
|
-
const hash =
|
|
853
|
+
const hash = ethers2.keccak256(content);
|
|
842
854
|
const hashStr = hash.slice(2);
|
|
843
855
|
const cidSuffix = (hashStr + hashStr).slice(0, 44);
|
|
844
856
|
return `Qm${cidSuffix}`;
|
|
@@ -910,7 +922,7 @@ var require_ipfs = __commonJS({
|
|
|
910
922
|
}
|
|
911
923
|
function workerUrl(kind, cid) {
|
|
912
924
|
const base = workerBaseUrl();
|
|
913
|
-
const ensure = (
|
|
925
|
+
const ensure = (path2) => path2.startsWith("/") ? path2 : `/${path2}`;
|
|
914
926
|
if (base) {
|
|
915
927
|
if (kind === "challenge") return `${base}${ensure(config.worker.challengePath || "/auth/challenge")}`;
|
|
916
928
|
if (kind === "upload") return `${base}${ensure(config.worker.uploadPath || "/ipfs/upload")}`;
|
|
@@ -1232,18 +1244,18 @@ var require_ipfs = __commonJS({
|
|
|
1232
1244
|
return postWorkerJson("discoveryEventsPath", "/discover/events", payload);
|
|
1233
1245
|
}
|
|
1234
1246
|
async function recordMcpUsageEvent({ promptId, metadata, address } = {}) {
|
|
1235
|
-
const
|
|
1236
|
-
if (!
|
|
1237
|
-
const payload = { promptId:
|
|
1247
|
+
const id2 = typeof promptId === "string" ? promptId.trim() : "";
|
|
1248
|
+
if (!id2) throw new Error("promptId required");
|
|
1249
|
+
const payload = { promptId: id2 };
|
|
1238
1250
|
if (metadata && typeof metadata === "object") payload.metadata = metadata;
|
|
1239
1251
|
const actor = address || config.worker.address;
|
|
1240
1252
|
if (actor) payload.address = actor;
|
|
1241
1253
|
return postWorkerJson("discoveryMcpPath", "/discover/mcp", payload);
|
|
1242
1254
|
}
|
|
1243
1255
|
async function recordLaunchEvent({ promptId, metadata, address } = {}) {
|
|
1244
|
-
const
|
|
1245
|
-
if (!
|
|
1246
|
-
const payload = { promptId:
|
|
1256
|
+
const id2 = typeof promptId === "string" ? promptId.trim() : "";
|
|
1257
|
+
if (!id2) throw new Error("promptId required");
|
|
1258
|
+
const payload = { promptId: id2 };
|
|
1247
1259
|
if (metadata && typeof metadata === "object") payload.metadata = metadata;
|
|
1248
1260
|
const actor = address || config.worker.address;
|
|
1249
1261
|
if (actor) payload.address = actor;
|
|
@@ -1273,11 +1285,11 @@ var require_ipfs = __commonJS({
|
|
|
1273
1285
|
}
|
|
1274
1286
|
async function reviewGovernanceReport(payload = {}) {
|
|
1275
1287
|
if (!payload || typeof payload !== "object") throw new Error("payload required");
|
|
1276
|
-
const
|
|
1277
|
-
if (!
|
|
1288
|
+
const id2 = typeof payload.id === "string" ? payload.id.trim() : "";
|
|
1289
|
+
if (!id2) throw new Error("report id required");
|
|
1278
1290
|
const status = typeof payload.status === "string" ? payload.status.trim() : "";
|
|
1279
1291
|
if (!status) throw new Error("status required");
|
|
1280
|
-
const body = { id, status };
|
|
1292
|
+
const body = { id: id2, status };
|
|
1281
1293
|
if (typeof payload.note === "string") body.note = payload.note;
|
|
1282
1294
|
if (typeof payload.action === "string") body.action = payload.action;
|
|
1283
1295
|
return postWorkerJson("governanceReviewPath", "/governance/report/review", body);
|
|
@@ -1393,7 +1405,7 @@ var require_ipfs = __commonJS({
|
|
|
1393
1405
|
verified
|
|
1394
1406
|
};
|
|
1395
1407
|
}
|
|
1396
|
-
|
|
1408
|
+
module2.exports = {
|
|
1397
1409
|
DEFAULT_GATEWAY,
|
|
1398
1410
|
createClient,
|
|
1399
1411
|
buildGatewayUrls,
|
|
@@ -1405,7 +1417,7 @@ var require_ipfs = __commonJS({
|
|
|
1405
1417
|
|
|
1406
1418
|
// src/library/search.js
|
|
1407
1419
|
var require_search = __commonJS({
|
|
1408
|
-
"src/library/search.js"(
|
|
1420
|
+
"src/library/search.js"(exports2, module2) {
|
|
1409
1421
|
var { Contract, getAddress } = __require("ethers");
|
|
1410
1422
|
var ABI = require_abi();
|
|
1411
1423
|
var { SageSDKError, CODES } = require_errors();
|
|
@@ -1576,7 +1588,7 @@ var require_search = __commonJS({
|
|
|
1576
1588
|
}
|
|
1577
1589
|
};
|
|
1578
1590
|
}
|
|
1579
|
-
|
|
1591
|
+
module2.exports = {
|
|
1580
1592
|
searchRegistry
|
|
1581
1593
|
};
|
|
1582
1594
|
}
|
|
@@ -1584,7 +1596,7 @@ var require_search = __commonJS({
|
|
|
1584
1596
|
|
|
1585
1597
|
// src/library/validation.js
|
|
1586
1598
|
var require_validation = __commonJS({
|
|
1587
|
-
"src/library/validation.js"(
|
|
1599
|
+
"src/library/validation.js"(exports2, module2) {
|
|
1588
1600
|
var fsDefault = __require("fs");
|
|
1589
1601
|
var pathDefault = __require("path");
|
|
1590
1602
|
function defaultAjvFactory() {
|
|
@@ -1603,18 +1615,18 @@ var require_validation = __commonJS({
|
|
|
1603
1615
|
} catch (_) {
|
|
1604
1616
|
}
|
|
1605
1617
|
}
|
|
1606
|
-
function normaliseSchemaPaths(schemaPaths, { path }) {
|
|
1618
|
+
function normaliseSchemaPaths(schemaPaths, { path: path2 }) {
|
|
1607
1619
|
if (Array.isArray(schemaPaths) && schemaPaths.length) {
|
|
1608
1620
|
return schemaPaths;
|
|
1609
1621
|
}
|
|
1610
1622
|
return [
|
|
1611
|
-
|
|
1612
|
-
|
|
1623
|
+
path2.join(process.cwd(), "docs", "schemas", "manifest.schema.json"),
|
|
1624
|
+
path2.join(__dirname, "..", "..", "docs", "schemas", "manifest.schema.json")
|
|
1613
1625
|
];
|
|
1614
1626
|
}
|
|
1615
|
-
function safeJsonParse(
|
|
1627
|
+
function safeJsonParse(fs2, file) {
|
|
1616
1628
|
try {
|
|
1617
|
-
const raw =
|
|
1629
|
+
const raw = fs2.readFileSync(file, "utf8");
|
|
1618
1630
|
return JSON.parse(raw);
|
|
1619
1631
|
} catch (_) {
|
|
1620
1632
|
return null;
|
|
@@ -1640,17 +1652,17 @@ var require_validation = __commonJS({
|
|
|
1640
1652
|
}
|
|
1641
1653
|
function createManifestValidator(options = {}) {
|
|
1642
1654
|
const {
|
|
1643
|
-
fs = fsDefault,
|
|
1644
|
-
path = pathDefault,
|
|
1655
|
+
fs: fs2 = fsDefault,
|
|
1656
|
+
path: path2 = pathDefault,
|
|
1645
1657
|
ajvFactory = defaultAjvFactory,
|
|
1646
1658
|
addFormats = defaultAddFormats,
|
|
1647
1659
|
schemaPaths
|
|
1648
1660
|
} = options;
|
|
1649
|
-
const searchPaths = normaliseSchemaPaths(schemaPaths, { path });
|
|
1661
|
+
const searchPaths = normaliseSchemaPaths(schemaPaths, { path: path2 });
|
|
1650
1662
|
function loadSchema() {
|
|
1651
1663
|
for (const schemaPath of searchPaths) {
|
|
1652
|
-
if (!
|
|
1653
|
-
const schema = safeJsonParse(
|
|
1664
|
+
if (!fs2.existsSync(schemaPath)) continue;
|
|
1665
|
+
const schema = safeJsonParse(fs2, schemaPath);
|
|
1654
1666
|
if (schema) return { schema, schemaPath };
|
|
1655
1667
|
}
|
|
1656
1668
|
return { schema: null, schemaPath: null };
|
|
@@ -1723,7 +1735,7 @@ var require_validation = __commonJS({
|
|
|
1723
1735
|
if (!manifestPath) {
|
|
1724
1736
|
throw new Error("manifestPath required");
|
|
1725
1737
|
}
|
|
1726
|
-
const data = safeJsonParse(
|
|
1738
|
+
const data = safeJsonParse(fs2, manifestPath);
|
|
1727
1739
|
if (!data) {
|
|
1728
1740
|
return {
|
|
1729
1741
|
ok: false,
|
|
@@ -1756,8 +1768,8 @@ var require_validation = __commonJS({
|
|
|
1756
1768
|
seenKeys.add(key);
|
|
1757
1769
|
const files = Array.isArray(prompt.files) ? prompt.files : [];
|
|
1758
1770
|
for (const file of files) {
|
|
1759
|
-
const resolved =
|
|
1760
|
-
if (!
|
|
1771
|
+
const resolved = path2.isAbsolute(file) ? file : manifestPath ? path2.join(path2.dirname(manifestPath), file) : file;
|
|
1772
|
+
if (!fs2.existsSync(resolved)) {
|
|
1761
1773
|
issues.push({
|
|
1762
1774
|
type: "missing_file",
|
|
1763
1775
|
message: `File not found: ${file}`,
|
|
@@ -1780,7 +1792,7 @@ var require_validation = __commonJS({
|
|
|
1780
1792
|
}
|
|
1781
1793
|
function bestPracticeCheckFile(manifestPath, options2 = {}) {
|
|
1782
1794
|
if (!manifestPath) throw new Error("manifestPath required");
|
|
1783
|
-
const data = safeJsonParse(
|
|
1795
|
+
const data = safeJsonParse(fs2, manifestPath);
|
|
1784
1796
|
if (!data) {
|
|
1785
1797
|
return [{ type: "parse_error", message: `Failed to parse JSON at ${manifestPath}`, manifestPath }];
|
|
1786
1798
|
}
|
|
@@ -1794,7 +1806,7 @@ var require_validation = __commonJS({
|
|
|
1794
1806
|
bestPracticeCheckFile
|
|
1795
1807
|
};
|
|
1796
1808
|
}
|
|
1797
|
-
|
|
1809
|
+
module2.exports = {
|
|
1798
1810
|
createManifestValidator
|
|
1799
1811
|
};
|
|
1800
1812
|
}
|
|
@@ -1802,8 +1814,8 @@ var require_validation = __commonJS({
|
|
|
1802
1814
|
|
|
1803
1815
|
// src/library/index.js
|
|
1804
1816
|
var require_library = __commonJS({
|
|
1805
|
-
"src/library/index.js"(
|
|
1806
|
-
var { Contract, getAddress, keccak256, toUtf8Bytes } = __require("ethers");
|
|
1817
|
+
"src/library/index.js"(exports2, module2) {
|
|
1818
|
+
var { Contract, getAddress, keccak256, toUtf8Bytes, AbiCoder } = __require("ethers");
|
|
1807
1819
|
var { Interface } = __require("ethers");
|
|
1808
1820
|
var ABI = require_abi();
|
|
1809
1821
|
var { SageSDKError, CODES } = require_errors();
|
|
@@ -1842,17 +1854,31 @@ var require_library = __commonJS({
|
|
|
1842
1854
|
promptCount: Number(promptCount)
|
|
1843
1855
|
};
|
|
1844
1856
|
}
|
|
1857
|
+
function _computeLibraryKey(subdao, libraryId) {
|
|
1858
|
+
const coder = AbiCoder.defaultAbiCoder ? AbiCoder.defaultAbiCoder() : new AbiCoder();
|
|
1859
|
+
const encoded = coder.encode(["address", "string"], [getAddress(subdao), String(libraryId)]);
|
|
1860
|
+
return keccak256(encoded);
|
|
1861
|
+
}
|
|
1845
1862
|
async function getLatestLibrary({ provider, registry, subdao, libraryId = "main" }) {
|
|
1846
1863
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
1847
1864
|
const addr = normalise(registry, "registry");
|
|
1848
1865
|
const sub = normalise(subdao, "subdao");
|
|
1849
1866
|
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
1850
|
-
const key =
|
|
1867
|
+
const key = _computeLibraryKey(sub, libraryId);
|
|
1851
1868
|
const latestCID = await contract.subdaoLibraryLatest(key).catch(() => "");
|
|
1852
1869
|
if (!latestCID || latestCID.length === 0) return null;
|
|
1853
1870
|
const info = await getManifestInfo({ provider, registry: addr, manifestCID: latestCID });
|
|
1854
1871
|
return info;
|
|
1855
1872
|
}
|
|
1873
|
+
async function getBeforeAfterForUpdate({ provider, registry, subdao, libraryId = "main", newCid }) {
|
|
1874
|
+
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
1875
|
+
const addr = normalise(registry, "registry");
|
|
1876
|
+
const sub = normalise(subdao, "subdao");
|
|
1877
|
+
const contract = new Contract(addr, ABI.LibraryRegistry, provider);
|
|
1878
|
+
const key = _computeLibraryKey(sub, libraryId);
|
|
1879
|
+
const prev = await contract.subdaoLibraryLatest(key).catch(() => "");
|
|
1880
|
+
return { previousCID: prev || null, newCID: String(newCid), libraryId: String(libraryId) };
|
|
1881
|
+
}
|
|
1856
1882
|
async function hasScopedOwnership({ provider, registry, subdao, manifestCID }) {
|
|
1857
1883
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
1858
1884
|
const addr = normalise(registry, "registry");
|
|
@@ -1872,12 +1898,14 @@ var require_library = __commonJS({
|
|
|
1872
1898
|
]);
|
|
1873
1899
|
return { to, data, value: 0n };
|
|
1874
1900
|
}
|
|
1875
|
-
|
|
1901
|
+
module2.exports = {
|
|
1876
1902
|
listManifests,
|
|
1877
1903
|
getManifestInfo,
|
|
1878
1904
|
getLatestLibrary,
|
|
1879
1905
|
hasScopedOwnership,
|
|
1880
1906
|
buildUpdateLibraryForSubDAOTx,
|
|
1907
|
+
_computeLibraryKey,
|
|
1908
|
+
getBeforeAfterForUpdate,
|
|
1881
1909
|
/** Build an authorizeTimelock(timelock, subdao) call for a LibraryRegistry. */
|
|
1882
1910
|
buildAuthorizeTimelockTx: function buildAuthorizeTimelockTx({ registry, timelock, subdao }) {
|
|
1883
1911
|
const to = normalise(registry, "registry");
|
|
@@ -1914,7 +1942,7 @@ var require_library = __commonJS({
|
|
|
1914
1942
|
|
|
1915
1943
|
// src/governance/index.js
|
|
1916
1944
|
var require_governance = __commonJS({
|
|
1917
|
-
"src/governance/index.js"(
|
|
1945
|
+
"src/governance/index.js"(exports2, module2) {
|
|
1918
1946
|
var { Contract, Interface, AbiCoder, getAddress, hexlify, keccak256, toUtf8Bytes } = __require("ethers");
|
|
1919
1947
|
var ABI = require_abi();
|
|
1920
1948
|
var { BigIntZero } = require_types();
|
|
@@ -1964,11 +1992,11 @@ var require_governance = __commonJS({
|
|
|
1964
1992
|
stakeAmount
|
|
1965
1993
|
};
|
|
1966
1994
|
}
|
|
1967
|
-
async function getProposal({ provider, governor, id }) {
|
|
1995
|
+
async function getProposal({ provider, governor, id: id2 }) {
|
|
1968
1996
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
1969
1997
|
const addr = normaliseGovernor(governor);
|
|
1970
1998
|
const g = new Contract(addr, ABI.Governor, provider);
|
|
1971
|
-
const pid = typeof
|
|
1999
|
+
const pid = typeof id2 === "bigint" ? id2 : String(id2).startsWith("0x") ? BigInt(id2) : BigInt(String(id2));
|
|
1972
2000
|
const [state, snapshot, deadline, votes] = await Promise.all([
|
|
1973
2001
|
g.state(pid),
|
|
1974
2002
|
g.proposalSnapshot(pid),
|
|
@@ -2022,12 +2050,12 @@ var require_governance = __commonJS({
|
|
|
2022
2050
|
}
|
|
2023
2051
|
return proposals;
|
|
2024
2052
|
}
|
|
2025
|
-
async function getProposalMetadata({ provider, governor, id, fromBlock = 0, toBlock = "latest" }) {
|
|
2053
|
+
async function getProposalMetadata({ provider, governor, id: id2, fromBlock = 0, toBlock = "latest" }) {
|
|
2026
2054
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2027
2055
|
const addr = normaliseGovernor(governor);
|
|
2028
2056
|
const iface = new Interface([ABI.Events.ProposalCreated]);
|
|
2029
2057
|
const topic = iface.getEvent("ProposalCreated").topicHash;
|
|
2030
|
-
const pid = typeof
|
|
2058
|
+
const pid = typeof id2 === "bigint" ? id2 : String(id2).startsWith("0x") ? BigInt(id2) : BigInt(String(id2));
|
|
2031
2059
|
const logs = await provider.getLogs({ address: addr, fromBlock, toBlock, topics: [topic] });
|
|
2032
2060
|
for (const log of logs) {
|
|
2033
2061
|
try {
|
|
@@ -2088,10 +2116,10 @@ var require_governance = __commonJS({
|
|
|
2088
2116
|
function buildCastVoteTx({ governor, proposalId, support, reason }) {
|
|
2089
2117
|
const addr = normaliseGovernor(governor);
|
|
2090
2118
|
const iface = new Interface(ABI.Governor);
|
|
2091
|
-
const
|
|
2119
|
+
const id2 = typeof proposalId === "bigint" ? proposalId : String(proposalId).startsWith("0x") ? BigInt(proposalId) : BigInt(String(proposalId));
|
|
2092
2120
|
const s = Number(support);
|
|
2093
2121
|
const hasReason = reason && String(reason).length > 0;
|
|
2094
|
-
const data = hasReason ? iface.encodeFunctionData("castVoteWithReason(uint256,uint8,string)", [
|
|
2122
|
+
const data = hasReason ? iface.encodeFunctionData("castVoteWithReason(uint256,uint8,string)", [id2, s, String(reason)]) : iface.encodeFunctionData("castVote(uint256,uint8)", [id2, s]);
|
|
2095
2123
|
return { to: addr, data, value: BigIntZero };
|
|
2096
2124
|
}
|
|
2097
2125
|
function cueTx(fn, { governor, targets = [], values = [], calldatas = [], descriptionOrHash = "" }) {
|
|
@@ -2112,17 +2140,73 @@ var require_governance = __commonJS({
|
|
|
2112
2140
|
function buildQueueByIdTx({ governor, proposalId }) {
|
|
2113
2141
|
const addr = normaliseGovernor(governor);
|
|
2114
2142
|
const iface = new Interface(ABI.Governor);
|
|
2115
|
-
const
|
|
2116
|
-
const data = iface.encodeFunctionData("queue(uint256)", [
|
|
2143
|
+
const id2 = typeof proposalId === "bigint" ? proposalId : String(proposalId).startsWith("0x") ? BigInt(proposalId) : BigInt(String(proposalId));
|
|
2144
|
+
const data = iface.encodeFunctionData("queue(uint256)", [id2]);
|
|
2117
2145
|
return { to: addr, data, value: BigIntZero };
|
|
2118
2146
|
}
|
|
2119
2147
|
function buildExecuteByIdTx({ governor, proposalId }) {
|
|
2120
2148
|
const addr = normaliseGovernor(governor);
|
|
2121
2149
|
const iface = new Interface(ABI.Governor);
|
|
2122
|
-
const
|
|
2123
|
-
const data = iface.encodeFunctionData("execute(uint256)", [
|
|
2150
|
+
const id2 = typeof proposalId === "bigint" ? proposalId : String(proposalId).startsWith("0x") ? BigInt(proposalId) : BigInt(String(proposalId));
|
|
2151
|
+
const data = iface.encodeFunctionData("execute(uint256)", [id2]);
|
|
2124
2152
|
return { to: addr, data, value: BigIntZero };
|
|
2125
2153
|
}
|
|
2154
|
+
async function decodeProposalEffects({ provider, governor, proposalId, fromBlock = 0, toBlock = "latest" }) {
|
|
2155
|
+
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2156
|
+
const govAddr = normaliseGovernor(governor);
|
|
2157
|
+
const iface = new Interface([ABI.Events.ProposalCreated]);
|
|
2158
|
+
const topic = iface.getEvent("ProposalCreated").topicHash;
|
|
2159
|
+
const id2 = typeof proposalId === "bigint" ? proposalId : String(proposalId).startsWith("0x") ? BigInt(proposalId) : BigInt(String(proposalId));
|
|
2160
|
+
let parsed = null;
|
|
2161
|
+
let logTxHash = null;
|
|
2162
|
+
const logs = await provider.getLogs({ address: govAddr, fromBlock, toBlock, topics: [topic] });
|
|
2163
|
+
for (const log of logs) {
|
|
2164
|
+
try {
|
|
2165
|
+
const p = iface.parseLog(log);
|
|
2166
|
+
if (BigInt(p.args.id.toString()) === id2) {
|
|
2167
|
+
parsed = p;
|
|
2168
|
+
logTxHash = log.transactionHash;
|
|
2169
|
+
break;
|
|
2170
|
+
}
|
|
2171
|
+
} catch (_) {
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
if (!parsed) throw new Error("ProposalCreated event not found");
|
|
2175
|
+
const targets = parsed.args.targets.map(getAddress);
|
|
2176
|
+
const calldatas = parsed.args.calldatas.map((d) => typeof d === "string" ? d : "0x" + Buffer.from(d).toString("hex"));
|
|
2177
|
+
const LibraryIface = new Interface(["function updateLibraryForSubDAO(address,string,string,uint256)", "function subdaoLibraryLatest(bytes32) view returns (string)"]);
|
|
2178
|
+
const PromptIface = new Interface(["function updatePromptByGovernance(string,string)"]);
|
|
2179
|
+
const coder = AbiCoder.defaultAbiCoder ? AbiCoder.defaultAbiCoder() : new AbiCoder();
|
|
2180
|
+
const effects = [];
|
|
2181
|
+
for (let i = 0; i < calldatas.length; i++) {
|
|
2182
|
+
const data = calldatas[i];
|
|
2183
|
+
const sel = data.slice(0, 10);
|
|
2184
|
+
try {
|
|
2185
|
+
const decoded = LibraryIface.decodeFunctionData("updateLibraryForSubDAO", data);
|
|
2186
|
+
const [subdao, libraryId, newCid, promptCount] = decoded;
|
|
2187
|
+
let previousCID = null;
|
|
2188
|
+
try {
|
|
2189
|
+
const reg = new Contract(targets[i], ["function subdaoLibraryLatest(bytes32) view returns (string)"], provider);
|
|
2190
|
+
const key = keccak256(coder.encode(["address", "string"], [getAddress(subdao), String(libraryId)]));
|
|
2191
|
+
const prev = await reg.subdaoLibraryLatest(key).catch(() => "");
|
|
2192
|
+
previousCID = prev && prev.length ? String(prev) : null;
|
|
2193
|
+
} catch (_) {
|
|
2194
|
+
}
|
|
2195
|
+
effects.push({ type: "libraryUpdate", index: i, target: targets[i], subdao: getAddress(subdao), libraryId: String(libraryId), previousCid: previousCID, newCid: String(newCid), promptCount: Number(promptCount) });
|
|
2196
|
+
continue;
|
|
2197
|
+
} catch (_) {
|
|
2198
|
+
}
|
|
2199
|
+
try {
|
|
2200
|
+
const decodedP = PromptIface.decodeFunctionData("updatePromptByGovernance", data);
|
|
2201
|
+
const [key, newCid] = decodedP;
|
|
2202
|
+
effects.push({ type: "promptUpdate", index: i, target: targets[i], key: String(key), newCid: String(newCid) });
|
|
2203
|
+
continue;
|
|
2204
|
+
} catch (_) {
|
|
2205
|
+
}
|
|
2206
|
+
effects.push({ type: "unknown", index: i, target: targets[i], selector: sel });
|
|
2207
|
+
}
|
|
2208
|
+
return { governor: govAddr, proposalId: id2, tx: logTxHash, actions: { count: calldatas.length }, effects };
|
|
2209
|
+
}
|
|
2126
2210
|
async function getQuorumAt({ provider, governor, blockTag }) {
|
|
2127
2211
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2128
2212
|
const addr = normaliseGovernor(governor);
|
|
@@ -2240,7 +2324,7 @@ var require_governance = __commonJS({
|
|
|
2240
2324
|
const token = await g.sxxxToken();
|
|
2241
2325
|
return buildDelegateTx({ token, delegatee: account });
|
|
2242
2326
|
}
|
|
2243
|
-
|
|
2327
|
+
module2.exports = {
|
|
2244
2328
|
getGovernorInfo,
|
|
2245
2329
|
getProposal,
|
|
2246
2330
|
listProposals,
|
|
@@ -2252,6 +2336,7 @@ var require_governance = __commonJS({
|
|
|
2252
2336
|
buildExecuteTx,
|
|
2253
2337
|
buildQueueByIdTx,
|
|
2254
2338
|
buildExecuteByIdTx,
|
|
2339
|
+
decodeProposalEffects,
|
|
2255
2340
|
makeProposalDescription,
|
|
2256
2341
|
stripProposalSalt,
|
|
2257
2342
|
getQuorumAt,
|
|
@@ -2509,7 +2594,7 @@ var require_governance = __commonJS({
|
|
|
2509
2594
|
|
|
2510
2595
|
// src/governance/intents.js
|
|
2511
2596
|
var require_intents = __commonJS({
|
|
2512
|
-
"src/governance/intents.js"(
|
|
2597
|
+
"src/governance/intents.js"(exports2, module2) {
|
|
2513
2598
|
var { Interface, getAddress } = __require("ethers");
|
|
2514
2599
|
var { SageSDKError, CODES } = require_errors();
|
|
2515
2600
|
function normalise(addr, label) {
|
|
@@ -2533,7 +2618,7 @@ var require_intents = __commonJS({
|
|
|
2533
2618
|
"function setPremiumRevSplit(address,uint16,uint16,uint16)",
|
|
2534
2619
|
"function setCreatorStakeBps(address,uint256)"
|
|
2535
2620
|
]);
|
|
2536
|
-
|
|
2621
|
+
module2.exports = {
|
|
2537
2622
|
// Governor targets
|
|
2538
2623
|
buildUpdateQuorumTx: ({ governor, quorumPercent }) => ({ to: normalise(governor, "governor"), data: GovIface.encodeFunctionData("updateQuorumNumerator", [Number(quorumPercent)]), value: 0n }),
|
|
2539
2624
|
buildSetVotingPeriodTx: ({ governor, blocks }) => ({ to: normalise(governor, "governor"), data: GovIface.encodeFunctionData("setVotingPeriodBlocks", [Number(blocks)]), value: 0n }),
|
|
@@ -2551,7 +2636,7 @@ var require_intents = __commonJS({
|
|
|
2551
2636
|
|
|
2552
2637
|
// src/utils/logs.js
|
|
2553
2638
|
var require_logs = __commonJS({
|
|
2554
|
-
"src/utils/logs.js"(
|
|
2639
|
+
"src/utils/logs.js"(exports2, module2) {
|
|
2555
2640
|
async function fetchLogsChunked({ provider, address, topics = [], fromBlock = 0, toBlock = "latest", chunkSize = 5e4 }) {
|
|
2556
2641
|
if (!provider) throw new Error("provider required");
|
|
2557
2642
|
const latest = toBlock === "latest" ? await provider.getBlockNumber() : Number(toBlock);
|
|
@@ -2565,7 +2650,7 @@ var require_logs = __commonJS({
|
|
|
2565
2650
|
}
|
|
2566
2651
|
return logs;
|
|
2567
2652
|
}
|
|
2568
|
-
|
|
2653
|
+
module2.exports = {
|
|
2569
2654
|
fetchLogsChunked
|
|
2570
2655
|
};
|
|
2571
2656
|
}
|
|
@@ -2573,7 +2658,7 @@ var require_logs = __commonJS({
|
|
|
2573
2658
|
|
|
2574
2659
|
// src/subdao/index.js
|
|
2575
2660
|
var require_subdao = __commonJS({
|
|
2576
|
-
"src/subdao/index.js"(
|
|
2661
|
+
"src/subdao/index.js"(exports2, module2) {
|
|
2577
2662
|
var { Contract, Interface, getAddress } = __require("ethers");
|
|
2578
2663
|
var ABI = require_abi();
|
|
2579
2664
|
var { fetchLogsChunked } = require_logs();
|
|
@@ -2671,7 +2756,7 @@ var require_subdao = __commonJS({
|
|
|
2671
2756
|
const data = SubDAOInterface.encodeFunctionData("unstake", [BigInt(amount)]);
|
|
2672
2757
|
return { to: addr, data, value: 0n };
|
|
2673
2758
|
}
|
|
2674
|
-
|
|
2759
|
+
module2.exports = {
|
|
2675
2760
|
discoverSubDAOs,
|
|
2676
2761
|
getSubDAOInfo,
|
|
2677
2762
|
getSubDAOUserStats,
|
|
@@ -2784,16 +2869,16 @@ var require_subdao = __commonJS({
|
|
|
2784
2869
|
const op = await makeOperator({ signer, subdao: created.subdao, operator, grantAdmin });
|
|
2785
2870
|
return { ...created, operatorResult: op };
|
|
2786
2871
|
}
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2872
|
+
module2.exports.ensureSxxxBurnAllowance = ensureSxxxBurnAllowance;
|
|
2873
|
+
module2.exports.createSubDAO = createSubDAO;
|
|
2874
|
+
module2.exports.makeOperator = makeOperator;
|
|
2875
|
+
module2.exports.createOperatorSubDAO = createOperatorSubDAO;
|
|
2791
2876
|
}
|
|
2792
2877
|
});
|
|
2793
2878
|
|
|
2794
2879
|
// src/governance/templates.js
|
|
2795
2880
|
var require_templates = __commonJS({
|
|
2796
|
-
"src/governance/templates.js"(
|
|
2881
|
+
"src/governance/templates.js"(exports2, module2) {
|
|
2797
2882
|
var { Contract, ZeroAddress, getAddress, isAddress } = __require("ethers");
|
|
2798
2883
|
var subdao = require_subdao();
|
|
2799
2884
|
var abi = require_abi();
|
|
@@ -2903,7 +2988,7 @@ var require_templates = __commonJS({
|
|
|
2903
2988
|
const receipts = await executeSequence(actions);
|
|
2904
2989
|
return { governor, timelock, receipts };
|
|
2905
2990
|
}
|
|
2906
|
-
|
|
2991
|
+
module2.exports = {
|
|
2907
2992
|
communityDraftsBoardExec,
|
|
2908
2993
|
tokenDemocracy
|
|
2909
2994
|
};
|
|
@@ -2912,7 +2997,7 @@ var require_templates = __commonJS({
|
|
|
2912
2997
|
|
|
2913
2998
|
// src/adapters/governance/openzeppelin.js
|
|
2914
2999
|
var require_openzeppelin = __commonJS({
|
|
2915
|
-
"src/adapters/governance/openzeppelin.js"(
|
|
3000
|
+
"src/adapters/governance/openzeppelin.js"(exports2, module2) {
|
|
2916
3001
|
var { Contract, Interface, getAddress } = __require("ethers");
|
|
2917
3002
|
var axios = __require("axios");
|
|
2918
3003
|
var ABI = require_abi();
|
|
@@ -2958,7 +3043,7 @@ var require_openzeppelin = __commonJS({
|
|
|
2958
3043
|
for (const log of logs) {
|
|
2959
3044
|
try {
|
|
2960
3045
|
const parsed = iface.parseLog(log);
|
|
2961
|
-
const
|
|
3046
|
+
const id2 = BigInt(parsed.args.id.toString());
|
|
2962
3047
|
const proposer = getAddress(parsed.args.proposer);
|
|
2963
3048
|
const targets = parsed.args.targets.map(getAddress);
|
|
2964
3049
|
const values = parsed.args.values.map((v) => BigInt(v.toString()));
|
|
@@ -2968,7 +3053,7 @@ var require_openzeppelin = __commonJS({
|
|
|
2968
3053
|
const block = await provider.getBlock(log.blockNumber).catch(() => ({ timestamp: 0 }));
|
|
2969
3054
|
const quorum = await governance.getQuorumAt({ provider, governor: addr, blockTag: BigInt(endBlock || log.blockNumber) }).catch(() => null);
|
|
2970
3055
|
const signatures = await getSignatureList({ provider, targets, calldatas, abiResolver, selectorResolver, chainId: resolvedChainId });
|
|
2971
|
-
items.push({ id, proposer, createdAt: Number(block.timestamp || 0), startBlock, endBlock, quorum, txHash: log.transactionHash, targets, values, calldatas, signatures });
|
|
3056
|
+
items.push({ id: id2, proposer, createdAt: Number(block.timestamp || 0), startBlock, endBlock, quorum, txHash: log.transactionHash, targets, values, calldatas, signatures });
|
|
2972
3057
|
} catch (_) {
|
|
2973
3058
|
}
|
|
2974
3059
|
}
|
|
@@ -2976,10 +3061,10 @@ var require_openzeppelin = __commonJS({
|
|
|
2976
3061
|
}
|
|
2977
3062
|
return { items, nextCursor: null };
|
|
2978
3063
|
}
|
|
2979
|
-
async function getTimelineOnchain({ provider, governor, id, fromBlock = 0, toBlock = "latest" }) {
|
|
3064
|
+
async function getTimelineOnchain({ provider, governor, id: id2, fromBlock = 0, toBlock = "latest" }) {
|
|
2980
3065
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
2981
3066
|
const addr = normaliseGovernor(governor);
|
|
2982
|
-
const pid = typeof
|
|
3067
|
+
const pid = typeof id2 === "bigint" ? id2 : String(id2).startsWith("0x") ? BigInt(id2) : BigInt(String(id2));
|
|
2983
3068
|
const iface = new Interface([Events.ProposalQueued, Events.ProposalExecuted, Events.ProposalCanceled]);
|
|
2984
3069
|
const topics = [
|
|
2985
3070
|
iface.getEvent("ProposalQueued").topicHash,
|
|
@@ -3144,7 +3229,7 @@ var require_openzeppelin = __commonJS({
|
|
|
3144
3229
|
}
|
|
3145
3230
|
return out;
|
|
3146
3231
|
}
|
|
3147
|
-
|
|
3232
|
+
module2.exports = {
|
|
3148
3233
|
getProposals,
|
|
3149
3234
|
getTimelineOnchain,
|
|
3150
3235
|
getSignatureList,
|
|
@@ -3199,7 +3284,7 @@ var require_openzeppelin = __commonJS({
|
|
|
3199
3284
|
|
|
3200
3285
|
// src/governance/operations.js
|
|
3201
3286
|
var require_operations = __commonJS({
|
|
3202
|
-
"src/governance/operations.js"(
|
|
3287
|
+
"src/governance/operations.js"(exports2, module2) {
|
|
3203
3288
|
var { Contract, getAddress, Interface, ZeroAddress, ZeroHash, keccak256, toUtf8Bytes, formatEther } = __require("ethers");
|
|
3204
3289
|
var governance = require_governance();
|
|
3205
3290
|
var ABI = require_abi();
|
|
@@ -3212,9 +3297,9 @@ var require_operations = __commonJS({
|
|
|
3212
3297
|
throw new SageSDKError(CODES.INVALID_ARGS, "invalid governor address", { cause: error });
|
|
3213
3298
|
}
|
|
3214
3299
|
}
|
|
3215
|
-
function normaliseProposalId(
|
|
3216
|
-
if (typeof
|
|
3217
|
-
const value = String(
|
|
3300
|
+
function normaliseProposalId(id2) {
|
|
3301
|
+
if (typeof id2 === "bigint") return id2;
|
|
3302
|
+
const value = String(id2);
|
|
3218
3303
|
try {
|
|
3219
3304
|
return value.startsWith("0x") ? BigInt(value) : BigInt(value);
|
|
3220
3305
|
} catch (error) {
|
|
@@ -3236,7 +3321,7 @@ var require_operations = __commonJS({
|
|
|
3236
3321
|
if (!load || !save) return null;
|
|
3237
3322
|
return { load, save };
|
|
3238
3323
|
}
|
|
3239
|
-
function normaliseTuple(governor,
|
|
3324
|
+
function normaliseTuple(governor, id2, metadata) {
|
|
3240
3325
|
const targets = Array.isArray(metadata.targets) ? metadata.targets.map((t) => getAddress(t)) : [];
|
|
3241
3326
|
let values = Array.isArray(metadata.values) ? metadata.values.map((v) => BigInt(v)) : new Array(targets.length).fill(BigIntZero);
|
|
3242
3327
|
const calldatas = Array.isArray(metadata.calldatas) ? metadata.calldatas.map(String) : [];
|
|
@@ -3246,7 +3331,7 @@ var require_operations = __commonJS({
|
|
|
3246
3331
|
const description = metadata.description || metadata.body || "";
|
|
3247
3332
|
const descriptionHash = metadata.descriptionHash || (typeof metadata.hashDescription === "function" ? metadata.hashDescription(description) : keccak256(toUtf8Bytes(String(description || ""))));
|
|
3248
3333
|
return {
|
|
3249
|
-
id,
|
|
3334
|
+
id: id2,
|
|
3250
3335
|
governor,
|
|
3251
3336
|
targets,
|
|
3252
3337
|
values,
|
|
@@ -3271,10 +3356,10 @@ var require_operations = __commonJS({
|
|
|
3271
3356
|
}) {
|
|
3272
3357
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
3273
3358
|
const govAddr = normaliseGovernor(governor);
|
|
3274
|
-
const
|
|
3359
|
+
const id2 = normaliseProposalId(proposalId);
|
|
3275
3360
|
const cacheAdapter = wrapCache(cache);
|
|
3276
3361
|
if (!refresh && cacheAdapter) {
|
|
3277
|
-
const cached = await cacheAdapter.load(govAddr,
|
|
3362
|
+
const cached = await cacheAdapter.load(govAddr, id2);
|
|
3278
3363
|
if (cached) return cached;
|
|
3279
3364
|
}
|
|
3280
3365
|
if (helperAddress) {
|
|
@@ -3283,10 +3368,10 @@ var require_operations = __commonJS({
|
|
|
3283
3368
|
"function getProposalTuple(uint256) view returns (address[] targets,uint256[] values,bytes[] calldatas,bytes32 descriptionHash,bool exists)"
|
|
3284
3369
|
];
|
|
3285
3370
|
const helper = new Contract(helperAddress, helperAbi, provider);
|
|
3286
|
-
const res = await helper.getProposalTuple(
|
|
3371
|
+
const res = await helper.getProposalTuple(id2);
|
|
3287
3372
|
if (res && res.exists) {
|
|
3288
3373
|
const tuple2 = {
|
|
3289
|
-
id,
|
|
3374
|
+
id: id2,
|
|
3290
3375
|
governor: normaliseGovernor(governor),
|
|
3291
3376
|
targets: res.targets || [],
|
|
3292
3377
|
values: (res.values || []).map((v) => BigInt(v)),
|
|
@@ -3295,7 +3380,7 @@ var require_operations = __commonJS({
|
|
|
3295
3380
|
descriptionHash: res.descriptionHash || null,
|
|
3296
3381
|
createdBlock: null
|
|
3297
3382
|
};
|
|
3298
|
-
if (cacheAdapter) await cacheAdapter.save(governor,
|
|
3383
|
+
if (cacheAdapter) await cacheAdapter.save(governor, id2, tuple2);
|
|
3299
3384
|
return tuple2;
|
|
3300
3385
|
}
|
|
3301
3386
|
} catch (_) {
|
|
@@ -3303,7 +3388,7 @@ var require_operations = __commonJS({
|
|
|
3303
3388
|
}
|
|
3304
3389
|
let metadata = null;
|
|
3305
3390
|
try {
|
|
3306
|
-
metadata = await governance.getProposalMetadata({ provider, governor: govAddr, id });
|
|
3391
|
+
metadata = await governance.getProposalMetadata({ provider, governor: govAddr, id: id2 });
|
|
3307
3392
|
} catch (_) {
|
|
3308
3393
|
metadata = null;
|
|
3309
3394
|
}
|
|
@@ -3312,7 +3397,7 @@ var require_operations = __commonJS({
|
|
|
3312
3397
|
try {
|
|
3313
3398
|
const govAbi = new Interface(ABI.Governor);
|
|
3314
3399
|
const govC = new Contract(govAddr, govAbi, provider);
|
|
3315
|
-
const snapshot = hints.snapshot ?? await govC.proposalSnapshot(
|
|
3400
|
+
const snapshot = hints.snapshot ?? await govC.proposalSnapshot(id2).catch(() => null);
|
|
3316
3401
|
const votingDelay = hints.votingDelay ?? await govC.votingDelay().catch(() => null);
|
|
3317
3402
|
if (snapshot !== null && votingDelay !== null) {
|
|
3318
3403
|
const approxCreation = Number(snapshot) - Number(votingDelay);
|
|
@@ -3335,9 +3420,9 @@ var require_operations = __commonJS({
|
|
|
3335
3420
|
try {
|
|
3336
3421
|
const parsed = govC.interface.parseLog(log);
|
|
3337
3422
|
const pid = normaliseProposalId(parsed.args.proposalId);
|
|
3338
|
-
if (pid ===
|
|
3423
|
+
if (pid === id2) {
|
|
3339
3424
|
metadata = {
|
|
3340
|
-
id,
|
|
3425
|
+
id: id2,
|
|
3341
3426
|
governor: govAddr,
|
|
3342
3427
|
targets: Array.from(parsed.args.targets || [], String),
|
|
3343
3428
|
values: Array.from(parsed.args.values || [], (v) => BigInt(v.toString())),
|
|
@@ -3362,7 +3447,7 @@ var require_operations = __commonJS({
|
|
|
3362
3447
|
const page = await governance.listProposals({ provider, governor: govAddr, fromBlock, toBlock: "latest" });
|
|
3363
3448
|
metadata = page.find((entry) => {
|
|
3364
3449
|
try {
|
|
3365
|
-
return normaliseProposalId(entry.id || entry.proposalId) ===
|
|
3450
|
+
return normaliseProposalId(entry.id || entry.proposalId) === id2;
|
|
3366
3451
|
} catch (_) {
|
|
3367
3452
|
return false;
|
|
3368
3453
|
}
|
|
@@ -3372,9 +3457,9 @@ var require_operations = __commonJS({
|
|
|
3372
3457
|
if (!metadata) {
|
|
3373
3458
|
throw new SageSDKError(CODES.NOT_FOUND, "proposal tuple not found");
|
|
3374
3459
|
}
|
|
3375
|
-
const tuple = normaliseTuple(govAddr,
|
|
3460
|
+
const tuple = normaliseTuple(govAddr, id2, metadata);
|
|
3376
3461
|
if (cacheAdapter) {
|
|
3377
|
-
await cacheAdapter.save(govAddr,
|
|
3462
|
+
await cacheAdapter.save(govAddr, id2, tuple);
|
|
3378
3463
|
}
|
|
3379
3464
|
return tuple;
|
|
3380
3465
|
}
|
|
@@ -3659,7 +3744,7 @@ var require_operations = __commonJS({
|
|
|
3659
3744
|
}
|
|
3660
3745
|
return results;
|
|
3661
3746
|
}
|
|
3662
|
-
|
|
3747
|
+
module2.exports = {
|
|
3663
3748
|
resolveProposalTuple,
|
|
3664
3749
|
queueProposal,
|
|
3665
3750
|
executeProposal,
|
|
@@ -3670,9 +3755,94 @@ var require_operations = __commonJS({
|
|
|
3670
3755
|
}
|
|
3671
3756
|
});
|
|
3672
3757
|
|
|
3758
|
+
// src/governance/grants.js
|
|
3759
|
+
var require_grants = __commonJS({
|
|
3760
|
+
"src/governance/grants.js"(exports2, module2) {
|
|
3761
|
+
var { Interface, getAddress, isAddress, parseUnits } = __require("ethers");
|
|
3762
|
+
var { SageSDKError, CODES } = require_errors();
|
|
3763
|
+
function normalizeAddress(label, value) {
|
|
3764
|
+
if (!value) throw new SageSDKError(CODES.INVALID_ARGS, `${label} required`);
|
|
3765
|
+
if (!isAddress(value)) throw new SageSDKError(CODES.INVALID_ARGS, `${label} invalid`);
|
|
3766
|
+
return getAddress(value);
|
|
3767
|
+
}
|
|
3768
|
+
async function buildGrantProposal({ provider = null, vault, token, recipient, amount, decimals = null, raw = false, description = null }) {
|
|
3769
|
+
const vaultAddr = normalizeAddress("vault", vault);
|
|
3770
|
+
const tokenAddr = normalizeAddress("token", token);
|
|
3771
|
+
const rcptAddr = normalizeAddress("recipient", recipient);
|
|
3772
|
+
if (amount == null) throw new SageSDKError(CODES.INVALID_ARGS, "amount required");
|
|
3773
|
+
let resolvedDecimals = decimals != null ? Number(decimals) : null;
|
|
3774
|
+
let symbol = null;
|
|
3775
|
+
if (provider && resolvedDecimals == null) {
|
|
3776
|
+
try {
|
|
3777
|
+
const erc20 = new (__require("ethers")).Contract(tokenAddr, ["function decimals() view returns (uint8)", "function symbol() view returns (string)"], provider);
|
|
3778
|
+
resolvedDecimals = Number(await erc20.decimals());
|
|
3779
|
+
symbol = await erc20.symbol().catch(() => null);
|
|
3780
|
+
} catch (_) {
|
|
3781
|
+
}
|
|
3782
|
+
}
|
|
3783
|
+
if (resolvedDecimals == null) resolvedDecimals = 18;
|
|
3784
|
+
let amtWei;
|
|
3785
|
+
if (raw) {
|
|
3786
|
+
amtWei = BigInt(String(amount));
|
|
3787
|
+
} else {
|
|
3788
|
+
amtWei = parseUnits(String(amount), resolvedDecimals);
|
|
3789
|
+
}
|
|
3790
|
+
const iface = new Interface(["function withdraw(address token,uint256 amount,address recipient)"]);
|
|
3791
|
+
const data = iface.encodeFunctionData("withdraw", [tokenAddr, amtWei, rcptAddr]);
|
|
3792
|
+
const targets = [vaultAddr];
|
|
3793
|
+
const values = [0n];
|
|
3794
|
+
const calldatas = [data];
|
|
3795
|
+
const desc = description && description.length ? description : `Grant ${String(amount)}${symbol ? " " + symbol : ""} to ${rcptAddr}`;
|
|
3796
|
+
return { targets, values, calldatas, description: desc };
|
|
3797
|
+
}
|
|
3798
|
+
module2.exports = {
|
|
3799
|
+
buildGrantProposal,
|
|
3800
|
+
/**
|
|
3801
|
+
* Build a batched proposal for multiple grants. Each item can specify its own vault
|
|
3802
|
+
* or inherit from defaultVault. Decimals are resolved per-token when provider is present.
|
|
3803
|
+
* items: Array<{ vault?, token, recipient, amount, decimals?, raw? }>
|
|
3804
|
+
*/
|
|
3805
|
+
buildBatchGrantProposal: async function buildBatchGrantProposal({ provider = null, items = [], defaultVault = null, description = null }) {
|
|
3806
|
+
if (!Array.isArray(items) || items.length === 0) {
|
|
3807
|
+
throw new SageSDKError(CODES.INVALID_ARGS, "items required");
|
|
3808
|
+
}
|
|
3809
|
+
const targets = [];
|
|
3810
|
+
const values = [];
|
|
3811
|
+
const calldatas = [];
|
|
3812
|
+
const iface = new Interface(["function withdraw(address token,uint256 amount,address recipient)"]);
|
|
3813
|
+
for (const [i, it] of items.entries()) {
|
|
3814
|
+
const vault = it.vault || defaultVault;
|
|
3815
|
+
if (!vault) throw new SageSDKError(CODES.INVALID_ARGS, `item[${i}]: vault missing and no defaultVault provided`);
|
|
3816
|
+
const vaultAddr = normalizeAddress("vault", vault);
|
|
3817
|
+
const tokenAddr = normalizeAddress("token", it.token);
|
|
3818
|
+
const rcptAddr = normalizeAddress("recipient", it.recipient);
|
|
3819
|
+
let resolvedDecimals = it.decimals != null ? Number(it.decimals) : null;
|
|
3820
|
+
if (provider && resolvedDecimals == null && !it.raw) {
|
|
3821
|
+
try {
|
|
3822
|
+
const erc20 = new (__require("ethers")).Contract(tokenAddr, ["function decimals() view returns (uint8)"], provider);
|
|
3823
|
+
resolvedDecimals = Number(await erc20.decimals());
|
|
3824
|
+
} catch (_) {
|
|
3825
|
+
}
|
|
3826
|
+
}
|
|
3827
|
+
if (resolvedDecimals == null) resolvedDecimals = 18;
|
|
3828
|
+
let amtWei;
|
|
3829
|
+
if (it.raw) amtWei = BigInt(String(it.amount));
|
|
3830
|
+
else amtWei = parseUnits(String(it.amount), resolvedDecimals);
|
|
3831
|
+
const data = iface.encodeFunctionData("withdraw", [tokenAddr, amtWei, rcptAddr]);
|
|
3832
|
+
targets.push(vaultAddr);
|
|
3833
|
+
values.push(0n);
|
|
3834
|
+
calldatas.push(data);
|
|
3835
|
+
}
|
|
3836
|
+
const desc = description && description.length ? description : `Batch Grants: ${items.length} transfer(s)`;
|
|
3837
|
+
return { targets, values, calldatas, description: desc };
|
|
3838
|
+
}
|
|
3839
|
+
};
|
|
3840
|
+
}
|
|
3841
|
+
});
|
|
3842
|
+
|
|
3673
3843
|
// src/timelock/index.js
|
|
3674
3844
|
var require_timelock = __commonJS({
|
|
3675
|
-
"src/timelock/index.js"(
|
|
3845
|
+
"src/timelock/index.js"(exports2, module2) {
|
|
3676
3846
|
var { Contract, Interface, getAddress } = __require("ethers");
|
|
3677
3847
|
var { SageSDKError, CODES } = require_errors();
|
|
3678
3848
|
var TimelockABI = [
|
|
@@ -3732,8 +3902,8 @@ var require_timelock = __commonJS({
|
|
|
3732
3902
|
for (const log of logs) {
|
|
3733
3903
|
try {
|
|
3734
3904
|
const parsed = iface.parseLog(log);
|
|
3735
|
-
const
|
|
3736
|
-
const op = operations.get(
|
|
3905
|
+
const id2 = parsed.args.id;
|
|
3906
|
+
const op = operations.get(id2) || { id: id2, scheduled: [], executed: [], cancelled: false };
|
|
3737
3907
|
if (parsed.name === "CallScheduled") {
|
|
3738
3908
|
op.scheduled.push({
|
|
3739
3909
|
index: Number(parsed.args.index),
|
|
@@ -3755,14 +3925,14 @@ var require_timelock = __commonJS({
|
|
|
3755
3925
|
} else if (parsed.name === "Cancelled") {
|
|
3756
3926
|
op.cancelled = true;
|
|
3757
3927
|
}
|
|
3758
|
-
operations.set(
|
|
3928
|
+
operations.set(id2, op);
|
|
3759
3929
|
} catch (err) {
|
|
3760
3930
|
continue;
|
|
3761
3931
|
}
|
|
3762
3932
|
}
|
|
3763
3933
|
return Array.from(operations.values());
|
|
3764
3934
|
}
|
|
3765
|
-
|
|
3935
|
+
module2.exports = {
|
|
3766
3936
|
getTimelockInfo,
|
|
3767
3937
|
listQueuedOperations,
|
|
3768
3938
|
buildScheduleTx: ({ timelock, target, value = 0n, data = "0x", predecessor = "0x0000000000000000000000000000000000000000000000000000000000000000", salt = "0x0000000000000000000000000000000000000000000000000000000000000000", delay = 0n }) => {
|
|
@@ -3778,10 +3948,10 @@ var require_timelock = __commonJS({
|
|
|
3778
3948
|
]);
|
|
3779
3949
|
return { to, data: payload, value: 0n };
|
|
3780
3950
|
},
|
|
3781
|
-
buildCancelTx: ({ timelock, id }) => {
|
|
3782
|
-
if (!
|
|
3951
|
+
buildCancelTx: ({ timelock, id: id2 }) => {
|
|
3952
|
+
if (!id2) throw new SageSDKError(CODES.INVALID_ARGS, "operation id required");
|
|
3783
3953
|
const addr = normalise(timelock, "timelock");
|
|
3784
|
-
const payload = TimelockInterface.encodeFunctionData("cancel", [
|
|
3954
|
+
const payload = TimelockInterface.encodeFunctionData("cancel", [id2]);
|
|
3785
3955
|
return { to: addr, data: payload, value: 0n };
|
|
3786
3956
|
},
|
|
3787
3957
|
buildExecuteTx: ({ timelock, target, value = 0n, data = "0x", predecessor = "0x0000000000000000000000000000000000000000000000000000000000000000", salt = "0x0000000000000000000000000000000000000000000000000000000000000000" }) => {
|
|
@@ -3801,7 +3971,7 @@ var require_timelock = __commonJS({
|
|
|
3801
3971
|
|
|
3802
3972
|
// src/factory/index.js
|
|
3803
3973
|
var require_factory = __commonJS({
|
|
3804
|
-
"src/factory/index.js"(
|
|
3974
|
+
"src/factory/index.js"(exports2, module2) {
|
|
3805
3975
|
var { Contract, Interface, getAddress } = __require("ethers");
|
|
3806
3976
|
var ABI = require_abi();
|
|
3807
3977
|
var { SageSDKError, CODES } = require_errors();
|
|
@@ -3890,10 +4060,10 @@ var require_factory = __commonJS({
|
|
|
3890
4060
|
const moduleContract = new Contract(templateAddr, ABI.TemplateModule, provider);
|
|
3891
4061
|
const ids = await moduleContract.getActiveTemplates().catch(() => []);
|
|
3892
4062
|
const templates = [];
|
|
3893
|
-
for (const
|
|
3894
|
-
const template = await moduleContract.getTemplateStruct(
|
|
4063
|
+
for (const id2 of ids) {
|
|
4064
|
+
const template = await moduleContract.getTemplateStruct(id2);
|
|
3895
4065
|
templates.push({
|
|
3896
|
-
id: Number(
|
|
4066
|
+
id: Number(id2),
|
|
3897
4067
|
name: template[0],
|
|
3898
4068
|
description: template[1],
|
|
3899
4069
|
accessModel: Number(template[2]),
|
|
@@ -4072,7 +4242,7 @@ var require_factory = __commonJS({
|
|
|
4072
4242
|
return null;
|
|
4073
4243
|
}
|
|
4074
4244
|
}
|
|
4075
|
-
|
|
4245
|
+
module2.exports = {
|
|
4076
4246
|
getFactoryConfig,
|
|
4077
4247
|
getFactoryStats,
|
|
4078
4248
|
listSubDAOs,
|
|
@@ -4090,7 +4260,7 @@ var require_factory = __commonJS({
|
|
|
4090
4260
|
|
|
4091
4261
|
// src/prompt/execute.js
|
|
4092
4262
|
var require_execute = __commonJS({
|
|
4093
|
-
"src/prompt/execute.js"(
|
|
4263
|
+
"src/prompt/execute.js"(exports2, module2) {
|
|
4094
4264
|
var axios = __require("axios");
|
|
4095
4265
|
var { createEchoOpenAI } = __require("@merit-systems/echo-typescript-sdk");
|
|
4096
4266
|
var { generateText } = __require("ai");
|
|
@@ -4280,13 +4450,13 @@ ${JSON.stringify(residual, null, 2)}`
|
|
|
4280
4450
|
forkDepth: Number(data.forkDepth || 0)
|
|
4281
4451
|
};
|
|
4282
4452
|
};
|
|
4283
|
-
|
|
4453
|
+
module2.exports = { SageEchoExecutor };
|
|
4284
4454
|
}
|
|
4285
4455
|
});
|
|
4286
4456
|
|
|
4287
4457
|
// src/prompt/index.js
|
|
4288
4458
|
var require_prompt = __commonJS({
|
|
4289
|
-
"src/prompt/index.js"(
|
|
4459
|
+
"src/prompt/index.js"(exports2, module2) {
|
|
4290
4460
|
var { Contract, getAddress } = __require("ethers");
|
|
4291
4461
|
var ABI = require_abi();
|
|
4292
4462
|
var { SageSDKError, CODES } = require_errors();
|
|
@@ -4348,8 +4518,8 @@ var require_prompt = __commonJS({
|
|
|
4348
4518
|
for (let i = 1; i <= upto; i++) ids.push(i);
|
|
4349
4519
|
}
|
|
4350
4520
|
const results = [];
|
|
4351
|
-
for (const
|
|
4352
|
-
const key = await contract.getPromptKey(
|
|
4521
|
+
for (const id2 of ids) {
|
|
4522
|
+
const key = await contract.getPromptKey(id2).catch(() => null);
|
|
4353
4523
|
if (!key) continue;
|
|
4354
4524
|
results.push(await getPromptData({ provider, registry: addr, key }));
|
|
4355
4525
|
}
|
|
@@ -4361,8 +4531,8 @@ var require_prompt = __commonJS({
|
|
|
4361
4531
|
const contract = new Contract(addr, ABI.PromptRegistry, provider);
|
|
4362
4532
|
const ids = await contract.getByTagPage(tagHash, BigInt(offset), BigInt(Math.min(Number(limit), 100)));
|
|
4363
4533
|
const out = [];
|
|
4364
|
-
for (const
|
|
4365
|
-
const key = await contract.getPromptKey(
|
|
4534
|
+
for (const id2 of ids) {
|
|
4535
|
+
const key = await contract.getPromptKey(id2).catch(() => null);
|
|
4366
4536
|
if (!key) continue;
|
|
4367
4537
|
out.push(await getPromptData({ provider, registry: addr, key }));
|
|
4368
4538
|
}
|
|
@@ -4374,8 +4544,8 @@ var require_prompt = __commonJS({
|
|
|
4374
4544
|
const contract = new Contract(addr, ABI.PromptRegistry, provider);
|
|
4375
4545
|
const ids = await contract.getByCreatorPage(getAddress(creator), BigInt(offset), BigInt(Math.min(Number(limit), 100)));
|
|
4376
4546
|
const out = [];
|
|
4377
|
-
for (const
|
|
4378
|
-
const key = await contract.getPromptKey(
|
|
4547
|
+
for (const id2 of ids) {
|
|
4548
|
+
const key = await contract.getPromptKey(id2).catch(() => null);
|
|
4379
4549
|
if (!key) continue;
|
|
4380
4550
|
out.push(await getPromptData({ provider, registry: addr, key }));
|
|
4381
4551
|
}
|
|
@@ -4387,8 +4557,8 @@ var require_prompt = __commonJS({
|
|
|
4387
4557
|
const contract = new Contract(addr, ABI.PromptRegistry, provider);
|
|
4388
4558
|
const ids = await contract.getByCategoryPage(Number(category), BigInt(offset), BigInt(Math.min(Number(limit), 100)));
|
|
4389
4559
|
const out = [];
|
|
4390
|
-
for (const
|
|
4391
|
-
const key = await contract.getPromptKey(
|
|
4560
|
+
for (const id2 of ids) {
|
|
4561
|
+
const key = await contract.getPromptKey(id2).catch(() => null);
|
|
4392
4562
|
if (!key) continue;
|
|
4393
4563
|
out.push(await getPromptData({ provider, registry: addr, key }));
|
|
4394
4564
|
}
|
|
@@ -4412,7 +4582,7 @@ var require_prompt = __commonJS({
|
|
|
4412
4582
|
const contract = new Contract(addr, ABI.PromptRegistry, provider);
|
|
4413
4583
|
return contract.usageCount(key).catch(() => 0);
|
|
4414
4584
|
}
|
|
4415
|
-
|
|
4585
|
+
module2.exports = {
|
|
4416
4586
|
getPromptData,
|
|
4417
4587
|
listPrompts,
|
|
4418
4588
|
listByTagPage,
|
|
@@ -4461,7 +4631,7 @@ var require_prompt = __commonJS({
|
|
|
4461
4631
|
|
|
4462
4632
|
// src/ipns/index.js
|
|
4463
4633
|
var require_ipns = __commonJS({
|
|
4464
|
-
"src/ipns/index.js"(
|
|
4634
|
+
"src/ipns/index.js"(exports2, module2) {
|
|
4465
4635
|
var axiosDefault = __require("axios");
|
|
4466
4636
|
var contentHashLib = null;
|
|
4467
4637
|
try {
|
|
@@ -4478,9 +4648,9 @@ var require_ipns = __commonJS({
|
|
|
4478
4648
|
function removeTrailingSlash(str) {
|
|
4479
4649
|
return str ? str.replace(/\/$/, "") : str;
|
|
4480
4650
|
}
|
|
4481
|
-
function ensureLeadingSlash(
|
|
4482
|
-
if (!
|
|
4483
|
-
return
|
|
4651
|
+
function ensureLeadingSlash(path2) {
|
|
4652
|
+
if (!path2) return "/";
|
|
4653
|
+
return path2.startsWith("/") ? path2 : `/${path2}`;
|
|
4484
4654
|
}
|
|
4485
4655
|
function dedupe(list = []) {
|
|
4486
4656
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -4575,10 +4745,10 @@ var require_ipns = __commonJS({
|
|
|
4575
4745
|
}
|
|
4576
4746
|
return null;
|
|
4577
4747
|
}
|
|
4578
|
-
async function fetchWithGateways(
|
|
4748
|
+
async function fetchWithGateways(path2, axiosInstance, gateways, { timeout, attempts = 3, baseDelay = 500, jitterMs = 250 } = {}) {
|
|
4579
4749
|
const errors = [];
|
|
4580
4750
|
const unique = dedupe(gateways);
|
|
4581
|
-
const suffix =
|
|
4751
|
+
const suffix = path2.replace(/^\/+/, "");
|
|
4582
4752
|
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
4583
4753
|
const delayMs = attempt === 0 ? 0 : jitter(baseDelay * attempt, jitterMs);
|
|
4584
4754
|
if (delayMs) await delay(delayMs);
|
|
@@ -4600,7 +4770,7 @@ var require_ipns = __commonJS({
|
|
|
4600
4770
|
}
|
|
4601
4771
|
}
|
|
4602
4772
|
}
|
|
4603
|
-
const failure = new Error(`Failed to fetch ${
|
|
4773
|
+
const failure = new Error(`Failed to fetch ${path2} from gateways`);
|
|
4604
4774
|
failure.attempts = errors;
|
|
4605
4775
|
throw failure;
|
|
4606
4776
|
}
|
|
@@ -4843,7 +5013,7 @@ var require_ipns = __commonJS({
|
|
|
4843
5013
|
}
|
|
4844
5014
|
};
|
|
4845
5015
|
}
|
|
4846
|
-
|
|
5016
|
+
module2.exports = {
|
|
4847
5017
|
createClient,
|
|
4848
5018
|
normalizeIpnsName,
|
|
4849
5019
|
normalizeCid,
|
|
@@ -4854,7 +5024,7 @@ var require_ipns = __commonJS({
|
|
|
4854
5024
|
|
|
4855
5025
|
// src/token/index.js
|
|
4856
5026
|
var require_token = __commonJS({
|
|
4857
|
-
"src/token/index.js"(
|
|
5027
|
+
"src/token/index.js"(exports2, module2) {
|
|
4858
5028
|
var { Contract, Interface, getAddress } = __require("ethers");
|
|
4859
5029
|
var ABI = require_abi();
|
|
4860
5030
|
var { SageSDKError, CODES } = require_errors();
|
|
@@ -5006,7 +5176,7 @@ var require_token = __commonJS({
|
|
|
5006
5176
|
function getBurnConstants() {
|
|
5007
5177
|
return { ...BURN_CONSTANTS };
|
|
5008
5178
|
}
|
|
5009
|
-
|
|
5179
|
+
module2.exports = {
|
|
5010
5180
|
getBalance,
|
|
5011
5181
|
getVotes,
|
|
5012
5182
|
getTotalSupply,
|
|
@@ -5026,8 +5196,8 @@ var require_token = __commonJS({
|
|
|
5026
5196
|
|
|
5027
5197
|
// src/personal/helpers.js
|
|
5028
5198
|
var require_helpers = __commonJS({
|
|
5029
|
-
"src/personal/helpers.js"(
|
|
5030
|
-
var { getAddress, ZeroAddress, id } = __require("ethers");
|
|
5199
|
+
"src/personal/helpers.js"(exports2, module2) {
|
|
5200
|
+
var { getAddress, ZeroAddress, id: id2 } = __require("ethers");
|
|
5031
5201
|
function normaliseAddress(addr, label) {
|
|
5032
5202
|
if (!addr) throw new Error(`[personal] missing ${label}`);
|
|
5033
5203
|
const value = addr.toString();
|
|
@@ -5038,9 +5208,9 @@ var require_helpers = __commonJS({
|
|
|
5038
5208
|
if (typeof key === "string" && key.startsWith("0x") && key.length === 66) {
|
|
5039
5209
|
return key;
|
|
5040
5210
|
}
|
|
5041
|
-
return
|
|
5211
|
+
return id2(key);
|
|
5042
5212
|
}
|
|
5043
|
-
|
|
5213
|
+
module2.exports = {
|
|
5044
5214
|
normaliseAddress,
|
|
5045
5215
|
toBytes32Key
|
|
5046
5216
|
};
|
|
@@ -5049,7 +5219,7 @@ var require_helpers = __commonJS({
|
|
|
5049
5219
|
|
|
5050
5220
|
// src/personal/receipt.js
|
|
5051
5221
|
var require_receipt = __commonJS({
|
|
5052
|
-
"src/personal/receipt.js"(
|
|
5222
|
+
"src/personal/receipt.js"(exports2, module2) {
|
|
5053
5223
|
var { Contract, getAddress, solidityPackedKeccak256 } = __require("ethers");
|
|
5054
5224
|
var ABI = require_abi();
|
|
5055
5225
|
var { normaliseAddress, toBytes32Key } = require_helpers();
|
|
@@ -5067,11 +5237,11 @@ var require_receipt = __commonJS({
|
|
|
5067
5237
|
const receiptAddress = normaliseAddress(receipt, "receipt");
|
|
5068
5238
|
const holderAddress = normaliseAddress(holder, "holder");
|
|
5069
5239
|
const contract = new Contract(receiptAddress, ABI.PersonalLicenseReceipt, provider);
|
|
5070
|
-
const
|
|
5071
|
-
const balance = await contract.balanceOf(holderAddress,
|
|
5240
|
+
const id2 = typeof receiptId === "bigint" ? receiptId : BigInt(receiptId);
|
|
5241
|
+
const balance = await contract.balanceOf(holderAddress, id2);
|
|
5072
5242
|
return typeof balance === "bigint" ? balance : BigInt(balance.toString());
|
|
5073
5243
|
}
|
|
5074
|
-
|
|
5244
|
+
module2.exports = {
|
|
5075
5245
|
computeReceiptId,
|
|
5076
5246
|
getReceiptBalance
|
|
5077
5247
|
};
|
|
@@ -5080,7 +5250,7 @@ var require_receipt = __commonJS({
|
|
|
5080
5250
|
|
|
5081
5251
|
// src/personal/access.js
|
|
5082
5252
|
var require_access = __commonJS({
|
|
5083
|
-
"src/personal/access.js"(
|
|
5253
|
+
"src/personal/access.js"(exports2, module2) {
|
|
5084
5254
|
var { uint8arrayToString } = __require("@lit-protocol/uint8arrays");
|
|
5085
5255
|
var subgraph = require_subgraph();
|
|
5086
5256
|
var { normaliseAddress, toBytes32Key } = require_helpers();
|
|
@@ -5255,7 +5425,7 @@ var require_access = __commonJS({
|
|
|
5255
5425
|
}
|
|
5256
5426
|
return uint8arrayToString(response.decryptedData, "utf8");
|
|
5257
5427
|
}
|
|
5258
|
-
|
|
5428
|
+
module2.exports = {
|
|
5259
5429
|
resolveEncryptedResource,
|
|
5260
5430
|
decryptWithLit
|
|
5261
5431
|
};
|
|
@@ -5264,7 +5434,7 @@ var require_access = __commonJS({
|
|
|
5264
5434
|
|
|
5265
5435
|
// src/personal/index.js
|
|
5266
5436
|
var require_personal = __commonJS({
|
|
5267
|
-
"src/personal/index.js"(
|
|
5437
|
+
"src/personal/index.js"(exports2, module2) {
|
|
5268
5438
|
var { Interface } = __require("ethers");
|
|
5269
5439
|
var ABI = require_abi();
|
|
5270
5440
|
var { normaliseAddress, toBytes32Key } = require_helpers();
|
|
@@ -5292,7 +5462,7 @@ var require_personal = __commonJS({
|
|
|
5292
5462
|
]);
|
|
5293
5463
|
return { to, data, value: 0n };
|
|
5294
5464
|
}
|
|
5295
|
-
|
|
5465
|
+
module2.exports = {
|
|
5296
5466
|
buildCreatePersonalRegistryTx,
|
|
5297
5467
|
buildSetPriceTx,
|
|
5298
5468
|
buildBuyTx,
|
|
@@ -5304,7 +5474,7 @@ var require_personal = __commonJS({
|
|
|
5304
5474
|
|
|
5305
5475
|
// src/utils/privateTx.js
|
|
5306
5476
|
var require_privateTx = __commonJS({
|
|
5307
|
-
"src/utils/privateTx.js"(
|
|
5477
|
+
"src/utils/privateTx.js"(exports2, module2) {
|
|
5308
5478
|
var axios = __require("axios");
|
|
5309
5479
|
async function sendPrivateRaw({ privateRpcUrl, signedTx, preferences = {} }) {
|
|
5310
5480
|
const body = {
|
|
@@ -5336,7 +5506,7 @@ var require_privateTx = __commonJS({
|
|
|
5336
5506
|
const sent = await signer.sendTransaction(tx);
|
|
5337
5507
|
return { hash: sent.hash, tx: sent };
|
|
5338
5508
|
}
|
|
5339
|
-
|
|
5509
|
+
module2.exports = {
|
|
5340
5510
|
sendTransaction
|
|
5341
5511
|
};
|
|
5342
5512
|
}
|
|
@@ -5344,7 +5514,7 @@ var require_privateTx = __commonJS({
|
|
|
5344
5514
|
|
|
5345
5515
|
// src/utils/safe.js
|
|
5346
5516
|
var require_safe = __commonJS({
|
|
5347
|
-
"src/utils/safe.js"(
|
|
5517
|
+
"src/utils/safe.js"(exports2, module2) {
|
|
5348
5518
|
function toSafeTx(tx, opts = {}) {
|
|
5349
5519
|
const op = Number(opts.operation ?? 0);
|
|
5350
5520
|
return {
|
|
@@ -5360,13 +5530,13 @@ var require_safe = __commonJS({
|
|
|
5360
5530
|
function toSafeTxList(txs, opts = {}) {
|
|
5361
5531
|
return txs.map((t, i) => toSafeTx(t, { ...opts, nonce: opts.nonce != null ? Number(opts.nonce) + i : void 0 }));
|
|
5362
5532
|
}
|
|
5363
|
-
|
|
5533
|
+
module2.exports = { toSafeTx, toSafeTxList };
|
|
5364
5534
|
}
|
|
5365
5535
|
});
|
|
5366
5536
|
|
|
5367
5537
|
// src/treasury/index.js
|
|
5368
5538
|
var require_treasury = __commonJS({
|
|
5369
|
-
"src/treasury/index.js"(
|
|
5539
|
+
"src/treasury/index.js"(exports2, module2) {
|
|
5370
5540
|
var { Contract, Interface, getAddress } = __require("ethers");
|
|
5371
5541
|
var ABI = require_abi();
|
|
5372
5542
|
var { SageSDKError, CODES } = require_errors();
|
|
@@ -5447,12 +5617,12 @@ var require_treasury = __commonJS({
|
|
|
5447
5617
|
idList = Array.from({ length: total - start }, (_, i) => start + i);
|
|
5448
5618
|
}
|
|
5449
5619
|
const withdrawals = [];
|
|
5450
|
-
for (const
|
|
5451
|
-
const entry = await contract.pendingWithdrawals(
|
|
5620
|
+
for (const id2 of idList) {
|
|
5621
|
+
const entry = await contract.pendingWithdrawals(id2).catch(() => null);
|
|
5452
5622
|
if (!entry || !entry.exists) continue;
|
|
5453
5623
|
const [token, recipient, amount, value, requester, balanceBefore, recipientBalanceBefore, depositSnapshot, isLP, isEmergency] = entry;
|
|
5454
5624
|
withdrawals.push({
|
|
5455
|
-
id: Number(
|
|
5625
|
+
id: Number(id2),
|
|
5456
5626
|
token: token && token !== ZERO_ADDRESS ? getAddress(token) : null,
|
|
5457
5627
|
recipient: recipient && recipient !== ZERO_ADDRESS ? getAddress(recipient) : null,
|
|
5458
5628
|
amount: toBigInt(amount),
|
|
@@ -5627,17 +5797,17 @@ var require_treasury = __commonJS({
|
|
|
5627
5797
|
id: parsed?.id != null ? Number(parsed.id) : null
|
|
5628
5798
|
};
|
|
5629
5799
|
}
|
|
5630
|
-
async function confirmWithdrawal({ signer, treasury, id, waitMs }) {
|
|
5800
|
+
async function confirmWithdrawal({ signer, treasury, id: id2, waitMs }) {
|
|
5631
5801
|
const contract = createWriteContract({ signer, treasury });
|
|
5632
|
-
const tx = await contract.confirmWithdrawal(Number(
|
|
5802
|
+
const tx = await contract.confirmWithdrawal(Number(id2));
|
|
5633
5803
|
const receipt = await waitForReceipt({ signer, tx, waitMs });
|
|
5634
|
-
return { transaction: tx, receipt, id: Number(
|
|
5804
|
+
return { transaction: tx, receipt, id: Number(id2) };
|
|
5635
5805
|
}
|
|
5636
|
-
async function cancelWithdrawal({ signer, treasury, id, waitMs }) {
|
|
5806
|
+
async function cancelWithdrawal({ signer, treasury, id: id2, waitMs }) {
|
|
5637
5807
|
const contract = createWriteContract({ signer, treasury });
|
|
5638
|
-
const tx = await contract.cancelWithdrawal(Number(
|
|
5808
|
+
const tx = await contract.cancelWithdrawal(Number(id2));
|
|
5639
5809
|
const receipt = await waitForReceipt({ signer, tx, waitMs });
|
|
5640
|
-
return { transaction: tx, receipt, id: Number(
|
|
5810
|
+
return { transaction: tx, receipt, id: Number(id2) };
|
|
5641
5811
|
}
|
|
5642
5812
|
async function setPriceOverride({ signer, treasury, token, price, ttlSeconds, waitMs }) {
|
|
5643
5813
|
const contract = createWriteContract({ signer, treasury });
|
|
@@ -5679,7 +5849,7 @@ var require_treasury = __commonJS({
|
|
|
5679
5849
|
}
|
|
5680
5850
|
return null;
|
|
5681
5851
|
}
|
|
5682
|
-
|
|
5852
|
+
module2.exports = {
|
|
5683
5853
|
getTreasuryInfo,
|
|
5684
5854
|
getPendingWithdrawals,
|
|
5685
5855
|
getCanonicalLiquidityPlans,
|
|
@@ -5691,14 +5861,30 @@ var require_treasury = __commonJS({
|
|
|
5691
5861
|
confirmWithdrawal,
|
|
5692
5862
|
cancelWithdrawal,
|
|
5693
5863
|
setPriceOverride,
|
|
5694
|
-
clearPriceOverride
|
|
5864
|
+
clearPriceOverride,
|
|
5865
|
+
// TX builders for app usage
|
|
5866
|
+
buildApproveTx: ({ token, spender, amount, decimals = 18 }) => {
|
|
5867
|
+
if (!token || !spender) throw new SageSDKError(CODES.INVALID_ARGS, "token and spender required");
|
|
5868
|
+
const iface = new Interface(["function approve(address,uint256)"]);
|
|
5869
|
+
return { to: getAddress(token), data: iface.encodeFunctionData("approve", [getAddress(spender), BigInt(amount.toString ? amount.toString() : amount)]), value: 0n };
|
|
5870
|
+
},
|
|
5871
|
+
buildTransferTx: ({ token, to, amount, decimals = 18 }) => {
|
|
5872
|
+
if (!token || !to) throw new SageSDKError(CODES.INVALID_ARGS, "token and to required");
|
|
5873
|
+
const iface = new Interface(["function transfer(address,uint256)"]);
|
|
5874
|
+
return { to: getAddress(token), data: iface.encodeFunctionData("transfer", [getAddress(to), BigInt(amount.toString ? amount.toString() : amount)]), value: 0n };
|
|
5875
|
+
},
|
|
5876
|
+
buildWrapEthTx: ({ weth, amountWei }) => {
|
|
5877
|
+
if (!weth) throw new SageSDKError(CODES.INVALID_ARGS, "weth required");
|
|
5878
|
+
const iface = new Interface(["function deposit() payable"]);
|
|
5879
|
+
return { to: getAddress(weth), data: iface.encodeFunctionData("deposit", []), value: BigInt(amountWei.toString ? amountWei.toString() : amountWei) };
|
|
5880
|
+
}
|
|
5695
5881
|
};
|
|
5696
5882
|
}
|
|
5697
5883
|
});
|
|
5698
5884
|
|
|
5699
5885
|
// src/boost/index.js
|
|
5700
5886
|
var require_boost = __commonJS({
|
|
5701
|
-
"src/boost/index.js"(
|
|
5887
|
+
"src/boost/index.js"(exports2, module2) {
|
|
5702
5888
|
var { Contract, Interface, getAddress } = __require("ethers");
|
|
5703
5889
|
var ABI = require_abi();
|
|
5704
5890
|
var { SageSDKError, CODES } = require_errors();
|
|
@@ -5777,7 +5963,7 @@ var require_boost = __commonJS({
|
|
|
5777
5963
|
const data = DirectInterface.encodeFunctionData("fund", [Number(proposalId), BigInt(amount ?? 0n)]);
|
|
5778
5964
|
return { to: addr, data, value: 0n };
|
|
5779
5965
|
}
|
|
5780
|
-
|
|
5966
|
+
module2.exports = {
|
|
5781
5967
|
getMerkleConfig,
|
|
5782
5968
|
buildMerkleFundTx,
|
|
5783
5969
|
buildMerkleSetRootTx,
|
|
@@ -5790,7 +5976,7 @@ var require_boost = __commonJS({
|
|
|
5790
5976
|
|
|
5791
5977
|
// src/bounty/index.js
|
|
5792
5978
|
var require_bounty = __commonJS({
|
|
5793
|
-
"src/bounty/index.js"(
|
|
5979
|
+
"src/bounty/index.js"(exports2, module2) {
|
|
5794
5980
|
var { Contract, Interface, getAddress, isAddress } = __require("ethers");
|
|
5795
5981
|
var subdao = require_subdao();
|
|
5796
5982
|
var governance = require_governance();
|
|
@@ -5903,8 +6089,8 @@ var require_bounty = __commonJS({
|
|
|
5903
6089
|
["function approveBountyCompletion(uint256,string)"],
|
|
5904
6090
|
signer
|
|
5905
6091
|
);
|
|
5906
|
-
const
|
|
5907
|
-
const tx = await bountyContract.approveBountyCompletion(
|
|
6092
|
+
const id2 = BigInt(bountyId);
|
|
6093
|
+
const tx = await bountyContract.approveBountyCompletion(id2, String(deliverable));
|
|
5908
6094
|
return tx.wait();
|
|
5909
6095
|
}
|
|
5910
6096
|
async function proposeApproveWinner({
|
|
@@ -5922,18 +6108,18 @@ var require_bounty = __commonJS({
|
|
|
5922
6108
|
const context = await subdao.getSubDAOInfo({ provider, subdao: subdaoAddress });
|
|
5923
6109
|
const governor = normaliseAddress("governor", context.governor);
|
|
5924
6110
|
const iface = new Interface(["function approveBountyCompletion(uint256,string)"]);
|
|
5925
|
-
const
|
|
5926
|
-
const data = iface.encodeFunctionData("approveBountyCompletion", [
|
|
6111
|
+
const id2 = BigInt(bountyId);
|
|
6112
|
+
const data = iface.encodeFunctionData("approveBountyCompletion", [id2, String(deliverable)]);
|
|
5927
6113
|
const proposalCall = governance.buildProposeTx({
|
|
5928
6114
|
governor,
|
|
5929
6115
|
targets: [bountySystemAddress],
|
|
5930
6116
|
values: [0n],
|
|
5931
6117
|
calldatas: [data],
|
|
5932
|
-
description: `Approve bounty completion for id=${
|
|
6118
|
+
description: `Approve bounty completion for id=${id2}`
|
|
5933
6119
|
});
|
|
5934
6120
|
return { governor, proposalCall };
|
|
5935
6121
|
}
|
|
5936
|
-
|
|
6122
|
+
module2.exports = {
|
|
5937
6123
|
configureWinnerMode,
|
|
5938
6124
|
fundFromTreasury,
|
|
5939
6125
|
approveWinner,
|
|
@@ -5942,251 +6128,9 @@ var require_bounty = __commonJS({
|
|
|
5942
6128
|
}
|
|
5943
6129
|
});
|
|
5944
6130
|
|
|
5945
|
-
// src/bond/index.js
|
|
5946
|
-
var require_bond = __commonJS({
|
|
5947
|
-
"src/bond/index.js"(exports, module) {
|
|
5948
|
-
var {
|
|
5949
|
-
Contract,
|
|
5950
|
-
Interface,
|
|
5951
|
-
MaxUint256,
|
|
5952
|
-
WeiPerEther,
|
|
5953
|
-
formatUnits,
|
|
5954
|
-
getAddress,
|
|
5955
|
-
parseUnits
|
|
5956
|
-
} = __require("ethers");
|
|
5957
|
-
var ABI = require_abi();
|
|
5958
|
-
var { SageSDKError, CODES } = require_errors();
|
|
5959
|
-
function normalise(address, label) {
|
|
5960
|
-
if (!address) throw new SageSDKError(CODES.INVALID_ARGS, `${label} required`);
|
|
5961
|
-
try {
|
|
5962
|
-
return getAddress(address);
|
|
5963
|
-
} catch (err) {
|
|
5964
|
-
throw new SageSDKError(CODES.INVALID_ARGS, `invalid ${label}`, { cause: err });
|
|
5965
|
-
}
|
|
5966
|
-
}
|
|
5967
|
-
var ERC20 = [
|
|
5968
|
-
"function decimals() view returns (uint8)",
|
|
5969
|
-
"function allowance(address owner, address spender) view returns (uint256)",
|
|
5970
|
-
"function approve(address spender, uint256 value) returns (bool)",
|
|
5971
|
-
"function balanceOf(address) view returns (uint256)"
|
|
5972
|
-
];
|
|
5973
|
-
var BondInterface = new Interface(ABI.BondDepository);
|
|
5974
|
-
async function getInfo({ provider, bond }) {
|
|
5975
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
5976
|
-
const addr = normalise(bond, "bond");
|
|
5977
|
-
const c = new Contract(addr, ABI.BondDepository, provider);
|
|
5978
|
-
const [terms, price, priceUsd, totalDebt, payoutToken, principalToken, treasury] = await Promise.all([
|
|
5979
|
-
c.terms(),
|
|
5980
|
-
c.bondPrice(),
|
|
5981
|
-
c.bondPriceInUSD().catch(() => 0n),
|
|
5982
|
-
// totalDebt is keyed by payout token in this implementation
|
|
5983
|
-
c.payoutToken().then((pt) => c.totalDebt(pt)).catch(() => 0n),
|
|
5984
|
-
c.payoutToken(),
|
|
5985
|
-
c.principalToken(),
|
|
5986
|
-
c.treasury()
|
|
5987
|
-
]);
|
|
5988
|
-
return {
|
|
5989
|
-
bond: addr,
|
|
5990
|
-
payoutToken,
|
|
5991
|
-
principalToken,
|
|
5992
|
-
treasury,
|
|
5993
|
-
terms: {
|
|
5994
|
-
controlVariable: BigInt(terms.controlVariable?.toString?.() || terms[0]?.toString?.() || "0"),
|
|
5995
|
-
minimumPrice: BigInt(terms.minimumPrice?.toString?.() || terms[1]?.toString?.() || "0"),
|
|
5996
|
-
maxPayoutBps: BigInt(terms.maxPayout?.toString?.() || terms[2]?.toString?.() || "0"),
|
|
5997
|
-
maxDebt: BigInt(terms.maxDebt?.toString?.() || terms[3]?.toString?.() || "0"),
|
|
5998
|
-
vestingTerm: BigInt(terms.vestingTerm?.toString?.() || terms[4]?.toString?.() || "0"),
|
|
5999
|
-
feeBps: BigInt(terms.fee?.toString?.() || terms[5]?.toString?.() || "0")
|
|
6000
|
-
},
|
|
6001
|
-
price: BigInt(price.toString()),
|
|
6002
|
-
priceUSD: BigInt(priceUsd.toString()),
|
|
6003
|
-
totalDebt: BigInt(totalDebt.toString())
|
|
6004
|
-
};
|
|
6005
|
-
}
|
|
6006
|
-
async function getPrice({ provider, bond }) {
|
|
6007
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
6008
|
-
const c = new Contract(normalise(bond, "bond"), ABI.BondDepository, provider);
|
|
6009
|
-
return c.bondPrice();
|
|
6010
|
-
}
|
|
6011
|
-
async function getUserStatus({ provider, bond, user }) {
|
|
6012
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
6013
|
-
const addr = normalise(bond, "bond");
|
|
6014
|
-
const who = normalise(user, "user");
|
|
6015
|
-
const c = new Contract(addr, ABI.BondDepository, provider);
|
|
6016
|
-
const [info, pending, vested] = await Promise.all([
|
|
6017
|
-
c.bondInfo(who),
|
|
6018
|
-
c.pendingPayout(who),
|
|
6019
|
-
c.percentVestedFor(who).catch(() => 0n)
|
|
6020
|
-
]);
|
|
6021
|
-
return {
|
|
6022
|
-
address: who,
|
|
6023
|
-
bond: addr,
|
|
6024
|
-
payoutRemaining: BigInt(info?.payout?.toString?.() || info[0]?.toString?.() || "0"),
|
|
6025
|
-
vestingBlocks: BigInt(info?.vesting?.toString?.() || info[1]?.toString?.() || "0"),
|
|
6026
|
-
lastInteractionBlock: BigInt(info?.lastBlock?.toString?.() || info[2]?.toString?.() || "0"),
|
|
6027
|
-
pricePaid: BigInt(info?.pricePaid?.toString?.() || info[3]?.toString?.() || "0"),
|
|
6028
|
-
pendingPayout: BigInt(pending.toString()),
|
|
6029
|
-
percentVestedBps: BigInt(vested.toString())
|
|
6030
|
-
};
|
|
6031
|
-
}
|
|
6032
|
-
function buildDepositTx({ bond, amount, maxPrice }) {
|
|
6033
|
-
const to = normalise(bond, "bond");
|
|
6034
|
-
const iface = new Interface(ABI.BondDepository);
|
|
6035
|
-
const data = iface.encodeFunctionData("deposit", [
|
|
6036
|
-
BigInt(amount ?? 0n),
|
|
6037
|
-
// principal amount in token units
|
|
6038
|
-
BigInt(maxPrice ?? 0n)
|
|
6039
|
-
// scaled by 1e18
|
|
6040
|
-
]);
|
|
6041
|
-
return { to, data, value: 0n };
|
|
6042
|
-
}
|
|
6043
|
-
function buildRedeemTx({ bond, recipient, stake = false }) {
|
|
6044
|
-
const to = normalise(bond, "bond");
|
|
6045
|
-
const iface = new Interface(ABI.BondDepository);
|
|
6046
|
-
const data = iface.encodeFunctionData("redeem", [normalise(recipient, "recipient"), !!stake]);
|
|
6047
|
-
return { to, data, value: 0n };
|
|
6048
|
-
}
|
|
6049
|
-
async function getTokenDecimals({ provider, token }) {
|
|
6050
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
6051
|
-
const c = new Contract(normalise(token, "token"), ERC20, provider);
|
|
6052
|
-
const d = await c.decimals().catch(() => 18);
|
|
6053
|
-
return Number(d);
|
|
6054
|
-
}
|
|
6055
|
-
async function getPrincipalAndPayout({ provider, bond }) {
|
|
6056
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
6057
|
-
const c = new Contract(normalise(bond, "bond"), ABI.BondDepository, provider);
|
|
6058
|
-
const [payoutToken, principalToken] = await Promise.all([
|
|
6059
|
-
c.payoutToken(),
|
|
6060
|
-
c.principalToken()
|
|
6061
|
-
]);
|
|
6062
|
-
return { payoutToken, principalToken };
|
|
6063
|
-
}
|
|
6064
|
-
async function estimatePayout({ provider, bond, amount, principalDecimals, payoutDecimals }) {
|
|
6065
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
6066
|
-
if (amount == null) throw new SageSDKError(CODES.INVALID_ARGS, "amount required");
|
|
6067
|
-
const { principalToken, payoutToken } = await getPrincipalAndPayout({ provider, bond });
|
|
6068
|
-
const principalDec = principalDecimals ?? await getTokenDecimals({ provider, token: principalToken });
|
|
6069
|
-
const payoutDec = payoutDecimals ?? await getTokenDecimals({ provider, token: payoutToken });
|
|
6070
|
-
const amountUnits = parseUnits(String(amount), principalDec);
|
|
6071
|
-
const price = await getPrice({ provider, bond });
|
|
6072
|
-
if (price === 0n) {
|
|
6073
|
-
throw new SageSDKError(CODES.RPC_ERROR, "bond price returned zero");
|
|
6074
|
-
}
|
|
6075
|
-
const payoutUnits = amountUnits * WeiPerEther / price;
|
|
6076
|
-
return {
|
|
6077
|
-
inputAmount: String(amount),
|
|
6078
|
-
expectedPayout: formatUnits(payoutUnits, payoutDec),
|
|
6079
|
-
bondPrice: formatUnits(price, 18),
|
|
6080
|
-
principalToken,
|
|
6081
|
-
payoutToken,
|
|
6082
|
-
principalDecimals: principalDec,
|
|
6083
|
-
payoutDecimals: payoutDec
|
|
6084
|
-
};
|
|
6085
|
-
}
|
|
6086
|
-
async function ensurePrincipalAllowance({ signer, bond, amount, principalToken }) {
|
|
6087
|
-
if (!signer) throw new SageSDKError(CODES.INVALID_ARGS, "signer required");
|
|
6088
|
-
const owner = await signer.getAddress();
|
|
6089
|
-
const provider = signer.provider;
|
|
6090
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "signer requires provider");
|
|
6091
|
-
const bondAddress = normalise(bond, "bond");
|
|
6092
|
-
const tokenAddress = principalToken ? normalise(principalToken, "principalToken") : (await getPrincipalAndPayout({ provider, bond: bondAddress })).principalToken;
|
|
6093
|
-
const principal = new Contract(tokenAddress, ERC20, signer);
|
|
6094
|
-
const allowance = await principal.allowance(owner, bondAddress);
|
|
6095
|
-
if (allowance >= amount) {
|
|
6096
|
-
return { approved: false, transactionHash: null };
|
|
6097
|
-
}
|
|
6098
|
-
const approvalTx = await principal.approve(bondAddress, MaxUint256);
|
|
6099
|
-
const receipt = await approvalTx.wait();
|
|
6100
|
-
return {
|
|
6101
|
-
approved: true,
|
|
6102
|
-
transactionHash: receipt.hash ?? approvalTx.hash ?? null
|
|
6103
|
-
};
|
|
6104
|
-
}
|
|
6105
|
-
async function purchase({ signer, bond, amount, maxPrice }) {
|
|
6106
|
-
if (!signer) throw new SageSDKError(CODES.INVALID_ARGS, "signer required");
|
|
6107
|
-
if (amount == null) throw new SageSDKError(CODES.INVALID_ARGS, "amount required");
|
|
6108
|
-
if (maxPrice == null) throw new SageSDKError(CODES.INVALID_ARGS, "maxPrice required");
|
|
6109
|
-
const provider = signer.provider;
|
|
6110
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "signer requires provider");
|
|
6111
|
-
const bondAddress = normalise(bond, "bond");
|
|
6112
|
-
const bondContract = new Contract(bondAddress, ABI.BondDepository, signer);
|
|
6113
|
-
const { principalToken, payoutToken } = await getPrincipalAndPayout({ provider, bond: bondAddress });
|
|
6114
|
-
const principalDec = await getTokenDecimals({ provider, token: principalToken });
|
|
6115
|
-
const payoutDec = await getTokenDecimals({ provider, token: payoutToken });
|
|
6116
|
-
const amountUnits = parseUnits(String(amount), principalDec);
|
|
6117
|
-
const maxPriceUnits = parseUnits(String(maxPrice), 18);
|
|
6118
|
-
const currentPrice = await getPrice({ provider, bond: bondAddress });
|
|
6119
|
-
if (currentPrice > maxPriceUnits) {
|
|
6120
|
-
throw new SageSDKError(CODES.INVALID_ARGS, "current bond price exceeds max price", {
|
|
6121
|
-
currentPrice: formatUnits(currentPrice, 18),
|
|
6122
|
-
maxPrice: String(maxPrice)
|
|
6123
|
-
});
|
|
6124
|
-
}
|
|
6125
|
-
await ensurePrincipalAllowance({ signer, bond: bondAddress, amount: amountUnits, principalToken });
|
|
6126
|
-
const tx = await bondContract.deposit(amountUnits, maxPriceUnits);
|
|
6127
|
-
const receipt = await tx.wait();
|
|
6128
|
-
let depositEvent = null;
|
|
6129
|
-
for (const log of receipt.logs || []) {
|
|
6130
|
-
try {
|
|
6131
|
-
const parsed = BondInterface.parseLog(log);
|
|
6132
|
-
if (parsed?.name === "BondCreated") {
|
|
6133
|
-
depositEvent = parsed.args;
|
|
6134
|
-
break;
|
|
6135
|
-
}
|
|
6136
|
-
} catch (_) {
|
|
6137
|
-
}
|
|
6138
|
-
}
|
|
6139
|
-
return {
|
|
6140
|
-
transactionHash: receipt.hash ?? tx.hash ?? null,
|
|
6141
|
-
deposit: formatUnits(depositEvent?.deposit ?? amountUnits, principalDec),
|
|
6142
|
-
payout: depositEvent?.payout != null ? formatUnits(depositEvent.payout, payoutDec) : null,
|
|
6143
|
-
expires: depositEvent?.expires ?? null,
|
|
6144
|
-
price: formatUnits(currentPrice, 18)
|
|
6145
|
-
};
|
|
6146
|
-
}
|
|
6147
|
-
async function redeem({ signer, bond, recipient, stake = false }) {
|
|
6148
|
-
if (!signer) throw new SageSDKError(CODES.INVALID_ARGS, "signer required");
|
|
6149
|
-
const provider = signer.provider;
|
|
6150
|
-
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "signer requires provider");
|
|
6151
|
-
const bondAddress = normalise(bond, "bond");
|
|
6152
|
-
const user = normalise(recipient || await signer.getAddress(), "recipient");
|
|
6153
|
-
const bondContract = new Contract(bondAddress, ABI.BondDepository, signer);
|
|
6154
|
-
const { payoutToken } = await getPrincipalAndPayout({ provider, bond: bondAddress });
|
|
6155
|
-
const payoutDec = await getTokenDecimals({ provider, token: payoutToken });
|
|
6156
|
-
const pending = await bondContract.pendingPayout(user);
|
|
6157
|
-
if (pending === 0n) {
|
|
6158
|
-
return {
|
|
6159
|
-
transactionHash: null,
|
|
6160
|
-
redeemed: "0",
|
|
6161
|
-
message: "No bonds available for redemption"
|
|
6162
|
-
};
|
|
6163
|
-
}
|
|
6164
|
-
const tx = await bondContract.redeem(user, !!stake);
|
|
6165
|
-
const receipt = await tx.wait();
|
|
6166
|
-
return {
|
|
6167
|
-
transactionHash: receipt.hash ?? tx.hash ?? null,
|
|
6168
|
-
redeemed: formatUnits(pending, payoutDec)
|
|
6169
|
-
};
|
|
6170
|
-
}
|
|
6171
|
-
module.exports = {
|
|
6172
|
-
getInfo,
|
|
6173
|
-
getPrice,
|
|
6174
|
-
getUserStatus,
|
|
6175
|
-
buildDepositTx,
|
|
6176
|
-
buildRedeemTx,
|
|
6177
|
-
getTokenDecimals,
|
|
6178
|
-
getPrincipalAndPayout,
|
|
6179
|
-
estimatePayout,
|
|
6180
|
-
ensurePrincipalAllowance,
|
|
6181
|
-
purchase,
|
|
6182
|
-
redeem
|
|
6183
|
-
};
|
|
6184
|
-
}
|
|
6185
|
-
});
|
|
6186
|
-
|
|
6187
6131
|
// src/utils/provider.js
|
|
6188
6132
|
var require_provider = __commonJS({
|
|
6189
|
-
"src/utils/provider.js"(
|
|
6133
|
+
"src/utils/provider.js"(exports2, module2) {
|
|
6190
6134
|
var { JsonRpcProvider } = __require("ethers");
|
|
6191
6135
|
function assertString(value, name) {
|
|
6192
6136
|
if (typeof value !== "string" || value.trim().length === 0) {
|
|
@@ -6197,7 +6141,7 @@ var require_provider = __commonJS({
|
|
|
6197
6141
|
assertString(rpcUrl, "rpcUrl");
|
|
6198
6142
|
return new JsonRpcProvider(rpcUrl);
|
|
6199
6143
|
}
|
|
6200
|
-
|
|
6144
|
+
module2.exports = {
|
|
6201
6145
|
getProvider,
|
|
6202
6146
|
assertString
|
|
6203
6147
|
};
|
|
@@ -6206,8 +6150,8 @@ var require_provider = __commonJS({
|
|
|
6206
6150
|
|
|
6207
6151
|
// src/wallet/index.js
|
|
6208
6152
|
var require_wallet = __commonJS({
|
|
6209
|
-
"src/wallet/index.js"(
|
|
6210
|
-
var { ethers } = __require("ethers");
|
|
6153
|
+
"src/wallet/index.js"(exports2, module2) {
|
|
6154
|
+
var { ethers: ethers2 } = __require("ethers");
|
|
6211
6155
|
var { SageSDKError, CODES } = require_errors();
|
|
6212
6156
|
var { getProvider } = require_provider();
|
|
6213
6157
|
function isBrowser() {
|
|
@@ -6234,7 +6178,7 @@ var require_wallet = __commonJS({
|
|
|
6234
6178
|
const rpcUrl = src.rpcUrl || getDefaultRpc();
|
|
6235
6179
|
const provider = getProvider({ rpcUrl });
|
|
6236
6180
|
const pk = src.privateKey.startsWith("0x") ? src.privateKey : "0x" + src.privateKey;
|
|
6237
|
-
const signer = new
|
|
6181
|
+
const signer = new ethers2.Wallet(pk, provider);
|
|
6238
6182
|
return { signer, provider };
|
|
6239
6183
|
}
|
|
6240
6184
|
case "pkEnv": {
|
|
@@ -6243,7 +6187,7 @@ var require_wallet = __commonJS({
|
|
|
6243
6187
|
if (!pk) throw new SageSDKError(CODES.INVALID_ARGS, `${envName} not set`);
|
|
6244
6188
|
const rpcUrl = src.rpcUrl || getDefaultRpc();
|
|
6245
6189
|
const provider = getProvider({ rpcUrl });
|
|
6246
|
-
const signer = new
|
|
6190
|
+
const signer = new ethers2.Wallet(pk.startsWith("0x") ? pk : "0x" + pk, provider);
|
|
6247
6191
|
return { signer, provider };
|
|
6248
6192
|
}
|
|
6249
6193
|
case "rpc": {
|
|
@@ -6254,7 +6198,7 @@ var require_wallet = __commonJS({
|
|
|
6254
6198
|
case "injected": {
|
|
6255
6199
|
if (!isBrowser()) throw new SageSDKError(CODES.MISSING_DEPENDENCY, "Injected provider only available in browser");
|
|
6256
6200
|
try {
|
|
6257
|
-
const provider = new
|
|
6201
|
+
const provider = new ethers2.BrowserProvider(window.ethereum);
|
|
6258
6202
|
const signer = await provider.getSigner();
|
|
6259
6203
|
return { signer, provider };
|
|
6260
6204
|
} catch (e) {
|
|
@@ -6282,7 +6226,7 @@ var require_wallet = __commonJS({
|
|
|
6282
6226
|
return process.env.RPC_URL || process.env.BASE_SEPOLIA_RPC_URL || process.env.BASE_SEPOLIA_RPC || "https://base-sepolia.publicnode.com";
|
|
6283
6227
|
}
|
|
6284
6228
|
function create() {
|
|
6285
|
-
const wallet =
|
|
6229
|
+
const wallet = ethers2.Wallet.createRandom();
|
|
6286
6230
|
return {
|
|
6287
6231
|
address: wallet.address,
|
|
6288
6232
|
// Intentionally do not expose privateKey by default to avoid accidental leaks
|
|
@@ -6295,7 +6239,7 @@ var require_wallet = __commonJS({
|
|
|
6295
6239
|
throw new SageSDKError(CODES.INVALID_ARGS, "secret required to import wallet");
|
|
6296
6240
|
}
|
|
6297
6241
|
const pk = secret.startsWith("0x") ? secret : "0x" + secret;
|
|
6298
|
-
const wallet = new
|
|
6242
|
+
const wallet = new ethers2.Wallet(pk);
|
|
6299
6243
|
return { address: wallet.address, _wallet: wallet };
|
|
6300
6244
|
}
|
|
6301
6245
|
function exportWallet(w) {
|
|
@@ -6314,7 +6258,7 @@ var require_wallet = __commonJS({
|
|
|
6314
6258
|
async function connectInjected() {
|
|
6315
6259
|
return loadSigner("injected");
|
|
6316
6260
|
}
|
|
6317
|
-
|
|
6261
|
+
module2.exports = {
|
|
6318
6262
|
listProviders,
|
|
6319
6263
|
loadSigner,
|
|
6320
6264
|
connectInjected,
|
|
@@ -6330,7 +6274,7 @@ var require_wallet = __commonJS({
|
|
|
6330
6274
|
} catch (_) {
|
|
6331
6275
|
if (!opts || !opts.mnemonic || !opts.rpcUrl) throw new SageSDKError(CODES.INVALID_ARGS, "mnemonic and rpcUrl required");
|
|
6332
6276
|
const provider = getProvider({ rpcUrl: opts.rpcUrl });
|
|
6333
|
-
const wallet =
|
|
6277
|
+
const wallet = ethers2.HDNodeWallet.fromPhrase(opts.mnemonic, opts.path);
|
|
6334
6278
|
const signer = wallet.connect(provider);
|
|
6335
6279
|
return { signer, provider };
|
|
6336
6280
|
}
|
|
@@ -6342,7 +6286,7 @@ var require_wallet = __commonJS({
|
|
|
6342
6286
|
} catch (_) {
|
|
6343
6287
|
if (!opts || !opts.json || !opts.password || !opts.rpcUrl) throw new SageSDKError(CODES.INVALID_ARGS, "json, password, rpcUrl required");
|
|
6344
6288
|
const provider = getProvider({ rpcUrl: opts.rpcUrl });
|
|
6345
|
-
const signer = await
|
|
6289
|
+
const signer = await ethers2.Wallet.fromEncryptedJson(opts.json, opts.password);
|
|
6346
6290
|
return { signer: signer.connect(provider), provider };
|
|
6347
6291
|
}
|
|
6348
6292
|
},
|
|
@@ -6388,7 +6332,7 @@ var require_wallet = __commonJS({
|
|
|
6388
6332
|
|
|
6389
6333
|
// src/wallet/session.js
|
|
6390
6334
|
var require_session = __commonJS({
|
|
6391
|
-
"src/wallet/session.js"(
|
|
6335
|
+
"src/wallet/session.js"(exports2, module2) {
|
|
6392
6336
|
var DEFAULT_WALLET_TYPE = "cast";
|
|
6393
6337
|
function resolveWalletType({ config, env = process.env } = {}) {
|
|
6394
6338
|
const envType = String(env.WALLET_TYPE || "").trim();
|
|
@@ -6416,7 +6360,7 @@ var require_session = __commonJS({
|
|
|
6416
6360
|
return false;
|
|
6417
6361
|
}
|
|
6418
6362
|
}
|
|
6419
|
-
|
|
6363
|
+
module2.exports = {
|
|
6420
6364
|
DEFAULT_WALLET_TYPE,
|
|
6421
6365
|
resolveWalletType,
|
|
6422
6366
|
shouldAllowInsecurePrivateKey,
|
|
@@ -6444,6 +6388,32 @@ var require_cast_manager = __commonJS({
|
|
|
6444
6388
|
blue: (text) => `\x1B[34m${text}\x1B[0m`,
|
|
6445
6389
|
cyan: (text) => `\x1B[36m${text}\x1B[0m`
|
|
6446
6390
|
};
|
|
6391
|
+
function optionalRequire(id) {
|
|
6392
|
+
try {
|
|
6393
|
+
const req = typeof __non_webpack_require__ === "function" ? __non_webpack_require__ : eval("require");
|
|
6394
|
+
return req(id);
|
|
6395
|
+
} catch (_) {
|
|
6396
|
+
return null;
|
|
6397
|
+
}
|
|
6398
|
+
}
|
|
6399
|
+
function loadConfigBridge() {
|
|
6400
|
+
const shared = optionalRequire("@sage-protocol/shared");
|
|
6401
|
+
if (shared) {
|
|
6402
|
+
if (shared.ConfigManager) return shared.ConfigManager;
|
|
6403
|
+
if (typeof shared.getProjectDir === "function" || typeof shared.readProfiles === "function") {
|
|
6404
|
+
return shared;
|
|
6405
|
+
}
|
|
6406
|
+
}
|
|
6407
|
+
const local = optionalRequire("./config");
|
|
6408
|
+
if (local) {
|
|
6409
|
+
if (local.ConfigManager) return local.ConfigManager;
|
|
6410
|
+
return local;
|
|
6411
|
+
}
|
|
6412
|
+
return {
|
|
6413
|
+
getProjectDir: () => process.cwd(),
|
|
6414
|
+
readProfiles: () => ({ profiles: {}, activeProfile: "default" })
|
|
6415
|
+
};
|
|
6416
|
+
}
|
|
6447
6417
|
var CastSigner = class extends ethers.VoidSigner {
|
|
6448
6418
|
constructor(address, provider, castWalletManager) {
|
|
6449
6419
|
super(address, provider);
|
|
@@ -6578,13 +6548,8 @@ var require_cast_manager = __commonJS({
|
|
|
6578
6548
|
if (!address) return;
|
|
6579
6549
|
try {
|
|
6580
6550
|
const normalized = ethers.getAddress(address);
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
({ ConfigManager: cfgModule } = __require("@sage-protocol/shared"));
|
|
6584
|
-
} catch (_) {
|
|
6585
|
-
cfgModule = __require("./config");
|
|
6586
|
-
}
|
|
6587
|
-
const projectDir = cfgModule.getProjectDir ? cfgModule.getProjectDir() : process.cwd();
|
|
6551
|
+
const cfgModule = loadConfigBridge();
|
|
6552
|
+
const projectDir = typeof cfgModule.getProjectDir === "function" ? cfgModule.getProjectDir() : process.cwd();
|
|
6588
6553
|
const cfgPath = path.join(projectDir, ".sage", "config.json");
|
|
6589
6554
|
const current = fs.existsSync(cfgPath) ? JSON.parse(fs.readFileSync(cfgPath, "utf8") || "{}") : {};
|
|
6590
6555
|
const active = current.activeProfile || "default";
|
|
@@ -6670,14 +6635,9 @@ var require_cast_manager = __commonJS({
|
|
|
6670
6635
|
console.log(colors.blue("\u{1F517} Connecting wallet using Cast keystore..."));
|
|
6671
6636
|
this.ensureKeystoreDir();
|
|
6672
6637
|
try {
|
|
6673
|
-
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
} catch (_) {
|
|
6677
|
-
cliConfig = __require("./config");
|
|
6678
|
-
}
|
|
6679
|
-
const profiles = cliConfig.readProfiles();
|
|
6680
|
-
const active = profiles.activeProfile || "default";
|
|
6638
|
+
const cliConfig = loadConfigBridge();
|
|
6639
|
+
const profiles = typeof cliConfig.readProfiles === "function" ? cliConfig.readProfiles() : { profiles: {}, activeProfile: "default" };
|
|
6640
|
+
const active = profiles?.activeProfile || "default";
|
|
6681
6641
|
const wanted = profiles?.profiles?.[active]?.wallet?.defaultAccount;
|
|
6682
6642
|
if (wanted && this.keystoreDir && fs.existsSync(this.keystoreDir)) {
|
|
6683
6643
|
const files = fs.readdirSync(this.keystoreDir);
|
|
@@ -6713,7 +6673,7 @@ var require_cast_manager = __commonJS({
|
|
|
6713
6673
|
this.ensureAccountSynced(walletData.address, walletData.keystorePath, { silent: true });
|
|
6714
6674
|
}
|
|
6715
6675
|
try {
|
|
6716
|
-
const { checkRpcHealth } =
|
|
6676
|
+
const { checkRpcHealth } = optionalRequire("./utils/rpc-health") || {};
|
|
6717
6677
|
const candidates = [
|
|
6718
6678
|
this.rpcUrl,
|
|
6719
6679
|
process.env.BASE_SEPOLIA_RPC,
|
|
@@ -7675,10 +7635,10 @@ ${error}` : ""}`;
|
|
|
7675
7635
|
|
|
7676
7636
|
// src/wallet/cdp-manager.js
|
|
7677
7637
|
var require_cdp_manager = __commonJS({
|
|
7678
|
-
"src/wallet/cdp-manager.js"(
|
|
7679
|
-
var
|
|
7680
|
-
var
|
|
7681
|
-
var { ethers } = __require("ethers");
|
|
7638
|
+
"src/wallet/cdp-manager.js"(exports2, module2) {
|
|
7639
|
+
var fs2 = __require("fs");
|
|
7640
|
+
var path2 = __require("path");
|
|
7641
|
+
var { ethers: ethers2 } = __require("ethers");
|
|
7682
7642
|
var MinimalCdpSigner = class {
|
|
7683
7643
|
constructor(manager, provider) {
|
|
7684
7644
|
this._mgr = manager;
|
|
@@ -7707,7 +7667,7 @@ var require_cdp_manager = __commonJS({
|
|
|
7707
7667
|
this.provider = null;
|
|
7708
7668
|
this.signer = null;
|
|
7709
7669
|
this.connected = false;
|
|
7710
|
-
this._profilePath =
|
|
7670
|
+
this._profilePath = path2.join(process.cwd(), ".cdp-wallet.json");
|
|
7711
7671
|
this._client = null;
|
|
7712
7672
|
this._userId = null;
|
|
7713
7673
|
this._walletId = null;
|
|
@@ -7730,9 +7690,9 @@ var require_cdp_manager = __commonJS({
|
|
|
7730
7690
|
}
|
|
7731
7691
|
}
|
|
7732
7692
|
_loadProfile() {
|
|
7733
|
-
if (
|
|
7693
|
+
if (fs2.existsSync(this._profilePath)) {
|
|
7734
7694
|
try {
|
|
7735
|
-
const x = JSON.parse(
|
|
7695
|
+
const x = JSON.parse(fs2.readFileSync(this._profilePath, "utf8"));
|
|
7736
7696
|
this._userId = x.userId || null;
|
|
7737
7697
|
this._walletId = x.walletId || null;
|
|
7738
7698
|
this.account = x.address || null;
|
|
@@ -7742,14 +7702,14 @@ var require_cdp_manager = __commonJS({
|
|
|
7742
7702
|
}
|
|
7743
7703
|
_saveProfile() {
|
|
7744
7704
|
const payload = { userId: this._userId, walletId: this._walletId, address: this.account };
|
|
7745
|
-
|
|
7705
|
+
fs2.writeFileSync(this._profilePath, JSON.stringify(payload, null, 2));
|
|
7746
7706
|
}
|
|
7747
7707
|
async connect() {
|
|
7748
7708
|
if (!process.env.CDP_API_KEY_ID || !process.env.CDP_API_KEY_SECRET) {
|
|
7749
7709
|
throw new Error("Missing CDP_API_KEY_ID/CDP_API_KEY_SECRET in env");
|
|
7750
7710
|
}
|
|
7751
7711
|
const rpc = process.env.RPC_URL || "https://base-sepolia.publicnode.com";
|
|
7752
|
-
this.provider = new
|
|
7712
|
+
this.provider = new ethers2.JsonRpcProvider(rpc);
|
|
7753
7713
|
this._loadProfile();
|
|
7754
7714
|
let client;
|
|
7755
7715
|
try {
|
|
@@ -7761,7 +7721,7 @@ var require_cdp_manager = __commonJS({
|
|
|
7761
7721
|
const email = process.env.CDP_USER_EMAIL || await this._promptEmail();
|
|
7762
7722
|
const fakeUserId = `user_${Buffer.from(email).toString("hex").slice(0, 8)}`;
|
|
7763
7723
|
const fakeWalletId = `w_${Date.now()}`;
|
|
7764
|
-
const fakeAddress = this.account ||
|
|
7724
|
+
const fakeAddress = this.account || ethers2.Wallet.createRandom().address;
|
|
7765
7725
|
this._userId = fakeUserId;
|
|
7766
7726
|
this._walletId = fakeWalletId;
|
|
7767
7727
|
this.account = fakeAddress;
|
|
@@ -7775,7 +7735,7 @@ var require_cdp_manager = __commonJS({
|
|
|
7775
7735
|
console.log("\u{1F4CD} Address:", this.account);
|
|
7776
7736
|
try {
|
|
7777
7737
|
const bal = await this.getBalance();
|
|
7778
|
-
console.log("\u{1F4B0} Balance:",
|
|
7738
|
+
console.log("\u{1F4B0} Balance:", ethers2.formatEther(bal), "ETH");
|
|
7779
7739
|
} catch (_) {
|
|
7780
7740
|
}
|
|
7781
7741
|
}
|
|
@@ -7800,7 +7760,7 @@ var require_cdp_manager = __commonJS({
|
|
|
7800
7760
|
if (!process.env.SAGE_QUIET_JSON) {
|
|
7801
7761
|
console.log("\u{1F4DD} Transaction Details:");
|
|
7802
7762
|
console.log("To:", to);
|
|
7803
|
-
console.log("Value:",
|
|
7763
|
+
console.log("Value:", ethers2.formatEther(value));
|
|
7804
7764
|
console.log("Data:", data);
|
|
7805
7765
|
console.log("\u{1F4E8} Check your email/app to approve the transaction...");
|
|
7806
7766
|
}
|
|
@@ -7845,14 +7805,14 @@ var require_cdp_manager = __commonJS({
|
|
|
7845
7805
|
if (!process.env.SAGE_QUIET_JSON) console.log("\u2705 CDP wallet disconnected");
|
|
7846
7806
|
}
|
|
7847
7807
|
};
|
|
7848
|
-
|
|
7808
|
+
module2.exports = CDPWalletManager;
|
|
7849
7809
|
}
|
|
7850
7810
|
});
|
|
7851
7811
|
|
|
7852
7812
|
// src/wallet/typed.js
|
|
7853
7813
|
var require_typed = __commonJS({
|
|
7854
|
-
"src/wallet/typed.js"(
|
|
7855
|
-
var { ethers } = __require("ethers");
|
|
7814
|
+
"src/wallet/typed.js"(exports2, module2) {
|
|
7815
|
+
var { ethers: ethers2 } = __require("ethers");
|
|
7856
7816
|
function buildGovernorDomain({ name, chainId, verifyingContract }) {
|
|
7857
7817
|
if (!name || !chainId || !verifyingContract) throw new Error("name, chainId, verifyingContract required");
|
|
7858
7818
|
return { name, version: "1", chainId: Number(chainId), verifyingContract };
|
|
@@ -7888,7 +7848,7 @@ var require_typed = __commonJS({
|
|
|
7888
7848
|
const typed = { owner, spender, value, nonce, deadline };
|
|
7889
7849
|
return await signer.signTypedData(domain, PermitTypes, typed);
|
|
7890
7850
|
}
|
|
7891
|
-
|
|
7851
|
+
module2.exports = {
|
|
7892
7852
|
buildGovernorDomain,
|
|
7893
7853
|
BallotTypes,
|
|
7894
7854
|
signVoteBySig,
|
|
@@ -7901,7 +7861,7 @@ var require_typed = __commonJS({
|
|
|
7901
7861
|
|
|
7902
7862
|
// src/doppler/index.js
|
|
7903
7863
|
var require_doppler = __commonJS({
|
|
7904
|
-
"src/doppler/index.js"(
|
|
7864
|
+
"src/doppler/index.js"(exports2, module2) {
|
|
7905
7865
|
var { createPublicClient, createWalletClient, http } = __require("viem");
|
|
7906
7866
|
var { privateKeyToAccount } = __require("viem/accounts");
|
|
7907
7867
|
var { erc20Abi } = __require("viem");
|
|
@@ -7969,12 +7929,40 @@ var require_doppler = __commonJS({
|
|
|
7969
7929
|
}
|
|
7970
7930
|
return { auctionAddress, note: "Lens API not available in this doppler-sdk version" };
|
|
7971
7931
|
}
|
|
7932
|
+
async function listAuctions(sdk, { limit = 10, cursor } = {}) {
|
|
7933
|
+
const lens = sdk.lens;
|
|
7934
|
+
if (lens) {
|
|
7935
|
+
if (typeof lens.listAuctions === "function") {
|
|
7936
|
+
try {
|
|
7937
|
+
return await lens.listAuctions({ limit, cursor });
|
|
7938
|
+
} catch (e) {
|
|
7939
|
+
}
|
|
7940
|
+
}
|
|
7941
|
+
if (typeof lens.getAuctions === "function") {
|
|
7942
|
+
try {
|
|
7943
|
+
return await lens.getAuctions({ limit, cursor });
|
|
7944
|
+
} catch (e) {
|
|
7945
|
+
}
|
|
7946
|
+
}
|
|
7947
|
+
}
|
|
7948
|
+
const fac = sdk.factory;
|
|
7949
|
+
if (fac && typeof fac.listAuctions === "function") {
|
|
7950
|
+
try {
|
|
7951
|
+
return await fac.listAuctions({ limit, cursor });
|
|
7952
|
+
} catch (e) {
|
|
7953
|
+
}
|
|
7954
|
+
}
|
|
7955
|
+
return { ok: false, error: "LIST_UNSUPPORTED", message: "Listing auctions not supported by this doppler-sdk version" };
|
|
7956
|
+
}
|
|
7972
7957
|
async function buyTokens(sdk, { auctionAddress, numeraireAmount }) {
|
|
7973
7958
|
const trade = sdk.trade || sdk.swap || sdk.auction;
|
|
7974
7959
|
if (trade && typeof trade.buy === "function") {
|
|
7975
|
-
|
|
7960
|
+
try {
|
|
7961
|
+
return await trade.buy({ auctionAddress, numeraireAmount });
|
|
7962
|
+
} catch (e) {
|
|
7963
|
+
}
|
|
7976
7964
|
}
|
|
7977
|
-
|
|
7965
|
+
return { ok: false, error: "BUY_UNSUPPORTED", message: "Buy not supported by this doppler-sdk version. Use executeV3BuyExactIn/urExecute helpers or upgrade doppler-sdk." };
|
|
7978
7966
|
}
|
|
7979
7967
|
async function migrate(sdk, asset) {
|
|
7980
7968
|
if (sdk.airlock && typeof sdk.airlock.migrate === "function") {
|
|
@@ -7982,14 +7970,15 @@ var require_doppler = __commonJS({
|
|
|
7982
7970
|
}
|
|
7983
7971
|
throw new Error("Migrate is not supported by the current doppler-sdk version");
|
|
7984
7972
|
}
|
|
7985
|
-
|
|
7973
|
+
module2.exports = {
|
|
7986
7974
|
initDoppler,
|
|
7987
7975
|
deployDynamicAuction,
|
|
7988
7976
|
getAuctionStatus,
|
|
7977
|
+
listAuctions,
|
|
7989
7978
|
buyTokens,
|
|
7990
7979
|
migrate
|
|
7991
7980
|
};
|
|
7992
|
-
|
|
7981
|
+
module2.exports.deployStaticAuction = async function deployStaticAuction(sdk, user, p) {
|
|
7993
7982
|
const StaticAuctionBuilder = dopplerLib.StaticAuctionBuilder || dopplerLib.default?.StaticAuctionBuilder;
|
|
7994
7983
|
if (!StaticAuctionBuilder) throw new Error("StaticAuctionBuilder missing from doppler-sdk");
|
|
7995
7984
|
const builder = new StaticAuctionBuilder().tokenConfig({ name: p.token.name, symbol: p.token.symbol, tokenURI: p.token.tokenURI }).saleConfig({ initialSupply: p.sale.initialSupply, numTokensToSell: p.sale.numTokensToSell, numeraire: p.sale.numeraire }).poolByTicks({ startTick: p.pool.startTick, endTick: p.pool.endTick, fee: p.pool.fee, numPositions: p.pool.numPositions || 15 }).withUserAddress(user);
|
|
@@ -8001,11 +7990,11 @@ var require_doppler = __commonJS({
|
|
|
8001
7990
|
const res = await sdk.factory.createStaticAuction(params);
|
|
8002
7991
|
return res;
|
|
8003
7992
|
};
|
|
8004
|
-
|
|
7993
|
+
module2.exports.getStaticPoolInfo = async function getStaticPoolInfo(sdk, poolAddress) {
|
|
8005
7994
|
const auction = await sdk.getStaticAuction(poolAddress);
|
|
8006
7995
|
return auction.getPoolInfo();
|
|
8007
7996
|
};
|
|
8008
|
-
|
|
7997
|
+
module2.exports.quoteV3ExactIn = async function quoteV3ExactIn(sdk, { tokenIn, tokenOut, amountIn, fee, sqrtPriceLimitX96 = 0n }) {
|
|
8009
7998
|
return sdk.quoter.quoteExactInputV3({ tokenIn, tokenOut, amountIn, fee, sqrtPriceLimitX96 });
|
|
8010
7999
|
};
|
|
8011
8000
|
var WETH_ABI = [
|
|
@@ -8013,7 +8002,7 @@ var require_doppler = __commonJS({
|
|
|
8013
8002
|
{ type: "function", name: "withdraw", stateMutability: "nonpayable", inputs: [{ name: "wad", type: "uint256" }], outputs: [] },
|
|
8014
8003
|
{ type: "function", name: "balanceOf", stateMutability: "view", inputs: [{ name: "a", type: "address" }], outputs: [{ type: "uint256" }] }
|
|
8015
8004
|
];
|
|
8016
|
-
|
|
8005
|
+
module2.exports.wrapEthToWethIfNeeded = async function wrapEthToWethIfNeeded({ rpcUrl, chainId, privateKey, weth, owner, minAmount }) {
|
|
8017
8006
|
const chain = getChainById(chainId);
|
|
8018
8007
|
const accountObj = privateKeyToAccount(privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`);
|
|
8019
8008
|
const publicClient = createPublicClient({ chain, transport: http(rpcUrl) });
|
|
@@ -8025,17 +8014,17 @@ var require_doppler = __commonJS({
|
|
|
8025
8014
|
await publicClient.waitForTransactionReceipt({ hash });
|
|
8026
8015
|
return { deposited: needed, hash };
|
|
8027
8016
|
};
|
|
8028
|
-
|
|
8017
|
+
module2.exports.getDynamicHookInfo = async function getDynamicHookInfo(sdk, hookAddress) {
|
|
8029
8018
|
const auction = await sdk.getDynamicAuction(hookAddress);
|
|
8030
8019
|
return auction.getHookInfo();
|
|
8031
8020
|
};
|
|
8032
|
-
|
|
8021
|
+
module2.exports.quoteV4ExactIn = async function quoteV4ExactIn(sdk, { poolKey, zeroForOne, exactAmount, hookData }) {
|
|
8033
8022
|
return sdk.quoter.quoteExactInputV4({ poolKey, zeroForOne, exactAmount, hookData });
|
|
8034
8023
|
};
|
|
8035
8024
|
var UR_ABI = [
|
|
8036
8025
|
{ name: "execute", type: "function", stateMutability: "payable", inputs: [{ name: "commands", type: "bytes" }, { name: "inputs", type: "bytes[]" }], outputs: [] }
|
|
8037
8026
|
];
|
|
8038
|
-
|
|
8027
|
+
module2.exports.urExecute = async function urExecute({ rpcUrl, chainId, privateKey, universalRouter, commands, inputs, value }) {
|
|
8039
8028
|
const chain = getChainById(chainId);
|
|
8040
8029
|
const accountObj = privateKeyToAccount(privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`);
|
|
8041
8030
|
const publicClient = createPublicClient({ chain, transport: http(rpcUrl) });
|
|
@@ -8044,7 +8033,7 @@ var require_doppler = __commonJS({
|
|
|
8044
8033
|
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
8045
8034
|
return { hash, receipt };
|
|
8046
8035
|
};
|
|
8047
|
-
|
|
8036
|
+
module2.exports.simulateCreateStaticAuction = async function simulateCreateStaticAuction(sdk, builderParams) {
|
|
8048
8037
|
const StaticAuctionBuilder = dopplerLib.StaticAuctionBuilder || dopplerLib.default?.StaticAuctionBuilder;
|
|
8049
8038
|
if (!StaticAuctionBuilder) throw new Error("StaticAuctionBuilder missing from doppler-sdk");
|
|
8050
8039
|
const builder = new StaticAuctionBuilder().tokenConfig(builderParams.token).saleConfig(builderParams.sale).poolByTicks(builderParams.pool).withUserAddress(builderParams.userAddress);
|
|
@@ -8055,10 +8044,10 @@ var require_doppler = __commonJS({
|
|
|
8055
8044
|
const params = builder.build();
|
|
8056
8045
|
return sdk.factory.simulateCreateStaticAuction(params);
|
|
8057
8046
|
};
|
|
8058
|
-
|
|
8047
|
+
module2.exports.simulateBundleExactOut = async function simulateBundleExactOut(sdk, createParams, { tokenIn, tokenOut, amount, fee, sqrtPriceLimitX96 = 0n }) {
|
|
8059
8048
|
return sdk.factory.simulateBundleExactOutput(createParams, { tokenIn, tokenOut, amount, fee, sqrtPriceLimitX96 });
|
|
8060
8049
|
};
|
|
8061
|
-
|
|
8050
|
+
module2.exports.factoryBundle = async function factoryBundle(sdk, createParams, { commands, inputs, value }) {
|
|
8062
8051
|
return sdk.factory.bundle(createParams, commands, inputs, { value });
|
|
8063
8052
|
};
|
|
8064
8053
|
var V3_SWAP_ROUTER_ABI = [
|
|
@@ -8085,7 +8074,7 @@ var require_doppler = __commonJS({
|
|
|
8085
8074
|
outputs: [{ name: "amountOut", type: "uint256" }]
|
|
8086
8075
|
}
|
|
8087
8076
|
];
|
|
8088
|
-
|
|
8077
|
+
module2.exports.executeV3BuyExactIn = async function executeV3BuyExactIn({
|
|
8089
8078
|
rpcUrl,
|
|
8090
8079
|
chainId,
|
|
8091
8080
|
privateKey,
|
|
@@ -8140,15 +8129,962 @@ var require_doppler = __commonJS({
|
|
|
8140
8129
|
}
|
|
8141
8130
|
});
|
|
8142
8131
|
|
|
8132
|
+
// src/services/utils/cache.js
|
|
8133
|
+
var require_cache = __commonJS({
|
|
8134
|
+
"src/services/utils/cache.js"(exports2, module2) {
|
|
8135
|
+
var SimpleCache = class {
|
|
8136
|
+
constructor(options = {}) {
|
|
8137
|
+
this.enabled = options.enabled !== false;
|
|
8138
|
+
this.defaultTTL = options.ttl || 3e4;
|
|
8139
|
+
this.maxSize = options.maxSize || 100;
|
|
8140
|
+
this._store = /* @__PURE__ */ new Map();
|
|
8141
|
+
}
|
|
8142
|
+
/**
|
|
8143
|
+
* Get value from cache
|
|
8144
|
+
* @param {string} key - Cache key
|
|
8145
|
+
* @returns {any|null} - Cached value or null if expired/missing
|
|
8146
|
+
*/
|
|
8147
|
+
get(key) {
|
|
8148
|
+
if (!this.enabled) return null;
|
|
8149
|
+
const entry = this._store.get(key);
|
|
8150
|
+
if (!entry) return null;
|
|
8151
|
+
if (Date.now() > entry.expires) {
|
|
8152
|
+
this._store.delete(key);
|
|
8153
|
+
return null;
|
|
8154
|
+
}
|
|
8155
|
+
return entry.data;
|
|
8156
|
+
}
|
|
8157
|
+
/**
|
|
8158
|
+
* Set value in cache with TTL
|
|
8159
|
+
* @param {string} key - Cache key
|
|
8160
|
+
* @param {any} data - Data to cache
|
|
8161
|
+
* @param {number} ttl - Time to live in milliseconds (optional)
|
|
8162
|
+
*/
|
|
8163
|
+
set(key, data, ttl) {
|
|
8164
|
+
if (!this.enabled) return;
|
|
8165
|
+
if (this._store.size >= this.maxSize && !this._store.has(key)) {
|
|
8166
|
+
const firstKey = this._store.keys().next().value;
|
|
8167
|
+
this._store.delete(firstKey);
|
|
8168
|
+
}
|
|
8169
|
+
this._store.set(key, {
|
|
8170
|
+
data,
|
|
8171
|
+
expires: Date.now() + (ttl || this.defaultTTL)
|
|
8172
|
+
});
|
|
8173
|
+
}
|
|
8174
|
+
/**
|
|
8175
|
+
* Clear all cached entries
|
|
8176
|
+
*/
|
|
8177
|
+
clear() {
|
|
8178
|
+
this._store.clear();
|
|
8179
|
+
}
|
|
8180
|
+
/**
|
|
8181
|
+
* Delete specific key
|
|
8182
|
+
* @param {string} key - Cache key to delete
|
|
8183
|
+
*/
|
|
8184
|
+
delete(key) {
|
|
8185
|
+
this._store.delete(key);
|
|
8186
|
+
}
|
|
8187
|
+
/**
|
|
8188
|
+
* Get cache statistics
|
|
8189
|
+
* @returns {object} - Cache stats (size, enabled)
|
|
8190
|
+
*/
|
|
8191
|
+
stats() {
|
|
8192
|
+
return {
|
|
8193
|
+
size: this._store.size,
|
|
8194
|
+
maxSize: this.maxSize,
|
|
8195
|
+
enabled: this.enabled
|
|
8196
|
+
};
|
|
8197
|
+
}
|
|
8198
|
+
};
|
|
8199
|
+
module2.exports = { SimpleCache };
|
|
8200
|
+
}
|
|
8201
|
+
});
|
|
8202
|
+
|
|
8203
|
+
// src/services/utils/retry.js
|
|
8204
|
+
var require_retry = __commonJS({
|
|
8205
|
+
"src/services/utils/retry.js"(exports2, module2) {
|
|
8206
|
+
async function retryWithBackoff(fn, options = {}) {
|
|
8207
|
+
const {
|
|
8208
|
+
attempts = 3,
|
|
8209
|
+
baseDelay = 1e3,
|
|
8210
|
+
maxDelay = 1e4,
|
|
8211
|
+
onRetry = null
|
|
8212
|
+
} = options;
|
|
8213
|
+
let lastError;
|
|
8214
|
+
for (let i = 0; i < attempts; i++) {
|
|
8215
|
+
try {
|
|
8216
|
+
return await fn();
|
|
8217
|
+
} catch (error) {
|
|
8218
|
+
lastError = error;
|
|
8219
|
+
if (i === attempts - 1) {
|
|
8220
|
+
break;
|
|
8221
|
+
}
|
|
8222
|
+
const delay = Math.min(baseDelay * Math.pow(2, i), maxDelay);
|
|
8223
|
+
if (onRetry) {
|
|
8224
|
+
onRetry({
|
|
8225
|
+
attempt: i + 1,
|
|
8226
|
+
totalAttempts: attempts,
|
|
8227
|
+
delay,
|
|
8228
|
+
error
|
|
8229
|
+
});
|
|
8230
|
+
}
|
|
8231
|
+
await sleep(delay);
|
|
8232
|
+
}
|
|
8233
|
+
}
|
|
8234
|
+
throw lastError;
|
|
8235
|
+
}
|
|
8236
|
+
function sleep(ms) {
|
|
8237
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
8238
|
+
}
|
|
8239
|
+
module2.exports = { retryWithBackoff, sleep };
|
|
8240
|
+
}
|
|
8241
|
+
});
|
|
8242
|
+
|
|
8243
|
+
// src/errors/index.js
|
|
8244
|
+
var require_errors2 = __commonJS({
|
|
8245
|
+
"src/errors/index.js"(exports2, module2) {
|
|
8246
|
+
var SageSDKError = class extends Error {
|
|
8247
|
+
constructor(message, code, retryable = false, originalError = null) {
|
|
8248
|
+
super(message);
|
|
8249
|
+
this.name = this.constructor.name;
|
|
8250
|
+
this.code = code;
|
|
8251
|
+
this.retryable = retryable;
|
|
8252
|
+
this.originalError = originalError;
|
|
8253
|
+
}
|
|
8254
|
+
};
|
|
8255
|
+
var SubgraphError = class extends SageSDKError {
|
|
8256
|
+
/**
|
|
8257
|
+
* @param {string} message - Error message
|
|
8258
|
+
* @param {'TIMEOUT'|'NETWORK'|'INVALID_RESPONSE'|'NOT_FOUND'|'QUERY_FAILED'} code - Error code
|
|
8259
|
+
* @param {boolean} retryable - Whether error is retryable
|
|
8260
|
+
* @param {Error} originalError - Original error (optional)
|
|
8261
|
+
*/
|
|
8262
|
+
constructor(message, code, retryable = false, originalError = null) {
|
|
8263
|
+
super(message, code, retryable, originalError);
|
|
8264
|
+
}
|
|
8265
|
+
};
|
|
8266
|
+
var IPFSError = class extends SageSDKError {
|
|
8267
|
+
/**
|
|
8268
|
+
* @param {string} message - Error message
|
|
8269
|
+
* @param {'TIMEOUT'|'PIN_FAILED'|'INVALID_CID'|'NOT_FOUND'|'GATEWAY_FAILED'|'UPLOAD_FAILED'} code - Error code
|
|
8270
|
+
* @param {boolean} retryable - Whether error is retryable
|
|
8271
|
+
* @param {Error} originalError - Original error (optional)
|
|
8272
|
+
*/
|
|
8273
|
+
constructor(message, code, retryable = false, originalError = null) {
|
|
8274
|
+
super(message, code, retryable, originalError);
|
|
8275
|
+
}
|
|
8276
|
+
};
|
|
8277
|
+
function formatErrorMessage(error) {
|
|
8278
|
+
if (!error) return "An unknown error occurred";
|
|
8279
|
+
if (error instanceof SubgraphError || error instanceof IPFSError) {
|
|
8280
|
+
switch (error.code) {
|
|
8281
|
+
case "TIMEOUT":
|
|
8282
|
+
return "Request timed out. Please try again.";
|
|
8283
|
+
case "NETWORK":
|
|
8284
|
+
return "Network error. Check your connection and try again.";
|
|
8285
|
+
case "INVALID_RESPONSE":
|
|
8286
|
+
return "Received invalid data from server.";
|
|
8287
|
+
case "NOT_FOUND":
|
|
8288
|
+
return "Content not found.";
|
|
8289
|
+
case "PIN_FAILED":
|
|
8290
|
+
return "Failed to pin content to IPFS. Please try again.";
|
|
8291
|
+
case "INVALID_CID":
|
|
8292
|
+
return "Invalid content identifier (CID).";
|
|
8293
|
+
case "GATEWAY_FAILED":
|
|
8294
|
+
return "All IPFS gateways failed. Content may be temporarily unavailable.";
|
|
8295
|
+
case "UPLOAD_FAILED":
|
|
8296
|
+
return "Failed to upload content. Please try again.";
|
|
8297
|
+
case "QUERY_FAILED":
|
|
8298
|
+
return "Failed to query data. Please try again.";
|
|
8299
|
+
default:
|
|
8300
|
+
return error.message || "An error occurred";
|
|
8301
|
+
}
|
|
8302
|
+
}
|
|
8303
|
+
return error.message || "An error occurred";
|
|
8304
|
+
}
|
|
8305
|
+
function isRetryable(error) {
|
|
8306
|
+
if (error instanceof SageSDKError) {
|
|
8307
|
+
return error.retryable;
|
|
8308
|
+
}
|
|
8309
|
+
if (error.name === "AbortError" || error.name === "TimeoutError") {
|
|
8310
|
+
return true;
|
|
8311
|
+
}
|
|
8312
|
+
const message = String(error.message || "").toLowerCase();
|
|
8313
|
+
const retryablePatterns = [
|
|
8314
|
+
"timeout",
|
|
8315
|
+
"network",
|
|
8316
|
+
"econnrefused",
|
|
8317
|
+
"econnreset",
|
|
8318
|
+
"etimedout",
|
|
8319
|
+
"fetch failed"
|
|
8320
|
+
];
|
|
8321
|
+
return retryablePatterns.some((pattern) => message.includes(pattern));
|
|
8322
|
+
}
|
|
8323
|
+
module2.exports = {
|
|
8324
|
+
SageSDKError,
|
|
8325
|
+
SubgraphError,
|
|
8326
|
+
IPFSError,
|
|
8327
|
+
formatErrorMessage,
|
|
8328
|
+
isRetryable
|
|
8329
|
+
};
|
|
8330
|
+
}
|
|
8331
|
+
});
|
|
8332
|
+
|
|
8333
|
+
// src/services/subgraph/client.js
|
|
8334
|
+
var require_client = __commonJS({
|
|
8335
|
+
"src/services/subgraph/client.js"(exports2, module2) {
|
|
8336
|
+
var subgraph = require_subgraph();
|
|
8337
|
+
var { SimpleCache } = require_cache();
|
|
8338
|
+
var { retryWithBackoff } = require_retry();
|
|
8339
|
+
var { SubgraphError } = require_errors2();
|
|
8340
|
+
var SubgraphService = class {
|
|
8341
|
+
/**
|
|
8342
|
+
* @param {object} config - Service configuration
|
|
8343
|
+
* @param {string} config.url - Subgraph GraphQL endpoint
|
|
8344
|
+
* @param {number} [config.timeout=10000] - Request timeout in ms
|
|
8345
|
+
* @param {number} [config.retries=3] - Number of retry attempts
|
|
8346
|
+
* @param {object} [config.cache] - Cache configuration
|
|
8347
|
+
* @param {boolean} [config.cache.enabled=true] - Enable caching
|
|
8348
|
+
* @param {number} [config.cache.ttl=30000] - Cache TTL in ms
|
|
8349
|
+
* @param {number} [config.cache.maxSize=100] - Max cache entries
|
|
8350
|
+
*/
|
|
8351
|
+
constructor(config) {
|
|
8352
|
+
if (!config || !config.url) {
|
|
8353
|
+
throw new Error("SubgraphService requires a url in config");
|
|
8354
|
+
}
|
|
8355
|
+
this.url = config.url;
|
|
8356
|
+
this.timeout = config.timeout || 1e4;
|
|
8357
|
+
this.retries = config.retries || 3;
|
|
8358
|
+
this._cache = new SimpleCache({
|
|
8359
|
+
enabled: config.cache?.enabled !== false,
|
|
8360
|
+
ttl: config.cache?.ttl || 3e4,
|
|
8361
|
+
maxSize: config.cache?.maxSize || 100
|
|
8362
|
+
});
|
|
8363
|
+
}
|
|
8364
|
+
/**
|
|
8365
|
+
* Get list of SubDAOs
|
|
8366
|
+
* @param {object} [options] - Query options
|
|
8367
|
+
* @param {number} [options.limit=50] - Max results
|
|
8368
|
+
* @param {number} [options.skip=0] - Results to skip
|
|
8369
|
+
* @param {boolean} [options.cache=true] - Use cache
|
|
8370
|
+
* @returns {Promise<Array>} - List of SubDAOs
|
|
8371
|
+
*/
|
|
8372
|
+
async getSubDAOs(options = {}) {
|
|
8373
|
+
const { limit = 50, skip = 0, cache = true } = options;
|
|
8374
|
+
const cacheKey = `subdaos:${limit}:${skip}`;
|
|
8375
|
+
if (cache) {
|
|
8376
|
+
const cached = this._cache.get(cacheKey);
|
|
8377
|
+
if (cached) return cached;
|
|
8378
|
+
}
|
|
8379
|
+
try {
|
|
8380
|
+
const result = await retryWithBackoff(
|
|
8381
|
+
() => this._querySubDAOs({ limit, skip }),
|
|
8382
|
+
{ attempts: this.retries }
|
|
8383
|
+
);
|
|
8384
|
+
if (cache) {
|
|
8385
|
+
this._cache.set(cacheKey, result);
|
|
8386
|
+
}
|
|
8387
|
+
return result;
|
|
8388
|
+
} catch (error) {
|
|
8389
|
+
throw new SubgraphError(
|
|
8390
|
+
`Failed to fetch SubDAOs: ${error.message}`,
|
|
8391
|
+
"QUERY_FAILED",
|
|
8392
|
+
true,
|
|
8393
|
+
error
|
|
8394
|
+
);
|
|
8395
|
+
}
|
|
8396
|
+
}
|
|
8397
|
+
/**
|
|
8398
|
+
* Get list of proposals
|
|
8399
|
+
* @param {object} [options] - Query options
|
|
8400
|
+
* @param {string} [options.governor] - Filter by governor address
|
|
8401
|
+
* @param {string} [options.subdao] - Filter by SubDAO address
|
|
8402
|
+
* @param {string[]} [options.states] - Filter by proposal states
|
|
8403
|
+
* @param {number} [options.fromTimestamp] - Filter by creation time (>=)
|
|
8404
|
+
* @param {number} [options.toTimestamp] - Filter by creation time (<=)
|
|
8405
|
+
* @param {number} [options.limit=20] - Max results
|
|
8406
|
+
* @param {number} [options.skip=0] - Results to skip
|
|
8407
|
+
* @param {boolean} [options.cache=true] - Use cache
|
|
8408
|
+
* @returns {Promise<Array>} - List of proposals
|
|
8409
|
+
*/
|
|
8410
|
+
async getProposals(options = {}) {
|
|
8411
|
+
const {
|
|
8412
|
+
governor,
|
|
8413
|
+
subdao,
|
|
8414
|
+
states,
|
|
8415
|
+
fromTimestamp,
|
|
8416
|
+
toTimestamp,
|
|
8417
|
+
limit = 20,
|
|
8418
|
+
skip = 0,
|
|
8419
|
+
cache = true
|
|
8420
|
+
} = options;
|
|
8421
|
+
const cacheKey = `proposals:${JSON.stringify({
|
|
8422
|
+
governor,
|
|
8423
|
+
subdao,
|
|
8424
|
+
states,
|
|
8425
|
+
fromTimestamp,
|
|
8426
|
+
toTimestamp,
|
|
8427
|
+
limit,
|
|
8428
|
+
skip
|
|
8429
|
+
})}`;
|
|
8430
|
+
if (cache) {
|
|
8431
|
+
const cached = this._cache.get(cacheKey);
|
|
8432
|
+
if (cached) return cached;
|
|
8433
|
+
}
|
|
8434
|
+
try {
|
|
8435
|
+
const result = await retryWithBackoff(
|
|
8436
|
+
() => this._queryProposals({
|
|
8437
|
+
governor,
|
|
8438
|
+
subdao,
|
|
8439
|
+
states,
|
|
8440
|
+
fromTimestamp,
|
|
8441
|
+
toTimestamp,
|
|
8442
|
+
limit,
|
|
8443
|
+
skip
|
|
8444
|
+
}),
|
|
8445
|
+
{ attempts: this.retries }
|
|
8446
|
+
);
|
|
8447
|
+
if (cache) {
|
|
8448
|
+
this._cache.set(cacheKey, result);
|
|
8449
|
+
}
|
|
8450
|
+
return result;
|
|
8451
|
+
} catch (error) {
|
|
8452
|
+
throw new SubgraphError(
|
|
8453
|
+
`Failed to fetch proposals: ${error.message}`,
|
|
8454
|
+
"QUERY_FAILED",
|
|
8455
|
+
true,
|
|
8456
|
+
error
|
|
8457
|
+
);
|
|
8458
|
+
}
|
|
8459
|
+
}
|
|
8460
|
+
/**
|
|
8461
|
+
* Get proposal by ID
|
|
8462
|
+
* @param {string} id - Proposal ID
|
|
8463
|
+
* @param {object} [options] - Query options
|
|
8464
|
+
* @param {boolean} [options.cache=true] - Use cache
|
|
8465
|
+
* @returns {Promise<object|null>} - Proposal or null
|
|
8466
|
+
*/
|
|
8467
|
+
async getProposalById(id2, options = {}) {
|
|
8468
|
+
const { cache = true } = options;
|
|
8469
|
+
const cacheKey = `proposal:${id2}`;
|
|
8470
|
+
if (cache) {
|
|
8471
|
+
const cached = this._cache.get(cacheKey);
|
|
8472
|
+
if (cached !== null) return cached;
|
|
8473
|
+
}
|
|
8474
|
+
try {
|
|
8475
|
+
const result = await retryWithBackoff(
|
|
8476
|
+
() => subgraph.getProposalById({ url: this.url, id: id2 }),
|
|
8477
|
+
{ attempts: this.retries }
|
|
8478
|
+
);
|
|
8479
|
+
if (cache) {
|
|
8480
|
+
this._cache.set(cacheKey, result);
|
|
8481
|
+
}
|
|
8482
|
+
return result;
|
|
8483
|
+
} catch (error) {
|
|
8484
|
+
throw new SubgraphError(
|
|
8485
|
+
`Failed to fetch proposal ${id2}: ${error.message}`,
|
|
8486
|
+
"QUERY_FAILED",
|
|
8487
|
+
true,
|
|
8488
|
+
error
|
|
8489
|
+
);
|
|
8490
|
+
}
|
|
8491
|
+
}
|
|
8492
|
+
/**
|
|
8493
|
+
* Get libraries
|
|
8494
|
+
* @param {object} [options] - Query options
|
|
8495
|
+
* @param {string} [options.subdao] - Filter by SubDAO address
|
|
8496
|
+
* @param {number} [options.limit=50] - Max results
|
|
8497
|
+
* @param {number} [options.skip=0] - Results to skip
|
|
8498
|
+
* @param {boolean} [options.cache=true] - Use cache
|
|
8499
|
+
* @returns {Promise<Array>} - List of libraries
|
|
8500
|
+
*/
|
|
8501
|
+
async getLibraries(options = {}) {
|
|
8502
|
+
const { subdao, limit = 50, skip = 0, cache = true } = options;
|
|
8503
|
+
const cacheKey = `libraries:${subdao || "all"}:${limit}:${skip}`;
|
|
8504
|
+
if (cache) {
|
|
8505
|
+
const cached = this._cache.get(cacheKey);
|
|
8506
|
+
if (cached) return cached;
|
|
8507
|
+
}
|
|
8508
|
+
try {
|
|
8509
|
+
const result = await retryWithBackoff(
|
|
8510
|
+
() => subgraph.listLibraries({ url: this.url, subdao, first: limit, skip }),
|
|
8511
|
+
{ attempts: this.retries }
|
|
8512
|
+
);
|
|
8513
|
+
if (cache) {
|
|
8514
|
+
this._cache.set(cacheKey, result);
|
|
8515
|
+
}
|
|
8516
|
+
return result;
|
|
8517
|
+
} catch (error) {
|
|
8518
|
+
throw new SubgraphError(
|
|
8519
|
+
`Failed to fetch libraries: ${error.message}`,
|
|
8520
|
+
"QUERY_FAILED",
|
|
8521
|
+
true,
|
|
8522
|
+
error
|
|
8523
|
+
);
|
|
8524
|
+
}
|
|
8525
|
+
}
|
|
8526
|
+
/**
|
|
8527
|
+
* Get prompts by tag
|
|
8528
|
+
* @param {object} options - Query options
|
|
8529
|
+
* @param {string} options.tagsHash - Tag hash to filter by
|
|
8530
|
+
* @param {string} [options.registry] - Filter by registry address
|
|
8531
|
+
* @param {number} [options.limit=50] - Max results
|
|
8532
|
+
* @param {number} [options.skip=0] - Results to skip
|
|
8533
|
+
* @param {boolean} [options.cache=true] - Use cache
|
|
8534
|
+
* @returns {Promise<Array>} - List of prompts
|
|
8535
|
+
*/
|
|
8536
|
+
async getPromptsByTag(options) {
|
|
8537
|
+
if (!options || !options.tagsHash) {
|
|
8538
|
+
throw new Error("tagsHash is required");
|
|
8539
|
+
}
|
|
8540
|
+
const { tagsHash, registry, limit = 50, skip = 0, cache = true } = options;
|
|
8541
|
+
const cacheKey = `prompts-tag:${tagsHash}:${registry || "all"}:${limit}:${skip}`;
|
|
8542
|
+
if (cache) {
|
|
8543
|
+
const cached = this._cache.get(cacheKey);
|
|
8544
|
+
if (cached) return cached;
|
|
8545
|
+
}
|
|
8546
|
+
try {
|
|
8547
|
+
const result = await retryWithBackoff(
|
|
8548
|
+
() => subgraph.listPromptsByTag({
|
|
8549
|
+
url: this.url,
|
|
8550
|
+
tagsHash,
|
|
8551
|
+
registry,
|
|
8552
|
+
first: limit,
|
|
8553
|
+
skip
|
|
8554
|
+
}),
|
|
8555
|
+
{ attempts: this.retries }
|
|
8556
|
+
);
|
|
8557
|
+
if (cache) {
|
|
8558
|
+
this._cache.set(cacheKey, result);
|
|
8559
|
+
}
|
|
8560
|
+
return result;
|
|
8561
|
+
} catch (error) {
|
|
8562
|
+
throw new SubgraphError(
|
|
8563
|
+
`Failed to fetch prompts by tag: ${error.message}`,
|
|
8564
|
+
"QUERY_FAILED",
|
|
8565
|
+
true,
|
|
8566
|
+
error
|
|
8567
|
+
);
|
|
8568
|
+
}
|
|
8569
|
+
}
|
|
8570
|
+
/**
|
|
8571
|
+
* Get registry prompts
|
|
8572
|
+
* @param {object} options - Query options
|
|
8573
|
+
* @param {string} options.registry - Registry address
|
|
8574
|
+
* @param {number} [options.limit=50] - Max results
|
|
8575
|
+
* @param {number} [options.skip=0] - Results to skip
|
|
8576
|
+
* @param {boolean} [options.cache=true] - Use cache
|
|
8577
|
+
* @returns {Promise<Array>} - List of prompts
|
|
8578
|
+
*/
|
|
8579
|
+
async getRegistryPrompts(options) {
|
|
8580
|
+
if (!options || !options.registry) {
|
|
8581
|
+
throw new Error("registry is required");
|
|
8582
|
+
}
|
|
8583
|
+
const { registry, limit = 50, skip = 0, cache = true } = options;
|
|
8584
|
+
const cacheKey = `registry-prompts:${registry}:${limit}:${skip}`;
|
|
8585
|
+
if (cache) {
|
|
8586
|
+
const cached = this._cache.get(cacheKey);
|
|
8587
|
+
if (cached) return cached;
|
|
8588
|
+
}
|
|
8589
|
+
try {
|
|
8590
|
+
const result = await retryWithBackoff(
|
|
8591
|
+
() => subgraph.listRegistryPrompts({
|
|
8592
|
+
url: this.url,
|
|
8593
|
+
registry,
|
|
8594
|
+
first: limit,
|
|
8595
|
+
skip
|
|
8596
|
+
}),
|
|
8597
|
+
{ attempts: this.retries }
|
|
8598
|
+
);
|
|
8599
|
+
if (cache) {
|
|
8600
|
+
this._cache.set(cacheKey, result);
|
|
8601
|
+
}
|
|
8602
|
+
return result;
|
|
8603
|
+
} catch (error) {
|
|
8604
|
+
throw new SubgraphError(
|
|
8605
|
+
`Failed to fetch registry prompts: ${error.message}`,
|
|
8606
|
+
"QUERY_FAILED",
|
|
8607
|
+
true,
|
|
8608
|
+
error
|
|
8609
|
+
);
|
|
8610
|
+
}
|
|
8611
|
+
}
|
|
8612
|
+
/**
|
|
8613
|
+
* Clear cache
|
|
8614
|
+
*/
|
|
8615
|
+
clearCache() {
|
|
8616
|
+
this._cache.clear();
|
|
8617
|
+
}
|
|
8618
|
+
/**
|
|
8619
|
+
* Get cache statistics
|
|
8620
|
+
* @returns {object} - Cache stats
|
|
8621
|
+
*/
|
|
8622
|
+
getCacheStats() {
|
|
8623
|
+
return this._cache.stats();
|
|
8624
|
+
}
|
|
8625
|
+
// Private methods
|
|
8626
|
+
async _querySubDAOs({ limit, skip }) {
|
|
8627
|
+
const data = await subgraph.query(
|
|
8628
|
+
this.url,
|
|
8629
|
+
`
|
|
8630
|
+
query($first: Int!, $skip: Int!) {
|
|
8631
|
+
subDAOs(first: $first, skip: $skip, orderBy: createdAt, orderDirection: desc) {
|
|
8632
|
+
id
|
|
8633
|
+
address
|
|
8634
|
+
name
|
|
8635
|
+
description
|
|
8636
|
+
governor
|
|
8637
|
+
registry
|
|
8638
|
+
token
|
|
8639
|
+
createdAt
|
|
8640
|
+
}
|
|
8641
|
+
}
|
|
8642
|
+
`,
|
|
8643
|
+
{ first: limit, skip }
|
|
8644
|
+
);
|
|
8645
|
+
return data?.subDAOs || [];
|
|
8646
|
+
}
|
|
8647
|
+
async _queryProposals({ governor, subdao, states, fromTimestamp, toTimestamp, limit, skip }) {
|
|
8648
|
+
return await subgraph.listProposalsFiltered({
|
|
8649
|
+
url: this.url,
|
|
8650
|
+
governor,
|
|
8651
|
+
states,
|
|
8652
|
+
fromTimestamp,
|
|
8653
|
+
toTimestamp,
|
|
8654
|
+
first: limit,
|
|
8655
|
+
skip
|
|
8656
|
+
});
|
|
8657
|
+
}
|
|
8658
|
+
};
|
|
8659
|
+
module2.exports = { SubgraphService };
|
|
8660
|
+
}
|
|
8661
|
+
});
|
|
8662
|
+
|
|
8663
|
+
// src/services/ipfs/client.js
|
|
8664
|
+
var require_client2 = __commonJS({
|
|
8665
|
+
"src/services/ipfs/client.js"(exports2, module2) {
|
|
8666
|
+
var ipfs = require_ipfs();
|
|
8667
|
+
var { SimpleCache } = require_cache();
|
|
8668
|
+
var { retryWithBackoff } = require_retry();
|
|
8669
|
+
var { IPFSError } = require_errors2();
|
|
8670
|
+
var IPFSService = class {
|
|
8671
|
+
/**
|
|
8672
|
+
* @param {object} config - Service configuration
|
|
8673
|
+
* @param {string} config.workerBaseUrl - IPFS worker base URL
|
|
8674
|
+
* @param {string} config.gateway - Primary IPFS gateway URL
|
|
8675
|
+
* @param {object} [config.signer] - ethers v6 signer for worker auth
|
|
8676
|
+
* @param {Function} [config.getAuth] - Function to get auth credentials
|
|
8677
|
+
* @param {string} [config.workerToken] - Bearer token for worker auth
|
|
8678
|
+
* @param {number} [config.timeout=15000] - Request timeout in ms
|
|
8679
|
+
* @param {number} [config.retries=2] - Number of retry attempts
|
|
8680
|
+
* @param {object} [config.cache] - Cache configuration
|
|
8681
|
+
* @param {boolean} [config.cache.enabled=true] - Enable caching
|
|
8682
|
+
* @param {number} [config.cache.ttl=300000] - Cache TTL in ms (default 5min for immutable CIDs)
|
|
8683
|
+
* @param {number} [config.cache.maxSize=50] - Max cache entries
|
|
8684
|
+
*/
|
|
8685
|
+
constructor(config) {
|
|
8686
|
+
if (!config) {
|
|
8687
|
+
throw new Error("IPFSService requires a config object");
|
|
8688
|
+
}
|
|
8689
|
+
this.workerBaseUrl = config.workerBaseUrl;
|
|
8690
|
+
this.gateway = config.gateway;
|
|
8691
|
+
this.timeout = config.timeout || 15e3;
|
|
8692
|
+
this.retries = config.retries || 2;
|
|
8693
|
+
this._client = ipfs.createClient({
|
|
8694
|
+
workerBaseUrl: config.workerBaseUrl,
|
|
8695
|
+
gateway: config.gateway,
|
|
8696
|
+
workerSigner: config.signer,
|
|
8697
|
+
workerGetAuth: config.getAuth,
|
|
8698
|
+
workerToken: config.workerToken,
|
|
8699
|
+
timeoutMs: this.timeout,
|
|
8700
|
+
retries: this.retries
|
|
8701
|
+
});
|
|
8702
|
+
this._cache = new SimpleCache({
|
|
8703
|
+
enabled: config.cache?.enabled !== false,
|
|
8704
|
+
ttl: config.cache?.ttl || 3e5,
|
|
8705
|
+
// 5 minutes
|
|
8706
|
+
maxSize: config.cache?.maxSize || 50
|
|
8707
|
+
});
|
|
8708
|
+
}
|
|
8709
|
+
/**
|
|
8710
|
+
* Upload content to IPFS worker
|
|
8711
|
+
* @param {any} content - Content to upload (will be JSON stringified)
|
|
8712
|
+
* @param {object} [options] - Upload options
|
|
8713
|
+
* @param {string} [options.name] - Content name
|
|
8714
|
+
* @param {boolean} [options.warm=false] - Warm gateways after upload
|
|
8715
|
+
* @returns {Promise<string>} - CID of uploaded content
|
|
8716
|
+
*/
|
|
8717
|
+
async upload(content, options = {}) {
|
|
8718
|
+
const { name = "upload", warm = false } = options;
|
|
8719
|
+
try {
|
|
8720
|
+
const result = await retryWithBackoff(
|
|
8721
|
+
() => this._client.uploadJson(content, name, {
|
|
8722
|
+
provider: "worker",
|
|
8723
|
+
warm
|
|
8724
|
+
}),
|
|
8725
|
+
{ attempts: this.retries }
|
|
8726
|
+
);
|
|
8727
|
+
return result.cid;
|
|
8728
|
+
} catch (error) {
|
|
8729
|
+
throw new IPFSError(
|
|
8730
|
+
`Failed to upload content: ${error.message}`,
|
|
8731
|
+
"UPLOAD_FAILED",
|
|
8732
|
+
true,
|
|
8733
|
+
error
|
|
8734
|
+
);
|
|
8735
|
+
}
|
|
8736
|
+
}
|
|
8737
|
+
/**
|
|
8738
|
+
* Fetch JSON content by CID with parallel gateway fetching
|
|
8739
|
+
* @param {string} cid - IPFS CID
|
|
8740
|
+
* @param {object} [options] - Fetch options
|
|
8741
|
+
* @param {boolean} [options.cache=true] - Use cache
|
|
8742
|
+
* @param {number} [options.timeout=5000] - Timeout per gateway in ms
|
|
8743
|
+
* @param {string[]} [options.extraGateways] - Additional gateways to try
|
|
8744
|
+
* @returns {Promise<any|null>} - Parsed JSON content or null
|
|
8745
|
+
*/
|
|
8746
|
+
async fetchByCID(cid, options = {}) {
|
|
8747
|
+
if (!cid) {
|
|
8748
|
+
throw new IPFSError("CID is required", "INVALID_CID", false);
|
|
8749
|
+
}
|
|
8750
|
+
const { cache = true, timeout = 5e3, extraGateways = [] } = options;
|
|
8751
|
+
if (cache) {
|
|
8752
|
+
const cached = this._cache.get(cid);
|
|
8753
|
+
if (cached) return cached;
|
|
8754
|
+
}
|
|
8755
|
+
const urls = this._client.buildGatewayUrls(cid, extraGateways);
|
|
8756
|
+
try {
|
|
8757
|
+
const result = await this._parallelFetch(urls, timeout);
|
|
8758
|
+
if (result === null) {
|
|
8759
|
+
throw new IPFSError(
|
|
8760
|
+
`All gateways failed for CID ${cid}`,
|
|
8761
|
+
"GATEWAY_FAILED",
|
|
8762
|
+
true
|
|
8763
|
+
);
|
|
8764
|
+
}
|
|
8765
|
+
if (cache) {
|
|
8766
|
+
this._cache.set(cid, result);
|
|
8767
|
+
}
|
|
8768
|
+
return result;
|
|
8769
|
+
} catch (error) {
|
|
8770
|
+
if (error instanceof IPFSError) throw error;
|
|
8771
|
+
throw new IPFSError(
|
|
8772
|
+
`Failed to fetch CID ${cid}: ${error.message}`,
|
|
8773
|
+
"GATEWAY_FAILED",
|
|
8774
|
+
true,
|
|
8775
|
+
error
|
|
8776
|
+
);
|
|
8777
|
+
}
|
|
8778
|
+
}
|
|
8779
|
+
/**
|
|
8780
|
+
* Pin CIDs to IPFS worker
|
|
8781
|
+
* @param {string|string[]} cids - CID or array of CIDs to pin
|
|
8782
|
+
* @param {object} [options] - Pin options
|
|
8783
|
+
* @param {boolean} [options.warm=false] - Warm gateways after pinning
|
|
8784
|
+
* @returns {Promise<void>}
|
|
8785
|
+
*/
|
|
8786
|
+
async pin(cids, options = {}) {
|
|
8787
|
+
const { warm = false } = options;
|
|
8788
|
+
const cidList = Array.isArray(cids) ? cids : [cids];
|
|
8789
|
+
if (cidList.length === 0) {
|
|
8790
|
+
throw new IPFSError("At least one CID is required", "INVALID_CID", false);
|
|
8791
|
+
}
|
|
8792
|
+
try {
|
|
8793
|
+
await retryWithBackoff(
|
|
8794
|
+
() => this._client.pin({ cids: cidList, warm }),
|
|
8795
|
+
{ attempts: this.retries }
|
|
8796
|
+
);
|
|
8797
|
+
} catch (error) {
|
|
8798
|
+
throw new IPFSError(
|
|
8799
|
+
`Failed to pin CIDs: ${error.message}`,
|
|
8800
|
+
"PIN_FAILED",
|
|
8801
|
+
true,
|
|
8802
|
+
error
|
|
8803
|
+
);
|
|
8804
|
+
}
|
|
8805
|
+
}
|
|
8806
|
+
/**
|
|
8807
|
+
* Warm gateways for a CID (prefetch)
|
|
8808
|
+
* @param {string} cid - CID to warm
|
|
8809
|
+
* @param {object} [options] - Warm options
|
|
8810
|
+
* @param {string[]} [options.gateways] - Specific gateways to warm
|
|
8811
|
+
* @returns {Promise<object>} - Warm result
|
|
8812
|
+
*/
|
|
8813
|
+
async warm(cid, options = {}) {
|
|
8814
|
+
const { gateways } = options;
|
|
8815
|
+
try {
|
|
8816
|
+
return await this._client.warmGateways(cid, { gateways });
|
|
8817
|
+
} catch (error) {
|
|
8818
|
+
return { warmed: [] };
|
|
8819
|
+
}
|
|
8820
|
+
}
|
|
8821
|
+
/**
|
|
8822
|
+
* Clear cache
|
|
8823
|
+
*/
|
|
8824
|
+
clearCache() {
|
|
8825
|
+
this._cache.clear();
|
|
8826
|
+
}
|
|
8827
|
+
/**
|
|
8828
|
+
* Get cache statistics
|
|
8829
|
+
* @returns {object} - Cache stats
|
|
8830
|
+
*/
|
|
8831
|
+
getCacheStats() {
|
|
8832
|
+
return this._cache.stats();
|
|
8833
|
+
}
|
|
8834
|
+
// Private methods
|
|
8835
|
+
/**
|
|
8836
|
+
* Fetch from multiple gateways in parallel
|
|
8837
|
+
* @param {string[]} urls - Gateway URLs to try
|
|
8838
|
+
* @param {number} timeout - Timeout per gateway in ms
|
|
8839
|
+
* @returns {Promise<any|null>} - First successful result or null
|
|
8840
|
+
* @private
|
|
8841
|
+
*/
|
|
8842
|
+
async _parallelFetch(urls, timeout) {
|
|
8843
|
+
if (!urls || urls.length === 0) {
|
|
8844
|
+
return null;
|
|
8845
|
+
}
|
|
8846
|
+
const fetchOne = async (url) => {
|
|
8847
|
+
const controller = new AbortController();
|
|
8848
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
8849
|
+
try {
|
|
8850
|
+
const response = await fetch(url, {
|
|
8851
|
+
signal: controller.signal,
|
|
8852
|
+
headers: { Accept: "application/json" }
|
|
8853
|
+
});
|
|
8854
|
+
clearTimeout(timeoutId);
|
|
8855
|
+
if (!response.ok) {
|
|
8856
|
+
return null;
|
|
8857
|
+
}
|
|
8858
|
+
const text = await response.text();
|
|
8859
|
+
try {
|
|
8860
|
+
return JSON.parse(text);
|
|
8861
|
+
} catch {
|
|
8862
|
+
return text;
|
|
8863
|
+
}
|
|
8864
|
+
} catch (error) {
|
|
8865
|
+
clearTimeout(timeoutId);
|
|
8866
|
+
return null;
|
|
8867
|
+
}
|
|
8868
|
+
};
|
|
8869
|
+
const results = await Promise.allSettled(urls.map((url) => fetchOne(url)));
|
|
8870
|
+
for (const result of results) {
|
|
8871
|
+
if (result.status === "fulfilled" && result.value !== null) {
|
|
8872
|
+
return result.value;
|
|
8873
|
+
}
|
|
8874
|
+
}
|
|
8875
|
+
return null;
|
|
8876
|
+
}
|
|
8877
|
+
};
|
|
8878
|
+
module2.exports = { IPFSService };
|
|
8879
|
+
}
|
|
8880
|
+
});
|
|
8881
|
+
|
|
8882
|
+
// src/hooks/useSubDAOs.js
|
|
8883
|
+
var require_useSubDAOs = __commonJS({
|
|
8884
|
+
"src/hooks/useSubDAOs.js"(exports2, module2) {
|
|
8885
|
+
var useSWR = __require("swr");
|
|
8886
|
+
function useSubDAOs(subgraphService, options = {}) {
|
|
8887
|
+
const {
|
|
8888
|
+
limit = 50,
|
|
8889
|
+
skip = 0,
|
|
8890
|
+
cache = true,
|
|
8891
|
+
refreshInterval,
|
|
8892
|
+
revalidateOnFocus = true,
|
|
8893
|
+
revalidateOnReconnect = true
|
|
8894
|
+
} = options;
|
|
8895
|
+
const cacheKey = subgraphService ? ["subdaos", subgraphService.url, limit, skip] : null;
|
|
8896
|
+
const fetcher = async () => {
|
|
8897
|
+
if (!subgraphService) {
|
|
8898
|
+
throw new Error("SubgraphService is required");
|
|
8899
|
+
}
|
|
8900
|
+
return await subgraphService.getSubDAOs({ limit, skip, cache });
|
|
8901
|
+
};
|
|
8902
|
+
return useSWR(cacheKey, fetcher, {
|
|
8903
|
+
refreshInterval,
|
|
8904
|
+
revalidateOnFocus,
|
|
8905
|
+
revalidateOnReconnect,
|
|
8906
|
+
dedupingInterval: cache ? 3e4 : 0
|
|
8907
|
+
// Match service cache TTL
|
|
8908
|
+
});
|
|
8909
|
+
}
|
|
8910
|
+
module2.exports = { useSubDAOs };
|
|
8911
|
+
}
|
|
8912
|
+
});
|
|
8913
|
+
|
|
8914
|
+
// src/hooks/useProposals.js
|
|
8915
|
+
var require_useProposals = __commonJS({
|
|
8916
|
+
"src/hooks/useProposals.js"(exports2, module2) {
|
|
8917
|
+
var useSWR = __require("swr");
|
|
8918
|
+
function useProposals(subgraphService, options = {}) {
|
|
8919
|
+
const {
|
|
8920
|
+
governor,
|
|
8921
|
+
subdao,
|
|
8922
|
+
states,
|
|
8923
|
+
fromTimestamp,
|
|
8924
|
+
toTimestamp,
|
|
8925
|
+
limit = 20,
|
|
8926
|
+
skip = 0,
|
|
8927
|
+
cache = true,
|
|
8928
|
+
refreshInterval,
|
|
8929
|
+
revalidateOnFocus = true,
|
|
8930
|
+
revalidateOnReconnect = true
|
|
8931
|
+
} = options;
|
|
8932
|
+
const cacheKey = subgraphService ? [
|
|
8933
|
+
"proposals",
|
|
8934
|
+
subgraphService.url,
|
|
8935
|
+
governor,
|
|
8936
|
+
subdao,
|
|
8937
|
+
states?.join(","),
|
|
8938
|
+
fromTimestamp,
|
|
8939
|
+
toTimestamp,
|
|
8940
|
+
limit,
|
|
8941
|
+
skip
|
|
8942
|
+
] : null;
|
|
8943
|
+
const fetcher = async () => {
|
|
8944
|
+
if (!subgraphService) {
|
|
8945
|
+
throw new Error("SubgraphService is required");
|
|
8946
|
+
}
|
|
8947
|
+
return await subgraphService.getProposals({
|
|
8948
|
+
governor,
|
|
8949
|
+
subdao,
|
|
8950
|
+
states,
|
|
8951
|
+
fromTimestamp,
|
|
8952
|
+
toTimestamp,
|
|
8953
|
+
limit,
|
|
8954
|
+
skip,
|
|
8955
|
+
cache
|
|
8956
|
+
});
|
|
8957
|
+
};
|
|
8958
|
+
return useSWR(cacheKey, fetcher, {
|
|
8959
|
+
refreshInterval,
|
|
8960
|
+
revalidateOnFocus,
|
|
8961
|
+
revalidateOnReconnect,
|
|
8962
|
+
dedupingInterval: cache ? 3e4 : 0
|
|
8963
|
+
// Match service cache TTL
|
|
8964
|
+
});
|
|
8965
|
+
}
|
|
8966
|
+
module2.exports = { useProposals };
|
|
8967
|
+
}
|
|
8968
|
+
});
|
|
8969
|
+
|
|
8970
|
+
// src/hooks/useFetchCID.js
|
|
8971
|
+
var require_useFetchCID = __commonJS({
|
|
8972
|
+
"src/hooks/useFetchCID.js"(exports2, module2) {
|
|
8973
|
+
var useSWR = __require("swr");
|
|
8974
|
+
function useFetchCID(ipfsService, cid, options = {}) {
|
|
8975
|
+
const {
|
|
8976
|
+
cache = true,
|
|
8977
|
+
timeout = 5e3,
|
|
8978
|
+
extraGateways = [],
|
|
8979
|
+
refreshInterval,
|
|
8980
|
+
revalidateOnFocus = false,
|
|
8981
|
+
// CIDs are immutable
|
|
8982
|
+
revalidateOnReconnect = false
|
|
8983
|
+
// CIDs are immutable
|
|
8984
|
+
} = options;
|
|
8985
|
+
const cacheKey = ipfsService && cid ? ["ipfs-cid", cid] : null;
|
|
8986
|
+
const fetcher = async () => {
|
|
8987
|
+
if (!ipfsService) {
|
|
8988
|
+
throw new Error("IPFSService is required");
|
|
8989
|
+
}
|
|
8990
|
+
if (!cid) {
|
|
8991
|
+
throw new Error("CID is required");
|
|
8992
|
+
}
|
|
8993
|
+
return await ipfsService.fetchByCID(cid, {
|
|
8994
|
+
cache,
|
|
8995
|
+
timeout,
|
|
8996
|
+
extraGateways
|
|
8997
|
+
});
|
|
8998
|
+
};
|
|
8999
|
+
return useSWR(cacheKey, fetcher, {
|
|
9000
|
+
refreshInterval,
|
|
9001
|
+
revalidateOnFocus,
|
|
9002
|
+
revalidateOnReconnect,
|
|
9003
|
+
dedupingInterval: cache ? 3e5 : 0,
|
|
9004
|
+
// Match service cache TTL (5min)
|
|
9005
|
+
// CIDs are immutable, so we can cache errors too
|
|
9006
|
+
shouldRetryOnError: true,
|
|
9007
|
+
errorRetryInterval: 5e3,
|
|
9008
|
+
errorRetryCount: 3
|
|
9009
|
+
});
|
|
9010
|
+
}
|
|
9011
|
+
module2.exports = { useFetchCID };
|
|
9012
|
+
}
|
|
9013
|
+
});
|
|
9014
|
+
|
|
9015
|
+
// src/hooks/useUpload.js
|
|
9016
|
+
var require_useUpload = __commonJS({
|
|
9017
|
+
"src/hooks/useUpload.js"(exports2, module2) {
|
|
9018
|
+
var { useState, useCallback } = __require("react");
|
|
9019
|
+
function useUpload(ipfsService) {
|
|
9020
|
+
const [isUploading, setIsUploading] = useState(false);
|
|
9021
|
+
const [error, setError] = useState(null);
|
|
9022
|
+
const [data, setData] = useState(null);
|
|
9023
|
+
const upload = useCallback(
|
|
9024
|
+
async (content, options = {}) => {
|
|
9025
|
+
if (!ipfsService) {
|
|
9026
|
+
const err = new Error("IPFSService is required");
|
|
9027
|
+
setError(err);
|
|
9028
|
+
throw err;
|
|
9029
|
+
}
|
|
9030
|
+
setIsUploading(true);
|
|
9031
|
+
setError(null);
|
|
9032
|
+
try {
|
|
9033
|
+
const cid = await ipfsService.upload(content, options);
|
|
9034
|
+
setData(cid);
|
|
9035
|
+
return cid;
|
|
9036
|
+
} catch (err) {
|
|
9037
|
+
setError(err);
|
|
9038
|
+
throw err;
|
|
9039
|
+
} finally {
|
|
9040
|
+
setIsUploading(false);
|
|
9041
|
+
}
|
|
9042
|
+
},
|
|
9043
|
+
[ipfsService]
|
|
9044
|
+
);
|
|
9045
|
+
const reset = useCallback(() => {
|
|
9046
|
+
setIsUploading(false);
|
|
9047
|
+
setError(null);
|
|
9048
|
+
setData(null);
|
|
9049
|
+
}, []);
|
|
9050
|
+
return {
|
|
9051
|
+
upload,
|
|
9052
|
+
isUploading,
|
|
9053
|
+
error,
|
|
9054
|
+
data,
|
|
9055
|
+
reset
|
|
9056
|
+
};
|
|
9057
|
+
}
|
|
9058
|
+
module2.exports = { useUpload };
|
|
9059
|
+
}
|
|
9060
|
+
});
|
|
9061
|
+
|
|
9062
|
+
// src/hooks/index.js
|
|
9063
|
+
var require_hooks = __commonJS({
|
|
9064
|
+
"src/hooks/index.js"(exports2, module2) {
|
|
9065
|
+
var { useSubDAOs } = require_useSubDAOs();
|
|
9066
|
+
var { useProposals } = require_useProposals();
|
|
9067
|
+
var { useFetchCID } = require_useFetchCID();
|
|
9068
|
+
var { useUpload } = require_useUpload();
|
|
9069
|
+
module2.exports = {
|
|
9070
|
+
useSubDAOs,
|
|
9071
|
+
useProposals,
|
|
9072
|
+
useFetchCID,
|
|
9073
|
+
useUpload
|
|
9074
|
+
};
|
|
9075
|
+
}
|
|
9076
|
+
});
|
|
9077
|
+
|
|
8143
9078
|
// src/index.js
|
|
8144
9079
|
var require_src = __commonJS({
|
|
8145
|
-
"src/index.js"(
|
|
9080
|
+
"src/index.js"(exports2, module2) {
|
|
8146
9081
|
var pkg = require_package();
|
|
8147
9082
|
var abi = require_abi();
|
|
8148
9083
|
var governance = require_governance();
|
|
8149
9084
|
governance.intents = require_intents();
|
|
8150
9085
|
var governanceTemplates = require_templates();
|
|
8151
9086
|
governance.operations = require_operations();
|
|
9087
|
+
governance.grants = require_grants();
|
|
8152
9088
|
var subdao = require_subdao();
|
|
8153
9089
|
var timelock = require_timelock();
|
|
8154
9090
|
var factory = require_factory();
|
|
@@ -8165,7 +9101,6 @@ var require_src = __commonJS({
|
|
|
8165
9101
|
var treasury = require_treasury();
|
|
8166
9102
|
var boost = require_boost();
|
|
8167
9103
|
var bounty = require_bounty();
|
|
8168
|
-
var bond = require_bond();
|
|
8169
9104
|
var wallet = require_wallet();
|
|
8170
9105
|
wallet.session = require_session();
|
|
8171
9106
|
var walletCastManager = require_cast_manager();
|
|
@@ -8180,7 +9115,17 @@ var require_src = __commonJS({
|
|
|
8180
9115
|
openzeppelin: require_openzeppelin()
|
|
8181
9116
|
}
|
|
8182
9117
|
};
|
|
8183
|
-
|
|
9118
|
+
var { SubgraphService } = require_client();
|
|
9119
|
+
var { IPFSService } = require_client2();
|
|
9120
|
+
var serviceErrors = require_errors2();
|
|
9121
|
+
var { SimpleCache } = require_cache();
|
|
9122
|
+
var { retryWithBackoff } = require_retry();
|
|
9123
|
+
var hooks = null;
|
|
9124
|
+
try {
|
|
9125
|
+
hooks = require_hooks();
|
|
9126
|
+
} catch (err) {
|
|
9127
|
+
}
|
|
9128
|
+
module2.exports = {
|
|
8184
9129
|
version: pkg.version,
|
|
8185
9130
|
getProvider: utils.getProvider,
|
|
8186
9131
|
abi,
|
|
@@ -8198,7 +9143,7 @@ var require_src = __commonJS({
|
|
|
8198
9143
|
personal,
|
|
8199
9144
|
treasury,
|
|
8200
9145
|
boost,
|
|
8201
|
-
bond
|
|
9146
|
+
// bond module removed; bonds deprecated in CLI/SDK
|
|
8202
9147
|
subgraph,
|
|
8203
9148
|
utils: { ...utils, privateTx, safe },
|
|
8204
9149
|
bounty,
|
|
@@ -8210,6 +9155,18 @@ var require_src = __commonJS({
|
|
|
8210
9155
|
errors,
|
|
8211
9156
|
doppler,
|
|
8212
9157
|
adapters,
|
|
9158
|
+
// New service layer exports
|
|
9159
|
+
services: {
|
|
9160
|
+
SubgraphService,
|
|
9161
|
+
IPFSService
|
|
9162
|
+
},
|
|
9163
|
+
serviceErrors,
|
|
9164
|
+
serviceUtils: {
|
|
9165
|
+
SimpleCache,
|
|
9166
|
+
retryWithBackoff
|
|
9167
|
+
},
|
|
9168
|
+
// React hooks (optional - requires react + swr peer dependencies)
|
|
9169
|
+
hooks,
|
|
8213
9170
|
// Legacy exports (deprecated): maintain compatibility while consumers migrate
|
|
8214
9171
|
resolveGovernanceContext: async function legacyResolveGovernanceContext(args) {
|
|
8215
9172
|
console.warn("[@sage-protocol/sdk] resolveGovernanceContext is deprecated. Use governance helpers instead.");
|