@sage-protocol/sdk 0.1.13 → 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/dist/browser/index.mjs +289 -90
- package/dist/index.cjs +350 -91
- package/dist/index.mjs +350 -91
- package/dist/node/index.cjs +350 -91
- package/dist/node/index.mjs +350 -91
- 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",
|
|
@@ -406,6 +407,32 @@ var require_subgraph = __commonJS({
|
|
|
406
407
|
var axios = __require("axios");
|
|
407
408
|
var { getAddress } = __require("ethers");
|
|
408
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
|
+
}
|
|
409
436
|
async function query(url, document, variables) {
|
|
410
437
|
if (!url) throw new Error("subgraph url required");
|
|
411
438
|
const resp = await axios.post(url, { query: document, variables }, { timeout: 1e4 });
|
|
@@ -428,15 +455,21 @@ var require_subgraph = __commonJS({
|
|
|
428
455
|
}
|
|
429
456
|
}
|
|
430
457
|
`, { governor: String(governor).toLowerCase(), first, skip });
|
|
431
|
-
return (data?.proposals
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
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
|
+
});
|
|
440
473
|
}
|
|
441
474
|
var STATE_STRING_TO_NUMBER = {
|
|
442
475
|
PENDING: 0,
|
|
@@ -453,6 +486,8 @@ var require_subgraph = __commonJS({
|
|
|
453
486
|
async function listProposalsFiltered({ url, governor, states, fromTimestamp, toTimestamp, first = 20, skip = 0, orderBy = "createdAt", orderDirection = "desc" }) {
|
|
454
487
|
const govLower = governor ? String(governor).toLowerCase() : null;
|
|
455
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");
|
|
456
491
|
const doc = `
|
|
457
492
|
query($first: Int!, $skip: Int!, $governor: Bytes, $states: [String!], $from: Int, $to: Int) {
|
|
458
493
|
proposals(
|
|
@@ -464,8 +499,8 @@ var require_subgraph = __commonJS({
|
|
|
464
499
|
}
|
|
465
500
|
first: $first
|
|
466
501
|
skip: $skip
|
|
467
|
-
orderBy: ${
|
|
468
|
-
orderDirection: ${
|
|
502
|
+
orderBy: ${safeOrderBy}
|
|
503
|
+
orderDirection: ${safeOrderDirection}
|
|
469
504
|
) {
|
|
470
505
|
id
|
|
471
506
|
proposer
|
|
@@ -486,19 +521,23 @@ var require_subgraph = __commonJS({
|
|
|
486
521
|
if (fromTimestamp !== void 0) variables.from = Number(fromTimestamp);
|
|
487
522
|
if (toTimestamp !== void 0) variables.to = Number(toTimestamp);
|
|
488
523
|
const data = await query(url, doc, variables);
|
|
489
|
-
return (data?.proposals
|
|
524
|
+
return mapSafe(data?.proposals, (p) => {
|
|
490
525
|
const stateStr = String(p.state || "").toUpperCase();
|
|
491
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;
|
|
492
531
|
return {
|
|
493
532
|
id: BigInt(p.id),
|
|
494
|
-
proposer
|
|
533
|
+
proposer,
|
|
495
534
|
description: p.description || "",
|
|
496
535
|
createdAt: Number(p.createdAt || 0),
|
|
497
536
|
updatedAt: Number(p.updatedAt || 0),
|
|
498
537
|
state: stateStr,
|
|
499
538
|
stateNum,
|
|
500
539
|
eta: p.eta ? BigInt(String(p.eta)) : null,
|
|
501
|
-
targets
|
|
540
|
+
targets,
|
|
502
541
|
values: (p.values || []).map((value) => BigInt(String(value))),
|
|
503
542
|
calldatas: p.calldatas || []
|
|
504
543
|
};
|
|
@@ -517,19 +556,127 @@ var require_subgraph = __commonJS({
|
|
|
517
556
|
}
|
|
518
557
|
}
|
|
519
558
|
`, { first, skip });
|
|
520
|
-
return (data?.libraries
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
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
|
+
});
|
|
527
672
|
}
|
|
528
673
|
module2.exports = {
|
|
529
674
|
query,
|
|
530
675
|
listProposals,
|
|
531
676
|
listProposalsFiltered,
|
|
532
677
|
listLibraries,
|
|
678
|
+
getSubdaoLibraries,
|
|
679
|
+
getSubdaoPrompts,
|
|
533
680
|
/**
|
|
534
681
|
* Canonical proposal timeline. Tries common fields first, then event-style fallbacks.
|
|
535
682
|
* Returns { id, createdAt, queuedAt, executedAt, canceledAt, eta, state } (numbers/strings may be null when unavailable).
|
|
@@ -595,86 +742,127 @@ var require_subgraph = __commonJS({
|
|
|
595
742
|
async listLiquidityAddPlans({ url, subdao = null, first = 50, skip = 0, orderBy = "blockTimestamp", orderDirection = "desc" }) {
|
|
596
743
|
if (!url) throw new Error("subgraph url required");
|
|
597
744
|
const filters = [];
|
|
598
|
-
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
|
+
}
|
|
599
750
|
const where = filters.length ? `where: { ${filters.join(", ")} }` : "";
|
|
751
|
+
const safeOrderBy = sanitizeOrderBy(orderBy, ["blockTimestamp", "blockNumber"], "blockTimestamp");
|
|
752
|
+
const safeOrderDirection = sanitizeOrderDirection(orderDirection, "desc");
|
|
600
753
|
const doc = `
|
|
601
754
|
query($first:Int!,$skip:Int!){
|
|
602
|
-
liquidityAddPlans(${where} first:$first, skip:$skip, orderBy: ${
|
|
755
|
+
liquidityAddPlans(${where} first:$first, skip:$skip, orderBy: ${safeOrderBy}, orderDirection: ${safeOrderDirection}){
|
|
603
756
|
id subdao pool sxxxToken stableToken sxxxAmount stableAmount lpRecipient blockNumber blockTimestamp transactionHash
|
|
604
757
|
}
|
|
605
758
|
}
|
|
606
759
|
`;
|
|
607
760
|
const data = await query(url, doc, { first, skip });
|
|
608
|
-
return (data?.liquidityAddPlans
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
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
|
+
});
|
|
621
782
|
},
|
|
622
783
|
async listLiquidityRemovePlans({ url, subdao = null, first = 50, skip = 0, orderBy = "blockTimestamp", orderDirection = "desc" }) {
|
|
623
784
|
if (!url) throw new Error("subgraph url required");
|
|
624
785
|
const filters = [];
|
|
625
|
-
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
|
+
}
|
|
626
791
|
const where = filters.length ? `where: { ${filters.join(", ")} }` : "";
|
|
792
|
+
const safeOrderBy = sanitizeOrderBy(orderBy, ["blockTimestamp", "blockNumber"], "blockTimestamp");
|
|
793
|
+
const safeOrderDirection = sanitizeOrderDirection(orderDirection, "desc");
|
|
627
794
|
const doc = `
|
|
628
795
|
query($first:Int!,$skip:Int!){
|
|
629
|
-
liquidityRemovePlans(${where} first:$first, skip:$skip, orderBy: ${
|
|
796
|
+
liquidityRemovePlans(${where} first:$first, skip:$skip, orderBy: ${safeOrderBy}, orderDirection: ${safeOrderDirection}){
|
|
630
797
|
id subdao pool lpToken lpAmount recipient blockNumber blockTimestamp transactionHash
|
|
631
798
|
}
|
|
632
799
|
}
|
|
633
800
|
`;
|
|
634
801
|
const data = await query(url, doc, { first, skip });
|
|
635
|
-
return (data?.liquidityRemovePlans
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
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
|
+
});
|
|
646
820
|
},
|
|
647
821
|
async listPromptsByTag({ url, tagsHash, registry = null, first = 50, skip = 0, orderBy = "updatedAt", orderDirection = "desc" }) {
|
|
648
822
|
if (!url) throw new Error("subgraph url required");
|
|
649
823
|
const clauses = [`tagsHash: "${String(tagsHash)}"`];
|
|
650
|
-
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
|
+
}
|
|
651
829
|
const where = `where: { ${clauses.join(", ")} }`;
|
|
830
|
+
const safeOrderBy = sanitizeOrderBy(orderBy, ["updatedAt"], "updatedAt");
|
|
831
|
+
const safeOrderDirection = sanitizeOrderDirection(orderDirection, "desc");
|
|
652
832
|
const doc = `
|
|
653
833
|
query($first:Int!,$skip:Int!) {
|
|
654
|
-
prompts(${where} first:$first, skip:$skip, orderBy: ${
|
|
834
|
+
prompts(${where} first:$first, skip:$skip, orderBy: ${safeOrderBy}, orderDirection: ${safeOrderDirection}) {
|
|
655
835
|
id key cid version author registry updatedAt tagsHash
|
|
656
836
|
}
|
|
657
837
|
}
|
|
658
838
|
`;
|
|
659
839
|
const data = await query(url, doc, { first, skip });
|
|
660
|
-
return (data?.prompts
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
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
|
+
});
|
|
670
855
|
},
|
|
671
856
|
// Prompt helpers (registry scoped)
|
|
672
857
|
async listRegistryPrompts({ url, registry, first = 50, skip = 0, orderBy = "updatedAt", orderDirection = "desc" }) {
|
|
673
858
|
if (!url) throw new Error("subgraph url required");
|
|
674
|
-
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");
|
|
675
863
|
const doc = `
|
|
676
864
|
query($first:Int!,$skip:Int!,$registry:Bytes!) {
|
|
677
|
-
prompts(where:{ registry: $registry }, first:$first, skip:$skip, orderBy: ${
|
|
865
|
+
prompts(where:{ registry: $registry }, first:$first, skip:$skip, orderBy: ${safeOrderBy}, orderDirection: ${safeOrderDirection}) {
|
|
678
866
|
id
|
|
679
867
|
key
|
|
680
868
|
cid
|
|
@@ -686,19 +874,25 @@ var require_subgraph = __commonJS({
|
|
|
686
874
|
}
|
|
687
875
|
`;
|
|
688
876
|
const data = await query(url, doc, { first, skip, registry: reg.toLowerCase() });
|
|
689
|
-
return (data?.prompts
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
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
|
+
});
|
|
698
891
|
},
|
|
699
892
|
async getPromptByKey({ url, registry, key }) {
|
|
700
893
|
if (!url) throw new Error("subgraph url required");
|
|
701
|
-
const reg =
|
|
894
|
+
const reg = safeGetAddress(registry);
|
|
895
|
+
if (!reg) throw new Error("invalid registry address");
|
|
702
896
|
const doc = `
|
|
703
897
|
query($registry:Bytes!,$key:String!) {
|
|
704
898
|
prompts(where:{ registry: $registry, key: $key }, first:1) {
|
|
@@ -714,15 +908,19 @@ var require_subgraph = __commonJS({
|
|
|
714
908
|
`;
|
|
715
909
|
const data = await query(url, doc, { registry: reg.toLowerCase(), key: String(key) });
|
|
716
910
|
const p = (data?.prompts || [])[0];
|
|
717
|
-
|
|
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 {
|
|
718
916
|
id: String(p.id),
|
|
719
917
|
key: String(p.key),
|
|
720
918
|
cid: String(p.cid),
|
|
721
919
|
version: BigInt(p.version || "0"),
|
|
722
|
-
author
|
|
723
|
-
registry:
|
|
920
|
+
author,
|
|
921
|
+
registry: regAddr,
|
|
724
922
|
updatedAt: Number(p.updatedAt || 0)
|
|
725
|
-
}
|
|
923
|
+
};
|
|
726
924
|
},
|
|
727
925
|
async getProposalById({ url, id: id2 }) {
|
|
728
926
|
if (!url) throw new Error("subgraph url required");
|
|
@@ -730,18 +928,26 @@ var require_subgraph = __commonJS({
|
|
|
730
928
|
const data = await query(url, doc, { id: String(id2) });
|
|
731
929
|
const p = data?.proposal;
|
|
732
930
|
if (!p) return null;
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
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
|
+
}
|
|
745
951
|
}
|
|
746
952
|
};
|
|
747
953
|
}
|
|
@@ -5630,6 +5836,58 @@ var require_safe = __commonJS({
|
|
|
5630
5836
|
}
|
|
5631
5837
|
});
|
|
5632
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
|
+
|
|
5633
5891
|
// src/treasury/index.js
|
|
5634
5892
|
var require_treasury = __commonJS({
|
|
5635
5893
|
"src/treasury/index.js"(exports2, module2) {
|
|
@@ -9194,6 +9452,7 @@ var require_src = __commonJS({
|
|
|
9194
9452
|
var subgraph = require_subgraph();
|
|
9195
9453
|
var privateTx = require_privateTx();
|
|
9196
9454
|
var safe = require_safe();
|
|
9455
|
+
var time = require_time();
|
|
9197
9456
|
var treasury = require_treasury();
|
|
9198
9457
|
var boost = require_boost();
|
|
9199
9458
|
var bounty = require_bounty();
|
|
@@ -9241,7 +9500,7 @@ var require_src = __commonJS({
|
|
|
9241
9500
|
boost,
|
|
9242
9501
|
// bond module removed; bonds deprecated in CLI/SDK
|
|
9243
9502
|
subgraph,
|
|
9244
|
-
utils: { ...utils, privateTx, safe },
|
|
9503
|
+
utils: { ...utils, privateTx, safe, time },
|
|
9245
9504
|
bounty,
|
|
9246
9505
|
wallet: Object.assign(wallet, {
|
|
9247
9506
|
cast: walletCastManager,
|