@sage-protocol/sdk 0.1.11 → 0.1.14
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 +2 -2
- package/dist/browser/index.mjs +301 -91
- package/dist/index.cjs +472 -93
- package/dist/index.mjs +472 -93
- package/dist/node/index.cjs +472 -93
- package/dist/node/index.mjs +472 -93
- package/package.json +2 -1
package/dist/index.mjs
CHANGED
|
@@ -20,7 +20,7 @@ var require_package = __commonJS({
|
|
|
20
20
|
"package.json"(exports2, module2) {
|
|
21
21
|
module2.exports = {
|
|
22
22
|
name: "@sage-protocol/sdk",
|
|
23
|
-
version: "0.1.
|
|
23
|
+
version: "0.1.14",
|
|
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",
|
|
@@ -76,6 +76,7 @@ var require_package = __commonJS({
|
|
|
76
76
|
release: "yarn build && npm publish --workspace @sage-protocol/sdk"
|
|
77
77
|
},
|
|
78
78
|
dependencies: {
|
|
79
|
+
"content-hash": "^2.5.2",
|
|
79
80
|
"@merit-systems/echo-typescript-sdk": "^1.0.17",
|
|
80
81
|
"@whetstone-research/doppler-sdk": "^0.0.1-alpha.40",
|
|
81
82
|
ai: "^3.2.3",
|
|
@@ -149,11 +150,22 @@ var require_abi = __commonJS({
|
|
|
149
150
|
"function stats() view returns (uint128 totalSubDAOsCreated, uint128 totalBurnedForCreation)",
|
|
150
151
|
// On-chain enumeration fallback (naming follows FactoryCoreFacet)
|
|
151
152
|
"function getSubDAOCount() view returns (uint256)",
|
|
152
|
-
"function subDaos(uint256) view returns (address)"
|
|
153
|
+
"function subDaos(uint256) view returns (address)",
|
|
154
|
+
// ISubDAOFactory interface functions
|
|
155
|
+
"function getAllSubDAOs() view returns (address[])",
|
|
156
|
+
"function getSubDAORegistry(address subdaoAddress) view returns (address)",
|
|
157
|
+
"function getRegistrySubDAO(address registryAddress) view returns (address)",
|
|
158
|
+
"function getFactoryStats() view returns (uint256 totalSubDAOs, uint256 totalBurned, uint256 averageBurnPerSubDAO)",
|
|
159
|
+
"function isSubDAO(address subdaoAddress) view returns (bool)"
|
|
153
160
|
];
|
|
154
161
|
var FactoryWrite = [
|
|
155
162
|
"function createSubDAO(string name, string description, uint8 accessModel, uint256 minStakeAmount, uint256 burnAmount) returns (address subDAO, address registry)",
|
|
156
163
|
"function createSubDAOWithStable(string name, string description, uint8 accessModel, uint256 minStakeAmount, (uint256 value,uint256 deadline,uint8 v,bytes32 r,bytes32 s) permit) returns (address subDAO, address registry)",
|
|
164
|
+
"function createSubDAOWithParams(string name, string description, uint8 accessModel, uint256 minStakeAmount, uint256 burnAmount, uint256 votingDelay, uint256 votingPeriod, uint256 proposalThreshold, uint256 quorumPercentage, uint8 initialForkPolicy, uint8 initialMembershipPolicy, string profileCID) returns (address subDAO, address registry)",
|
|
165
|
+
"function createSubDAOOperatorWithStable(string name, string description, uint8 accessModel, uint256 minStakeAmount, address operatorExecutor, address operatorAdmin, (uint256 value,uint256 deadline,uint8 v,bytes32 r,bytes32 s) permit) returns (address subDAO, address registry)",
|
|
166
|
+
"function createSubDAOOperatorWithStableAdvanced(string name, string description, uint8 accessModel, uint256 minStakeAmount, address operatorExecutor, address operatorAdmin, bool anyoneExec, bool governorProposer, (uint256 value,uint256 deadline,uint8 v,bytes32 r,bytes32 s) permit) returns (address subDAO, address registry)",
|
|
167
|
+
"function createSubDAOOperator(string name, string description, uint8 accessModel, uint256 minStakeAmount, uint256 burnAmount, address operatorExecutor, address operatorAdmin) returns (address subDAO, address registry)",
|
|
168
|
+
"function createSubDAOOperatorAdvanced(string name, string description, uint8 accessModel, uint256 minStakeAmount, uint256 burnAmount, address operatorExecutor, address operatorAdmin, bool anyoneExec, bool governorProposer) returns (address subDAO, address registry)",
|
|
157
169
|
"function createForkedSubDAO(string newName, string newDescription, string originalName, address originalSubDAO, address forker) returns (address subDAO, address registry)",
|
|
158
170
|
"function createForkedSubDAOWithStable(string newName, string newDescription, string originalName, address originalSubDAO, address forker, uint64 authorizationNonce, (uint256 value,uint256 deadline,uint8 v,bytes32 r,bytes32 s) permit) returns (address subDAO, address registry)"
|
|
159
171
|
];
|
|
@@ -395,6 +407,32 @@ var require_subgraph = __commonJS({
|
|
|
395
407
|
var axios = __require("axios");
|
|
396
408
|
var { getAddress } = __require("ethers");
|
|
397
409
|
var { keccak256, toUtf8Bytes } = __require("ethers");
|
|
410
|
+
function sanitizeOrderBy(orderBy, allowed, fallback) {
|
|
411
|
+
const value = (orderBy || "").toString();
|
|
412
|
+
return allowed.includes(value) ? value : fallback;
|
|
413
|
+
}
|
|
414
|
+
function sanitizeOrderDirection(direction, fallback = "desc") {
|
|
415
|
+
const v = (direction || "").toString().toLowerCase();
|
|
416
|
+
return v === "asc" ? "asc" : "desc";
|
|
417
|
+
}
|
|
418
|
+
function safeGetAddress(value) {
|
|
419
|
+
try {
|
|
420
|
+
return getAddress(value);
|
|
421
|
+
} catch {
|
|
422
|
+
return null;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
function mapSafe(list, mapper) {
|
|
426
|
+
const out = [];
|
|
427
|
+
for (const item of list || []) {
|
|
428
|
+
try {
|
|
429
|
+
const v = mapper(item);
|
|
430
|
+
if (v != null) out.push(v);
|
|
431
|
+
} catch {
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
return out;
|
|
435
|
+
}
|
|
398
436
|
async function query(url, document, variables) {
|
|
399
437
|
if (!url) throw new Error("subgraph url required");
|
|
400
438
|
const resp = await axios.post(url, { query: document, variables }, { timeout: 1e4 });
|
|
@@ -417,15 +455,21 @@ var require_subgraph = __commonJS({
|
|
|
417
455
|
}
|
|
418
456
|
}
|
|
419
457
|
`, { governor: String(governor).toLowerCase(), first, skip });
|
|
420
|
-
return (data?.proposals
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
458
|
+
return mapSafe(data?.proposals, (p) => {
|
|
459
|
+
const proposer = safeGetAddress(p.proposer);
|
|
460
|
+
if (!proposer) return null;
|
|
461
|
+
const targets = (p.targets || []).map((t) => safeGetAddress(t)).filter(Boolean);
|
|
462
|
+
if (!targets.length && (p.targets || []).length) return null;
|
|
463
|
+
return {
|
|
464
|
+
id: BigInt(p.id),
|
|
465
|
+
proposer,
|
|
466
|
+
description: p.description,
|
|
467
|
+
createdAt: Number(p.createdAt || 0),
|
|
468
|
+
targets,
|
|
469
|
+
values: (p.values || []).map((value) => BigInt(String(value))),
|
|
470
|
+
calldatas: p.calldatas || []
|
|
471
|
+
};
|
|
472
|
+
});
|
|
429
473
|
}
|
|
430
474
|
var STATE_STRING_TO_NUMBER = {
|
|
431
475
|
PENDING: 0,
|
|
@@ -442,6 +486,8 @@ var require_subgraph = __commonJS({
|
|
|
442
486
|
async function listProposalsFiltered({ url, governor, states, fromTimestamp, toTimestamp, first = 20, skip = 0, orderBy = "createdAt", orderDirection = "desc" }) {
|
|
443
487
|
const govLower = governor ? String(governor).toLowerCase() : null;
|
|
444
488
|
const statesUpper = Array.isArray(states) && states.length ? states.map((s) => String(s).toUpperCase()) : null;
|
|
489
|
+
const safeOrderBy = sanitizeOrderBy(orderBy, ["createdAt", "updatedAt", "eta"], "createdAt");
|
|
490
|
+
const safeOrderDirection = sanitizeOrderDirection(orderDirection, "desc");
|
|
445
491
|
const doc = `
|
|
446
492
|
query($first: Int!, $skip: Int!, $governor: Bytes, $states: [String!], $from: Int, $to: Int) {
|
|
447
493
|
proposals(
|
|
@@ -453,8 +499,8 @@ var require_subgraph = __commonJS({
|
|
|
453
499
|
}
|
|
454
500
|
first: $first
|
|
455
501
|
skip: $skip
|
|
456
|
-
orderBy: ${
|
|
457
|
-
orderDirection: ${
|
|
502
|
+
orderBy: ${safeOrderBy}
|
|
503
|
+
orderDirection: ${safeOrderDirection}
|
|
458
504
|
) {
|
|
459
505
|
id
|
|
460
506
|
proposer
|
|
@@ -475,19 +521,23 @@ var require_subgraph = __commonJS({
|
|
|
475
521
|
if (fromTimestamp !== void 0) variables.from = Number(fromTimestamp);
|
|
476
522
|
if (toTimestamp !== void 0) variables.to = Number(toTimestamp);
|
|
477
523
|
const data = await query(url, doc, variables);
|
|
478
|
-
return (data?.proposals
|
|
524
|
+
return mapSafe(data?.proposals, (p) => {
|
|
479
525
|
const stateStr = String(p.state || "").toUpperCase();
|
|
480
526
|
const stateNum = STATE_STRING_TO_NUMBER[stateStr] != null ? STATE_STRING_TO_NUMBER[stateStr] : null;
|
|
527
|
+
const proposer = safeGetAddress(p.proposer);
|
|
528
|
+
if (!proposer) return null;
|
|
529
|
+
const targets = (p.targets || []).map((t) => safeGetAddress(t)).filter(Boolean);
|
|
530
|
+
if (!targets.length && (p.targets || []).length) return null;
|
|
481
531
|
return {
|
|
482
532
|
id: BigInt(p.id),
|
|
483
|
-
proposer
|
|
533
|
+
proposer,
|
|
484
534
|
description: p.description || "",
|
|
485
535
|
createdAt: Number(p.createdAt || 0),
|
|
486
536
|
updatedAt: Number(p.updatedAt || 0),
|
|
487
537
|
state: stateStr,
|
|
488
538
|
stateNum,
|
|
489
539
|
eta: p.eta ? BigInt(String(p.eta)) : null,
|
|
490
|
-
targets
|
|
540
|
+
targets,
|
|
491
541
|
values: (p.values || []).map((value) => BigInt(String(value))),
|
|
492
542
|
calldatas: p.calldatas || []
|
|
493
543
|
};
|
|
@@ -506,19 +556,127 @@ var require_subgraph = __commonJS({
|
|
|
506
556
|
}
|
|
507
557
|
}
|
|
508
558
|
`, { first, skip });
|
|
509
|
-
return (data?.libraries
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
559
|
+
return mapSafe(data?.libraries, (lib) => {
|
|
560
|
+
const sub = safeGetAddress(lib.subDAO);
|
|
561
|
+
const proposer = safeGetAddress(lib.proposer);
|
|
562
|
+
if (!sub || !proposer) return null;
|
|
563
|
+
return {
|
|
564
|
+
id: lib.id,
|
|
565
|
+
manifestCID: lib.manifestCID,
|
|
566
|
+
subdao: sub,
|
|
567
|
+
proposer,
|
|
568
|
+
createdAt: Number(lib.createdAt || 0)
|
|
569
|
+
};
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
async function getSubdaoLibraries({ url, subdao, first = 20, skip = 0 }) {
|
|
573
|
+
if (!url) throw new Error("subgraph url required");
|
|
574
|
+
const hasFilter = !!subdao;
|
|
575
|
+
const whereClause = hasFilter ? "where:{ subdao:$subdao }" : "";
|
|
576
|
+
const doc = `
|
|
577
|
+
query($subdao:Bytes,$first:Int!,$skip:Int!){
|
|
578
|
+
subDAOLibraryPointers(
|
|
579
|
+
${whereClause}
|
|
580
|
+
first:$first,
|
|
581
|
+
skip:$skip,
|
|
582
|
+
orderBy: updatedAt,
|
|
583
|
+
orderDirection: desc
|
|
584
|
+
){
|
|
585
|
+
id
|
|
586
|
+
subdao
|
|
587
|
+
libraryId
|
|
588
|
+
manifestCID
|
|
589
|
+
previousCID
|
|
590
|
+
promptCount
|
|
591
|
+
updatedAt
|
|
592
|
+
createdAt
|
|
593
|
+
blockNumber
|
|
594
|
+
blockTimestamp
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
`;
|
|
598
|
+
const variables = {
|
|
599
|
+
first: Math.min(Math.max(1, Number(first || 20)), 100),
|
|
600
|
+
skip
|
|
601
|
+
};
|
|
602
|
+
if (hasFilter) {
|
|
603
|
+
const addr = safeGetAddress(subdao);
|
|
604
|
+
if (!addr) throw new Error("invalid subdao address");
|
|
605
|
+
variables.subdao = addr.toLowerCase();
|
|
606
|
+
}
|
|
607
|
+
const data = await query(url, doc, variables);
|
|
608
|
+
return mapSafe(data?.subDAOLibraryPointers, (row) => {
|
|
609
|
+
const id2 = row?.id;
|
|
610
|
+
const manifestCID = row?.manifestCID;
|
|
611
|
+
const sub = safeGetAddress(row?.subdao);
|
|
612
|
+
if (!id2 || !manifestCID || !sub) return null;
|
|
613
|
+
const timestamp = (row.updatedAt != null ? Number(row.updatedAt) : null) || (row.createdAt != null ? Number(row.createdAt) : null) || (row.blockTimestamp != null ? Number(row.blockTimestamp) : null);
|
|
614
|
+
return {
|
|
615
|
+
id: String(id2),
|
|
616
|
+
subdao: sub,
|
|
617
|
+
libraryId: String(row.libraryId || "main"),
|
|
618
|
+
manifestCID: String(manifestCID),
|
|
619
|
+
previousCID: row.previousCID || null,
|
|
620
|
+
promptCount: row.promptCount != null ? Number(row.promptCount) : null,
|
|
621
|
+
updatedAt: timestamp,
|
|
622
|
+
createdAt: row.createdAt != null ? Number(row.createdAt) : null,
|
|
623
|
+
blockNumber: row.blockNumber != null ? Number(row.blockNumber) : null,
|
|
624
|
+
blockTimestamp: row.blockTimestamp != null ? Number(row.blockTimestamp) : null
|
|
625
|
+
};
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
async function getSubdaoPrompts({ url, registry, first = 50, skip = 0, orderBy = "updatedAt", orderDirection = "desc" }) {
|
|
629
|
+
if (!url) throw new Error("subgraph url required");
|
|
630
|
+
const reg = safeGetAddress(registry);
|
|
631
|
+
if (!reg) throw new Error("invalid registry address");
|
|
632
|
+
const safeOrderBy = sanitizeOrderBy(orderBy, ["updatedAt"], "updatedAt");
|
|
633
|
+
const safeOrderDirection = sanitizeOrderDirection(orderDirection, "desc");
|
|
634
|
+
const doc = `
|
|
635
|
+
query($registry:Bytes!,$first:Int!,$skip:Int!){
|
|
636
|
+
prompts(
|
|
637
|
+
where:{ registry:$registry },
|
|
638
|
+
first:$first,
|
|
639
|
+
skip:$skip,
|
|
640
|
+
orderBy: ${safeOrderBy},
|
|
641
|
+
orderDirection: ${safeOrderDirection}
|
|
642
|
+
){
|
|
643
|
+
id
|
|
644
|
+
key
|
|
645
|
+
cid
|
|
646
|
+
version
|
|
647
|
+
author
|
|
648
|
+
registry
|
|
649
|
+
updatedAt
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
`;
|
|
653
|
+
const data = await query(url, doc, {
|
|
654
|
+
registry: reg.toLowerCase(),
|
|
655
|
+
first: Math.min(Math.max(1, Number(first || 50)), 100),
|
|
656
|
+
skip
|
|
657
|
+
});
|
|
658
|
+
return mapSafe(data?.prompts, (p) => {
|
|
659
|
+
const author = safeGetAddress(p.author);
|
|
660
|
+
const regAddr = safeGetAddress(p.registry);
|
|
661
|
+
if (!author || !regAddr) return null;
|
|
662
|
+
return {
|
|
663
|
+
id: String(p.id),
|
|
664
|
+
key: String(p.key),
|
|
665
|
+
cid: String(p.cid),
|
|
666
|
+
version: BigInt(p.version || "0"),
|
|
667
|
+
author,
|
|
668
|
+
registry: regAddr,
|
|
669
|
+
updatedAt: Number(p.updatedAt || 0)
|
|
670
|
+
};
|
|
671
|
+
});
|
|
516
672
|
}
|
|
517
673
|
module2.exports = {
|
|
518
674
|
query,
|
|
519
675
|
listProposals,
|
|
520
676
|
listProposalsFiltered,
|
|
521
677
|
listLibraries,
|
|
678
|
+
getSubdaoLibraries,
|
|
679
|
+
getSubdaoPrompts,
|
|
522
680
|
/**
|
|
523
681
|
* Canonical proposal timeline. Tries common fields first, then event-style fallbacks.
|
|
524
682
|
* Returns { id, createdAt, queuedAt, executedAt, canceledAt, eta, state } (numbers/strings may be null when unavailable).
|
|
@@ -584,86 +742,127 @@ var require_subgraph = __commonJS({
|
|
|
584
742
|
async listLiquidityAddPlans({ url, subdao = null, first = 50, skip = 0, orderBy = "blockTimestamp", orderDirection = "desc" }) {
|
|
585
743
|
if (!url) throw new Error("subgraph url required");
|
|
586
744
|
const filters = [];
|
|
587
|
-
if (subdao)
|
|
745
|
+
if (subdao) {
|
|
746
|
+
const addr = safeGetAddress(subdao);
|
|
747
|
+
if (!addr) throw new Error("invalid subdao address");
|
|
748
|
+
filters.push(`subdao: "${addr.toLowerCase()}"`);
|
|
749
|
+
}
|
|
588
750
|
const where = filters.length ? `where: { ${filters.join(", ")} }` : "";
|
|
751
|
+
const safeOrderBy = sanitizeOrderBy(orderBy, ["blockTimestamp", "blockNumber"], "blockTimestamp");
|
|
752
|
+
const safeOrderDirection = sanitizeOrderDirection(orderDirection, "desc");
|
|
589
753
|
const doc = `
|
|
590
754
|
query($first:Int!,$skip:Int!){
|
|
591
|
-
liquidityAddPlans(${where} first:$first, skip:$skip, orderBy: ${
|
|
755
|
+
liquidityAddPlans(${where} first:$first, skip:$skip, orderBy: ${safeOrderBy}, orderDirection: ${safeOrderDirection}){
|
|
592
756
|
id subdao pool sxxxToken stableToken sxxxAmount stableAmount lpRecipient blockNumber blockTimestamp transactionHash
|
|
593
757
|
}
|
|
594
758
|
}
|
|
595
759
|
`;
|
|
596
760
|
const data = await query(url, doc, { first, skip });
|
|
597
|
-
return (data?.liquidityAddPlans
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
761
|
+
return mapSafe(data?.liquidityAddPlans, (e) => {
|
|
762
|
+
const sub = safeGetAddress(e.subdao);
|
|
763
|
+
const pool = safeGetAddress(e.pool);
|
|
764
|
+
const sxxxToken = safeGetAddress(e.sxxxToken);
|
|
765
|
+
const stableToken = safeGetAddress(e.stableToken);
|
|
766
|
+
const lpRecipient = safeGetAddress(e.lpRecipient);
|
|
767
|
+
if (!sub || !pool || !sxxxToken || !stableToken || !lpRecipient) return null;
|
|
768
|
+
return {
|
|
769
|
+
id: String(e.id),
|
|
770
|
+
subdao: sub,
|
|
771
|
+
pool,
|
|
772
|
+
sxxxToken,
|
|
773
|
+
stableToken,
|
|
774
|
+
sxxxAmount: BigInt(String(e.sxxxAmount)),
|
|
775
|
+
stableAmount: BigInt(String(e.stableAmount)),
|
|
776
|
+
lpRecipient,
|
|
777
|
+
blockNumber: Number(e.blockNumber || 0),
|
|
778
|
+
blockTimestamp: Number(e.blockTimestamp || 0),
|
|
779
|
+
transactionHash: e.transactionHash
|
|
780
|
+
};
|
|
781
|
+
});
|
|
610
782
|
},
|
|
611
783
|
async listLiquidityRemovePlans({ url, subdao = null, first = 50, skip = 0, orderBy = "blockTimestamp", orderDirection = "desc" }) {
|
|
612
784
|
if (!url) throw new Error("subgraph url required");
|
|
613
785
|
const filters = [];
|
|
614
|
-
if (subdao)
|
|
786
|
+
if (subdao) {
|
|
787
|
+
const addr = safeGetAddress(subdao);
|
|
788
|
+
if (!addr) throw new Error("invalid subdao address");
|
|
789
|
+
filters.push(`subdao: "${addr.toLowerCase()}"`);
|
|
790
|
+
}
|
|
615
791
|
const where = filters.length ? `where: { ${filters.join(", ")} }` : "";
|
|
792
|
+
const safeOrderBy = sanitizeOrderBy(orderBy, ["blockTimestamp", "blockNumber"], "blockTimestamp");
|
|
793
|
+
const safeOrderDirection = sanitizeOrderDirection(orderDirection, "desc");
|
|
616
794
|
const doc = `
|
|
617
795
|
query($first:Int!,$skip:Int!){
|
|
618
|
-
liquidityRemovePlans(${where} first:$first, skip:$skip, orderBy: ${
|
|
796
|
+
liquidityRemovePlans(${where} first:$first, skip:$skip, orderBy: ${safeOrderBy}, orderDirection: ${safeOrderDirection}){
|
|
619
797
|
id subdao pool lpToken lpAmount recipient blockNumber blockTimestamp transactionHash
|
|
620
798
|
}
|
|
621
799
|
}
|
|
622
800
|
`;
|
|
623
801
|
const data = await query(url, doc, { first, skip });
|
|
624
|
-
return (data?.liquidityRemovePlans
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
802
|
+
return mapSafe(data?.liquidityRemovePlans, (e) => {
|
|
803
|
+
const sub = safeGetAddress(e.subdao);
|
|
804
|
+
const pool = safeGetAddress(e.pool);
|
|
805
|
+
const lpToken = safeGetAddress(e.lpToken);
|
|
806
|
+
const recipient = safeGetAddress(e.recipient);
|
|
807
|
+
if (!sub || !pool || !lpToken || !recipient) return null;
|
|
808
|
+
return {
|
|
809
|
+
id: String(e.id),
|
|
810
|
+
subdao: sub,
|
|
811
|
+
pool,
|
|
812
|
+
lpToken,
|
|
813
|
+
lpAmount: BigInt(String(e.lpAmount)),
|
|
814
|
+
recipient,
|
|
815
|
+
blockNumber: Number(e.blockNumber || 0),
|
|
816
|
+
blockTimestamp: Number(e.blockTimestamp || 0),
|
|
817
|
+
transactionHash: e.transactionHash
|
|
818
|
+
};
|
|
819
|
+
});
|
|
635
820
|
},
|
|
636
821
|
async listPromptsByTag({ url, tagsHash, registry = null, first = 50, skip = 0, orderBy = "updatedAt", orderDirection = "desc" }) {
|
|
637
822
|
if (!url) throw new Error("subgraph url required");
|
|
638
823
|
const clauses = [`tagsHash: "${String(tagsHash)}"`];
|
|
639
|
-
if (registry)
|
|
824
|
+
if (registry) {
|
|
825
|
+
const addr = safeGetAddress(registry);
|
|
826
|
+
if (!addr) throw new Error("invalid registry address");
|
|
827
|
+
clauses.push(`registry: "${addr.toLowerCase()}"`);
|
|
828
|
+
}
|
|
640
829
|
const where = `where: { ${clauses.join(", ")} }`;
|
|
830
|
+
const safeOrderBy = sanitizeOrderBy(orderBy, ["updatedAt"], "updatedAt");
|
|
831
|
+
const safeOrderDirection = sanitizeOrderDirection(orderDirection, "desc");
|
|
641
832
|
const doc = `
|
|
642
833
|
query($first:Int!,$skip:Int!) {
|
|
643
|
-
prompts(${where} first:$first, skip:$skip, orderBy: ${
|
|
834
|
+
prompts(${where} first:$first, skip:$skip, orderBy: ${safeOrderBy}, orderDirection: ${safeOrderDirection}) {
|
|
644
835
|
id key cid version author registry updatedAt tagsHash
|
|
645
836
|
}
|
|
646
837
|
}
|
|
647
838
|
`;
|
|
648
839
|
const data = await query(url, doc, { first, skip });
|
|
649
|
-
return (data?.prompts
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
840
|
+
return mapSafe(data?.prompts, (p) => {
|
|
841
|
+
const author = safeGetAddress(p.author);
|
|
842
|
+
const regAddr = safeGetAddress(p.registry);
|
|
843
|
+
if (!author || !regAddr) return null;
|
|
844
|
+
return {
|
|
845
|
+
id: String(p.id),
|
|
846
|
+
key: String(p.key),
|
|
847
|
+
cid: String(p.cid),
|
|
848
|
+
version: BigInt(p.version || "0"),
|
|
849
|
+
author,
|
|
850
|
+
registry: regAddr,
|
|
851
|
+
updatedAt: Number(p.updatedAt || 0),
|
|
852
|
+
tagsHash: String(p.tagsHash || "")
|
|
853
|
+
};
|
|
854
|
+
});
|
|
659
855
|
},
|
|
660
856
|
// Prompt helpers (registry scoped)
|
|
661
857
|
async listRegistryPrompts({ url, registry, first = 50, skip = 0, orderBy = "updatedAt", orderDirection = "desc" }) {
|
|
662
858
|
if (!url) throw new Error("subgraph url required");
|
|
663
|
-
const reg =
|
|
859
|
+
const reg = safeGetAddress(registry);
|
|
860
|
+
if (!reg) throw new Error("invalid registry address");
|
|
861
|
+
const safeOrderBy = sanitizeOrderBy(orderBy, ["updatedAt"], "updatedAt");
|
|
862
|
+
const safeOrderDirection = sanitizeOrderDirection(orderDirection, "desc");
|
|
664
863
|
const doc = `
|
|
665
864
|
query($first:Int!,$skip:Int!,$registry:Bytes!) {
|
|
666
|
-
prompts(where:{ registry: $registry }, first:$first, skip:$skip, orderBy: ${
|
|
865
|
+
prompts(where:{ registry: $registry }, first:$first, skip:$skip, orderBy: ${safeOrderBy}, orderDirection: ${safeOrderDirection}) {
|
|
667
866
|
id
|
|
668
867
|
key
|
|
669
868
|
cid
|
|
@@ -675,19 +874,25 @@ var require_subgraph = __commonJS({
|
|
|
675
874
|
}
|
|
676
875
|
`;
|
|
677
876
|
const data = await query(url, doc, { first, skip, registry: reg.toLowerCase() });
|
|
678
|
-
return (data?.prompts
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
877
|
+
return mapSafe(data?.prompts, (p) => {
|
|
878
|
+
const author = safeGetAddress(p.author);
|
|
879
|
+
const regAddr = safeGetAddress(p.registry);
|
|
880
|
+
if (!author || !regAddr) return null;
|
|
881
|
+
return {
|
|
882
|
+
id: String(p.id),
|
|
883
|
+
key: String(p.key),
|
|
884
|
+
cid: String(p.cid),
|
|
885
|
+
version: BigInt(p.version || "0"),
|
|
886
|
+
author,
|
|
887
|
+
registry: regAddr,
|
|
888
|
+
updatedAt: Number(p.updatedAt || 0)
|
|
889
|
+
};
|
|
890
|
+
});
|
|
687
891
|
},
|
|
688
892
|
async getPromptByKey({ url, registry, key }) {
|
|
689
893
|
if (!url) throw new Error("subgraph url required");
|
|
690
|
-
const reg =
|
|
894
|
+
const reg = safeGetAddress(registry);
|
|
895
|
+
if (!reg) throw new Error("invalid registry address");
|
|
691
896
|
const doc = `
|
|
692
897
|
query($registry:Bytes!,$key:String!) {
|
|
693
898
|
prompts(where:{ registry: $registry, key: $key }, first:1) {
|
|
@@ -703,15 +908,19 @@ var require_subgraph = __commonJS({
|
|
|
703
908
|
`;
|
|
704
909
|
const data = await query(url, doc, { registry: reg.toLowerCase(), key: String(key) });
|
|
705
910
|
const p = (data?.prompts || [])[0];
|
|
706
|
-
|
|
911
|
+
if (!p) return null;
|
|
912
|
+
const author = safeGetAddress(p.author);
|
|
913
|
+
const regAddr = safeGetAddress(p.registry);
|
|
914
|
+
if (!author || !regAddr) return null;
|
|
915
|
+
return {
|
|
707
916
|
id: String(p.id),
|
|
708
917
|
key: String(p.key),
|
|
709
918
|
cid: String(p.cid),
|
|
710
919
|
version: BigInt(p.version || "0"),
|
|
711
|
-
author
|
|
712
|
-
registry:
|
|
920
|
+
author,
|
|
921
|
+
registry: regAddr,
|
|
713
922
|
updatedAt: Number(p.updatedAt || 0)
|
|
714
|
-
}
|
|
923
|
+
};
|
|
715
924
|
},
|
|
716
925
|
async getProposalById({ url, id: id2 }) {
|
|
717
926
|
if (!url) throw new Error("subgraph url required");
|
|
@@ -719,18 +928,26 @@ var require_subgraph = __commonJS({
|
|
|
719
928
|
const data = await query(url, doc, { id: String(id2) });
|
|
720
929
|
const p = data?.proposal;
|
|
721
930
|
if (!p) return null;
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
931
|
+
try {
|
|
932
|
+
const proposer = safeGetAddress(p.proposer);
|
|
933
|
+
if (!proposer) return null;
|
|
934
|
+
const targets = (p.targets || []).map((t) => safeGetAddress(t)).filter(Boolean);
|
|
935
|
+
if (!targets.length && (p.targets || []).length) return null;
|
|
936
|
+
return {
|
|
937
|
+
id: BigInt(p.id),
|
|
938
|
+
proposer,
|
|
939
|
+
description: p.description || "",
|
|
940
|
+
createdAt: Number(p.createdAt || 0),
|
|
941
|
+
updatedAt: Number(p.updatedAt || 0),
|
|
942
|
+
state: String(p.state || ""),
|
|
943
|
+
eta: p.eta ? BigInt(String(p.eta)) : null,
|
|
944
|
+
targets,
|
|
945
|
+
values: (p.values || []).map((v) => BigInt(String(v))),
|
|
946
|
+
calldatas: p.calldatas || []
|
|
947
|
+
};
|
|
948
|
+
} catch {
|
|
949
|
+
return null;
|
|
950
|
+
}
|
|
734
951
|
}
|
|
735
952
|
};
|
|
736
953
|
}
|
|
@@ -3981,7 +4198,17 @@ var require_factory = __commonJS({
|
|
|
3981
4198
|
] = await Promise.all([
|
|
3982
4199
|
contract.stableFeeToken().catch(() => null),
|
|
3983
4200
|
contract.stableCreationFee().catch(() => null),
|
|
3984
|
-
|
|
4201
|
+
(async () => {
|
|
4202
|
+
try {
|
|
4203
|
+
return await contract.stableFeeReceiver();
|
|
4204
|
+
} catch (_) {
|
|
4205
|
+
try {
|
|
4206
|
+
return await contract.feeReceiver();
|
|
4207
|
+
} catch {
|
|
4208
|
+
return null;
|
|
4209
|
+
}
|
|
4210
|
+
}
|
|
4211
|
+
})(),
|
|
3985
4212
|
contract.allowStableFee().catch(() => null),
|
|
3986
4213
|
contract.stablePromptForkFee().catch(() => null),
|
|
3987
4214
|
contract.allowStablePromptForkFee().catch(() => null),
|
|
@@ -4148,6 +4375,102 @@ var require_factory = __commonJS({
|
|
|
4148
4375
|
]);
|
|
4149
4376
|
return { to: addr, data: payload, value: 0n };
|
|
4150
4377
|
}
|
|
4378
|
+
function buildCreateSubDAOWithParamsTx({
|
|
4379
|
+
factory,
|
|
4380
|
+
name,
|
|
4381
|
+
description,
|
|
4382
|
+
accessModel,
|
|
4383
|
+
minStakeAmount,
|
|
4384
|
+
burnAmount,
|
|
4385
|
+
votingDelay,
|
|
4386
|
+
votingPeriod,
|
|
4387
|
+
proposalThreshold,
|
|
4388
|
+
quorumPercentage,
|
|
4389
|
+
initialForkPolicy,
|
|
4390
|
+
initialMembershipPolicy,
|
|
4391
|
+
profileCID
|
|
4392
|
+
}) {
|
|
4393
|
+
const addr = normalise(factory, "factory");
|
|
4394
|
+
const payload = FactoryWriteInterface.encodeFunctionData("createSubDAOWithParams", [
|
|
4395
|
+
String(name),
|
|
4396
|
+
String(description),
|
|
4397
|
+
Number(accessModel),
|
|
4398
|
+
BigInt(minStakeAmount),
|
|
4399
|
+
BigInt(burnAmount),
|
|
4400
|
+
BigInt(votingDelay),
|
|
4401
|
+
BigInt(votingPeriod),
|
|
4402
|
+
BigInt(proposalThreshold),
|
|
4403
|
+
BigInt(quorumPercentage),
|
|
4404
|
+
Number(initialForkPolicy),
|
|
4405
|
+
Number(initialMembershipPolicy),
|
|
4406
|
+
String(profileCID ?? "")
|
|
4407
|
+
]);
|
|
4408
|
+
return { to: addr, data: payload, value: 0n };
|
|
4409
|
+
}
|
|
4410
|
+
function buildCreateOperatorSubDAOWithStableTx({
|
|
4411
|
+
factory,
|
|
4412
|
+
name,
|
|
4413
|
+
description,
|
|
4414
|
+
accessModel,
|
|
4415
|
+
minStakeAmount,
|
|
4416
|
+
operatorExecutor,
|
|
4417
|
+
operatorAdmin,
|
|
4418
|
+
permit
|
|
4419
|
+
}) {
|
|
4420
|
+
const addr = normalise(factory, "factory");
|
|
4421
|
+
if (!permit) throw new SageSDKError(CODES.INVALID_ARGS, "permit required for operator stable creation");
|
|
4422
|
+
const tuple = [
|
|
4423
|
+
BigInt(permit.value ?? 0n),
|
|
4424
|
+
BigInt(permit.deadline ?? 0n),
|
|
4425
|
+
Number(permit.v ?? 0),
|
|
4426
|
+
permit.r ?? "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
4427
|
+
permit.s ?? "0x0000000000000000000000000000000000000000000000000000000000000000"
|
|
4428
|
+
];
|
|
4429
|
+
const payload = FactoryWriteInterface.encodeFunctionData("createSubDAOOperatorWithStable", [
|
|
4430
|
+
String(name),
|
|
4431
|
+
String(description),
|
|
4432
|
+
Number(accessModel),
|
|
4433
|
+
BigInt(minStakeAmount),
|
|
4434
|
+
normalise(operatorExecutor, "operatorExecutor"),
|
|
4435
|
+
normalise(operatorAdmin, "operatorAdmin"),
|
|
4436
|
+
tuple
|
|
4437
|
+
]);
|
|
4438
|
+
return { to: addr, data: payload, value: 0n };
|
|
4439
|
+
}
|
|
4440
|
+
function buildCreateOperatorSubDAOWithStableAdvancedTx({
|
|
4441
|
+
factory,
|
|
4442
|
+
name,
|
|
4443
|
+
description,
|
|
4444
|
+
accessModel,
|
|
4445
|
+
minStakeAmount,
|
|
4446
|
+
operatorExecutor,
|
|
4447
|
+
operatorAdmin,
|
|
4448
|
+
anyoneExec = false,
|
|
4449
|
+
governorProposer = false,
|
|
4450
|
+
permit
|
|
4451
|
+
}) {
|
|
4452
|
+
const addr = normalise(factory, "factory");
|
|
4453
|
+
if (!permit) throw new SageSDKError(CODES.INVALID_ARGS, "permit required for operator stable creation");
|
|
4454
|
+
const tuple = [
|
|
4455
|
+
BigInt(permit.value ?? 0n),
|
|
4456
|
+
BigInt(permit.deadline ?? 0n),
|
|
4457
|
+
Number(permit.v ?? 0),
|
|
4458
|
+
permit.r ?? "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
4459
|
+
permit.s ?? "0x0000000000000000000000000000000000000000000000000000000000000000"
|
|
4460
|
+
];
|
|
4461
|
+
const payload = FactoryWriteInterface.encodeFunctionData("createSubDAOOperatorWithStableAdvanced", [
|
|
4462
|
+
String(name),
|
|
4463
|
+
String(description),
|
|
4464
|
+
Number(accessModel),
|
|
4465
|
+
BigInt(minStakeAmount),
|
|
4466
|
+
normalise(operatorExecutor, "operatorExecutor"),
|
|
4467
|
+
normalise(operatorAdmin, "operatorAdmin"),
|
|
4468
|
+
Boolean(anyoneExec),
|
|
4469
|
+
Boolean(governorProposer),
|
|
4470
|
+
tuple
|
|
4471
|
+
]);
|
|
4472
|
+
return { to: addr, data: payload, value: 0n };
|
|
4473
|
+
}
|
|
4151
4474
|
async function listSubDAOs({ provider, factory }) {
|
|
4152
4475
|
if (!provider) throw new SageSDKError(CODES.INVALID_ARGS, "provider required");
|
|
4153
4476
|
const addr = normalise(factory, "factory");
|
|
@@ -4228,6 +4551,9 @@ var require_factory = __commonJS({
|
|
|
4228
4551
|
getTemplateDetails,
|
|
4229
4552
|
buildCreateSubDAOTx,
|
|
4230
4553
|
buildCreateSubDAOWithStableTx,
|
|
4554
|
+
buildCreateSubDAOWithParamsTx,
|
|
4555
|
+
buildCreateOperatorSubDAOWithStableTx,
|
|
4556
|
+
buildCreateOperatorSubDAOWithStableAdvancedTx,
|
|
4231
4557
|
buildCreateForkedSubDAOTx,
|
|
4232
4558
|
buildCreateForkedSubDAOWithStableTx
|
|
4233
4559
|
};
|
|
@@ -5510,6 +5836,58 @@ var require_safe = __commonJS({
|
|
|
5510
5836
|
}
|
|
5511
5837
|
});
|
|
5512
5838
|
|
|
5839
|
+
// src/utils/time.js
|
|
5840
|
+
var require_time = __commonJS({
|
|
5841
|
+
"src/utils/time.js"(exports2, module2) {
|
|
5842
|
+
function relativeTime(ts) {
|
|
5843
|
+
if (!ts || typeof ts !== "number") return "\u2014";
|
|
5844
|
+
try {
|
|
5845
|
+
const ms = ts < 1e12 ? ts * 1e3 : ts;
|
|
5846
|
+
const diff = Date.now() - ms;
|
|
5847
|
+
if (diff < 0) return "just now";
|
|
5848
|
+
const minutes = Math.round(diff / 6e4);
|
|
5849
|
+
if (minutes < 1) return "just now";
|
|
5850
|
+
if (minutes < 60) return `${minutes}m ago`;
|
|
5851
|
+
const hours = Math.round(minutes / 60);
|
|
5852
|
+
if (hours < 24) return `${hours}h ago`;
|
|
5853
|
+
const days = Math.round(hours / 24);
|
|
5854
|
+
if (days < 30) return `${days}d ago`;
|
|
5855
|
+
const months = Math.round(days / 30);
|
|
5856
|
+
if (months < 12) return `${months}mo ago`;
|
|
5857
|
+
const years = Math.round(months / 12);
|
|
5858
|
+
return `${years}y ago`;
|
|
5859
|
+
} catch {
|
|
5860
|
+
return "\u2014";
|
|
5861
|
+
}
|
|
5862
|
+
}
|
|
5863
|
+
function formatDate(ts) {
|
|
5864
|
+
if (!ts || typeof ts !== "number") return null;
|
|
5865
|
+
try {
|
|
5866
|
+
const ms = ts < 1e12 ? ts * 1e3 : ts;
|
|
5867
|
+
const d = new Date(ms);
|
|
5868
|
+
return d.toLocaleDateString();
|
|
5869
|
+
} catch {
|
|
5870
|
+
return null;
|
|
5871
|
+
}
|
|
5872
|
+
}
|
|
5873
|
+
function formatDateTime(ts) {
|
|
5874
|
+
if (!ts || typeof ts !== "number") return null;
|
|
5875
|
+
try {
|
|
5876
|
+
const ms = ts < 1e12 ? ts * 1e3 : ts;
|
|
5877
|
+
const d = new Date(ms);
|
|
5878
|
+
return d.toLocaleString();
|
|
5879
|
+
} catch {
|
|
5880
|
+
return null;
|
|
5881
|
+
}
|
|
5882
|
+
}
|
|
5883
|
+
module2.exports = {
|
|
5884
|
+
relativeTime,
|
|
5885
|
+
formatDate,
|
|
5886
|
+
formatDateTime
|
|
5887
|
+
};
|
|
5888
|
+
}
|
|
5889
|
+
});
|
|
5890
|
+
|
|
5513
5891
|
// src/treasury/index.js
|
|
5514
5892
|
var require_treasury = __commonJS({
|
|
5515
5893
|
"src/treasury/index.js"(exports2, module2) {
|
|
@@ -9074,6 +9452,7 @@ var require_src = __commonJS({
|
|
|
9074
9452
|
var subgraph = require_subgraph();
|
|
9075
9453
|
var privateTx = require_privateTx();
|
|
9076
9454
|
var safe = require_safe();
|
|
9455
|
+
var time = require_time();
|
|
9077
9456
|
var treasury = require_treasury();
|
|
9078
9457
|
var boost = require_boost();
|
|
9079
9458
|
var bounty = require_bounty();
|
|
@@ -9121,7 +9500,7 @@ var require_src = __commonJS({
|
|
|
9121
9500
|
boost,
|
|
9122
9501
|
// bond module removed; bonds deprecated in CLI/SDK
|
|
9123
9502
|
subgraph,
|
|
9124
|
-
utils: { ...utils, privateTx, safe },
|
|
9503
|
+
utils: { ...utils, privateTx, safe, time },
|
|
9125
9504
|
bounty,
|
|
9126
9505
|
wallet: Object.assign(wallet, {
|
|
9127
9506
|
cast: walletCastManager,
|