@sage-protocol/sdk 0.1.13 → 0.1.15
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/node/index.cjs
CHANGED
|
@@ -14,7 +14,7 @@ var require_package = __commonJS({
|
|
|
14
14
|
"package.json"(exports2, module2) {
|
|
15
15
|
module2.exports = {
|
|
16
16
|
name: "@sage-protocol/sdk",
|
|
17
|
-
version: "0.1.
|
|
17
|
+
version: "0.1.15",
|
|
18
18
|
description: "Backend-agnostic SDK for interacting with the Sage Protocol (governance, SubDAOs, tokens).",
|
|
19
19
|
main: "dist/index.cjs",
|
|
20
20
|
module: "dist/index.mjs",
|
|
@@ -70,6 +70,7 @@ var require_package = __commonJS({
|
|
|
70
70
|
release: "yarn build && npm publish --workspace @sage-protocol/sdk"
|
|
71
71
|
},
|
|
72
72
|
dependencies: {
|
|
73
|
+
"content-hash": "^2.5.2",
|
|
73
74
|
"@merit-systems/echo-typescript-sdk": "^1.0.17",
|
|
74
75
|
"@whetstone-research/doppler-sdk": "^0.0.1-alpha.40",
|
|
75
76
|
ai: "^3.2.3",
|
|
@@ -400,6 +401,32 @@ var require_subgraph = __commonJS({
|
|
|
400
401
|
var axios = require("axios");
|
|
401
402
|
var { getAddress } = require("ethers");
|
|
402
403
|
var { keccak256, toUtf8Bytes } = require("ethers");
|
|
404
|
+
function sanitizeOrderBy(orderBy, allowed, fallback) {
|
|
405
|
+
const value = (orderBy || "").toString();
|
|
406
|
+
return allowed.includes(value) ? value : fallback;
|
|
407
|
+
}
|
|
408
|
+
function sanitizeOrderDirection(direction, fallback = "desc") {
|
|
409
|
+
const v = (direction || "").toString().toLowerCase();
|
|
410
|
+
return v === "asc" ? "asc" : "desc";
|
|
411
|
+
}
|
|
412
|
+
function safeGetAddress(value) {
|
|
413
|
+
try {
|
|
414
|
+
return getAddress(value);
|
|
415
|
+
} catch {
|
|
416
|
+
return null;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
function mapSafe(list, mapper) {
|
|
420
|
+
const out = [];
|
|
421
|
+
for (const item of list || []) {
|
|
422
|
+
try {
|
|
423
|
+
const v = mapper(item);
|
|
424
|
+
if (v != null) out.push(v);
|
|
425
|
+
} catch {
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
return out;
|
|
429
|
+
}
|
|
403
430
|
async function query(url, document, variables) {
|
|
404
431
|
if (!url) throw new Error("subgraph url required");
|
|
405
432
|
const resp = await axios.post(url, { query: document, variables }, { timeout: 1e4 });
|
|
@@ -422,15 +449,21 @@ var require_subgraph = __commonJS({
|
|
|
422
449
|
}
|
|
423
450
|
}
|
|
424
451
|
`, { governor: String(governor).toLowerCase(), first, skip });
|
|
425
|
-
return (data?.proposals
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
452
|
+
return mapSafe(data?.proposals, (p) => {
|
|
453
|
+
const proposer = safeGetAddress(p.proposer);
|
|
454
|
+
if (!proposer) return null;
|
|
455
|
+
const targets = (p.targets || []).map((t) => safeGetAddress(t)).filter(Boolean);
|
|
456
|
+
if (!targets.length && (p.targets || []).length) return null;
|
|
457
|
+
return {
|
|
458
|
+
id: BigInt(p.id),
|
|
459
|
+
proposer,
|
|
460
|
+
description: p.description,
|
|
461
|
+
createdAt: Number(p.createdAt || 0),
|
|
462
|
+
targets,
|
|
463
|
+
values: (p.values || []).map((value) => BigInt(String(value))),
|
|
464
|
+
calldatas: p.calldatas || []
|
|
465
|
+
};
|
|
466
|
+
});
|
|
434
467
|
}
|
|
435
468
|
var STATE_STRING_TO_NUMBER = {
|
|
436
469
|
PENDING: 0,
|
|
@@ -447,6 +480,8 @@ var require_subgraph = __commonJS({
|
|
|
447
480
|
async function listProposalsFiltered({ url, governor, states, fromTimestamp, toTimestamp, first = 20, skip = 0, orderBy = "createdAt", orderDirection = "desc" }) {
|
|
448
481
|
const govLower = governor ? String(governor).toLowerCase() : null;
|
|
449
482
|
const statesUpper = Array.isArray(states) && states.length ? states.map((s) => String(s).toUpperCase()) : null;
|
|
483
|
+
const safeOrderBy = sanitizeOrderBy(orderBy, ["createdAt", "updatedAt", "eta"], "createdAt");
|
|
484
|
+
const safeOrderDirection = sanitizeOrderDirection(orderDirection, "desc");
|
|
450
485
|
const doc = `
|
|
451
486
|
query($first: Int!, $skip: Int!, $governor: Bytes, $states: [String!], $from: Int, $to: Int) {
|
|
452
487
|
proposals(
|
|
@@ -458,8 +493,8 @@ var require_subgraph = __commonJS({
|
|
|
458
493
|
}
|
|
459
494
|
first: $first
|
|
460
495
|
skip: $skip
|
|
461
|
-
orderBy: ${
|
|
462
|
-
orderDirection: ${
|
|
496
|
+
orderBy: ${safeOrderBy}
|
|
497
|
+
orderDirection: ${safeOrderDirection}
|
|
463
498
|
) {
|
|
464
499
|
id
|
|
465
500
|
proposer
|
|
@@ -480,19 +515,23 @@ var require_subgraph = __commonJS({
|
|
|
480
515
|
if (fromTimestamp !== void 0) variables.from = Number(fromTimestamp);
|
|
481
516
|
if (toTimestamp !== void 0) variables.to = Number(toTimestamp);
|
|
482
517
|
const data = await query(url, doc, variables);
|
|
483
|
-
return (data?.proposals
|
|
518
|
+
return mapSafe(data?.proposals, (p) => {
|
|
484
519
|
const stateStr = String(p.state || "").toUpperCase();
|
|
485
520
|
const stateNum = STATE_STRING_TO_NUMBER[stateStr] != null ? STATE_STRING_TO_NUMBER[stateStr] : null;
|
|
521
|
+
const proposer = safeGetAddress(p.proposer);
|
|
522
|
+
if (!proposer) return null;
|
|
523
|
+
const targets = (p.targets || []).map((t) => safeGetAddress(t)).filter(Boolean);
|
|
524
|
+
if (!targets.length && (p.targets || []).length) return null;
|
|
486
525
|
return {
|
|
487
526
|
id: BigInt(p.id),
|
|
488
|
-
proposer
|
|
527
|
+
proposer,
|
|
489
528
|
description: p.description || "",
|
|
490
529
|
createdAt: Number(p.createdAt || 0),
|
|
491
530
|
updatedAt: Number(p.updatedAt || 0),
|
|
492
531
|
state: stateStr,
|
|
493
532
|
stateNum,
|
|
494
533
|
eta: p.eta ? BigInt(String(p.eta)) : null,
|
|
495
|
-
targets
|
|
534
|
+
targets,
|
|
496
535
|
values: (p.values || []).map((value) => BigInt(String(value))),
|
|
497
536
|
calldatas: p.calldatas || []
|
|
498
537
|
};
|
|
@@ -511,19 +550,127 @@ var require_subgraph = __commonJS({
|
|
|
511
550
|
}
|
|
512
551
|
}
|
|
513
552
|
`, { first, skip });
|
|
514
|
-
return (data?.libraries
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
553
|
+
return mapSafe(data?.libraries, (lib) => {
|
|
554
|
+
const sub = safeGetAddress(lib.subDAO);
|
|
555
|
+
const proposer = safeGetAddress(lib.proposer);
|
|
556
|
+
if (!sub || !proposer) return null;
|
|
557
|
+
return {
|
|
558
|
+
id: lib.id,
|
|
559
|
+
manifestCID: lib.manifestCID,
|
|
560
|
+
subdao: sub,
|
|
561
|
+
proposer,
|
|
562
|
+
createdAt: Number(lib.createdAt || 0)
|
|
563
|
+
};
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
async function getSubdaoLibraries({ url, subdao, first = 20, skip = 0 }) {
|
|
567
|
+
if (!url) throw new Error("subgraph url required");
|
|
568
|
+
const hasFilter = !!subdao;
|
|
569
|
+
const whereClause = hasFilter ? "where:{ subdao:$subdao }" : "";
|
|
570
|
+
const doc = `
|
|
571
|
+
query($subdao:Bytes,$first:Int!,$skip:Int!){
|
|
572
|
+
subDAOLibraryPointers(
|
|
573
|
+
${whereClause}
|
|
574
|
+
first:$first,
|
|
575
|
+
skip:$skip,
|
|
576
|
+
orderBy: updatedAt,
|
|
577
|
+
orderDirection: desc
|
|
578
|
+
){
|
|
579
|
+
id
|
|
580
|
+
subdao
|
|
581
|
+
libraryId
|
|
582
|
+
manifestCID
|
|
583
|
+
previousCID
|
|
584
|
+
promptCount
|
|
585
|
+
updatedAt
|
|
586
|
+
createdAt
|
|
587
|
+
blockNumber
|
|
588
|
+
blockTimestamp
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
`;
|
|
592
|
+
const variables = {
|
|
593
|
+
first: Math.min(Math.max(1, Number(first || 20)), 100),
|
|
594
|
+
skip
|
|
595
|
+
};
|
|
596
|
+
if (hasFilter) {
|
|
597
|
+
const addr = safeGetAddress(subdao);
|
|
598
|
+
if (!addr) throw new Error("invalid subdao address");
|
|
599
|
+
variables.subdao = addr.toLowerCase();
|
|
600
|
+
}
|
|
601
|
+
const data = await query(url, doc, variables);
|
|
602
|
+
return mapSafe(data?.subDAOLibraryPointers, (row) => {
|
|
603
|
+
const id2 = row?.id;
|
|
604
|
+
const manifestCID = row?.manifestCID;
|
|
605
|
+
const sub = safeGetAddress(row?.subdao);
|
|
606
|
+
if (!id2 || !manifestCID || !sub) return null;
|
|
607
|
+
const timestamp = (row.updatedAt != null ? Number(row.updatedAt) : null) || (row.createdAt != null ? Number(row.createdAt) : null) || (row.blockTimestamp != null ? Number(row.blockTimestamp) : null);
|
|
608
|
+
return {
|
|
609
|
+
id: String(id2),
|
|
610
|
+
subdao: sub,
|
|
611
|
+
libraryId: String(row.libraryId || "main"),
|
|
612
|
+
manifestCID: String(manifestCID),
|
|
613
|
+
previousCID: row.previousCID || null,
|
|
614
|
+
promptCount: row.promptCount != null ? Number(row.promptCount) : null,
|
|
615
|
+
updatedAt: timestamp,
|
|
616
|
+
createdAt: row.createdAt != null ? Number(row.createdAt) : null,
|
|
617
|
+
blockNumber: row.blockNumber != null ? Number(row.blockNumber) : null,
|
|
618
|
+
blockTimestamp: row.blockTimestamp != null ? Number(row.blockTimestamp) : null
|
|
619
|
+
};
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
async function getSubdaoPrompts({ url, registry, first = 50, skip = 0, orderBy = "updatedAt", orderDirection = "desc" }) {
|
|
623
|
+
if (!url) throw new Error("subgraph url required");
|
|
624
|
+
const reg = safeGetAddress(registry);
|
|
625
|
+
if (!reg) throw new Error("invalid registry address");
|
|
626
|
+
const safeOrderBy = sanitizeOrderBy(orderBy, ["updatedAt"], "updatedAt");
|
|
627
|
+
const safeOrderDirection = sanitizeOrderDirection(orderDirection, "desc");
|
|
628
|
+
const doc = `
|
|
629
|
+
query($registry:Bytes!,$first:Int!,$skip:Int!){
|
|
630
|
+
prompts(
|
|
631
|
+
where:{ registry:$registry },
|
|
632
|
+
first:$first,
|
|
633
|
+
skip:$skip,
|
|
634
|
+
orderBy: ${safeOrderBy},
|
|
635
|
+
orderDirection: ${safeOrderDirection}
|
|
636
|
+
){
|
|
637
|
+
id
|
|
638
|
+
key
|
|
639
|
+
cid
|
|
640
|
+
version
|
|
641
|
+
author
|
|
642
|
+
registry
|
|
643
|
+
updatedAt
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
`;
|
|
647
|
+
const data = await query(url, doc, {
|
|
648
|
+
registry: reg.toLowerCase(),
|
|
649
|
+
first: Math.min(Math.max(1, Number(first || 50)), 100),
|
|
650
|
+
skip
|
|
651
|
+
});
|
|
652
|
+
return mapSafe(data?.prompts, (p) => {
|
|
653
|
+
const author = safeGetAddress(p.author);
|
|
654
|
+
const regAddr = safeGetAddress(p.registry);
|
|
655
|
+
if (!author || !regAddr) return null;
|
|
656
|
+
return {
|
|
657
|
+
id: String(p.id),
|
|
658
|
+
key: String(p.key),
|
|
659
|
+
cid: String(p.cid),
|
|
660
|
+
version: BigInt(p.version || "0"),
|
|
661
|
+
author,
|
|
662
|
+
registry: regAddr,
|
|
663
|
+
updatedAt: Number(p.updatedAt || 0)
|
|
664
|
+
};
|
|
665
|
+
});
|
|
521
666
|
}
|
|
522
667
|
module2.exports = {
|
|
523
668
|
query,
|
|
524
669
|
listProposals,
|
|
525
670
|
listProposalsFiltered,
|
|
526
671
|
listLibraries,
|
|
672
|
+
getSubdaoLibraries,
|
|
673
|
+
getSubdaoPrompts,
|
|
527
674
|
/**
|
|
528
675
|
* Canonical proposal timeline. Tries common fields first, then event-style fallbacks.
|
|
529
676
|
* Returns { id, createdAt, queuedAt, executedAt, canceledAt, eta, state } (numbers/strings may be null when unavailable).
|
|
@@ -589,86 +736,127 @@ var require_subgraph = __commonJS({
|
|
|
589
736
|
async listLiquidityAddPlans({ url, subdao = null, first = 50, skip = 0, orderBy = "blockTimestamp", orderDirection = "desc" }) {
|
|
590
737
|
if (!url) throw new Error("subgraph url required");
|
|
591
738
|
const filters = [];
|
|
592
|
-
if (subdao)
|
|
739
|
+
if (subdao) {
|
|
740
|
+
const addr = safeGetAddress(subdao);
|
|
741
|
+
if (!addr) throw new Error("invalid subdao address");
|
|
742
|
+
filters.push(`subdao: "${addr.toLowerCase()}"`);
|
|
743
|
+
}
|
|
593
744
|
const where = filters.length ? `where: { ${filters.join(", ")} }` : "";
|
|
745
|
+
const safeOrderBy = sanitizeOrderBy(orderBy, ["blockTimestamp", "blockNumber"], "blockTimestamp");
|
|
746
|
+
const safeOrderDirection = sanitizeOrderDirection(orderDirection, "desc");
|
|
594
747
|
const doc = `
|
|
595
748
|
query($first:Int!,$skip:Int!){
|
|
596
|
-
liquidityAddPlans(${where} first:$first, skip:$skip, orderBy: ${
|
|
749
|
+
liquidityAddPlans(${where} first:$first, skip:$skip, orderBy: ${safeOrderBy}, orderDirection: ${safeOrderDirection}){
|
|
597
750
|
id subdao pool sxxxToken stableToken sxxxAmount stableAmount lpRecipient blockNumber blockTimestamp transactionHash
|
|
598
751
|
}
|
|
599
752
|
}
|
|
600
753
|
`;
|
|
601
754
|
const data = await query(url, doc, { first, skip });
|
|
602
|
-
return (data?.liquidityAddPlans
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
755
|
+
return mapSafe(data?.liquidityAddPlans, (e) => {
|
|
756
|
+
const sub = safeGetAddress(e.subdao);
|
|
757
|
+
const pool = safeGetAddress(e.pool);
|
|
758
|
+
const sxxxToken = safeGetAddress(e.sxxxToken);
|
|
759
|
+
const stableToken = safeGetAddress(e.stableToken);
|
|
760
|
+
const lpRecipient = safeGetAddress(e.lpRecipient);
|
|
761
|
+
if (!sub || !pool || !sxxxToken || !stableToken || !lpRecipient) return null;
|
|
762
|
+
return {
|
|
763
|
+
id: String(e.id),
|
|
764
|
+
subdao: sub,
|
|
765
|
+
pool,
|
|
766
|
+
sxxxToken,
|
|
767
|
+
stableToken,
|
|
768
|
+
sxxxAmount: BigInt(String(e.sxxxAmount)),
|
|
769
|
+
stableAmount: BigInt(String(e.stableAmount)),
|
|
770
|
+
lpRecipient,
|
|
771
|
+
blockNumber: Number(e.blockNumber || 0),
|
|
772
|
+
blockTimestamp: Number(e.blockTimestamp || 0),
|
|
773
|
+
transactionHash: e.transactionHash
|
|
774
|
+
};
|
|
775
|
+
});
|
|
615
776
|
},
|
|
616
777
|
async listLiquidityRemovePlans({ url, subdao = null, first = 50, skip = 0, orderBy = "blockTimestamp", orderDirection = "desc" }) {
|
|
617
778
|
if (!url) throw new Error("subgraph url required");
|
|
618
779
|
const filters = [];
|
|
619
|
-
if (subdao)
|
|
780
|
+
if (subdao) {
|
|
781
|
+
const addr = safeGetAddress(subdao);
|
|
782
|
+
if (!addr) throw new Error("invalid subdao address");
|
|
783
|
+
filters.push(`subdao: "${addr.toLowerCase()}"`);
|
|
784
|
+
}
|
|
620
785
|
const where = filters.length ? `where: { ${filters.join(", ")} }` : "";
|
|
786
|
+
const safeOrderBy = sanitizeOrderBy(orderBy, ["blockTimestamp", "blockNumber"], "blockTimestamp");
|
|
787
|
+
const safeOrderDirection = sanitizeOrderDirection(orderDirection, "desc");
|
|
621
788
|
const doc = `
|
|
622
789
|
query($first:Int!,$skip:Int!){
|
|
623
|
-
liquidityRemovePlans(${where} first:$first, skip:$skip, orderBy: ${
|
|
790
|
+
liquidityRemovePlans(${where} first:$first, skip:$skip, orderBy: ${safeOrderBy}, orderDirection: ${safeOrderDirection}){
|
|
624
791
|
id subdao pool lpToken lpAmount recipient blockNumber blockTimestamp transactionHash
|
|
625
792
|
}
|
|
626
793
|
}
|
|
627
794
|
`;
|
|
628
795
|
const data = await query(url, doc, { first, skip });
|
|
629
|
-
return (data?.liquidityRemovePlans
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
796
|
+
return mapSafe(data?.liquidityRemovePlans, (e) => {
|
|
797
|
+
const sub = safeGetAddress(e.subdao);
|
|
798
|
+
const pool = safeGetAddress(e.pool);
|
|
799
|
+
const lpToken = safeGetAddress(e.lpToken);
|
|
800
|
+
const recipient = safeGetAddress(e.recipient);
|
|
801
|
+
if (!sub || !pool || !lpToken || !recipient) return null;
|
|
802
|
+
return {
|
|
803
|
+
id: String(e.id),
|
|
804
|
+
subdao: sub,
|
|
805
|
+
pool,
|
|
806
|
+
lpToken,
|
|
807
|
+
lpAmount: BigInt(String(e.lpAmount)),
|
|
808
|
+
recipient,
|
|
809
|
+
blockNumber: Number(e.blockNumber || 0),
|
|
810
|
+
blockTimestamp: Number(e.blockTimestamp || 0),
|
|
811
|
+
transactionHash: e.transactionHash
|
|
812
|
+
};
|
|
813
|
+
});
|
|
640
814
|
},
|
|
641
815
|
async listPromptsByTag({ url, tagsHash, registry = null, first = 50, skip = 0, orderBy = "updatedAt", orderDirection = "desc" }) {
|
|
642
816
|
if (!url) throw new Error("subgraph url required");
|
|
643
817
|
const clauses = [`tagsHash: "${String(tagsHash)}"`];
|
|
644
|
-
if (registry)
|
|
818
|
+
if (registry) {
|
|
819
|
+
const addr = safeGetAddress(registry);
|
|
820
|
+
if (!addr) throw new Error("invalid registry address");
|
|
821
|
+
clauses.push(`registry: "${addr.toLowerCase()}"`);
|
|
822
|
+
}
|
|
645
823
|
const where = `where: { ${clauses.join(", ")} }`;
|
|
824
|
+
const safeOrderBy = sanitizeOrderBy(orderBy, ["updatedAt"], "updatedAt");
|
|
825
|
+
const safeOrderDirection = sanitizeOrderDirection(orderDirection, "desc");
|
|
646
826
|
const doc = `
|
|
647
827
|
query($first:Int!,$skip:Int!) {
|
|
648
|
-
prompts(${where} first:$first, skip:$skip, orderBy: ${
|
|
828
|
+
prompts(${where} first:$first, skip:$skip, orderBy: ${safeOrderBy}, orderDirection: ${safeOrderDirection}) {
|
|
649
829
|
id key cid version author registry updatedAt tagsHash
|
|
650
830
|
}
|
|
651
831
|
}
|
|
652
832
|
`;
|
|
653
833
|
const data = await query(url, doc, { first, skip });
|
|
654
|
-
return (data?.prompts
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
834
|
+
return mapSafe(data?.prompts, (p) => {
|
|
835
|
+
const author = safeGetAddress(p.author);
|
|
836
|
+
const regAddr = safeGetAddress(p.registry);
|
|
837
|
+
if (!author || !regAddr) return null;
|
|
838
|
+
return {
|
|
839
|
+
id: String(p.id),
|
|
840
|
+
key: String(p.key),
|
|
841
|
+
cid: String(p.cid),
|
|
842
|
+
version: BigInt(p.version || "0"),
|
|
843
|
+
author,
|
|
844
|
+
registry: regAddr,
|
|
845
|
+
updatedAt: Number(p.updatedAt || 0),
|
|
846
|
+
tagsHash: String(p.tagsHash || "")
|
|
847
|
+
};
|
|
848
|
+
});
|
|
664
849
|
},
|
|
665
850
|
// Prompt helpers (registry scoped)
|
|
666
851
|
async listRegistryPrompts({ url, registry, first = 50, skip = 0, orderBy = "updatedAt", orderDirection = "desc" }) {
|
|
667
852
|
if (!url) throw new Error("subgraph url required");
|
|
668
|
-
const reg =
|
|
853
|
+
const reg = safeGetAddress(registry);
|
|
854
|
+
if (!reg) throw new Error("invalid registry address");
|
|
855
|
+
const safeOrderBy = sanitizeOrderBy(orderBy, ["updatedAt"], "updatedAt");
|
|
856
|
+
const safeOrderDirection = sanitizeOrderDirection(orderDirection, "desc");
|
|
669
857
|
const doc = `
|
|
670
858
|
query($first:Int!,$skip:Int!,$registry:Bytes!) {
|
|
671
|
-
prompts(where:{ registry: $registry }, first:$first, skip:$skip, orderBy: ${
|
|
859
|
+
prompts(where:{ registry: $registry }, first:$first, skip:$skip, orderBy: ${safeOrderBy}, orderDirection: ${safeOrderDirection}) {
|
|
672
860
|
id
|
|
673
861
|
key
|
|
674
862
|
cid
|
|
@@ -680,19 +868,25 @@ var require_subgraph = __commonJS({
|
|
|
680
868
|
}
|
|
681
869
|
`;
|
|
682
870
|
const data = await query(url, doc, { first, skip, registry: reg.toLowerCase() });
|
|
683
|
-
return (data?.prompts
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
871
|
+
return mapSafe(data?.prompts, (p) => {
|
|
872
|
+
const author = safeGetAddress(p.author);
|
|
873
|
+
const regAddr = safeGetAddress(p.registry);
|
|
874
|
+
if (!author || !regAddr) return null;
|
|
875
|
+
return {
|
|
876
|
+
id: String(p.id),
|
|
877
|
+
key: String(p.key),
|
|
878
|
+
cid: String(p.cid),
|
|
879
|
+
version: BigInt(p.version || "0"),
|
|
880
|
+
author,
|
|
881
|
+
registry: regAddr,
|
|
882
|
+
updatedAt: Number(p.updatedAt || 0)
|
|
883
|
+
};
|
|
884
|
+
});
|
|
692
885
|
},
|
|
693
886
|
async getPromptByKey({ url, registry, key }) {
|
|
694
887
|
if (!url) throw new Error("subgraph url required");
|
|
695
|
-
const reg =
|
|
888
|
+
const reg = safeGetAddress(registry);
|
|
889
|
+
if (!reg) throw new Error("invalid registry address");
|
|
696
890
|
const doc = `
|
|
697
891
|
query($registry:Bytes!,$key:String!) {
|
|
698
892
|
prompts(where:{ registry: $registry, key: $key }, first:1) {
|
|
@@ -708,15 +902,19 @@ var require_subgraph = __commonJS({
|
|
|
708
902
|
`;
|
|
709
903
|
const data = await query(url, doc, { registry: reg.toLowerCase(), key: String(key) });
|
|
710
904
|
const p = (data?.prompts || [])[0];
|
|
711
|
-
|
|
905
|
+
if (!p) return null;
|
|
906
|
+
const author = safeGetAddress(p.author);
|
|
907
|
+
const regAddr = safeGetAddress(p.registry);
|
|
908
|
+
if (!author || !regAddr) return null;
|
|
909
|
+
return {
|
|
712
910
|
id: String(p.id),
|
|
713
911
|
key: String(p.key),
|
|
714
912
|
cid: String(p.cid),
|
|
715
913
|
version: BigInt(p.version || "0"),
|
|
716
|
-
author
|
|
717
|
-
registry:
|
|
914
|
+
author,
|
|
915
|
+
registry: regAddr,
|
|
718
916
|
updatedAt: Number(p.updatedAt || 0)
|
|
719
|
-
}
|
|
917
|
+
};
|
|
720
918
|
},
|
|
721
919
|
async getProposalById({ url, id: id2 }) {
|
|
722
920
|
if (!url) throw new Error("subgraph url required");
|
|
@@ -724,18 +922,26 @@ var require_subgraph = __commonJS({
|
|
|
724
922
|
const data = await query(url, doc, { id: String(id2) });
|
|
725
923
|
const p = data?.proposal;
|
|
726
924
|
if (!p) return null;
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
925
|
+
try {
|
|
926
|
+
const proposer = safeGetAddress(p.proposer);
|
|
927
|
+
if (!proposer) return null;
|
|
928
|
+
const targets = (p.targets || []).map((t) => safeGetAddress(t)).filter(Boolean);
|
|
929
|
+
if (!targets.length && (p.targets || []).length) return null;
|
|
930
|
+
return {
|
|
931
|
+
id: BigInt(p.id),
|
|
932
|
+
proposer,
|
|
933
|
+
description: p.description || "",
|
|
934
|
+
createdAt: Number(p.createdAt || 0),
|
|
935
|
+
updatedAt: Number(p.updatedAt || 0),
|
|
936
|
+
state: String(p.state || ""),
|
|
937
|
+
eta: p.eta ? BigInt(String(p.eta)) : null,
|
|
938
|
+
targets,
|
|
939
|
+
values: (p.values || []).map((v) => BigInt(String(v))),
|
|
940
|
+
calldatas: p.calldatas || []
|
|
941
|
+
};
|
|
942
|
+
} catch {
|
|
943
|
+
return null;
|
|
944
|
+
}
|
|
739
945
|
}
|
|
740
946
|
};
|
|
741
947
|
}
|
|
@@ -5624,6 +5830,58 @@ var require_safe = __commonJS({
|
|
|
5624
5830
|
}
|
|
5625
5831
|
});
|
|
5626
5832
|
|
|
5833
|
+
// src/utils/time.js
|
|
5834
|
+
var require_time = __commonJS({
|
|
5835
|
+
"src/utils/time.js"(exports2, module2) {
|
|
5836
|
+
function relativeTime(ts) {
|
|
5837
|
+
if (!ts || typeof ts !== "number") return "\u2014";
|
|
5838
|
+
try {
|
|
5839
|
+
const ms = ts < 1e12 ? ts * 1e3 : ts;
|
|
5840
|
+
const diff = Date.now() - ms;
|
|
5841
|
+
if (diff < 0) return "just now";
|
|
5842
|
+
const minutes = Math.round(diff / 6e4);
|
|
5843
|
+
if (minutes < 1) return "just now";
|
|
5844
|
+
if (minutes < 60) return `${minutes}m ago`;
|
|
5845
|
+
const hours = Math.round(minutes / 60);
|
|
5846
|
+
if (hours < 24) return `${hours}h ago`;
|
|
5847
|
+
const days = Math.round(hours / 24);
|
|
5848
|
+
if (days < 30) return `${days}d ago`;
|
|
5849
|
+
const months = Math.round(days / 30);
|
|
5850
|
+
if (months < 12) return `${months}mo ago`;
|
|
5851
|
+
const years = Math.round(months / 12);
|
|
5852
|
+
return `${years}y ago`;
|
|
5853
|
+
} catch {
|
|
5854
|
+
return "\u2014";
|
|
5855
|
+
}
|
|
5856
|
+
}
|
|
5857
|
+
function formatDate(ts) {
|
|
5858
|
+
if (!ts || typeof ts !== "number") return null;
|
|
5859
|
+
try {
|
|
5860
|
+
const ms = ts < 1e12 ? ts * 1e3 : ts;
|
|
5861
|
+
const d = new Date(ms);
|
|
5862
|
+
return d.toLocaleDateString();
|
|
5863
|
+
} catch {
|
|
5864
|
+
return null;
|
|
5865
|
+
}
|
|
5866
|
+
}
|
|
5867
|
+
function formatDateTime(ts) {
|
|
5868
|
+
if (!ts || typeof ts !== "number") return null;
|
|
5869
|
+
try {
|
|
5870
|
+
const ms = ts < 1e12 ? ts * 1e3 : ts;
|
|
5871
|
+
const d = new Date(ms);
|
|
5872
|
+
return d.toLocaleString();
|
|
5873
|
+
} catch {
|
|
5874
|
+
return null;
|
|
5875
|
+
}
|
|
5876
|
+
}
|
|
5877
|
+
module2.exports = {
|
|
5878
|
+
relativeTime,
|
|
5879
|
+
formatDate,
|
|
5880
|
+
formatDateTime
|
|
5881
|
+
};
|
|
5882
|
+
}
|
|
5883
|
+
});
|
|
5884
|
+
|
|
5627
5885
|
// src/treasury/index.js
|
|
5628
5886
|
var require_treasury = __commonJS({
|
|
5629
5887
|
"src/treasury/index.js"(exports2, module2) {
|
|
@@ -9188,6 +9446,7 @@ var require_src = __commonJS({
|
|
|
9188
9446
|
var subgraph = require_subgraph();
|
|
9189
9447
|
var privateTx = require_privateTx();
|
|
9190
9448
|
var safe = require_safe();
|
|
9449
|
+
var time = require_time();
|
|
9191
9450
|
var treasury = require_treasury();
|
|
9192
9451
|
var boost = require_boost();
|
|
9193
9452
|
var bounty = require_bounty();
|
|
@@ -9235,7 +9494,7 @@ var require_src = __commonJS({
|
|
|
9235
9494
|
boost,
|
|
9236
9495
|
// bond module removed; bonds deprecated in CLI/SDK
|
|
9237
9496
|
subgraph,
|
|
9238
|
-
utils: { ...utils, privateTx, safe },
|
|
9497
|
+
utils: { ...utils, privateTx, safe, time },
|
|
9239
9498
|
bounty,
|
|
9240
9499
|
wallet: Object.assign(wallet, {
|
|
9241
9500
|
cast: walletCastManager,
|